const express = require('express'); const db = require('../utils/database'); const { authenticateToken, requireAdmin } = require('../middleware/auth'); const router = express.Router(); // 获取企业列表 router.get('/', authenticateToken, requireAdmin, async (req, res) => { try { const { page = 1, limit = 20, search = '' } = req.query; const offset = (page - 1) * limit; let query = ` SELECT c.company_name, c.created_at as first_created, c.updated_at as last_created, c.is_active, (SELECT COUNT(*) FROM serials s WHERE s.company_name = c.company_name) as serial_count, (SELECT COUNT(*) FROM serials s WHERE s.company_name = c.company_name AND s.is_active = 1) as active_count FROM companies c `; let countQuery = 'SELECT COUNT(*) as total FROM companies'; let params = []; if (search) { query += ' WHERE c.company_name LIKE ?'; countQuery += ' WHERE company_name LIKE ?'; params.push(`%${search}%`); } query += ' ORDER BY c.updated_at DESC LIMIT ? OFFSET ?'; params.push(parseInt(limit), parseInt(offset)); const [companies, countResult] = await Promise.all([ db.all(query, params), db.get(countQuery, params.slice(0, -2)) ]); const total = countResult ? countResult.total : 0; const totalPages = Math.ceil(total / limit); res.json({ message: '获取企业列表成功', data: companies.map(company => ({ companyName: company.company_name, firstCreated: company.first_created, lastCreated: company.last_created, serialCount: company.serial_count, activeCount: company.active_count, status: company.is_active ? 'active' : 'disabled' })), pagination: { page: parseInt(page), limit: parseInt(limit), total, totalPages } }); } catch (error) { console.error('获取企业列表错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); // 获取企业详情 router.get('/:companyName', authenticateToken, requireAdmin, async (req, res) => { try { const { companyName } = req.params; const decodedCompanyName = decodeURIComponent(companyName); const { page = 1, limit = 20 } = req.query; const offset = (page - 1) * limit; // 获取企业基本信息 const companyInfo = await db.get('SELECT * FROM companies WHERE company_name = ?', [decodedCompanyName]); if (!companyInfo) { return res.status(404).json({ error: '企业不存在' }); } // 获取序列号统计信息 const serialStats = await db.get(` SELECT COUNT(*) as serial_count, SUM(CASE WHEN is_active = 1 THEN 1 ELSE 0 END) as active_count, SUM(CASE WHEN is_active = 0 THEN 1 ELSE 0 END) as disabled_count, SUM(CASE WHEN valid_until IS NOT NULL AND valid_until <= datetime('now') THEN 1 ELSE 0 END) as expired_count FROM serials WHERE company_name = ? `, [decodedCompanyName]); // 获取企业的序列号列表 const serials = await db.all(` SELECT s.*, u.name as created_by_name FROM serials s LEFT JOIN users u ON s.created_by = u.id WHERE s.company_name = ? ORDER BY s.created_at DESC LIMIT ? OFFSET ? `, [decodedCompanyName, parseInt(limit), parseInt(offset)]); // 获取统计数据 const stats = await db.all(` SELECT strftime('%Y-%m', created_at) as month, COUNT(*) as count FROM serials WHERE company_name = ? GROUP BY strftime('%Y-%m', created_at) ORDER BY month DESC LIMIT 12 `, [decodedCompanyName]); res.json({ message: '获取企业详情成功', data: { companyName: decodedCompanyName, serialCount: serialStats?.serial_count || 0, activeCount: serialStats?.active_count || 0, disabledCount: serialStats?.disabled_count || 0, expiredCount: serialStats?.expired_count || 0, firstCreated: companyInfo.created_at, lastCreated: companyInfo.updated_at, status: companyInfo.is_active ? 'active' : 'disabled', serials: serials.map(s => ({ serialNumber: s.serial_number, validUntil: s.valid_until, isActive: s.is_active, createdAt: s.created_at, createdBy: s.created_by_name })), monthlyStats: stats.map(stat => ({ month: stat.month, count: stat.count })) } }); } catch (error) { console.error('获取企业详情错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); // 更新企业信息 router.patch('/:companyName', authenticateToken, requireAdmin, async (req, res) => { try { const { companyName } = req.params; const decodedCompanyName = decodeURIComponent(companyName); const { newCompanyName } = req.body; if (!newCompanyName || newCompanyName.trim() === '') { return res.status(400).json({ error: '新企业名称不能为空' }); } // 检查企业是否存在 const existingCompany = db.get( 'SELECT COUNT(*) as count FROM serials WHERE company_name = ?', [decodedCompanyName] ); if (!existingCompany || existingCompany.count === 0) { return res.status(404).json({ error: '企业不存在' }); } // 检查新企业名称是否已存在 const duplicateCompany = db.get( 'SELECT COUNT(*) as count FROM serials WHERE company_name = ?', [newCompanyName] ); if (duplicateCompany && duplicateCompany.count > 0) { return res.status(400).json({ error: '企业名称已存在' }); } // 更新企业名称 db.run( 'UPDATE serials SET company_name = ?, updated_at = CURRENT_TIMESTAMP WHERE company_name = ?', [newCompanyName, decodedCompanyName] ); res.json({ message: '企业名称更新成功', data: { oldCompanyName: decodedCompanyName, newCompanyName } }); } catch (error) { console.error('更新企业信息错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); // 删除企业(物理删除,完全删除企业和所有序列号) router.delete('/:companyName', authenticateToken, requireAdmin, async (req, res) => { try { const { companyName } = req.params; console.log('原始参数:', companyName); const decodedCompanyName = decodeURIComponent(companyName); console.log('解码后参数:', decodedCompanyName); // 检查企业是否存在 const existingCompany = await db.get( 'SELECT * FROM companies WHERE company_name = ?', [decodedCompanyName] ); if (!existingCompany) { return res.status(404).json({ error: '企业不存在' }); } // 开始事务 db.run('BEGIN TRANSACTION'); try { // 删除该企业的所有序列号 const serialDeleteResult = db.run( 'DELETE FROM serials WHERE company_name = ?', [decodedCompanyName] ); console.log('删除序列号结果:', serialDeleteResult); // 删除企业记录 const companyDeleteResult = db.run( 'DELETE FROM companies WHERE company_name = ?', [decodedCompanyName] ); console.log('删除企业结果:', companyDeleteResult); if (companyDeleteResult.changes === 0) { db.run('ROLLBACK'); return res.status(404).json({ error: '企业不存在' }); } db.run('COMMIT'); res.json({ message: '企业已完全删除,所有相关序列号已删除', data: { companyName: decodedCompanyName, deletedSerialCount: serialDeleteResult.changes, deletedCompanyCount: companyDeleteResult.changes } }); } catch (error) { console.error('删除企业过程中错误:', error); db.run('ROLLBACK'); throw error; } } catch (error) { console.error('删除企业错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); // 获取企业统计数据 router.get('/stats/overview', authenticateToken, requireAdmin, async (req, res) => { try { // 获取总企业数 const companyCount = await db.get('SELECT COUNT(*) as count FROM companies'); // 获取总序列号数 const serialCount = await db.get('SELECT COUNT(*) as count FROM serials'); // 获取活跃序列号数 const activeCount = await db.get(` SELECT COUNT(*) as count FROM serials WHERE is_active = 1 AND (valid_until IS NULL OR valid_until > datetime('now')) `); // 按月份统计 - 使用正确的日期格式 const monthlyStats = await db.all(` SELECT strftime('%Y-%m', created_at) as month, COUNT(DISTINCT company_name) as company_count, COUNT(*) as serial_count FROM serials WHERE created_at >= strftime('%Y-%m-%d', datetime('now', '-12 months')) GROUP BY strftime('%Y-%m', created_at) ORDER BY month ASC `); // 获取最新添加的企业 const recentCompanies = await db.all(` SELECT c.company_name, c.created_at as last_created, c.is_active FROM companies c ORDER BY c.updated_at DESC LIMIT 10 `); // 获取最近生成的序列号 const recentSerials = await db.all(` SELECT s.serial_number, s.company_name, s.is_active, s.created_at FROM serials s ORDER BY s.created_at DESC LIMIT 10 `); // 如果没有数据,生成过去12个月的空数据 if (monthlyStats.length === 0) { const now = new Date(); for (let i = 11; i >=0; i--) { const date = new Date(now.getFullYear(), now.getMonth() - i, 1); const month = date.toISOString().substr(0, 7); monthlyStats.push({ month, company_count: 0, serial_count: 0 }); } } res.json({ message: '获取统计数据成功', data: { overview: { totalCompanies: companyCount.count || 0, totalSerials: serialCount.count || 0, activeSerials: activeCount.count || 0, inactiveSerials: (serialCount.count || 0) - (activeCount.count || 0) }, monthlyStats: monthlyStats.map(stat => ({ month: stat.month, company_count: stat.company_count, serial_count: stat.serial_count })), recentCompanies: recentCompanies.map(c => ({ companyName: c.company_name, lastCreated: c.last_created, status: c.is_active ? 'active' : 'disabled' })), recentSerials: recentSerials.map(s => ({ serialNumber: s.serial_number, companyName: s.company_name, isActive: s.is_active, createdAt: s.created_at })) } }); } catch (error) { console.error('获取统计数据错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); // 吊销单个序列号 router.delete('/:companyName/serials/:serialNumber', authenticateToken, requireAdmin, async (req, res) => { try { const { companyName, serialNumber } = req.params; // 检查序列号是否存在且属于该企业 const serial = await db.get( 'SELECT * FROM serials WHERE serial_number = ? AND company_name = ?', [serialNumber.toUpperCase(), companyName] ); if (!serial) { return res.status(404).json({ error: '序列号不存在或不属于该企业' }); } // 物理删除序列号 await db.run( 'DELETE FROM serials WHERE serial_number = ? AND company_name = ?', [serialNumber.toUpperCase(), companyName] ); res.json({ message: '序列号已成功吊删除', data: { serialNumber: serial.serial_number, companyName } }); } catch (error) { console.error('吊销序列号错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); // 吊销企业 router.post('/:companyName/revoke', authenticateToken, requireAdmin, async (req, res) => { try { const { companyName } = req.params; const decodedCompanyName = decodeURIComponent(companyName); // 检查企业是否存在 const existingCompany = await db.get( 'SELECT COUNT(*) as count FROM serials WHERE company_name = ?', [decodedCompanyName] ); if (!existingCompany || existingCompany.count === 0) { return res.status(404).json({ error: '企业不存在' }); } // 吊销该企业的所有序列号(将 is_active 设为 0) await db.run( 'UPDATE serials SET is_active = 0, updated_at = CURRENT_TIMESTAMP WHERE company_name = ?', [decodedCompanyName] ); res.json({ message: '企业已吊销,所有序列号已失效', data: { companyName: decodedCompanyName } }); } catch (error) { console.error('吊销企业错误:', error); res.status(500).json({ error: '服务器内部错误' }); } }); module.exports = router;