const express = require('express'); const router = express.Router(); const Payment = require('../models/Payment'); const { authMiddleware, requireRole } = require('../middleware/auth'); // 获取收支明细(仅 admin) router.get('/', authMiddleware, requireRole('admin'), async (req, res) => { try { const { type, startDate, endDate, party } = req.query; const filter = {}; if (type) filter.type = type; if (party) filter.party = new RegExp(party, 'i'); if (startDate || endDate) { filter.createdAt = {}; if (startDate) filter.createdAt.$gte = new Date(startDate); if (endDate) filter.createdAt.$lte = new Date(endDate); } const payments = await Payment.find(filter).sort('-createdAt').limit(100); let totalIncome = 0; let totalExpense = 0; const incomeMap = {}; const expenseMap = {}; const allPayments = await Payment.find(filter); for (const p of allPayments) { if (['income', '收入', '租金收入', '押金退还', '租金'].includes(p.type)) { totalIncome += p.amount; incomeMap[p.category || '其他'] = (incomeMap[p.category || '其他'] || 0) + p.amount; } else { totalExpense += p.amount; expenseMap[p.category || '其他'] = (expenseMap[p.category || '其他'] || 0) + p.amount; } } res.json({ success: true, data: { list: payments, summary: { totalIncome, totalExpense, balance: totalIncome - totalExpense }, incomeByCategory: incomeMap, expenseByCategory: expenseMap } }); } catch (error) { res.status(500).json({ success: false, message: error.message }); } }); // 创建收支记录(仅 admin) router.post('/', authMiddleware, requireRole('admin'), async (req, res) => { try { const payment = new Payment(req.body); await payment.save(); res.json({ success: true, data: payment }); } catch (error) { res.status(400).json({ success: false, message: error.message }); } }); // 更新收支记录(仅 admin) router.put('/:id', authMiddleware, requireRole('admin'), async (req, res) => { try { const payment = await Payment.findByIdAndUpdate(req.params.id, req.body, { new: true }); res.json({ success: true, data: payment }); } catch (error) { res.status(400).json({ success: false, message: error.message }); } }); // 删除收支记录(仅 admin) router.delete('/:id', authMiddleware, requireRole('admin'), async (req, res) => { try { await Payment.findByIdAndDelete(req.params.id); res.json({ success: true }); } catch (error) { res.status(400).json({ success: false, message: error.message }); } }); // 清空所有收支记录(仅 admin) router.post('/delete-all', authMiddleware, requireRole('admin'), async (req, res) => { try { await Payment.deleteMany({}); res.json({ success: true, message: 'All payments deleted' }); } catch (error) { res.status(400).json({ success: false, message: error.message }); } }); // 收支统计(仅 admin) router.get('/stats', authMiddleware, requireRole('admin'), async (req, res) => { try { const { period = 'month' } = req.query; let startDate; const now = new Date(); switch (period) { case 'week': startDate = new Date(now - 7 * 24 * 60 * 60 * 1000); break; case 'month': startDate = new Date(now.getFullYear(), now.getMonth(), 1); break; case 'quarter': startDate = new Date(now.getFullYear(), Math.floor(now.getMonth() / 3) * 3, 1); break; case 'year': startDate = new Date(now.getFullYear(), 0, 1); break; default: startDate = new Date(now.getFullYear(), now.getMonth(), 1); } const incomeAgg = await Payment.aggregate([ { $match: { type: '收入', createdAt: { $gte: startDate } } }, { $group: { _id: null, total: { $sum: '$amount' } } } ]); const expenseAgg = await Payment.aggregate([ { $match: { type: '支出', createdAt: { $gte: startDate } } }, { $group: { _id: null, total: { $sum: '$amount' } } } ]); const incomeByCategory = await Payment.aggregate([ { $match: { type: '收入', createdAt: { $gte: startDate } } }, { $group: { _id: '$category', total: { $sum: '$amount' } } } ]); const expenseByCategory = await Payment.aggregate([ { $match: { type: '支出', createdAt: { $gte: startDate } } }, { $group: { _id: '$category', total: { $sum: '$amount' } } } ]); const totalIncome = incomeAgg[0]?.total || 0; const totalExpense = expenseAgg[0]?.total || 0; res.json({ success: true, data: { income: totalIncome, expense: totalExpense, balance: totalIncome - totalExpense, incomeByCategory: incomeByCategory.reduce((acc, item) => { acc[item._id || '其他'] = item.total; return acc; }, {}), expenseByCategory: expenseByCategory.reduce((acc, item) => { acc[item._id || '其他'] = item.total; return acc; }, {}) } }); } catch (error) { res.status(500).json({ success: false, message: error.message }); } }); module.exports = router;