diff --git a/static/modules/overview_finance.js b/static/modules/overview_finance.js index 6c7030f..b7b24cb 100644 --- a/static/modules/overview_finance.js +++ b/static/modules/overview_finance.js @@ -20,6 +20,15 @@ function renderOverviewFinance() { }); } + +function isAllZero(data, tenants, keys, mi) { + for (var ti = 0; ti < tenants.length; ti++) { + for (var ki = 0; ki < keys.length; ki++) { + if ((data.data[tenants[ti]][keys[ki]][mi] || 0) !== 0) return false; + } + } + return true; +} // ====== 项目经营详情报表(顶部定义,避免调用时未注册) ====== function renderFinanceProjectMatrix() { @@ -47,12 +56,17 @@ function renderFinanceProjectMatrixData(data, container) { var vBtns = financeBtnBar('project_matrix'); var cards = ''; - for (var mi = 0; mi < 12; mi++) { - var th = '指标'; + for (var mi = 11; mi >= 0; mi--) { + var th = '指标月度合计'; for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } - th += '合计'; + th += ''; + if (isAllZero(data, tenants, keys, mi)) continue; + var th = '指标月度合计'; + for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } + th += ''; + var tb = financeProjectMatrixTbody(data, tenants, mi, keys, labels, mf); - cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; + cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; } container.innerHTML = '
' + vBtns + '
' + cards + '
'; if (window.lucide) window.lucide.createIcons(); @@ -63,20 +77,24 @@ function financeProjectMatrixTbody(data, tenants, mi, keys, labels, mf) { var tb = ''; for (var ri = 0; ri < keys.length; ri++) { var rowCls = ri === keys.length - 1 ? 'font-semibold' : ''; - var rh = '' + labels[ri] + ''; var ts = 0; + var vals = []; for (var ti = 0; ti < tenants.length; ti++) { var v = data.data[tenants[ti]][keys[ri]][mi] || 0; ts += v; - var cls = 'text-slate-700'; - if (ri === 2) cls = 'text-green-600'; - if (ri === keys.length - 1) cls = v >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(v) + ''; + vals.push(v); } var tCls = 'text-slate-700'; if (ri === 2) tCls = 'text-green-600'; if (ri === keys.length - 1) tCls = ts >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(ts) + ''; + var rh = '' + labels[ri] + '' + mf(ts) + ''; + for (var ti = 0; ti < tenants.length; ti++) { + var cls = 'text-slate-700'; + if (ri === 2) cls = 'text-green-600'; + if (ri === keys.length - 1) cls = vals[ti] >= 0 ? 'text-green-600' : 'text-red-600'; + rh += '' + mf(vals[ti]) + ''; + } + rh += ''; tb += rh; } return tb; @@ -186,12 +204,12 @@ function renderFinanceDeptMatrixData(data, container) { var mL = ['01月','02月','03月','04月','05月','06月','07月','08月','09月','10月','11月','12月']; var vBtns = financeBtnBar('matrix'); var cards = ''; - for (var mi = 0; mi < 12; mi++) { - var th = '指标'; + for (var mi = 11; mi >= 0; mi--) { + var th = '指标月度合计'; for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } - th += '合计'; + th += ''; var tb = financeMatrixTbody(data, tenants, mi, ['project_gross','dept_expense','profit'], ['项目毛利','部门费用','利润'], mf); - cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; + cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; } container.innerHTML = '
' + vBtns + '
' + cards + '
'; if (window.lucide) window.lucide.createIcons(); @@ -214,12 +232,12 @@ function renderFinanceCfMatrixData(data, container) { var mL = ['01月','02月','03月','04月','05月','06月','07月','08月','09月','10月','11月','12月']; var vBtns = financeBtnBar('cf_matrix'); var cards = ''; - for (var mi = 0; mi < 12; mi++) { - var th = '指标'; + for (var mi = 11; mi >= 0; mi--) { + var th = '指标月度合计'; for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } - th += '合计'; + th += ''; var tb = financeMatrixTbody(data, tenants, mi, ['project_cf','dept_cf','bl_cf'], ['项目现金流','部门现金流','经营现金流'], mf); - cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; + cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; } container.innerHTML = '
' + vBtns + '
' + cards + '
'; if (window.lucide) window.lucide.createIcons(); @@ -241,16 +259,20 @@ function financeMatrixTbody(data, tenants, mi, keys, labels, mf) { var tb = ''; for (var ri = 0; ri < keys.length; ri++) { var rowCls = ri === keys.length - 1 ? 'font-semibold' : ''; - var rh = '' + labels[ri] + ''; var ts = 0; + var vals = []; for (var ti = 0; ti < tenants.length; ti++) { var v = data.data[tenants[ti]][keys[ri]][mi] || 0; ts += v; - var cls = v >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(v) + ''; + vals.push(v); } var tCls = ts >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(ts) + ''; + var rh = '' + labels[ri] + '' + mf(ts) + ''; + for (var ti = 0; ti < tenants.length; ti++) { + var cls = vals[ti] >= 0 ? 'text-green-600' : 'text-red-600'; + rh += '' + mf(vals[ti]) + ''; + } + rh += ''; tb += rh; } return tb; diff --git a/static/modules/overview_plan.js b/static/modules/overview_plan.js index c99dbcc..91ffb18 100644 --- a/static/modules/overview_plan.js +++ b/static/modules/overview_plan.js @@ -44,13 +44,18 @@ function renderProjectMatrixData(data, container) { var vBtns = btnBar('project_matrix'); var cards = ''; - for (var mi = 0; mi < 12; mi++) { - var th = '指标'; + for (var mi = 11; mi >= 0; mi--) { + var th = '指标月度合计'; for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } - th += '合计'; + th += ''; + + if (isAllZero(data, tenants, keys, mi)) continue; + var th = '指标月度合计'; + for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } + th += ''; var tb = projectMatrixTbody(data, tenants, mi, keys, labels, mf); - cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; + cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; } container.innerHTML = '
' + vBtns + '
' + cards + '
'; if (window.lucide) window.lucide.createIcons(); @@ -61,20 +66,24 @@ function projectMatrixTbody(data, tenants, mi, keys, labels, mf) { var tb = ''; for (var ri = 0; ri < keys.length; ri++) { var rowCls = ri === keys.length - 1 ? 'font-semibold' : ''; - var rh = '' + labels[ri] + ''; var ts = 0; + var vals = []; for (var ti = 0; ti < tenants.length; ti++) { var v = data.data[tenants[ti]][keys[ri]][mi] || 0; ts += v; - var cls = 'text-slate-700'; - if (ri === 2) cls = 'text-green-600'; - if (ri === keys.length - 1) cls = v >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(v) + ''; + vals.push(v); } var tCls = 'text-slate-700'; if (ri === 2) tCls = 'text-green-600'; if (ri === keys.length - 1) tCls = ts >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(ts) + ''; + var rh = '' + labels[ri] + '' + mf(ts) + ''; + for (var ti = 0; ti < tenants.length; ti++) { + var cls = 'text-slate-700'; + if (ri === 2) cls = 'text-green-600'; + if (ri === keys.length - 1) cls = vals[ti] >= 0 ? 'text-green-600' : 'text-red-600'; + rh += '' + mf(vals[ti]) + ''; + } + rh += ''; tb += rh; } return tb; @@ -197,13 +206,14 @@ function renderDeptMatrixData(data, container) { var vBtns = btnBar('matrix'); var cards = ''; - for (var mi = 0; mi < 12; mi++) { - var th = '指标'; + for (var mi = 11; mi >= 0; mi--) { + if (isAllZero(data, tenants, ['project_gross','dept_expense','profit'], mi)) continue; + var th = '指标月度合计'; for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } - th += '合计'; + th += ''; var tb = matrixTbody(data, tenants, mi, ['project_gross','dept_expense','profit'], ['项目毛利','部门费用','利润'], mf); - cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; + cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; } container.innerHTML = '
' + vBtns + '
' + cards + '
'; if (window.lucide) window.lucide.createIcons(); @@ -227,13 +237,18 @@ function renderCfMatrixData(data, container) { var vBtns = btnBar('cf_matrix'); var cards = ''; - for (var mi = 0; mi < 12; mi++) { - var th = '指标'; + for (var mi = 11; mi >= 0; mi--) { + var th = '指标月度合计'; for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } - th += '合计'; + th += ''; + + if (isAllZero(data, tenants, ['project_cf','dept_cf','bl_cf'], mi)) continue; + var th = '指标月度合计'; + for (var ti = 0; ti < tenants.length; ti++) { th += '' + sn[ti] + ''; } + th += ''; var tb = matrixTbody(data, tenants, mi, ['project_cf','dept_cf','bl_cf'], ['项目现金流','部门现金流','经营现金流'], mf); - cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; + cards += '
' + mL[mi] + '
' + th + '' + tb + '
'; } container.innerHTML = '
' + vBtns + '
' + cards + '
'; if (window.lucide) window.lucide.createIcons(); @@ -254,20 +269,33 @@ function matrixTbody(data, tenants, mi, keys, labels, mf) { var tb = ''; for (var ri = 0; ri < keys.length; ri++) { var rowCls = ri === keys.length - 1 ? 'font-semibold' : ''; - var rh = '' + labels[ri] + ''; var ts = 0; + var vals = []; for (var ti = 0; ti < tenants.length; ti++) { var v = data.data[tenants[ti]][keys[ri]][mi] || 0; ts += v; - var cls = v >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(v) + ''; + vals.push(v); } var tCls = ts >= 0 ? 'text-green-600' : 'text-red-600'; - rh += '' + mf(ts) + ''; + var rh = '' + labels[ri] + '' + mf(ts) + ''; + for (var ti = 0; ti < tenants.length; ti++) { + var cls = vals[ti] >= 0 ? 'text-green-600' : 'text-red-600'; + rh += '' + mf(vals[ti]) + ''; + } + rh += ''; tb += rh; } return tb; + +function isAllZero(data, tenants, keys, mi) { + for (var ti = 0; ti < tenants.length; ti++) { + for (var ki = 0; ki < keys.length; ki++) { + if ((data.data[tenants[ti]][keys[ki]][mi] || 0) !== 0) return false; + } + } + return true; +} // ====== 项目经营详情报表 ====== diff --git a/static/modules/utils.js b/static/modules/utils.js index 0eeba7a..00dc43a 100644 --- a/static/modules/utils.js +++ b/static/modules/utils.js @@ -193,7 +193,7 @@ async function load() { // 按需加载当前 tab 的数据(必须在 ensureStandardProposals 之前,否则会被 return 跳过) await ensureTabData(state.active); // 首次加载时确保标准资料库 7 项已初始化(仅首次,避免每次切换工作台都触发) - if (!_proposalsInitialized && typeof ensureStandardProposals === "function") { + if (!_proposalsInitialized && typeof ensureStandardProposals === "function" && state.tenant !== '总览') { _proposalsInitialized = true; try { const proposalsData = await api("/api/proposals/list?tenant=" + encodeURIComponent(state.tenant)); diff --git a/templates/index.html b/templates/index.html index 0b80e7a..95d0a3f 100644 --- a/templates/index.html +++ b/templates/index.html @@ -84,7 +84,7 @@
-

OPC Manager v1.2.0.26

+

OPC Manager v1.2.0.27

科普 OPC 工作台