From 14368e83d07af6c6c0e46df4769dfa4c8194244d Mon Sep 17 00:00:00 2001 From: mac Date: Sat, 11 Jul 2026 15:39:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9C=88=E6=8A=A5/=E5=AD=A3=E6=8A=A5?= =?UTF-8?q?=E6=80=BB=E8=A7=88=E5=90=88=E5=90=8C=E9=87=91=E9=A2=9D=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=BA0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端新增sign_monthly[12]按月份拆分签单数据 - 月报/季报API均导出sign_monthly,季度转换包含sign_monthly - 前端projVals首项改用sign_monthly替代硬编码0 - 版本号 v1.2.0.32 --- backend/routes.py | 11 +++++++++-- static/modules/overview_finance.js | 6 +++--- static/modules/overview_plan.js | 6 +++--- templates/index.html | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/backend/routes.py b/backend/routes.py index a767c8a..606e429 100644 --- a/backend/routes.py +++ b/backend/routes.py @@ -1093,6 +1093,7 @@ def _aggregate_monthly_from_json(conn, table, tenants): _year = date.today().year months = [f"{_year}-{m:02d}" for m in range(1, 13)] rev, gross, payment, cost, paid = [0]*12, [0]*12, [0]*12, [0]*12, [0]*12 + sign_monthly = [0]*12 sign_total = 0 sign_cnt = 0 @@ -1103,6 +1104,10 @@ def _aggregate_monthly_from_json(conn, table, tenants): if sm.startswith(str(_year)): sign_total += float(pf.get("sign_amount") or 0) sign_cnt += 1 + # 签单按月拆分 + sm7 = sm[:7] + if sm7 in months: + sign_monthly[months.index(sm7)] += float(pf.get("sign_amount") or 0) try: bd = json.loads(pf.get("budget_data") or "[]") except: @@ -1130,6 +1135,7 @@ def _aggregate_monthly_from_json(conn, table, tenants): "rev": rev, "gross": gross, "payment": payment, "cost": cost, "paid": paid, "cashflow": [payment[i] - paid[i] for i in range(12)], "sign_total": sign_total, "sign_cnt": sign_cnt, + "sign_monthly": sign_monthly, } @@ -1181,6 +1187,7 @@ def _build_overview_result(agg, exp_amount, exp_incurred): # 项目经营详情 project = { "sign": agg["sign_total"], + "sign_monthly": agg["sign_monthly"], "revenue": rev, "gross": gross, "cost": cost, @@ -1218,7 +1225,7 @@ def overview_plan_quarterly(): conn.close() # Convert monthly to quarterly result = _build_overview_result(agg, exp_amount, exp_incurred) - for key in ["revenue","gross","payment","cost","paid","cashflow"]: + for key in ["sign_monthly","revenue","gross","payment","cost","paid","cashflow"]: result["project"][key] = _quarterly_from_monthly(result["project"][key]) result["dept"]["project_gross"] = _quarterly_from_monthly(result["dept"]["project_gross"]) result["dept"]["dept_expense"] = _quarterly_from_monthly(result["dept"]["dept_expense"]) @@ -1247,7 +1254,7 @@ def overview_finance_quarterly(): exp_amount, exp_incurred = _aggregate_expenses(conn, "expense_records", OVERVIEW_TENANTS) conn.close() result = _build_overview_result(agg, exp_amount, exp_incurred) - for key in ["revenue","gross","payment","cost","paid","cashflow"]: + for key in ["sign_monthly","revenue","gross","payment","cost","paid","cashflow"]: result["project"][key] = _quarterly_from_monthly(result["project"][key]) result["dept"]["project_gross"] = _quarterly_from_monthly(result["dept"]["project_gross"]) result["dept"]["dept_expense"] = _quarterly_from_monthly(result["dept"]["dept_expense"]) diff --git a/static/modules/overview_finance.js b/static/modules/overview_finance.js index 52660b0..49d65c4 100644 --- a/static/modules/overview_finance.js +++ b/static/modules/overview_finance.js @@ -161,7 +161,7 @@ function renderOverviewFinanceData(data, view) { var cfCard = card('

部门现金流 部门现金流=所有项目产生的现金流 - 部门一级因费用产生的现金流出或流入

' + deptThead + '' + cfTbody + '
', 'p-4'); var LABELS = ['合同金额','确收金额','确收毛利','成本','支出','回款','项目现金流']; - var projVals = [p.revenue, p.gross, p.cost, p.paid, p.payment, p.cashflow]; + var projVals = [p.sign_monthly || [], p.revenue, p.gross, p.cost, p.paid, p.payment, p.cashflow]; var projAnnual = p.annual; var projThead = '指标年度累计'; for (var phi = 0; phi < cols; phi++) { projThead += '' + headers[phi] + ''; } @@ -169,9 +169,9 @@ function renderOverviewFinanceData(data, view) { var projTbody = ''; for (var ri = 0; ri < 7; ri++) { var rowHtml = '' + LABELS[ri] + ''; - rowHtml += '' + (ri === 0 ? moneyIntL(p.sign) : moneyIntL(projAnnual[ri])) + ''; + rowHtml += '' + moneyIntL(projAnnual[ri]) + ''; for (var i = 0; i < cols; i++) { - var val = ri === 0 ? 0 : (projVals[ri - 1] ? projVals[ri - 1][i] : 0); + var val = projVals[ri] ? (projVals[ri][i] || 0) : 0; var cls = 'text-slate-700'; if (ri === 2) cls = 'text-green-600'; if (ri === 6) cls = val >= 0 ? 'text-green-600' : 'text-red-600'; diff --git a/static/modules/overview_plan.js b/static/modules/overview_plan.js index 87957b0..dc8a0bf 100644 --- a/static/modules/overview_plan.js +++ b/static/modules/overview_plan.js @@ -160,7 +160,7 @@ function renderOverviewPlanData(data, view) { // ====== 项目经营详情 ====== var LABELS = ['合同金额','确收金额','确收毛利','成本','支出','回款','项目现金流']; - var projVals = [p.revenue, p.gross, p.cost, p.paid, p.payment, p.cashflow]; + var projVals = [p.sign_monthly || [], p.revenue, p.gross, p.cost, p.paid, p.payment, p.cashflow]; var projAnnual = p.annual; var projThead = '指标年度累计'; @@ -170,9 +170,9 @@ function renderOverviewPlanData(data, view) { var projTbody = ''; for (var ri = 0; ri < 7; ri++) { var rowHtml = '' + LABELS[ri] + ''; - rowHtml += '' + (ri === 0 ? moneyIntL(p.sign) : moneyIntL(projAnnual[ri])) + ''; + rowHtml += '' + moneyIntL(projAnnual[ri]) + ''; for (var i = 0; i < cols; i++) { - var val = ri === 0 ? 0 : (projVals[ri - 1] ? projVals[ri - 1][i] : 0); + var val = projVals[ri] ? (projVals[ri][i] || 0) : 0; var cls = 'text-slate-700'; if (ri === 2) cls = 'text-green-600'; if (ri === 6) cls = val >= 0 ? 'text-green-600' : 'text-red-600'; diff --git a/templates/index.html b/templates/index.html index 58793b3..b1474c2 100644 --- a/templates/index.html +++ b/templates/index.html @@ -84,7 +84,7 @@
-

OPC Manager v1.2.0.31

+

OPC Manager v1.2.0.32

科普 OPC 工作台