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:
@@ -168,9 +168,19 @@ router.get('/region/comparison', async (req: AuthRequest, res) => {
|
||||
const month = parseMonth(req)
|
||||
|
||||
const result = await query(`
|
||||
WITH store_metrics AS (
|
||||
WITH bill_region AS (
|
||||
SELECT COALESCE(ds.region, '未知区域') AS region,
|
||||
round(sum(b.consumption)::numeric, 2) AS total_consumption,
|
||||
round(sum(b.discount_total)::numeric, 2) AS total_discount
|
||||
FROM analytics.bill_fact b
|
||||
JOIN analytics.dim_store ds ON b.store_code = ds.store_code
|
||||
WHERE b.closed_at >= $1::date AND b.closed_at < ($1::date + interval '1 month')
|
||||
AND ds.region IS NOT NULL
|
||||
GROUP BY COALESCE(ds.region, '未知区域')
|
||||
),
|
||||
store_metrics AS (
|
||||
SELECT
|
||||
ds.region,
|
||||
COALESCE(ds.region, '未知区域') AS region,
|
||||
count(DISTINCT r.store_code) as store_count,
|
||||
sum(r.received) as total_revenue,
|
||||
round(avg(r.avg_bill_value)::numeric, 2) as avg_bill_value,
|
||||
@@ -180,24 +190,26 @@ router.get('/region/comparison', async (req: AuthRequest, res) => {
|
||||
FROM analytics.mv_store_risk_rating_monthly r
|
||||
JOIN analytics.dim_store ds ON r.store_code = ds.store_code
|
||||
WHERE r.month_start = $1
|
||||
AND ds.region IS NOT NULL AND ds.region != '未知区域'
|
||||
GROUP BY ds.region
|
||||
AND ds.region IS NOT NULL
|
||||
GROUP BY COALESCE(ds.region, '未知区域')
|
||||
),
|
||||
expense_metrics AS (
|
||||
SELECT
|
||||
ds.region,
|
||||
COALESCE(ds.region, '未知区域') AS region,
|
||||
avg(oe.operating_expense_rate_pct) as avg_expense_rate,
|
||||
avg(oe.rent_rate_pct) as avg_rent_rate,
|
||||
avg(oe.wage_rate_pct) as avg_wage_rate
|
||||
FROM analytics.mv_store_operating_expense_monthly oe
|
||||
JOIN analytics.dim_store ds ON oe.sales_store_code = ds.store_code
|
||||
WHERE oe.report_month = $1
|
||||
AND ds.region IS NOT NULL AND ds.region != '未知区域'
|
||||
GROUP BY ds.region
|
||||
AND ds.region IS NOT NULL
|
||||
GROUP BY COALESCE(ds.region, '未知区域')
|
||||
)
|
||||
SELECT
|
||||
sm.region,
|
||||
sm.store_count,
|
||||
br.total_consumption,
|
||||
br.total_discount,
|
||||
round(sm.total_revenue::numeric, 2) as total_revenue,
|
||||
round((sm.total_revenue / sm.store_count)::numeric, 2) as revenue_per_store,
|
||||
round(sm.avg_bill_value::numeric, 2) as avg_bill_value,
|
||||
@@ -209,6 +221,7 @@ router.get('/region/comparison', async (req: AuthRequest, res) => {
|
||||
round(em.avg_rent_rate::numeric, 2) as avg_rent_rate,
|
||||
round(em.avg_wage_rate::numeric, 2) as avg_wage_rate
|
||||
FROM store_metrics sm
|
||||
LEFT JOIN bill_region br ON sm.region = br.region
|
||||
LEFT JOIN expense_metrics em ON sm.region = em.region
|
||||
ORDER BY sm.total_revenue DESC
|
||||
`, [month])
|
||||
|
||||
Reference in New Issue
Block a user