Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2aab73a86a | ||
|
|
e0000c2abb |
@@ -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 = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th>';
|
||||
for (var mi = 11; mi >= 0; mi--) {
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '<th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">合计</th></tr>';
|
||||
th += '</tr>';
|
||||
if (isAllZero(data, tenants, keys.filter(function(k) { return k !== 'sign'; }), mi)) continue;
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '</tr>';
|
||||
|
||||
var tb = financeProjectMatrixTbody(data, tenants, mi, keys, labels, mf);
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-slate-300" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-blue-200" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
}
|
||||
container.innerHTML = '<div class="grid gap-2.5">' + vBtns + '<div class="flex flex-col gap-2">' + cards + '</div></div>';
|
||||
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 = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td>';
|
||||
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 += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(v) + '</td>';
|
||||
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 += '<td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td></tr>';
|
||||
var rh = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td><td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td>';
|
||||
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 += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(vals[ti]) + '</td>';
|
||||
}
|
||||
rh += '</tr>';
|
||||
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 = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th>';
|
||||
for (var mi = 11; mi >= 0; mi--) {
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '<th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">合计</th></tr>';
|
||||
th += '</tr>';
|
||||
var tb = financeMatrixTbody(data, tenants, mi, ['project_gross','dept_expense','profit'], ['项目毛利','部门费用','利润'], mf);
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-slate-300" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-blue-200" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
}
|
||||
container.innerHTML = '<div class="grid gap-2.5">' + vBtns + '<div class="flex flex-col gap-2">' + cards + '</div></div>';
|
||||
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 = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th>';
|
||||
for (var mi = 11; mi >= 0; mi--) {
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '<th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">合计</th></tr>';
|
||||
th += '</tr>';
|
||||
var tb = financeMatrixTbody(data, tenants, mi, ['project_cf','dept_cf','bl_cf'], ['项目现金流','部门现金流','经营现金流'], mf);
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-slate-300" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-blue-200" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
}
|
||||
container.innerHTML = '<div class="grid gap-2.5">' + vBtns + '<div class="flex flex-col gap-2">' + cards + '</div></div>';
|
||||
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 = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td>';
|
||||
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 += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(v) + '</td>';
|
||||
vals.push(v);
|
||||
}
|
||||
var tCls = ts >= 0 ? 'text-green-600' : 'text-red-600';
|
||||
rh += '<td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td></tr>';
|
||||
var rh = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td><td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) {
|
||||
var cls = vals[ti] >= 0 ? 'text-green-600' : 'text-red-600';
|
||||
rh += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(vals[ti]) + '</td>';
|
||||
}
|
||||
rh += '</tr>';
|
||||
tb += rh;
|
||||
}
|
||||
return tb;
|
||||
|
||||
@@ -44,13 +44,18 @@ function renderProjectMatrixData(data, container) {
|
||||
|
||||
var vBtns = btnBar('project_matrix');
|
||||
var cards = '';
|
||||
for (var mi = 0; mi < 12; mi++) {
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th>';
|
||||
for (var mi = 11; mi >= 0; mi--) {
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '<th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">合计</th></tr>';
|
||||
th += '</tr>';
|
||||
|
||||
if (isAllZero(data, tenants, keys.filter(function(k) { return k !== 'sign'; }), mi)) continue;
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '</tr>';
|
||||
|
||||
var tb = projectMatrixTbody(data, tenants, mi, keys, labels, mf);
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-slate-300" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-blue-200" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
}
|
||||
container.innerHTML = '<div class="grid gap-2.5">' + vBtns + '<div class="flex flex-col gap-2">' + cards + '</div></div>';
|
||||
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 = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td>';
|
||||
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 += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(v) + '</td>';
|
||||
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 += '<td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td></tr>';
|
||||
var rh = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td><td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td>';
|
||||
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 += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(vals[ti]) + '</td>';
|
||||
}
|
||||
rh += '</tr>';
|
||||
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 = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th>';
|
||||
for (var mi = 11; mi >= 0; mi--) {
|
||||
if (isAllZero(data, tenants, ['project_gross','dept_expense','profit'], mi)) continue;
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '<th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">合计</th></tr>';
|
||||
th += '</tr>';
|
||||
|
||||
var tb = matrixTbody(data, tenants, mi, ['project_gross','dept_expense','profit'], ['项目毛利','部门费用','利润'], mf);
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-slate-300" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-blue-200" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
}
|
||||
container.innerHTML = '<div class="grid gap-2.5">' + vBtns + '<div class="flex flex-col gap-2">' + cards + '</div></div>';
|
||||
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 = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th>';
|
||||
for (var mi = 11; mi >= 0; mi--) {
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '<th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">合计</th></tr>';
|
||||
th += '</tr>';
|
||||
|
||||
if (isAllZero(data, tenants, ['project_cf','dept_cf','bl_cf'], mi)) continue;
|
||||
var th = '<tr class="border-b border-slate-200"><th class="py-1.5 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-1.5 text-right font-semibold text-slate-700 whitespace-nowrap">月度合计</th>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) { th += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + sn[ti] + '</th>'; }
|
||||
th += '</tr>';
|
||||
|
||||
var tb = matrixTbody(data, tenants, mi, ['project_cf','dept_cf','bl_cf'], ['项目现金流','部门现金流','经营现金流'], mf);
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-slate-300" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
cards += '<div class="flex items-center gap-3"><div class="text-5xl font-bold text-blue-200" style="width:120px;text-align:center;white-space:nowrap">' + mL[mi] + '</div><div class="card p-4 flex-1"><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + th + '</thead><tbody>' + tb + '</tbody></table></div></div></div>';
|
||||
}
|
||||
container.innerHTML = '<div class="grid gap-2.5">' + vBtns + '<div class="flex flex-col gap-2">' + cards + '</div></div>';
|
||||
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 = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td>';
|
||||
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 += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(v) + '</td>';
|
||||
vals.push(v);
|
||||
}
|
||||
var tCls = ts >= 0 ? 'text-green-600' : 'text-red-600';
|
||||
rh += '<td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td></tr>';
|
||||
var rh = '<tr class="border-b border-slate-100 last:border-0"><td class="py-1.5 text-left ' + rowCls + ' text-slate-700 whitespace-nowrap">' + labels[ri] + '</td><td class="py-1.5 text-right font-semibold text-sm whitespace-nowrap ' + tCls + '">' + mf(ts) + '</td>';
|
||||
for (var ti = 0; ti < tenants.length; ti++) {
|
||||
var cls = vals[ti] >= 0 ? 'text-green-600' : 'text-red-600';
|
||||
rh += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cls + '">' + mf(vals[ti]) + '</td>';
|
||||
}
|
||||
rh += '</tr>';
|
||||
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;
|
||||
}
|
||||
// ====== 项目经营详情报表 ======
|
||||
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<header class="topbar border-b border-slate-200 bg-white px-8 py-5">
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<div class="flex-1">
|
||||
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager <span class="ml-2 text-xs font-normal text-slate-400 tracking-normal">v1.2.0.26</span></p>
|
||||
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager <span class="ml-2 text-xs font-normal text-slate-400 tracking-normal">v1.2.0.28</span></p>
|
||||
<div class="flex items-center gap-4 mt-1">
|
||||
<h1 class="text-2xl font-semibold" id="workspaceTitle">科普 OPC 工作台</h1>
|
||||
<div class="hidden sm:flex items-center gap-1.5 bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-100 rounded-full px-4 py-1.5">
|
||||
|
||||
Reference in New Issue
Block a user