cangku/backend/src/api/productCodeBoard.js

160 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const multer = require('multer');
const {
getProductCodeMeta,
getProductCodeSequence,
listProductCodes,
buildProductCodeBatchImportTemplateBuffer,
buildProductCodeExportBuffer,
createProductCodes,
createProductCodeBatch,
importProductCodeBatchWorkbook,
} = require('../services/productCodeBoard');
const router = express.Router();
const productCodeBatchImportUpload = multer({
storage: multer.memoryStorage(),
limits: {
fileSize: 10 * 1024 * 1024,
},
fileFilter: (_req, file, callback) => {
const lowerName = String(file.originalname || '').toLowerCase();
if (lowerName.endsWith('.xlsx') || lowerName.endsWith('.xls')) {
callback(null, true);
return;
}
callback(new Error('仅支持上传 Excel 文件(.xlsx / .xls)'));
},
});
function sendError(res, error, fallbackMessage) {
const status = error.status || error.statusCode || 500;
res.status(status).json({
success: false,
error: error.message || fallbackMessage,
});
}
router.get('/meta', async (_req, res) => {
try {
const data = await getProductCodeMeta();
res.json({
success: true,
data,
});
} catch (error) {
sendError(res, error, '获取编码规则失败');
}
});
router.get('/sequence', async (req, res) => {
try {
const data = await getProductCodeSequence({
operationCenter: req.query.operationCenter,
categoryName: req.query.categoryName,
});
res.json({ success: true, data });
} catch (error) {
sendError(res, error, '获取编码序号失败');
}
});
router.get('/items', async (req, res) => {
try {
const data = await listProductCodes({
page: req.query.page,
pageSize: req.query.pageSize,
keyword: req.query.keyword,
operationCenter: req.query.operationCenter,
categoryName: req.query.categoryName,
productStatus: req.query.productStatus,
createdByNames: req.query.createdByNames,
createdAtStart: req.query.createdAtStart,
createdAtEnd: req.query.createdAtEnd,
});
res.json({ success: true, data });
} catch (error) {
sendError(res, error, '获取商品编码看板失败');
}
});
router.get('/items/export', async (req, res) => {
try {
const { buffer, totalRows } = await buildProductCodeExportBuffer({
keyword: req.query.keyword,
operationCenter: req.query.operationCenter,
categoryName: req.query.categoryName,
productStatus: req.query.productStatus,
createdByNames: req.query.createdByNames,
createdAtStart: req.query.createdAtStart,
createdAtEnd: req.query.createdAtEnd,
});
const fileName = encodeURIComponent('测款数据导出.xlsx');
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${fileName}`);
res.setHeader('X-Export-Count', String(totalRows));
res.send(buffer);
} catch (error) {
sendError(res, error, '导出测款数据失败');
}
});
router.get('/batch-template', (_req, res) => {
try {
const buffer = buildProductCodeBatchImportTemplateBuffer();
const fileName = encodeURIComponent('测款批量新增模板.xlsx');
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${fileName}`);
res.send(buffer);
} catch (error) {
sendError(res, error, '下载批量导入模板失败');
}
});
router.post('/items', async (req, res) => {
try {
const data = await createProductCodes(req.body, req.user || {});
res.json({ success: true, data });
} catch (error) {
sendError(res, error, '新增商品编码失败');
}
});
router.post('/items/batch', async (req, res) => {
try {
const data = await createProductCodeBatch(req.body, req.user || {});
res.json({ success: true, data });
} catch (error) {
sendError(res, error, '批量新增商品编码失败');
}
});
router.post('/items/batch-import', (req, res, next) => {
productCodeBatchImportUpload.single('file')(req, res, (error) => {
if (error) {
return res.status(400).json({ success: false, error: error.message || '上传文件失败' });
}
return next();
});
}, async (req, res) => {
try {
if (!req.file?.buffer) {
return res.status(400).json({ success: false, error: '请上传批量新增 Excel 文件' });
}
const data = await importProductCodeBatchWorkbook(req.file.buffer, {
operationCenter: req.body.operationCenter,
categoryName: req.body.categoryName,
}, req.user || {});
res.json({
success: true,
message: `已导入 ${data.productCount || data.importedProductCount || 0} 个商品、${data.skuCount || data.importedSkuCount || 0} 个规格`,
data,
});
} catch (error) {
sendError(res, error, '批量导入商品失败');
}
});
module.exports = router;