Merge branch 'dev'
All checks were successful
Deploy / deploy (push) Successful in 12s

This commit is contained in:
mac
2026-07-06 21:42:24 +08:00
3 changed files with 8 additions and 8 deletions

View File

@@ -67,7 +67,7 @@ def migrate_add_columns():
_add_column_if_missing(conn, "project_finances", col,
f"ALTER TABLE project_finances ADD COLUMN {col} DOUBLE NOT NULL DEFAULT 0")
# project_finances 总视图字段:已回款 / 应付 / 已付
# project_finances 总视图字段:已回款 / 成本 / 已付
_add_column_if_missing(conn, "project_finances", "total_payment",
"ALTER TABLE project_finances ADD COLUMN total_payment DOUBLE NOT NULL DEFAULT 0")
_add_column_if_missing(conn, "project_finances", "total_cost",

View File

@@ -188,7 +188,7 @@ function renderFinance() {
<div id="financeTabCost" class="hidden">
<div class="grid grid-cols-2 gap-3 mb-4" id="costSummary">
<div class="bg-rose-50 rounded-lg p-3 text-center border border-rose-100">
<p class="text-xs text-rose-600 font-medium">应付</p>
<p class="text-xs text-rose-600 font-medium">成本</p>
<p class="text-lg font-bold text-rose-700" id="costTotalCost">¥0</p>
</div>
<div class="bg-purple-50 rounded-lg p-3 text-center border border-purple-100">
@@ -197,7 +197,7 @@ function renderFinance() {
</div>
</div>
<table class="w-full text-sm border border-slate-200 rounded-lg overflow-hidden" id="costTable">
<thead><tr class="bg-slate-50 border-b border-slate-200"><th class="p-2.5 text-left font-medium text-slate-500" style="min-width:140px">月份</th><th class="p-2.5 text-left font-medium text-slate-500" style="min-width:120px"></th><th class="p-2.5 text-right font-medium text-slate-500"></th><th class="p-2.5 text-right font-medium text-slate-500"></th><th class="p-2.5 text-left font-medium text-slate-500"></th><th class="p-2.5 w-8"></th></tr></thead>
<thead><tr class="bg-slate-50 border-b border-slate-200"><th class="p-2.5 text-left font-medium text-slate-500" style="min-width:140px">月份</th><th class="p-2.5 text-left font-medium text-slate-500" style="min-width:120px"></th><th class="p-2.5 text-right font-medium text-slate-500"></th><th class="p-2.5 text-right font-medium text-slate-500"></th><th class="p-2.5 text-left font-medium text-slate-500"></th><th class="p-2.5 w-8"></th></tr></thead>
<tbody id="costTbody"></tbody>
</table>
<button type="button" class="btn btn-ghost btn-sm mt-3" onclick="addCostRow()"><i data-lucide="plus"></i></button>
@@ -238,7 +238,7 @@ function renderFinance() {
{ label: '签约金额', value: ctx => moneyWan(ctx.signTotal), color: 'text-slate-700' },
{ label: '已确收', value: ctx => moneyWan(ctx.sumRev), color: 'text-blue-700' },
{ label: '毛利', value: ctx => money(ctx.sumGross), color: 'text-green-700' },
{ label: '应付', value: ctx => moneyWan(ctx.sumCost), color: 'text-rose-700' },
{ label: '成本', value: ctx => moneyWan(ctx.sumCost), color: 'text-rose-700' },
{ label: '项目利润', value: ctx => { const v = ctx.sumGross; return { val: moneyWan(v), cls: v >= 0 ? 'text-green-600' : 'text-red-600' }; }, color: null },
{ label: '已回款', value: ctx => moneyWan(ctx.sumPay), color: 'text-amber-700' },
{ label: '已付', value: ctx => moneyWan(ctx.sumPaid), color: 'text-purple-700' },
@@ -261,7 +261,7 @@ function renderFinance() {
'<th class="p-2 text-center font-semibold align-middle">签约金额</th>' +
'<th class="p-2 text-center font-semibold align-middle text-blue-600">已确收</th>' +
'<th class="p-2 text-center font-semibold align-middle">毛利</th>' +
'<th class="p-2 text-center font-semibold align-middle text-rose-600">应付</th>' +
'<th class="p-2 text-center font-semibold align-middle text-rose-600">成本</th>' +
'<th class="p-2 text-center font-semibold align-middle">项目利润</th>' +
'<th class="p-2 text-center font-semibold align-middle text-amber-600">已回款</th>' +
'<th class="p-2 text-center font-semibold align-middle text-purple-600">已付</th>' +
@@ -274,7 +274,7 @@ function renderFinance() {
const tbody = rows.length ? `<tbody>${rows.join("")}</tbody>` : `<tr><td colspan="15" class="p-6 text-center text-slate-400">${emptyText}</td></tr>`;
return card(`<div class="grid grid-cols-6 gap-3 mb-3">${cards.map(([l, v, c]) => '<div class="metric-card p-3"><span class="flex items-center gap-2 text-xs text-slate-500">' + l + '</span><strong class="mt-2 block text-xl ' + c + '">' + v + '</strong></div>').join("")}</div>`, "p-4") +
card(`<h3 class="text-sm font-bold text-slate-700">项目财务明细</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 应付 → 项目利润 → 回款 → 已付 → 现金流 → 执行率 → 毛利率 → 回款率 → 付款率</p><div class="overflow-x-auto"><table class="w-full text-sm">${thead}${tbody}</table></div>`, "p-4");
card(`<h3 class="text-sm font-bold text-slate-700">项目财务明细</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 已付 → 现金流 → 执行率 → 毛利率 → 回款率 → 付款率</p><div class="overflow-x-auto"><table class="w-full text-sm">${thead}${tbody}</table></div>`, "p-4");
};
const fmtNoUnit = (v) => v ? `<span class="font-medium">${Number(v||0).toLocaleString('zh-CN')}</span>` : '<span class="text-slate-300">—</span>';

View File

@@ -75,7 +75,7 @@ function renderHome() {
return '<span class="' + cls + '">' + sign + pct + '%</span>';
};
const COLORS = ['text-slate-700','text-blue-600','text-green-600','text-rose-600','text-indigo-600','text-amber-600','text-purple-600','text-cyan-600'];
const LABELS = ['合同金额','确收金额','确收毛利','应付金额','项目利润','回款金额','已付','现金流'];
const LABELS = ['合同金额','确收金额','确收毛利','成本','项目利润','回款金额','已付','现金流'];
const Q_FIELDS = [m.signed_q2||0, m.revenue_q2, m.gross_q2, m.cost_q2||0, m.profit_q2||0, m.payment_q2||0, m.paid_q2||0, m.cashflow_q2||0];
const Q_PREV = [m.signed_prev_q||0, m.revenue_prev_q||0, m.gross_prev_q||0, m.cost_prev_q||0, m.profit_prev_q||0, m.payment_prev_q||0, m.paid_prev_q||0, m.cashflow_prev_q||0];
const M_FIELDS = [m.signed_month||0, m.monthly_revenue, m.monthly_net_profit, m.cost_month||0, m.profit_month||0, m.payment_month||0, m.paid_month||0, m.cashflow_month||0];
@@ -145,7 +145,7 @@ function renderHome() {
return h;
})()}
</tbody></table></div>`, "p-4")}
${card(`<h3 class="text-sm font-bold text-slate-700">业务(项目)财务概览</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 应付 → 项目利润 → 回款 → 已付 → 现金流</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>${thead}</thead><tbody>${tbody}</tbody></table></div>`, "p-4")}
${card(`<h3 class="text-sm font-bold text-slate-700">业务(项目)财务概览</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 已付 → 现金流</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>${thead}</thead><tbody>${tbody}</tbody></table></div>`, "p-4")}
<div class="grid grid-cols-4 gap-5">
${card(`<div class="mb-3 flex items-center justify-between"><h2 class="text-sm font-bold text-slate-600">月度签约趋势</h2><span class="text-xs text-slate-400">2026</span></div><div style="position:relative;height:200px"><canvas id="chartSign"></canvas></div>`, "p-4")}
${card(`<div class="mb-3 flex items-center justify-between"><h2 class="text-sm font-bold text-slate-600">月度确收与毛利</h2><span class="text-xs text-slate-400">2026</span></div><div style="position:relative;height:200px"><canvas id="chartRev"></canvas></div>`, "p-4")}