perf: 优化数据库查询和前端代码质量
- 添加 records 表常用字段索引提升查询性能 - 合并月度/老板/陪玩记录查询减少数据库往返 - 提取重复的横向柱状图渲染逻辑为通用函数 - 移除调试用的 console.log 语句 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
14927f74aa
commit
0b450a65ed
@@ -32,6 +32,14 @@ db.exec(`
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_records_user_id ON records(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_category ON records(category);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_created_at ON records(created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_type ON records(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_boss ON records(boss);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_partner ON records(partner);
|
||||
CREATE INDEX IF NOT EXISTS idx_records_source ON records(source);
|
||||
`);
|
||||
|
||||
// 迁移:去掉 category 的 CHECK 约束
|
||||
|
||||
+28
-46
@@ -40,23 +40,19 @@ router.get('/monthly-records', (req, res) => {
|
||||
const { startDate, endDate } = getMonthRange(req.query.year, req.query.month);
|
||||
const offset = (Number(page) - 1) * Number(limit);
|
||||
|
||||
const summary = db.prepare(`
|
||||
SELECT COALESCE(SUM(amount), 0) as total
|
||||
// 合并 summary 和 total 为一次查询
|
||||
const stats = db.prepare(`
|
||||
SELECT COALESCE(SUM(amount), 0) as total, COUNT(*) as count
|
||||
FROM records WHERE user_id = ? AND type = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
|
||||
`).get(req.user.id, type, startDate, endDate);
|
||||
|
||||
const total = db.prepare(`
|
||||
SELECT COUNT(*) as count FROM records
|
||||
WHERE user_id = ? AND type = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
|
||||
`).get(req.user.id, type, startDate, endDate).count;
|
||||
|
||||
const records = db.prepare(`
|
||||
SELECT * FROM records
|
||||
WHERE user_id = ? AND type = ? AND DATE(created_at, 'localtime') >= ? AND DATE(created_at, 'localtime') < ?
|
||||
ORDER BY created_at DESC LIMIT ? OFFSET ?
|
||||
`).all(req.user.id, type, startDate, endDate, Number(limit), offset);
|
||||
|
||||
res.json({ total: summary.total, records, page: Number(page), limit: Number(limit), totalCount: total });
|
||||
res.json({ total: stats.total, records, page: Number(page), limit: Number(limit), totalCount: stats.count });
|
||||
});
|
||||
|
||||
// 年度净收入按年统计
|
||||
@@ -256,40 +252,32 @@ router.get('/boss-records', (req, res) => {
|
||||
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'${dateFilter}
|
||||
`).get(req.user.id, boss, ...dateParams);
|
||||
|
||||
const expenseSummary = db.prepare(`
|
||||
// 合并 summary 查询为一次
|
||||
const summary = db.prepare(`
|
||||
SELECT
|
||||
COALESCE(SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END), 0) as my_income,
|
||||
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,
|
||||
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
|
||||
COALESCE(SUM(CASE WHEN category = '接单' THEN quantity ELSE 0 END), 0) as take_count,
|
||||
COUNT(*) as 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) = ?${dateFilter}
|
||||
`).get(req.user.id, boss, ...dateParams).count;
|
||||
|
||||
const records = db.prepare(`
|
||||
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,
|
||||
my_income: summary.my_income,
|
||||
boss_total_expense: summary.dispatch_expense + summary.order_expense + summary.redEnvelope_expense,
|
||||
take_count: summary.take_count,
|
||||
dispatch_count: summary.dispatch_count,
|
||||
records,
|
||||
page: Number(page),
|
||||
limit: Number(limit),
|
||||
totalCount: total
|
||||
totalCount: summary.count
|
||||
});
|
||||
});
|
||||
|
||||
@@ -310,26 +298,19 @@ router.get('/partner-records', (req, res) => {
|
||||
dateParams = [startDate, endDate];
|
||||
}
|
||||
|
||||
const dispatchStats = db.prepare(`
|
||||
// 合并 summary 查询为一次
|
||||
const summary = 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 = ?${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 = ?${dateFilter}
|
||||
`).get(req.user.id, partner, ...dateParams);
|
||||
|
||||
const total = db.prepare(`
|
||||
SELECT COUNT(*) as count FROM records
|
||||
WHERE user_id = ? AND (
|
||||
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity ELSE 0 END), 0) as dispatch_count,
|
||||
COALESCE(SUM(CASE WHEN category = '派单' THEN quantity * (COALESCE(unit_price, 0) - COALESCE(rebate, amount * 1.0 / CASE WHEN quantity > 0 THEN quantity ELSE 1 END)) ELSE 0 END), 0) as spread_income,
|
||||
COALESCE(SUM(CASE WHEN category = '派单' THEN amount ELSE 0 END), 0) as rebate_income,
|
||||
COALESCE(SUM(CASE WHEN type = 'income' AND category != '派单' AND category != '接单' AND source = ? THEN amount ELSE 0 END), 0) as other_income,
|
||||
COUNT(*) as count
|
||||
FROM records WHERE user_id = ? AND (
|
||||
(category = '派单' AND partner = ?) OR
|
||||
(type = 'income' AND category != '派单' AND category != '接单' AND source = ?)
|
||||
)${dateFilter}
|
||||
`).get(req.user.id, partner, partner, ...dateParams).count;
|
||||
`).get(partner, req.user.id, partner, ...dateParams);
|
||||
|
||||
const records = db.prepare(`
|
||||
SELECT * FROM records
|
||||
@@ -341,13 +322,14 @@ router.get('/partner-records', (req, res) => {
|
||||
|
||||
res.json({
|
||||
dispatch_count: dispatchStats.dispatch_count,
|
||||
spread_income: dispatchStats.spread_income,
|
||||
rebate_income: dispatchStats.rebate_income,
|
||||
other_income: otherIncome.total,
|
||||
dispatch_count: summary.dispatch_count,
|
||||
spread_income: summary.spread_income,
|
||||
rebate_income: summary.rebate_income,
|
||||
other_income: summary.other_income,
|
||||
records,
|
||||
page: Number(page),
|
||||
limit: Number(limit),
|
||||
totalCount: total
|
||||
totalCount: summary.count
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user