165 lines
4.8 KiB
JavaScript
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;
|