Compare commits

...

1 Commits

Author SHA1 Message Date
mac
f5dd152ca4 feat: 季报环比+指标改名
- 部门损益/部门现金流季报Q2/Q3/Q4后增加环比列
- 部门损益卡片行改名: 毛利→项目毛利, 平台费用→部门费用
- 部门现金流卡片行改名: 平台费用→部门现金流, 部门现金流→经营现金流
- 版本号 v1.2.0.22
2026-07-11 11:50:18 +08:00
3 changed files with 23 additions and 19 deletions

View File

@@ -1027,8 +1027,8 @@ function renderFinanceOverview() {
for (var dmi = 0; dmi < 12; dmi++) { deptThead += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + mLbl[dmi] + '</th>'; }
deptThead += '</tr>';
var deptRows = [
{ label: '毛利', vals: fm.map(function(x) { return x ? x.gross : 0; }), annual: grossAnnual },
{ label: '平台费用', vals: expMonthly, annual: expAnnual },
{ label: '项目毛利', vals: fm.map(function(x) { return x ? x.gross : 0; }), annual: grossAnnual },
{ label: '部门费用', vals: expMonthly, annual: expAnnual },
{ label: '利润', vals: fm.map(function(x, i) { return (x ? x.gross : 0) - expMonthly[i]; }), annual: grossAnnual - expAnnual }
];
var deptTbody = '';
@@ -1061,8 +1061,8 @@ function renderFinanceOverview() {
var blCfAnnual = cfAnnual - expPaidAnnual;
var cfRows = [
{ label: '项目现金流', vals: cfMonthly, annual: cfAnnual },
{ label: '平台费用(支出)', vals: expPaidMonthly, annual: expPaidAnnual },
{ label: '部门现金流', vals: blCfMonthly, annual: blCfAnnual }
{ label: '部门现金流', vals: expPaidMonthly, annual: expPaidAnnual },
{ label: '经营现金流', vals: blCfMonthly, annual: blCfAnnual }
];
var cfTbody = '';
for (var cfri = 0; cfri < 3; cfri++) {
@@ -1159,11 +1159,11 @@ function renderFinanceQuarterlyOverview() {
var grossQ = [qData[2][0], qData[2][1], qData[2][2], qData[2][3]];
var grossAnnual = m.gross_annual || 0;
var deptThead = '<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 qi = 0; qi < 4; qi++) { deptThead += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">Q' + (qi+1) + '</th>'; }
for (var qi = 0; qi < 4; qi++) { deptThead += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">Q' + (qi+1) + '</th>'; if (qi > 0) deptThead += '<th class="py-1.5 text-right font-semibold text-slate-400 whitespace-nowrap">环比</th>'; }
deptThead += '</tr>';
var deptRows = [
{ label: '毛利', vals: grossQ, annual: grossAnnual },
{ label: '平台费用', vals: expQ, annual: expAnnual },
{ label: '项目毛利', vals: grossQ, annual: grossAnnual },
{ label: '部门费用', vals: expQ, annual: expAnnual },
{ label: '利润', vals: grossQ.map(function(v, i) { return v - expQ[i]; }), annual: grossAnnual - expAnnual }
];
var deptTbody = '';
@@ -1176,6 +1176,7 @@ function renderFinanceQuarterlyOverview() {
for (var qi = 0; qi < 4; qi++) {
var cellCls = dri === 2 ? (dr.vals[qi] >= 0 ? 'text-green-600' : 'text-red-600') : 'text-slate-700';
rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cellCls + '">' + moneyIntL(dr.vals[qi]) + '</td>';
if (qi > 0) rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap">' + qoq(dr.vals[qi], dr.vals[qi - 1]) + '</td>';
}
deptTbody += rowHtml + '</tr>';
}
@@ -1195,8 +1196,8 @@ function renderFinanceQuarterlyOverview() {
var blCfAnnual = cfAnnual - expPaidAnnual;
var cfRows = [
{ label: '项目现金流', vals: cfQ, annual: cfAnnual },
{ label: '平台费用(已付)', vals: expPaidQ, annual: expPaidAnnual },
{ label: '部门现金流', vals: blCfQ, annual: blCfAnnual }
{ label: '部门现金流', vals: expPaidQ, annual: expPaidAnnual },
{ label: '经营现金流', vals: blCfQ, annual: blCfAnnual }
];
var cfTbody = '';
for (var cfri = 0; cfri < 3; cfri++) {
@@ -1208,6 +1209,7 @@ function renderFinanceQuarterlyOverview() {
for (var qi = 0; qi < 4; qi++) {
var cellCls = cfri === 2 ? (blCfQ[qi] >= 0 ? 'text-green-600' : 'text-red-600') : 'text-slate-700';
rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cellCls + '">' + moneyIntL(cfdr.vals[qi]) + '</td>';
if (qi > 0) rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap">' + qoq(cfdr.vals[qi], cfdr.vals[qi - 1]) + '</td>';
}
cfTbody += rowHtml + '</tr>';
}

View File

@@ -1116,8 +1116,8 @@ function renderPlanOverview() {
for (var dmi = 0; dmi < 12; dmi++) { deptThead += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">' + mLbl[dmi] + '</th>'; }
deptThead += '</tr>';
var deptRows = [
{ label: '毛利', vals: fm.map(function(x) { return x ? x.gross : 0; }), annual: grossAnnual },
{ label: '平台费用', vals: expMonthly, annual: expAnnual },
{ label: '项目毛利', vals: fm.map(function(x) { return x ? x.gross : 0; }), annual: grossAnnual },
{ label: '部门费用', vals: expMonthly, annual: expAnnual },
{ label: '利润', vals: fm.map(function(x, i) { return (x ? x.gross : 0) - expMonthly[i]; }), annual: grossAnnual - expAnnual }
];
var deptTbody = '';
@@ -1151,8 +1151,8 @@ function renderPlanOverview() {
var blCfAnnual = cfAnnual - expPaidAnnual;
var cfRows = [
{ label: '项目现金流', vals: cfMonthly, annual: cfAnnual },
{ label: '平台费用(已付)', vals: expPaidMonthly, annual: expPaidAnnual },
{ label: '部门现金流', vals: blCfMonthly, annual: blCfAnnual }
{ label: '部门现金流', vals: expPaidMonthly, annual: expPaidAnnual },
{ label: '经营现金流', vals: blCfMonthly, annual: blCfAnnual }
];
var cfTbody = '';
for (var cfri = 0; cfri < 3; cfri++) {
@@ -1253,11 +1253,11 @@ function renderPlanQuarterlyOverview() {
var grossQ = [qData[2][0], qData[2][1], qData[2][2], qData[2][3]];
var grossAnnual = annualSums2.gross;
var deptThead = '<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 qi = 0; qi < 4; qi++) { deptThead += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">Q' + (qi+1) + '</th>'; }
for (var qi = 0; qi < 4; qi++) { deptThead += '<th class="py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap">Q' + (qi+1) + '</th>'; if (qi > 0) deptThead += '<th class="py-1.5 text-right font-semibold text-slate-400 whitespace-nowrap">环比</th>'; }
deptThead += '</tr>';
var deptRows = [
{ label: '毛利', vals: grossQ, annual: grossAnnual },
{ label: '平台费用', vals: expQ, annual: expAnnual },
{ label: '项目毛利', vals: grossQ, annual: grossAnnual },
{ label: '部门费用', vals: expQ, annual: expAnnual },
{ label: '利润', vals: grossQ.map(function(v, i) { return v - expQ[i]; }), annual: grossAnnual - expAnnual }
];
var deptTbody = '';
@@ -1270,6 +1270,7 @@ function renderPlanQuarterlyOverview() {
for (var qi = 0; qi < 4; qi++) {
var cellCls = dri === 2 ? (dr.vals[qi] >= 0 ? 'text-green-600' : 'text-red-600') : 'text-slate-700';
rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cellCls + '">' + moneyIntL(dr.vals[qi]) + '</td>';
if (qi > 0) rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap">' + qoq(dr.vals[qi], dr.vals[qi - 1]) + '</td>';
}
deptTbody += rowHtml + '</tr>';
}
@@ -1288,8 +1289,8 @@ function renderPlanQuarterlyOverview() {
var blCfAnnual = cfAnnual - expPaidAnnual;
var cfRows = [
{ label: '项目现金流', vals: cfQ, annual: cfAnnual },
{ label: '平台费用(已付)', vals: expPaidQ, annual: expPaidAnnual },
{ label: '部门现金流', vals: blCfQ, annual: blCfAnnual }
{ label: '部门现金流', vals: expPaidQ, annual: expPaidAnnual },
{ label: '经营现金流', vals: blCfQ, annual: blCfAnnual }
];
var cfTbody = '';
for (var cfri = 0; cfri < 3; cfri++) {
@@ -1301,6 +1302,7 @@ function renderPlanQuarterlyOverview() {
for (var qi = 0; qi < 4; qi++) {
var cellCls = cfri === 2 ? (blCfQ[qi] >= 0 ? 'text-green-600' : 'text-red-600') : 'text-slate-700';
rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap ' + cellCls + '">' + moneyIntL(cfdr.vals[qi]) + '</td>';
if (qi > 0) rowHtml += '<td class="py-1.5 text-right text-sm whitespace-nowrap">' + qoq(cfdr.vals[qi], cfdr.vals[qi - 1]) + '</td>';
}
cfTbody += rowHtml + '</tr>';
}

View File

@@ -76,7 +76,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.21</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.22</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">