const express = require('express'); const router = express.Router(); const Joi = require('joi'); const { Supplier } = require('../models'); const { Sequelize } = require('sequelize'); // 验证schemas const supplierCreateSchema = Joi.object({ name: Joi.string().min(2).max(100).required(), code: Joi.string().min(3).max(20).required(), contact: Joi.string().min(2).max(50).required(), phone: Joi.string().pattern(/^1[3-9]\d{9}$/).required(), address: Joi.string().min(5).max(200).required(), businessLicense: Joi.string().max(255).optional(), qualificationLevel: Joi.string().valid('A+', 'A', 'B+', 'B', 'C').required(), certifications: Joi.array().items(Joi.string()).optional(), cattleTypes: Joi.array().items(Joi.string()).min(1).required(), capacity: Joi.number().integer().min(1).required(), region: Joi.string().valid('north', 'south', 'east', 'west', 'northeast', 'northwest', 'southeast', 'southwest', 'central').required() }); const supplierUpdateSchema = Joi.object({ name: Joi.string().min(2).max(100), contact: Joi.string().min(2).max(50), phone: Joi.string().pattern(/^1[3-9]\d{9}$/), address: Joi.string().min(5).max(200), businessLicense: Joi.string().max(255).optional(), qualificationLevel: Joi.string().valid('A+', 'A', 'B+', 'B', 'C'), certifications: Joi.array().items(Joi.string()).optional(), cattleTypes: Joi.array().items(Joi.string()).min(1), capacity: Joi.number().integer().min(1), region: Joi.string().valid('north', 'south', 'east', 'west', 'northeast', 'northwest', 'southeast', 'southwest', 'central'), status: Joi.string().valid('active', 'inactive', 'suspended') }); // 获取供应商列表 router.get('/', async (req, res) => { try { const { page = 1, pageSize = 20, keyword, region, qualificationLevel, status } = req.query; // 构建查询条件 const whereConditions = {}; // 状态筛选 if (status) { whereConditions.status = status; } // 区域筛选 if (region) { whereConditions.region = region; } // 资质等级筛选 if (qualificationLevel) { whereConditions.qualificationLevel = qualificationLevel; } // 关键词搜索 if (keyword) { whereConditions[Sequelize.Op.or] = [ { name: { [Sequelize.Op.like]: `%${keyword}%` } }, { code: { [Sequelize.Op.like]: `%${keyword}%` } }, { contact: { [Sequelize.Op.like]: `%${keyword}%` } } ]; } // 分页参数 const offset = (page - 1) * pageSize; const limit = parseInt(pageSize); // 查询数据库 const { rows, count } = await Supplier.findAndCountAll({ where: whereConditions, offset, limit, order: [['created_at', 'DESC']] }); // 解析JSON字段 const processedRows = rows.map(row => { const rowData = row.toJSON(); if (rowData.cattleTypes && typeof rowData.cattleTypes === 'string') { rowData.cattleTypes = JSON.parse(rowData.cattleTypes); } if (rowData.certifications && typeof rowData.certifications === 'string') { rowData.certifications = JSON.parse(rowData.certifications); } return rowData; }); res.json({ success: true, data: { list: processedRows, pagination: { page: parseInt(page), pageSize: limit, total: count, totalPages: Math.ceil(count / limit) } } }); } catch (error) { console.error('获取供应商列表失败:', error); res.status(500).json({ success: false, message: '获取供应商列表失败', error: error.message }); } }); // 获取供应商详情 router.get('/:id', async (req, res) => { try { const { id } = req.params; // 查询数据库 const supplier = await Supplier.findByPk(id); if (!supplier) { return res.status(404).json({ success: false, message: '供应商不存在' }); } // 解析JSON字段 const supplierData = supplier.toJSON(); if (supplierData.cattleTypes && typeof supplierData.cattleTypes === 'string') { supplierData.cattleTypes = JSON.parse(supplierData.cattleTypes); } if (supplierData.certifications && typeof supplierData.certifications === 'string') { supplierData.certifications = JSON.parse(supplierData.certifications); } res.json({ success: true, data: supplierData }); } catch (error) { console.error('获取供应商详情失败:', error); res.status(500).json({ success: false, message: '获取供应商详情失败', error: error.message }); } }); // 创建供应商 router.post('/', async (req, res) => { try { const { error, value } = supplierCreateSchema.validate(req.body); if (error) { return res.status(400).json({ success: false, message: '参数验证失败', errors: error.details.map(detail => detail.message) }); } // 检查编码是否重复 const existingSupplier = await Supplier.findOne({ where: { code: value.code } }); if (existingSupplier) { return res.status(400).json({ success: false, message: '供应商编码已存在' }); } // 检查电话是否重复 const existingPhone = await Supplier.findOne({ where: { phone: value.phone } }); if (existingPhone) { return res.status(400).json({ success: false, message: '供应商电话已存在' }); } // 创建新供应商 const newSupplier = await Supplier.create({ ...value, businessLicense: value.businessLicense || '', certifications: value.certifications ? JSON.stringify(value.certifications) : JSON.stringify([]), cattleTypes: JSON.stringify(value.cattleTypes), rating: 0, cooperationStartDate: new Date(), status: 'active' }); res.status(201).json({ success: true, message: '供应商创建成功', data: newSupplier }); } catch (error) { console.error('创建供应商失败:', error); res.status(500).json({ success: false, message: '创建供应商失败', error: error.message }); } }); // 更新供应商 router.put('/:id', async (req, res) => { try { const { id } = req.params; const { error, value } = supplierUpdateSchema.validate(req.body); if (error) { return res.status(400).json({ success: false, message: '参数验证失败', errors: error.details.map(detail => detail.message) }); } // 查找供应商 const supplier = await Supplier.findByPk(id); if (!supplier) { return res.status(404).json({ success: false, message: '供应商不存在' }); } // 如果更新了电话号码,检查是否重复 if (value.phone && value.phone !== supplier.phone) { const existingPhone = await Supplier.findOne({ where: { phone: value.phone } }); if (existingPhone) { return res.status(400).json({ success: false, message: '供应商电话已存在' }); } } // 更新供应商信息 await supplier.update({ ...value, businessLicense: value.businessLicense !== undefined ? value.businessLicense : undefined, certifications: value.certifications !== undefined ? JSON.stringify(value.certifications) : undefined, cattleTypes: value.cattleTypes ? JSON.stringify(value.cattleTypes) : undefined }); res.json({ success: true, message: '供应商更新成功', data: supplier }); } catch (error) { console.error('更新供应商失败:', error); res.status(500).json({ success: false, message: '更新供应商失败', error: error.message }); } }); // 删除供应商 router.delete('/:id', async (req, res) => { try { const { id } = req.params; // 查找供应商 const supplier = await Supplier.findByPk(id); if (!supplier) { return res.status(404).json({ success: false, message: '供应商不存在' }); } // 删除供应商 await supplier.destroy(); res.json({ success: true, message: '供应商删除成功' }); } catch (error) { console.error('删除供应商失败:', error); res.status(500).json({ success: false, message: '删除供应商失败', error: error.message }); } }); // 获取供应商统计信息 router.get('/stats/overview', async (req, res) => { try { // 获取总数和活跃数 const totalSuppliers = await Supplier.count(); const activeSuppliers = await Supplier.count({ where: { status: 'active' } }); // 获取平均评分(排除评分为0的供应商) const ratingResult = await Supplier.findOne({ attributes: [ [Sequelize.fn('AVG', Sequelize.col('rating')), 'averageRating'] ], where: { rating: { [Sequelize.Op.gt]: 0 } } }); const averageRating = ratingResult ? parseFloat(ratingResult.getDataValue('averageRating')).toFixed(2) : 0; // 获取总产能 const capacityResult = await Supplier.findOne({ attributes: [ [Sequelize.fn('SUM', Sequelize.col('capacity')), 'totalCapacity'] ] }); const totalCapacity = capacityResult ? capacityResult.getDataValue('totalCapacity') : 0; // 按等级统计 const levelStatsResult = await Supplier.findAll({ attributes: [ 'qualificationLevel', [Sequelize.fn('COUNT', Sequelize.col('id')), 'count'] ], group: ['qualificationLevel'] }); const levelStats = levelStatsResult.reduce((stats, item) => { stats[item.qualificationLevel] = item.getDataValue('count'); return stats; }, {}); // 按区域统计 const regionStatsResult = await Supplier.findAll({ attributes: [ 'region', [Sequelize.fn('COUNT', Sequelize.col('id')), 'count'] ], group: ['region'] }); const regionStats = regionStatsResult.reduce((stats, item) => { stats[item.region] = item.getDataValue('count'); return stats; }, {}); res.json({ success: true, data: { totalSuppliers, activeSuppliers, averageRating: parseFloat(averageRating), totalCapacity, levelStats, regionStats } }); } catch (error) { console.error('获取供应商统计信息失败:', error); res.status(500).json({ success: false, message: '获取供应商统计信息失败', error: error.message }); } }); // 批量操作供应商 router.post('/batch', async (req, res) => { try { const { ids, action } = req.body; if (!ids || !Array.isArray(ids) || ids.length === 0) { return res.status(400).json({ success: false, message: '请选择要操作的供应商' }); } if (!['activate', 'deactivate', 'delete'].includes(action)) { return res.status(400).json({ success: false, message: '无效的操作类型' }); } switch (action) { case 'activate': await Supplier.update( { status: 'active' }, { where: { id: ids } } ); break; case 'deactivate': await Supplier.update( { status: 'inactive' }, { where: { id: ids } } ); break; case 'delete': await Supplier.destroy({ where: { id: ids } }); break; } res.json({ success: true, message: '批量操作成功' }); } catch (error) { console.error('批量操作失败:', error); res.status(500).json({ success: false, message: '批量操作失败', error: error.message }); } }); module.exports = router;