feat: 首页重构 — 财务概览转置+部门经营卡片+命名统一
首页: - 5卡片→表格(行=指标,列=时间),新增已付/现金流/项目利润行,费用行 - 行列对换:8列(年度/季度/季环比/本月/月环比/上季度/上月)×9行 - 新增「部门经营情况」卡片(部门利润/费用/净利) - 趋势图3→4列,新增月度项目利润折线图(indigo) - 命名:利润→项目利润,费用→项目费用,月度利润→月度项目利润 - 卡片改名:经营管理→项目管理,财务概览→业务(项目)财务概览 - 指标列统一颜色,去掉行编号 项目模块: - 利润→项目利润,费用→项目费用,总费用→总项目费用 - 月度回款与费用→月度回款与已付,柱状图→折线图 后端: - 新增paid/cashflow/profit指标聚合(单/多租户) - monthly_finance新增paid字段 - helpers.py修复重复return data
This commit is contained in:
@@ -186,12 +186,12 @@ function renderFinance() {
|
||||
<p class="text-lg font-bold text-purple-700" id="budgetTotalPaid">¥0</p>
|
||||
</div>
|
||||
<div class="bg-orange-50 rounded-lg p-3 text-center border border-orange-100" id="budgetTotalExpenseCard">
|
||||
<p class="text-xs text-orange-600 font-medium">总费用</p>
|
||||
<p class="text-xs text-orange-600 font-medium">总项目费用</p>
|
||||
<p class="text-lg font-bold text-orange-700" id="budgetTotalExpense">¥0</p>
|
||||
</div>
|
||||
</div>
|
||||
<table class="w-full text-sm border border-slate-200 rounded-lg overflow-hidden" id="budgetTable">
|
||||
<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-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-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-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 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-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-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-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 w-8"></th></tr></thead>
|
||||
<tbody id="budgetTbody"></tbody>
|
||||
</table>
|
||||
<button type="button" class="btn btn-ghost btn-sm mt-3" onclick="addBudgetRow()"><i data-lucide="plus"></i>添加月份</button>
|
||||
@@ -235,14 +235,14 @@ function renderFinance() {
|
||||
{ label: '执行率', value: ctx => ctx.sumRev && ctx.signTotal ? Math.round(ctx.sumRev / ctx.signTotal * 100) + '%' : '—', color: 'text-slate-500' },
|
||||
{ label: '毛利', value: ctx => money(ctx.sumGross), color: 'text-green-700' },
|
||||
{ label: '毛利率', value: ctx => ctx.sumRev && ctx.sumGross ? Math.round(ctx.sumGross / ctx.sumRev * 100) + '%' : '—', color: 'text-slate-500' },
|
||||
{ label: '费用', value: ctx => money(ctx.sumExpense), color: 'text-orange-700' },
|
||||
{ label: '项目费用', value: ctx => money(ctx.sumExpense), color: 'text-orange-700' },
|
||||
{ label: '已回款', value: ctx => moneyWan(ctx.sumPay), color: 'text-amber-700' },
|
||||
{ label: '回款率', value: ctx => ctx.sumRev && ctx.sumPay ? Math.round(ctx.sumPay / ctx.sumRev * 100) + '%' : '—', color: 'text-slate-500' },
|
||||
{ label: '应付', value: ctx => moneyWan(ctx.sumCost), color: 'text-rose-700' },
|
||||
{ label: '已付', value: ctx => moneyWan(ctx.sumPaid), color: 'text-purple-700' },
|
||||
{ label: '付款率', value: ctx => ctx.sumCost && ctx.sumPaid ? Math.round(ctx.sumPaid / ctx.sumCost * 100) + '%' : '—', color: 'text-slate-500' },
|
||||
{ label: '现金流', value: ctx => { const v = ctx.sumPay - ctx.sumPaid; return { val: money(v), cls: v >= 0 ? 'text-green-600' : 'text-red-600' }; }, color: null },
|
||||
{ label: '利润', value: ctx => { const v = ctx.sumGross - ctx.sumExpense; return { val: moneyWan(v), cls: v >= 0 ? 'text-green-600' : 'text-red-600' }; }, color: null },
|
||||
{ label: '项目利润', value: ctx => { const v = ctx.sumGross - ctx.sumExpense; return { val: moneyWan(v), cls: v >= 0 ? 'text-green-600' : 'text-red-600' }; }, color: null },
|
||||
];
|
||||
|
||||
const renderView = (rows, sumRev, sumPay, sumCost, sumPaid, sumGross, sumExpense, signTotal, signCnt, emptyText) => {
|
||||
@@ -264,9 +264,9 @@ function renderFinance() {
|
||||
'<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-purple-600">已付</th>' +
|
||||
'<th class="p-2 text-center font-semibold align-middle">付款率</th>' +
|
||||
'<th class="p-2 text-center font-semibold align-middle text-orange-600">费用</th>' +
|
||||
'<th class="p-2 text-center font-semibold align-middle text-orange-600">项目费用</th>' +
|
||||
'<th class="p-2 text-center font-semibold align-middle text-slate-700">现金流</th>' +
|
||||
'<th class="p-2 text-center font-semibold align-middle">利润</th>' +
|
||||
'<th class="p-2 text-center font-semibold align-middle">项目利润</th>' +
|
||||
'</tr></thead>';
|
||||
const tbody = rows.length ? `<tbody>${rows.join("")}</tbody>` : `<tr><td colspan="15" class="p-6 text-center text-slate-400">${emptyText}</td></tr>`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user