const express = require('express'); const router = express.Router(); const Joi = require('joi'); // 模拟供应商数据 let suppliers = [ { id: 1, name: '山东优质牲畜合作社', code: 'SUP001', contact: '李经理', phone: '15888888888', address: '山东省济南市历城区牲畜养殖基地', businessLicense: 'SUP001_license.pdf', qualificationLevel: 'A', certifications: ['动物防疫合格证', '饲料生产许可证'], cattleTypes: ['肉牛', '奶牛'], capacity: 5000, rating: 4.8, cooperationStartDate: '2022-01-15', status: 'active', region: 'east', createdAt: new Date('2022-01-15'), updatedAt: new Date('2024-01-15') }, { id: 2, name: '内蒙古草原牲畜有限公司', code: 'SUP002', contact: '王总', phone: '13999999999', address: '内蒙古呼和浩特市草原牧场', businessLicense: 'SUP002_license.pdf', qualificationLevel: 'A+', certifications: ['有机认证', '绿色食品认证'], cattleTypes: ['草原牛', '黄牛'], capacity: 8000, rating: 4.9, cooperationStartDate: '2021-08-20', status: 'active', region: 'north', createdAt: new Date('2021-08-20'), updatedAt: new Date('2024-01-20') }, { id: 3, name: '四川高原牲畜养殖场', code: 'SUP003', contact: '张场长', phone: '18777777777', address: '四川省成都市高原养殖区', businessLicense: 'SUP003_license.pdf', qualificationLevel: 'B+', certifications: ['无公害产品认证'], cattleTypes: ['高原牛'], capacity: 3000, rating: 4.5, cooperationStartDate: '2022-06-10', status: 'active', region: 'southwest', createdAt: new Date('2022-06-10'), updatedAt: new Date('2024-01-10') } ]; // 验证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(), qualificationLevel: Joi.string().valid('A+', 'A', 'B+', 'B', 'C').required(), 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), qualificationLevel: Joi.string().valid('A+', 'A', 'B+', 'B', 'C'), 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('/', (req, res) => { try { const { page = 1, pageSize = 20, keyword, region, qualificationLevel, status = 'active' } = req.query; let filteredSuppliers = [...suppliers]; // 关键词搜索 if (keyword) { filteredSuppliers = filteredSuppliers.filter(supplier => supplier.name.includes(keyword) || supplier.code.includes(keyword) || supplier.contact.includes(keyword) ); } // 区域筛选 if (region) { filteredSuppliers = filteredSuppliers.filter(supplier => supplier.region === region); } // 资质等级筛选 if (qualificationLevel) { filteredSuppliers = filteredSuppliers.filter(supplier => supplier.qualificationLevel === qualificationLevel); } // 状态筛选 if (status) { filteredSuppliers = filteredSuppliers.filter(supplier => supplier.status === status); } // 分页处理 const startIndex = (page - 1) * pageSize; const endIndex = startIndex + parseInt(pageSize); const paginatedSuppliers = filteredSuppliers.slice(startIndex, endIndex); res.json({ success: true, data: { list: paginatedSuppliers, pagination: { page: parseInt(page), pageSize: parseInt(pageSize), total: filteredSuppliers.length, totalPages: Math.ceil(filteredSuppliers.length / pageSize) } } }); } catch (error) { res.status(500).json({ success: false, message: '获取供应商列表失败', error: error.message }); } }); // 获取供应商详情 router.get('/:id', (req, res) => { try { const { id } = req.params; const supplier = suppliers.find(s => s.id === parseInt(id)); if (!supplier) { return res.status(404).json({ success: false, message: '供应商不存在' }); } res.json({ success: true, data: supplier }); } catch (error) { res.status(500).json({ success: false, message: '获取供应商详情失败', error: error.message }); } }); // 创建供应商 router.post('/', (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 = suppliers.find(s => s.code === value.code); if (existingSupplier) { return res.status(400).json({ success: false, message: '供应商编码已存在' }); } const newSupplier = { id: Math.max(...suppliers.map(s => s.id)) + 1, ...value, businessLicense: '', certifications: [], rating: 0, cooperationStartDate: new Date().toISOString().split('T')[0], status: 'active', createdAt: new Date(), updatedAt: new Date() }; suppliers.push(newSupplier); res.status(201).json({ success: true, message: '供应商创建成功', data: newSupplier }); } catch (error) { res.status(500).json({ success: false, message: '创建供应商失败', error: error.message }); } }); // 更新供应商 router.put('/:id', (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 supplierIndex = suppliers.findIndex(s => s.id === parseInt(id)); if (supplierIndex === -1) { return res.status(404).json({ success: false, message: '供应商不存在' }); } suppliers[supplierIndex] = { ...suppliers[supplierIndex], ...value, updatedAt: new Date() }; res.json({ success: true, message: '供应商更新成功', data: suppliers[supplierIndex] }); } catch (error) { res.status(500).json({ success: false, message: '更新供应商失败', error: error.message }); } }); // 删除供应商 router.delete('/:id', (req, res) => { try { const { id } = req.params; const supplierIndex = suppliers.findIndex(s => s.id === parseInt(id)); if (supplierIndex === -1) { return res.status(404).json({ success: false, message: '供应商不存在' }); } suppliers.splice(supplierIndex, 1); res.json({ success: true, message: '供应商删除成功' }); } catch (error) { res.status(500).json({ success: false, message: '删除供应商失败', error: error.message }); } }); // 获取供应商统计信息 router.get('/stats/overview', (req, res) => { try { const totalSuppliers = suppliers.length; const activeSuppliers = suppliers.filter(s => s.status === 'active').length; const averageRating = suppliers.reduce((sum, s) => sum + s.rating, 0) / totalSuppliers; const totalCapacity = suppliers.reduce((sum, s) => sum + s.capacity, 0); // 按等级统计 const levelStats = suppliers.reduce((stats, supplier) => { stats[supplier.qualificationLevel] = (stats[supplier.qualificationLevel] || 0) + 1; return stats; }, {}); // 按区域统计 const regionStats = suppliers.reduce((stats, supplier) => { stats[supplier.region] = (stats[supplier.region] || 0) + 1; return stats; }, {}); res.json({ success: true, data: { totalSuppliers, activeSuppliers, averageRating: Math.round(averageRating * 10) / 10, totalCapacity, levelStats, regionStats } }); } catch (error) { res.status(500).json({ success: false, message: '获取供应商统计信息失败', error: error.message }); } }); // 批量操作 router.post('/batch', (req, res) => { try { const { action, ids } = req.body; if (!action || !Array.isArray(ids) || ids.length === 0) { return res.status(400).json({ success: false, message: '参数错误' }); } let affectedCount = 0; switch (action) { case 'activate': suppliers.forEach(supplier => { if (ids.includes(supplier.id)) { supplier.status = 'active'; supplier.updatedAt = new Date(); affectedCount++; } }); break; case 'deactivate': suppliers.forEach(supplier => { if (ids.includes(supplier.id)) { supplier.status = 'inactive'; supplier.updatedAt = new Date(); affectedCount++; } }); break; case 'delete': suppliers = suppliers.filter(supplier => { if (ids.includes(supplier.id)) { affectedCount++; return false; } return true; }); break; default: return res.status(400).json({ success: false, message: '不支持的操作类型' }); } res.json({ success: true, message: `批量${action}成功`, data: { affectedCount } }); } catch (error) { res.status(500).json({ success: false, message: '批量操作失败', error: error.message }); } }); module.exports = router;