160 lines
4.9 KiB
JavaScript
160 lines
4.9 KiB
JavaScript
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;
|