HEL-342: 管理总览 KPI 绑定真实 dashboard 接口
去掉写死的演示金额与账期进度,改由 /api/admin/dashboard 的 totals 与 period_progress 填充;无数据走空态。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
b905cba52c
commit
b2bcd47e62
+67
@@ -1467,6 +1467,63 @@ function updateDashAuditCard(audit) {
|
||||
applyAuditCounts(audit, { fromApi: true });
|
||||
}
|
||||
|
||||
function formatDashWan(value) {
|
||||
const num = Number(value);
|
||||
if (!Number.isFinite(num)) return "0.00";
|
||||
return Math.abs(num).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
}
|
||||
|
||||
function applyDashKpis(data) {
|
||||
const totals = data?.totals || {};
|
||||
const from = data?.from_date || "—";
|
||||
const cutoff = data?.cutoff || "—";
|
||||
const periodLabel = data?.period_label || "";
|
||||
const companyCount = Number(totals.company_count) || 0;
|
||||
const detailCount = Number(totals.detail_count) || 0;
|
||||
const debit = formatDashWan(totals.debit_wan);
|
||||
const credit = formatDashWan(totals.credit_wan);
|
||||
|
||||
const pageSub = $("#dashPageSub");
|
||||
if (pageSub) {
|
||||
if (!companyCount && !detailCount) {
|
||||
pageSub.textContent = `${from} 至 ${cutoff},暂无成员公司往来数据。导入并归集银行流水后,金额将显示在此。页面上任意数字与公司均可逐级穿透,直至银行原始流水。`;
|
||||
} else {
|
||||
pageSub.textContent = `${from} 至 ${cutoff},集团 ${companyCount} 家成员公司相互往来累计发生 ${debit} 万元、${detailCount} 笔明细。页面上任意数字与公司均可逐级穿透,直至银行原始流水。`;
|
||||
}
|
||||
}
|
||||
const debitVal = $("#dashDebitValue");
|
||||
if (debitVal) debitVal.innerHTML = `${debit}<span class="unit">万元</span>`;
|
||||
const debitFoot = $("#dashDebitFoot");
|
||||
if (debitFoot) debitFoot.textContent = `${companyCount} 家公司合计 · 明细 ${detailCount} 笔`;
|
||||
const creditVal = $("#dashCreditValue");
|
||||
if (creditVal) creditVal.innerHTML = `${credit}<span class="unit">万元</span>`;
|
||||
const creditFoot = $("#dashCreditFoot");
|
||||
if (creditFoot) creditFoot.textContent = `${companyCount} 家公司合计 · 与借方同源互证`;
|
||||
|
||||
const progress = data?.period_progress || {};
|
||||
const ym = progress.year_month || periodLabel;
|
||||
const monthNum = ym ? Number(String(ym).slice(5, 7)) : 0;
|
||||
const labelEl = $("#dashPeriodLabel");
|
||||
if (labelEl) labelEl.textContent = monthNum ? `${monthNum} 月账期确认进度` : "账期确认进度";
|
||||
const percent = Number(progress.percent) || 0;
|
||||
const pctEl = $("#dashPeriodPercent");
|
||||
if (pctEl) pctEl.innerHTML = `${percent}<span class="unit">%</span>`;
|
||||
const bar = $("#dashPeriodBar");
|
||||
if (bar) bar.style.width = `${Math.max(0, Math.min(100, percent))}%`;
|
||||
const periodFoot = $("#dashPeriodFoot");
|
||||
if (periodFoot) {
|
||||
const enabled = Number(progress.enabled_count) || 0;
|
||||
periodFoot.textContent = enabled
|
||||
? `${progress.done || 0} 家已完成 · ${progress.in_progress || 0} 家在途 · ${progress.unsubmitted || 0} 家未提交`
|
||||
: "尚无已启用银行账户";
|
||||
}
|
||||
|
||||
const tbPeriod = $("#topbarPeriod");
|
||||
if (tbPeriod) tbPeriod.textContent = periodLabel ? `账期 ${periodLabel}` : "账期 —";
|
||||
const tbCutoff = $("#topbarCutoff");
|
||||
if (tbCutoff) tbCutoff.textContent = cutoff && cutoff !== "—" ? `统计截止 ${cutoff}` : "统计截止 —";
|
||||
}
|
||||
|
||||
function renderDashCompanyRows(companies, selectedId) {
|
||||
const list = $("#dashCompanyRows");
|
||||
if (!list) return;
|
||||
@@ -1681,11 +1738,15 @@ async function loadAdminDashboard() {
|
||||
const response = await fetch(`/api/admin/dashboard?from=${encodeURIComponent(from)}`).catch(() => null);
|
||||
if (!response?.ok) {
|
||||
$("#dashCompanyRows").innerHTML = '<div class="dash-company-empty muted">总览加载失败</div>';
|
||||
const pageSub = $("#dashPageSub");
|
||||
if (pageSub) pageSub.textContent = "总览加载失败,请刷新后重试。";
|
||||
return;
|
||||
}
|
||||
const data = await response.json().catch(() => null);
|
||||
if (!data || data.status !== "ok") {
|
||||
$("#dashCompanyRows").innerHTML = '<div class="dash-company-empty muted">总览加载失败</div>';
|
||||
const pageSub = $("#dashPageSub");
|
||||
if (pageSub) pageSub.textContent = "总览加载失败,请刷新后重试。";
|
||||
return;
|
||||
}
|
||||
state.dashCompanies = data.companies || [];
|
||||
@@ -1693,6 +1754,7 @@ async function loadAdminDashboard() {
|
||||
state.dashCutoff = data.cutoff;
|
||||
state.dashPeriodMonth = data.period_month;
|
||||
updateDashAuditCard(data.audit);
|
||||
applyDashKpis(data);
|
||||
const listSub = $("#dashListSub");
|
||||
if (listSub) {
|
||||
listSub.textContent = `${data.from_date} 至 ${data.cutoff} · 单位:万元 · 左侧选择公司,右侧查看其往来明细`;
|
||||
@@ -1837,8 +1899,13 @@ function syncPendingCheckAll() {
|
||||
if (!master) return;
|
||||
const boxes = $$(".pending-check");
|
||||
const checked = boxes.filter((el) => el.checked).length;
|
||||
master.disabled = boxes.length === 0;
|
||||
master.checked = boxes.length > 0 && checked === boxes.length;
|
||||
master.indeterminate = checked > 0 && checked < boxes.length;
|
||||
if (boxes.length === 0) {
|
||||
master.checked = false;
|
||||
master.indeterminate = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadAdminRemindersHistory(sourceFilter) {
|
||||
|
||||
Reference in New Issue
Block a user