feat: 全页面增加营业收入/优惠指标 + 修复趋势预测空数据 + 区域对比口径统一 + StorePage最新经营日概览

- 后端: 所有API的discount改为从bill_fact累计discount_total
- 后端: revenue/daily-summary增加consumption字段
- 后端: situational-awareness/forecast修复c175字符串比较为timestamp
- 后端: region/comparison去掉未知区域排除,统一口径
- 后端: daily-card增加营业收入/优惠指标,返回target_date/baseline_date
- 前端: BossPage/DashboardPage/BankPage/StorePage/ExpenseOverviewTab/RegionalPage/RegionComparisonPage/RevenuePage 均增加营业收入和优惠指标卡
- 前端: StorePage日均经营概览改为最新经营日概览,显示具体对比日期
- 前端: 日期格式统一截取YYYY-MM-DD显示
This commit is contained in:
freedakgmail
2026-08-02 14:56:00 +08:00
parent a1a8b7ee5e
commit 271ad8041d
13 changed files with 204 additions and 76 deletions
+13 -6
View File
@@ -154,7 +154,9 @@ export function BossPage() {
// 利润瀑布数据
const waterfallSteps = wf ? [
{ name: '实收', value: Number(wf.received), type: 'total' },
{ name: '营业收入', value: Number(wf.consumption), type: 'total' },
{ name: '优惠', value: -Number(wf.discount), type: 'cost' },
{ name: '实收', value: Number(wf.received), type: 'subtotal' },
{ name: '食材成本', value: -Number(wf.food_cost), type: 'cost' },
{ name: '人工', value: -Number(wf.wage), type: 'cost' },
{ name: '房租', value: -Number(wf.rent), type: 'cost' },
@@ -171,6 +173,9 @@ export function BossPage() {
if (step.type === 'total') {
cumulative = step.value
return { name: step.name, base: 0, value: step.value, fill: '#3b82f6' }
} else if (step.type === 'subtotal') {
cumulative = step.value
return { name: step.name, base: 0, value: step.value, fill: '#6366f1' }
} else if (step.type === 'profit') {
return { name: step.name, base: 0, value: step.value, fill: '#22c55e' }
} else {
@@ -218,11 +223,13 @@ export function BossPage() {
</div>
{/* ① 核心经营指标 */}
<div className="grid grid-cols-2 gap-3 md:grid-cols-4">
<MetricCard title="实收总额" value={ex?.total_received} format="currency" trend={trendReceived} description={`全口径${ex?.total_stores}家门店。公式:全部门店实收合计。环比上周 ${trendReceived > 0 ? '↑' : '↓'} ${Math.abs(trendReceived)}%`} />
<MetricCard title="门店贡献利润估算" value={ex?.actual_net_profit} format="currency" status={Number(ex?.actual_net_margin_pct) < 5 ? 'bad' : Number(ex?.actual_net_margin_pct) < 10 ? 'warn' : 'good'} description={`贡献率 ${formatPercent(ex?.actual_net_margin_pct)} · 公式:实收 - 食材成本 - 经营费用(仅费用已匹配门店)。建议值:≥ 10% 优秀,5-10% 合格,< 5% 需整改`} />
<MetricCard title="门店数" value={ex?.total_stores} unit="家" description={`盈利 ${ex?.profitable_stores} / 亏损 ${ex?.loss_stores}家。无费用数据 ${ex?.no_expense_stores}`} />
<MetricCard title="客单价" value={ex?.avg_bill_value} format="currency" trend={trend((last7.length > 0 ? sumKey(last7, 'received') / sumKey(last7, 'bill_count') : 0), (prev7.length > 0 ? sumKey(prev7, 'received') / sumKey(prev7, 'bill_count') : 0))} description={`账单 ${formatNumber(ex?.total_bills)} 笔 · 公式:实收 ÷ 账单数`} />
<div className="grid grid-cols-2 gap-3 md:grid-cols-3 lg:grid-cols-6">
<MetricCard title="营业收入" value={ex?.total_consumption} format="currency" description="全部门店消费金额合计" />
<MetricCard title="优惠" value={ex?.total_discount} format="currency" description="各类优惠扣减合计" />
<MetricCard title="实收总额" value={ex?.total_received} format="currency" trend={trendReceived} description={`全口径${ex?.total_stores}门店。环比上周 ${trendReceived > 0 ? '↑' : '↓'} ${Math.abs(trendReceived)}%`} />
<MetricCard title="门店贡献利润估算" value={ex?.actual_net_profit} format="currency" status={Number(ex?.actual_net_margin_pct) < 5 ? 'bad' : Number(ex?.actual_net_margin_pct) < 10 ? 'warn' : 'good'} description={`贡献率 ${formatPercent(ex?.actual_net_margin_pct)}`} />
<MetricCard title="门店数" value={ex?.total_stores} unit="家" description={`盈利 ${ex?.profitable_stores}家 / 亏损 ${ex?.loss_stores}`} />
<MetricCard title="客单价" value={ex?.avg_bill_value} format="currency" trend={trend((last7.length > 0 ? sumKey(last7, 'received') / sumKey(last7, 'bill_count') : 0), (prev7.length > 0 ? sumKey(prev7, 'received') / sumKey(prev7, 'bill_count') : 0))} description={`账单 ${formatNumber(ex?.total_bills)}`} />
</div>
{/* ①b KPI达成率 */}