feat: 整合菜单7组 + 新增营收分析页面(渠道/时段/门店排名/日度趋势)

This commit is contained in:
freedakgmail
2026-07-30 15:01:49 +08:00
parent 188f607fbb
commit 1664247882
4 changed files with 450 additions and 11 deletions
+96
View File
@@ -564,4 +564,100 @@ router.get('/overview/store-profit-ranking', async (req: AuthRequest, res) => {
}
})
// ============ 营收分析 ============
// 渠道收入结构
router.get('/revenue/channel', async (req: AuthRequest, res) => {
try {
const result = await query(`
SELECT
business_date,
round(cash::numeric, 2) AS cash,
round(alipay::numeric, 2) AS alipay,
round(wechat::numeric, 2) AS wechat,
round(meituan::numeric, 2) AS meituan,
round(unionpay::numeric, 2) AS unionpay,
round(douyin::numeric, 2) AS douyin,
round(credit::numeric, 2) AS credit,
round(jd_delivery::numeric, 2) AS jd_delivery,
round(meituan_delivery::numeric, 2) AS meituan_delivery,
round(taobao_delivery::numeric, 2) AS taobao_delivery
FROM analytics.v_channel_daily
WHERE business_date >= DATE '2026-04-01'
ORDER BY business_date
`)
sendSuccess(res, result.rows)
} catch (err: any) {
sendError(res, err.message)
}
})
// 时段收入分布
router.get('/revenue/meal-period', async (req: AuthRequest, res) => {
try {
const result = await query(`
SELECT
meal_period,
sum(bill_count)::bigint AS bill_count,
round(sum(received)::numeric, 2) AS received,
round(avg(avg_bill_value)::numeric, 2) AS avg_bill_value
FROM analytics.v_meal_period_daily
WHERE business_date >= DATE '2026-04-01'
GROUP BY meal_period
ORDER BY sum(received) DESC
`)
sendSuccess(res, result.rows)
} catch (err: any) {
sendError(res, err.message)
}
})
// 门店营收排名
router.get('/revenue/store-ranking', async (req: AuthRequest, res) => {
try {
const result = await query(`
SELECT
store_code,
store_name,
sum(bill_count)::bigint AS bill_count,
round(sum(received)::numeric, 2) AS received,
round(sum(discounts)::numeric, 2) AS discounts,
round(avg(discount_rate_pct)::numeric, 2) AS avg_discount_rate_pct,
round(avg(avg_bill_value)::numeric, 2) AS avg_bill_value,
round(sum(guests)::numeric, 0) AS guests,
round(avg(theoretical_margin_pct)::numeric, 2) AS avg_theoretical_margin_pct
FROM analytics.v_store_daily
WHERE business_date >= DATE '2026-04-01'
GROUP BY store_code, store_name
ORDER BY sum(received) DESC
`)
sendSuccess(res, result.rows)
} catch (err: any) {
sendError(res, err.message)
}
})
// 日度营收汇总
router.get('/revenue/daily-summary', async (req: AuthRequest, res) => {
try {
const result = await query(`
SELECT
business_date,
sum(bill_count)::bigint AS bill_count,
round(sum(received)::numeric, 2) AS received,
round(sum(discounts)::numeric, 2) AS discounts,
round(avg(discount_rate_pct)::numeric, 2) AS avg_discount_rate_pct,
round(avg(avg_bill_value)::numeric, 2) AS avg_bill_value,
round(sum(guests)::numeric, 0) AS guests
FROM analytics.v_store_daily
WHERE business_date >= DATE '2026-04-01'
GROUP BY business_date
ORDER BY business_date
`)
sendSuccess(res, result.rows)
} catch (err: any) {
sendError(res, err.message)
}
})
export default router