// home.js — 首页渲染 + 财务趋势图 function renderHome() { const { summary, financeMonthly } = state.data; const m = summary.metrics; const moneyInt = (v) => `${Math.round(Number(v || 0)).toLocaleString("zh-CN")} 元`; const rows1 = [ ["年度累计", moneyInt(m.signed_annual || m.signed_amount)], ["本季度累计", moneyInt(m.signed_q2 || 0)], ["本月累计", moneyInt(m.signed_month || 0)], ["上本季度累计", moneyInt(m.signed_prev_q || 0)], ["上月累计", moneyInt(m.signed_prev_month || 0)], ]; const rows2 = [ ["年度累计", moneyInt(m.revenue_annual)], ["本季度累计", moneyInt(m.revenue_q2)], ["本月累计", moneyInt(m.monthly_revenue)], ["上本季度累计", moneyInt(m.revenue_prev_q || 0)], ["上月累计", moneyInt(m.revenue_prev_month || 0)], ]; const rows3 = [ ["年度累计", moneyInt(m.gross_annual)], ["本季度累计", moneyInt(m.gross_q2)], ["本月累计", moneyInt(m.monthly_net_profit)], ["上本季度累计", moneyInt(m.gross_prev_q || 0)], ["上月累计", moneyInt(m.gross_prev_month || 0)], ]; const rows4 = [ ["年度累计", moneyInt(m.payment_annual || 0)], ["本季度累计", moneyInt(m.payment_q2 || 0)], ["本月累计", moneyInt(m.payment_month || 0)], ["上本季度累计", moneyInt(m.payment_prev_q || 0)], ["上月累计", moneyInt(m.payment_prev_month || 0)], ]; const rows5 = [ ["年度累计", moneyInt(m.cost_annual || 0)], ["本季度累计", moneyInt(m.cost_q2 || 0)], ["本月累计", moneyInt(m.cost_month || 0)], ["上本季度累计", moneyInt(m.cost_prev_q || 0)], ["上月累计", moneyInt(m.cost_prev_month || 0)], ]; const rows7 = [ ["年度累计", moneyInt(m.paid_annual || 0)], ["本季度累计", moneyInt(m.paid_q2 || 0)], ["本月累计", moneyInt(m.paid_month || 0)], ["上本季度累计", moneyInt(m.paid_prev_q || 0)], ["上月累计", moneyInt(m.paid_prev_month || 0)], ]; const rowsProjExpense = [ ["年度累计", moneyInt(m.proj_expense_annual || 0)], ["本季度累计", moneyInt(m.proj_expense_q2 || 0)], ["本月累计", moneyInt(m.proj_expense_month || 0)], ["上本季度累计", moneyInt(m.proj_expense_prev_q || 0)], ["上月累计", moneyInt(m.proj_expense_prev_month || 0)], ]; const rows8 = [ ["年度累计", moneyInt(m.cashflow_annual || 0)], ["本季度累计", moneyInt(m.cashflow_q2 || 0)], ["本月累计", moneyInt(m.cashflow_month || 0)], ["上本季度累计", moneyInt(m.cashflow_prev_q || 0)], ["上月累计", moneyInt(m.cashflow_prev_month || 0)], ]; const rows9 = [ ["年度累计", moneyInt(m.profit_annual || 0)], ["本季度累计", moneyInt(m.profit_q2 || 0)], ["本月累计", moneyInt(m.profit_month || 0)], ["上本季度累计", moneyInt(m.profit_prev_q || 0)], ["上月累计", moneyInt(m.profit_prev_month || 0)], ]; const qoq = (cur, prev) => { if (!prev) return '—'; const pct = Math.round((cur - prev) / prev * 100); const cls = pct >= 0 ? 'text-green-600' : 'text-red-600'; const sign = pct >= 0 ? '+' : ''; return '' + sign + pct + '%'; }; const COLORS = ['text-slate-700','text-blue-600','text-green-600','text-rose-600','text-indigo-600','text-amber-600','text-purple-600','text-cyan-600']; const LABELS = ['合同金额','确收金额','确收毛利','成本','项目利润','回款金额','已付','现金流']; const Q_FIELDS = [m.signed_q2||0, m.revenue_q2, m.gross_q2, m.cost_q2||0, m.profit_q2||0, m.payment_q2||0, m.paid_q2||0, m.cashflow_q2||0]; const Q_PREV = [m.signed_prev_q||0, m.revenue_prev_q||0, m.gross_prev_q||0, m.cost_prev_q||0, m.profit_prev_q||0, m.payment_prev_q||0, m.paid_prev_q||0, m.cashflow_prev_q||0]; const M_FIELDS = [m.signed_month||0, m.monthly_revenue, m.monthly_net_profit, m.cost_month||0, m.profit_month||0, m.payment_month||0, m.paid_month||0, m.cashflow_month||0]; const M_PREV = [m.signed_prev_month||0, m.revenue_prev_month||0, m.gross_prev_month||0, m.cost_prev_month||0, m.profit_prev_month||0, m.payment_prev_month||0, m.paid_prev_month||0, m.cashflow_prev_month||0]; const ROWS = [rows1, rows2, rows3, rows5, rows9, rows4, rows7, rows8]; // 现金流和项目利润的原始值数组,用于正负着色 const CF_RAW = [m.cashflow_annual||0, m.cashflow_q2||0, m.cashflow_month||0, m.cashflow_prev_q||0, m.cashflow_prev_month||0]; const PF_RAW = [m.profit_annual||0, m.profit_q2||0, m.profit_month||0, m.profit_prev_q||0, m.profit_prev_month||0]; var valCls = function(ri) { return (ri === 4 || ri === 7) ? '' : 'text-slate-800'; }; var tdVal = function(ri, col, val) { if (ri === 4) return '
| 指标 | 年度累计 | 上季度累计 | 上月累计 | 本季度累计 | 季环比 | 本月累计 | 月环比 |
|---|---|---|---|---|---|---|---|
| ' + r[0] + ' | ' + '' + moneyInt(r[1][0]) + ' | ' + '' + moneyInt(r[1][3]) + ' | ' + '' + moneyInt(r[1][4]) + ' | ' + '' + moneyInt(r[1][1]) + ' | ' + '' + qoq(r[2][0], r[2][1]) + ' | ' + '' + moneyInt(r[1][2]) + ' | ' + '' + qoq(r[3][0], r[3][1]) + ' |
合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 已付 → 现金流