perf: 优化数据库查询和前端代码质量

- 添加 records 表常用字段索引提升查询性能
- 合并月度/老板/陪玩记录查询减少数据库往返
- 提取重复的横向柱状图渲染逻辑为通用函数
- 移除调试用的 console.log 语句

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lizhilun
2026-03-19 10:22:15 +08:00
co-authored by Claude Opus 4.6
parent 14927f74aa
commit 0b450a65ed
4 changed files with 62 additions and 74 deletions
+26 -27
View File
@@ -265,24 +265,36 @@ async function loadBossRankingPreview() {
} catch (e) { console.error(e); }
}
function renderBossRankingPreview(rows) {
const container = document.getElementById('rankingPreviewList');
// 渲染横向柱状图排行榜的通用函数
function renderHBarRanking(rows, { containerId, getValue, getLabel, onClick, formatValue }) {
const container = document.getElementById(containerId);
if (!rows || rows.length === 0) {
container.innerHTML = '<div class="ranking-empty">暂无数据</div>';
return;
}
const max = Math.max(...rows.map(r => r.total_income), 1);
const max = Math.max(...rows.map(r => getValue(r)), 1);
container.innerHTML = rows.map((r, i) => {
const pct = Math.max((r.total_income / max) * 100, 2);
return `<div class="hbar-row" onclick="openBossDetail('${r.boss.replace(/'/g, "\\'")}', 'homePage')">
const pct = Math.max((getValue(r) / max) * 100, 2);
const label = getLabel(r).replace(/'/g, "\\'");
const value = formatValue ? formatValue(getValue(r)) : (getValue(r).toFixed ? getValue(r).toFixed(2) : getValue(r));
return `<div class="hbar-row" onclick="${onClick}(${JSON.stringify(label).replace(/"/g, '&quot;')}, 'homePage')">
<div class="hbar-index ${i < 3 ? 'top' : ''}">${i + 1}</div>
<div class="hbar-label" title="${r.boss}">${r.boss}</div>
<div class="hbar-label" title="${label}">${label}</div>
<div class="hbar-track"><div class="hbar-fill" style="width:${pct}%"></div></div>
<div class="hbar-value">${r.total_income.toFixed(2)}</div>
<div class="hbar-value">${value}</div>
</div>`;
}).join('');
}
function renderBossRankingPreview(rows) {
renderHBarRanking(rows, {
containerId: 'rankingPreviewList',
getValue: r => r.total_income,
getLabel: r => r.boss,
onClick: 'openBossDetail'
});
}
let currentBossName = '';
let bossDetailFrom = 'homePage';
let bossDetailYear = 0;
@@ -498,21 +510,13 @@ async function loadPartnerRankingPreview() {
}
function renderPartnerRankingPreview(rows) {
const container = document.getElementById('partnerRankingPreviewList');
if (!rows || rows.length === 0) {
container.innerHTML = '<div class="ranking-empty">暂无数据</div>';
return;
}
const max = Math.max(...rows.map(r => r.dispatch_count), 1);
container.innerHTML = rows.map((r, i) => {
const pct = Math.max((r.dispatch_count / max) * 100, 2);
return `<div class="hbar-row" onclick="openPartnerDetail('${r.partner.replace(/'/g, "\\'")}', 'homePage')">
<div class="hbar-index ${i < 3 ? 'top' : ''}">${i + 1}</div>
<div class="hbar-label" title="${r.partner}">${r.partner}</div>
<div class="hbar-track"><div class="hbar-fill" style="width:${pct}%"></div></div>
<div class="hbar-value">${r.dispatch_count}单</div>
</div>`;
}).join('');
renderHBarRanking(rows, {
containerId: 'partnerRankingPreviewList',
getValue: r => r.dispatch_count,
getLabel: r => r.partner,
onClick: 'openPartnerDetail',
formatValue: v => v + '单'
});
}
function openPartnerRankingPage() {
@@ -537,20 +541,15 @@ async function loadPartnerRankingDetail() {
params.push('endDate=' + formatLocalDate(d));
}
if (params.length) url += '?' + params.join('&');
console.log('partner-ranking url:', url);
try {
const res = await fetch(url, { headers: headers() });
console.log('partner-ranking res.ok:', res.ok);
if (!res.ok) return;
const data = await res.json();
console.log('partner-ranking data:', data);
const rows = data.rows || [];
console.log('rows:', rows);
const summary = data.summary || { total_partner_income: 0, total_rebate_income: 0, total_milkTea_income: 0 };
// 计算派单总数(从列表)
const totalDispatch = rows.reduce((sum, r) => sum + (r.dispatch_count || 0), 0);
console.log('totalDispatch:', totalDispatch);
// 更新统计卡片
document.getElementById('partnerTotalDispatchCount').textContent = totalDispatch;