fix: 修复柱状图高度比例计算并添加月度筛选功能

- 修复最近7天收入柱状图高度使用百分比导致比例失真问题,改为像素计算
- 老板/陪玩交易详情页添加"全部/当月"切换按钮
- 老板/陪玩交易详情页添加月度导航切换功能
- 老板/陪玩交易详情页添加自动加载更多数据功能

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lizhilun
2026-03-19 10:13:02 +08:00
co-authored by Claude Opus 4.6
parent 3d8d03a66e
commit 14927f74aa
4 changed files with 380 additions and 75 deletions
+43 -22
View File
@@ -242,39 +242,50 @@ router.get('/total', (req, res) => {
// 老板交易记录
router.get('/boss-records', (req, res) => {
const boss = req.query.boss;
const { page = 1, limit = 20 } = req.query;
const { page = 1, limit = 20, year, month } = req.query;
if (!boss) return res.status(400).json({ error: '缺少老板参数' });
const offset = (Number(page) - 1) * Number(limit);
// 我的收入:只统计 type='income' 的记录(接单、派单返点、红包收入等)
// 使用 COALESCE(boss, source) 兼容旧数据(之前的红包收入只有 source 字段)
// 日期过滤条件
let dateFilter = '';
let dateParams = [];
if (year && month) {
const startDate = `${year}-${String(month).padStart(2, '0')}-01`;
const endDate = `${year}-${String(month).padStart(2, '0')}-31`;
dateFilter = ` AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') <= ?`;
dateParams = [startDate, endDate];
}
const myIncomeSummary = db.prepare(`
SELECT COALESCE(SUM(amount), 0) as total
FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? AND type = 'income'
`).get(req.user.id, boss);
FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? AND type = 'income'${dateFilter}
`).get(req.user.id, boss, ...dateParams);
// 老板支出:派单支出 + 接单支出 + 红包收入(老板发的红包也算老板支出)
const expenseSummary = db.prepare(`
SELECT
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity * COALESCE(unit_price, 0) ELSE 0 END), 0) as dispatch_expense,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity * COALESCE(unit_price, 0) ELSE 0 END), 0) as order_expense,
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_expense
FROM records WHERE user_id = ? AND COALESCE(boss, source) = ?
`).get(req.user.id, boss);
COALESCE(SUM(CASE WHEN category = '红包收入' THEN amount ELSE 0 END), 0) as redEnvelope_expense,
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count
FROM records WHERE user_id = ? AND COALESCE(boss, source) = ?${dateFilter}
`).get(req.user.id, boss, ...dateParams);
const boss_total_expense = expenseSummary.dispatch_expense + expenseSummary.order_expense + expenseSummary.redEnvelope_expense;
const total = db.prepare(`
SELECT COUNT(*) as count FROM records WHERE user_id = ? AND COALESCE(boss, source) = ?
`).get(req.user.id, boss).count;
SELECT COUNT(*) as count FROM records WHERE user_id = ? AND COALESCE(boss, source) = ?${dateFilter}
`).get(req.user.id, boss, ...dateParams).count;
const records = db.prepare(`
SELECT * FROM records WHERE user_id = ? AND COALESCE(boss, source) = ? ORDER BY created_at DESC LIMIT ? OFFSET ?
`).all(req.user.id, boss, Number(limit), offset);
SELECT * FROM records WHERE user_id = ? AND COALESCE(boss, source) = ?${dateFilter} ORDER BY created_at DESC LIMIT ? OFFSET ?
`).all(req.user.id, boss, ...dateParams, Number(limit), offset);
res.json({
my_income: myIncomeSummary.total,
boss_total_expense: boss_total_expense,
take_count: expenseSummary.take_count,
dispatch_count: expenseSummary.dispatch_count,
records,
page: Number(page),
limit: Number(limit),
@@ -285,38 +296,48 @@ router.get('/boss-records', (req, res) => {
// 陪玩交易记录
router.get('/partner-records', (req, res) => {
const partner = req.query.partner;
const { page = 1, limit = 20 } = req.query;
const { page = 1, limit = 20, year, month } = req.query;
if (!partner) return res.status(400).json({ error: '缺少陪玩参数' });
const offset = (Number(page) - 1) * Number(limit);
// 日期过滤条件
let dateFilter = '';
let dateParams = [];
if (year && month) {
const startDate = `${year}-${String(month).padStart(2, '0')}-01`;
const endDate = `${year}-${String(month).padStart(2, '0')}-31`;
dateFilter = ` AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') <= ?`;
dateParams = [startDate, endDate];
}
const dispatchStats = db.prepare(`
SELECT
COALESCE(SUM(quantity), 0) as dispatch_count,
COALESCE(SUM(quantity * (COALESCE(unit_price, 0) - COALESCE(rebate, amount * 1.0 / CASE WHEN quantity > 0 THEN quantity ELSE 1 END))), 0) as spread_income,
COALESCE(SUM(amount), 0) as rebate_income
FROM records WHERE user_id = ? AND category = '派单' AND partner = ?
`).get(req.user.id, partner);
FROM records WHERE user_id = ? AND category = '派单' AND partner = ?${dateFilter}
`).get(req.user.id, partner, ...dateParams);
const otherIncome = db.prepare(`
SELECT COALESCE(SUM(amount), 0) as total
FROM records WHERE user_id = ? AND type = 'income' AND category != '派单' AND category != '接单' AND source = ?
`).get(req.user.id, partner);
FROM records WHERE user_id = ? AND type = 'income' AND category != '派单' AND category != '接单' AND source = ?${dateFilter}
`).get(req.user.id, partner, ...dateParams);
const total = db.prepare(`
SELECT COUNT(*) as count FROM records
WHERE user_id = ? AND (
(category = '派单' AND partner = ?) OR
(type = 'income' AND category != '派单' AND category != '接单' AND source = ?)
)
`).get(req.user.id, partner, partner).count;
)${dateFilter}
`).get(req.user.id, partner, partner, ...dateParams).count;
const records = db.prepare(`
SELECT * FROM records
WHERE user_id = ? AND (
(category = '派单' AND partner = ?) OR
(type = 'income' AND category != '派单' AND category != '接单' AND source = ?)
) ORDER BY created_at DESC LIMIT ? OFFSET ?
`).all(req.user.id, partner, partner, Number(limit), offset);
)${dateFilter} ORDER BY created_at DESC LIMIT ? OFFSET ?
`).all(req.user.id, partner, partner, ...dateParams, Number(limit), offset);
res.json({
dispatch_count: dispatchStats.dispatch_count,