diff --git a/backend/routes.py b/backend/routes.py index 2d06019..20e21e4 100644 --- a/backend/routes.py +++ b/backend/routes.py @@ -247,6 +247,7 @@ def bootstrap(): t_ops = attach_common(conn, "operations", rows(conn, "SELECT * FROM operation_projects WHERE tenant=? ORDER BY id ASC", [t])) t_sales = attach_common(conn, "sales", rows(conn, "SELECT * FROM sales_leads WHERE tenant=? ORDER BY id DESC", [t])) t_products = attach_common(conn, "products", rows(conn, "SELECT * FROM product_versions WHERE tenant=? ORDER BY id DESC", [t])) + t_expense = rows(conn, "SELECT * FROM expense_records WHERE tenant=?", [t]) t_proposals = attach_common(conn, "proposals", rows(conn, "SELECT * FROM business_proposals WHERE tenant=? ORDER BY id DESC", [t])) t_signed_pfs = [x for x in t_pfs if x["status"] == "已签约"] def t_parse_budget(pf): @@ -305,10 +306,26 @@ def bootstrap(): "cost_prev_q": t_sum_budget("cost", _prev_q_range), "cost_prev_month": t_sum_budget("cost", [_prev_month]) if _prev_month else 0, }) + # 费用汇总(从 expense_records 表计算) + def t_expense_sum(m_range): + total = 0 + for r in t_expense: + m = (r.get("expense_month") or "").strip() + if not m or "-" not in m: continue + try: + if int(m.split("-")[1]) in m_range: + total += float(r.get("amount") or 0) + except: pass + return total + all_metrics[-1]["expense_annual"] = t_expense_sum(range(1, 13)) + all_metrics[-1]["expense_q2"] = t_expense_sum(_q_range) + all_metrics[-1]["expense_month"] = t_expense_sum([_now_month]) + all_metrics[-1]["expense_prev_q"] = t_expense_sum(_prev_q_range) + all_metrics[-1]["expense_prev_month"] = t_expense_sum([_prev_month]) if _prev_month else 0 all_monthly.append(monthly_finance(conn, t)) all_recent.extend(rows(conn, "SELECT * FROM follow_up_records WHERE tenant=? ORDER BY id DESC LIMIT 4", [t])) agg = {} - for key in ["total_projects","total_proposals","total_products","upcoming_products","signed_amount","signed_annual","signed_q2","signed_month","signed_prev_q","signed_prev_month","revenue_annual","revenue_q2","monthly_revenue","revenue_prev_q","revenue_prev_month","gross_annual","gross_q2","monthly_net_profit","gross_prev_q","gross_prev_month","payment_annual","payment_q2","payment_month","payment_prev_q","payment_prev_month","cost_annual","cost_q2","cost_month","cost_prev_q","cost_prev_month"]: + for key in ["total_projects","total_proposals","total_products","upcoming_products","signed_amount","signed_annual","signed_q2","signed_month","signed_prev_q","signed_prev_month","revenue_annual","revenue_q2","monthly_revenue","revenue_prev_q","revenue_prev_month","gross_annual","gross_q2","monthly_net_profit","gross_prev_q","gross_prev_month","payment_annual","payment_q2","payment_month","payment_prev_q","payment_prev_month","cost_annual","cost_q2","cost_month","cost_prev_q","cost_prev_month","expense_annual","expense_q2","expense_month","expense_prev_q","expense_prev_month"]: agg[key] = sum(m.get(key, 0) for m in all_metrics) merged_monthly = [] for i in range(12): @@ -380,6 +397,21 @@ def bootstrap(): cost_prev_q = sum_budget("cost", _prev_q_range) payment_prev_month = sum_budget("payment", [_prev_month]) if _prev_month else 0 cost_prev_month = sum_budget("cost", [_prev_month]) if _prev_month else 0 + def expense_sum(month_range): + total = 0 + for r in expense: + m = (r.get("expense_month") or "").strip() + if not m or "-" not in m: continue + try: + if int(m.split("-")[1]) in month_range: + total += float(r.get("amount") or 0) + except: pass + return total + expense_annual = expense_sum(range(1, 13)) + expense_q2 = expense_sum(_q_range) + expense_month_val = expense_sum([_now_month]) + expense_prev_q = expense_sum(_prev_q_range) + expense_prev_month = expense_sum([_prev_month]) if _prev_month else 0 def pf_status_sum(status): return sum(x["sign_amount"] or 0 for x in pfs if x["status"] == status) signed_amount = pf_status_sum("已签约") @@ -431,6 +463,11 @@ def bootstrap(): "cost_month": cost_month, "cost_prev_q": cost_prev_q, "cost_prev_month": cost_prev_month, + "expense_annual": expense_annual, + "expense_q2": expense_q2, + "expense_month": expense_month_val, + "expense_prev_q": expense_prev_q, + "expense_prev_month": expense_prev_month, "signed_not_executed": signed_not_executed, }, "recent": q("SELECT * FROM follow_up_records WHERE tenant=? ORDER BY id DESC LIMIT 8", tenant), diff --git a/static/modules/home.js b/static/modules/home.js index c36426b..3b7c039 100644 --- a/static/modules/home.js +++ b/static/modules/home.js @@ -39,24 +39,48 @@ function renderHome() { ["上季度累计", moneyInt(m.cost_prev_q || 0)], ["上月累计", moneyInt(m.cost_prev_month || 0)], ]; -let _cardId = 0; -const tblCard = (title, rows) => { - const id = 'finCard' + (++_cardId); - const visible = rows.slice(0, 3); - const extra = rows.slice(3); - const rowHtml = (r) => r.map(([label, value]) => `