From 2340c69e260a4be711cbd585d60796bc36e1bdc3 Mon Sep 17 00:00:00 2001 From: mac Date: Sun, 12 Jul 2026 21:48:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A2=84=E7=AE=97=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BA=94=E4=BB=98=E5=88=97+=E5=85=A8?= =?UTF-8?q?=E5=B9=B4=E8=A7=86=E5=9B=BE+=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 预算已签项目表新增应付列(当期成本-当期流出) - 已发生/预算筛选区增加全年按钮, 移除已发生总视图 - 默认选中全年视图, 年份默认当前年份 - 版本号 v1.2.0.38 --- static/modules/finance.js | 4 +++- static/modules/plan.js | 10 ++++++++-- templates/index.html | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/static/modules/finance.js b/static/modules/finance.js index b5a9de4..00e9d0f 100644 --- a/static/modules/finance.js +++ b/static/modules/finance.js @@ -105,13 +105,15 @@ function renderFinance() { const defaultMonth2 = now2.getFullYear() + "-" + String(now2.getMonth()+1).padStart(2,"0"); if (!state.finMonth) state.finMonth = defaultMonth2; if (state.finQuarter === undefined) state.finQuarter = Math.floor(now2.getMonth() / 3); + if (!state.finYear) state.finYear = now2.getFullYear(); + if (!state.finView) state.finView = 'annual'; const qLabels = ['Q1','Q2','Q3','Q4']; const qMonths = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]; const nowD = new Date(); const activeQ = state.finQuarter !== undefined ? state.finQuarter : Math.floor(nowD.getMonth() / 3); const activeMonths = qMonths[activeQ]; const yearOpts = [2024,2025,2026,2027]; - const finHeaderBase = `
|年份:|季度:${qLabels.map((q,i) => ``).join('')}|月度:${activeMonths.map(m => { const ms = `${state.finYear}-${String(m).padStart(2,'0')}`; return ``; }).join('')}
`; + const finHeaderBase = `
年份:||季度:${qLabels.map((q,i) => ``).join('')}|月度:${activeMonths.map(m => { const ms = `${state.finYear}-${String(m).padStart(2,'0')}`; return ``; }).join('')}
`; const finAddBtn = ``; const isOverviewMode = false; diff --git a/static/modules/plan.js b/static/modules/plan.js index 7164b9b..c270d69 100644 --- a/static/modules/plan.js +++ b/static/modules/plan.js @@ -103,13 +103,15 @@ function renderPlan() { const defaultMonth2 = now2.getFullYear() + "-" + String(now2.getMonth()+1).padStart(2,"0"); if (!state.planMonth) state.planMonth = defaultMonth2; if (state.planQuarter === undefined) state.planQuarter = Math.floor(now2.getMonth() / 3); + if (!state.planYear) state.planYear = now2.getFullYear(); + if (!state.planView) state.planView = 'annual'; const qLabels = ['Q1','Q2','Q3','Q4']; const qMonths = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]; const nowD = new Date(); const activeQ = state.planQuarter !== undefined ? state.planQuarter : Math.floor(nowD.getMonth() / 3); const activeMonths = qMonths[activeQ]; const yearOpts = [2024,2025,2026,2027]; - const finHeaderBase = `
|年份:|季度:${qLabels.map((q,i) => ``).join('')}|月度:${activeMonths.map(m => { const ms = `${state.planYear}-${String(m).padStart(2,'0')}`; return ``; }).join('')}
`; + const finHeaderBase = `
|年份:||季度:${qLabels.map((q,i) => ``).join('')}|月度:${activeMonths.map(m => { const ms = `${state.planYear}-${String(m).padStart(2,'0')}`; return ``; }).join('')}
`; const finAddBtn = ``; const isOverviewMode = false; @@ -297,6 +299,7 @@ function renderPlan() { { key: 'payment', label: '回款' }, { key: 'pending', label: '应收' }, { key: 'pay_rate', label: '回款率' }, + { key: 'payable', label: '应付' }, { key: 'cost', label: '当期成本' }, { key: 'paid', label: '当期流出' }, { key: 'cashflow', label: '现金流' }, @@ -367,6 +370,9 @@ function renderPlan() { const grossR = rev && gross ? Math.round(gross / rev * 100) + '%' : ''; const cf = cashflow ? money(cashflow) : ''; const cfCls = cashflow >= 0 ? 'text-green-600' : 'text-red-600'; + const payable = cost - paid; + const payableCls = payable > 0 ? 'text-rose-600' : payable < 0 ? 'text-green-600' : 'text-slate-400'; + const payableVal = payable ? (payable > 0 ? '+' : '') + money(payable) : ''; const pending = rev - payment; const pendingCls = pending > 0 ? 'text-red-600' : pending < 0 ? 'text-green-600' : 'text-slate-700'; const pendingVal = pending ? (pending > 0 ? '+' : '') + money(pending) : ''; @@ -392,7 +398,7 @@ function renderPlan() { var bCf = bPay - ePaid; return '' + m + '' + (bRev ? money(bRev) : '—') + '' + (bGross ? money(bGross) : '—') + '' + (bPay ? money(bPay) : '—') + '' + (eCost ? money(eCost) : '—') + '' + (ePaid ? money(ePaid) : '—') + '' + (bCf ? money(bCf) : '—') + '' + (bRev - bPay ? money(bRev - bPay) : '—') + ''; }).join(''); - return `${esc(pf.client_name || "")}${esc(pf.customer_name)}${planInlineSelect('weight', pf.id, 'weight', pf.weight || '20%', ['20%','40%','60%','80%','100%'])}${planInlineSelect('ptype', pf.id, 'project_type', pf.project_type || '待签约', ['待签约','已签约'])}${money(pf.sign_amount)}${fmtNoUnit(rev)}${fmtNoUnit(gross)}${grossR}${fmtNoUnit(payment)}${pendingVal}${payR}${fmtNoUnit(cost)}${fmtNoUnit(paid)}${cf}${detailRows}
月份确收毛利回款当期成本当期流出现金流应收
`; + return `${esc(pf.client_name || "")}${esc(pf.customer_name)}${planInlineSelect('weight', pf.id, 'weight', pf.weight || '20%', ['20%','40%','60%','80%','100%'])}${planInlineSelect('ptype', pf.id, 'project_type', pf.project_type || '待签约', ['待签约','已签约'])}${money(pf.sign_amount)}${fmtNoUnit(rev)}${fmtNoUnit(gross)}${grossR}${fmtNoUnit(payment)}${pendingVal}${payR}${fmtNoUnit(cost)}${fmtNoUnit(paid)}${payableVal}${cf}${detailRows}
月份确收毛利回款当期成本当期流出现金流应收
`; }; // 待签约简版行 const tdRowUnsigned = (pf, cost, gross) => { diff --git a/templates/index.html b/templates/index.html index 6fa3af3..79d687c 100644 --- a/templates/index.html +++ b/templates/index.html @@ -84,7 +84,7 @@
-

OPC Manager v1.2.0.37

+

OPC Manager v1.2.0.38

科普 OPC 工作台