e-scooter-rental-system/server/routes/finance.js

165 lines
4.8 KiB
JavaScript

const express = require('express');
const router = express.Router();
const Payment = require('../models/Payment');
// 获取收支明细列表
router.get('/', 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);
// 计算汇总 - 支持中英文
const income = await Payment.aggregate([
{ $match: { type: { $in: ['income', 'expense', '收入', '支出', '租金收入', '押金退还', '租金'] } } },
{ $group: { _id: '$type', total: { $sum: '$amount' } } }
]);
// 分开计算收入和支出
let totalIncome = 0;
let totalExpense = 0;
for (const item of income) {
if (item._id === 'income' || item._id === '收入' || item._id === '租金收入' || item._id === '押金退还' || item._id === '租金') {
totalIncome += item.total;
} else {
totalExpense += item.total;
}
}
res.json({
success: true,
data: {
list: payments,
summary: {
totalIncome: totalIncome,
totalExpense: totalExpense,
balance: totalIncome - totalExpense
}
}
});
} catch (error) {
res.status(500).json({ success: false, message: error.message });
}
});
// 创建收支记录
router.post('/', 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 });
}
});
// 更新收支记录
router.put('/:id', 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 });
}
});
// 删除收支记录
router.delete('/:id', 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 });
}
});
// 清空所有收支记录
router.post('/delete-all', 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 });
}
});
// 获取收支统计
router.get('/stats', 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 income = await Payment.aggregate([
{ $match: { type: '收入', createdAt: { $gte: startDate } } },
{ $group: { _id: null, total: { $sum: '$amount' } } }
]);
const expense = 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' } } }
]);
res.json({
success: true,
data: {
income: income[0]?.total || 0,
expense: expense[0]?.total || 0,
balance: (income[0]?.total || 0) - (expense[0]?.total || 0),
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;