fix: 修复/overview API理论毛利率和会员占比硬编码为0

- theoretical_margin_pct: 从bill_fact实时计算 sum(theoretical_profit)/sum(received)*100
- member_share_pct: 从bill_fact实时计算 会员账单实收/总实收*100
- member_bills: 统计member_id非空的账单数
- 修复前: 理论毛利率0% 会员占比0%
- 修复后: 理论毛利率61.84% 会员占比14.25%
This commit is contained in:
freedakgmail
2026-08-11 20:04:36 +08:00
parent baa49d1a94
commit 5ffde42590
+14 -8
View File
@@ -20,9 +20,9 @@ router.get('/overview', async (req: AuthRequest, res) => {
round(sum(received_total)::numeric, 2) AS received,
round(avg(received_total)::numeric, 2) AS avg_bill_value,
round(avg(CASE WHEN consumption > 0 THEN discount_total::numeric / consumption * 100 ELSE 0 END)::numeric, 2) AS discount_rate_pct,
0 AS theoretical_margin_pct,
0 AS member_bills,
0 AS member_share_pct,
round(sum(theoretical_profit) / nullif(sum(received_total), 0) * 100, 2) AS theoretical_margin_pct,
count(*) FILTER (WHERE member_id IS NOT NULL AND member_id <> '') AS member_bills,
round(sum(received_total) FILTER (WHERE member_id IS NOT NULL AND member_id <> '') / nullif(sum(received_total), 0) * 100, 2) AS member_share_pct,
round(sum(consumption)::numeric, 2) AS consumption,
round(sum(discount_total)::numeric, 2) AS discount
FROM analytics.bill_fact
@@ -31,13 +31,19 @@ router.get('/overview', async (req: AuthRequest, res) => {
sendSuccess(res, result.rows[0])
} else {
const result = await query(`
SELECT o.bill_count, o.received, o.avg_bill_value, o.discount_rate_pct, o.theoretical_margin_pct, o.member_bills, o.member_share_pct,
round(b.consumption::numeric, 2) AS consumption,
round(b.discount::numeric, 2) AS discount
SELECT o.bill_count, o.received, o.avg_bill_value, o.discount_rate_pct,
round(b.theoretical_margin_pct, 2) AS theoretical_margin_pct,
b.member_bills, b.member_share_pct,
round(b.consumption, 2) AS consumption,
round(b.discount, 2) AS discount
FROM analytics.mv_overview_monthly o
LEFT JOIN (
SELECT round(sum(consumption)::numeric, 2) AS consumption,
round(sum(discount_total)::numeric, 2) AS discount
SELECT
round(sum(consumption)::numeric, 2) AS consumption,
round(sum(discount_total)::numeric, 2) AS discount,
round(sum(theoretical_profit) / nullif(sum(received_total), 0) * 100, 2) AS theoretical_margin_pct,
count(*) FILTER (WHERE member_id IS NOT NULL AND member_id <> '') AS member_bills,
round(sum(received_total) FILTER (WHERE member_id IS NOT NULL AND member_id <> '') / nullif(sum(received_total), 0) * 100, 2) AS member_share_pct
FROM analytics.bill_fact
WHERE closed_at >= $1::date AND closed_at < ($1::date + interval '1 month')
) b ON true