优化财务仪表盘查询性能

This commit is contained in:
yml2213
2026-09-04 21:37:47 +08:00
parent 7a8773d25d
commit ba5aa48c8f
11 changed files with 1748 additions and 242 deletions
@@ -4,14 +4,16 @@ import (
"gorm.io/gorm"
)
func acceptedCheckoutSubquery(db *gorm.DB) *gorm.DB {
latest := db.Table("order_checkouts").Select("MAX(id) AS id").Where("status = ?", "accepted").Group("order_id")
func acceptedCheckoutForOrdersSubquery(db *gorm.DB, orderIDs []uint64) *gorm.DB {
latest := db.Table("order_checkouts").Select("MAX(id) AS id").
Where("status = ? AND order_id IN ?", "accepted", orderIDs).
Group("order_id")
return db.Table("order_checkouts AS oc").
Select("oc.*").
Joins("JOIN (?) AS latest ON latest.id = oc.id", latest)
}
func orderPaymentSubquery(db *gorm.DB) *gorm.DB {
func orderPaymentForOrdersSubquery(db *gorm.DB, orderIDs []uint64) *gorm.DB {
return db.Table("payment_orders").
Select(`order_id,
COALESCE(SUM(CASE WHEN biz_type = 'order_pay' AND status = 'paid' THEN amount_cent ELSE 0 END), 0) AS paid_amount_cent,
@@ -19,13 +21,14 @@ func orderPaymentSubquery(db *gorm.DB) *gorm.DB {
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunding' THEN amount_cent ELSE 0 END), 0) AS refunding_amount_cent,
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'failed' THEN amount_cent ELSE 0 END), 0) AS failed_refund_amount_cent`,
refundBizTypes(), refundBizTypes(), refundBizTypes()).
Where("order_id IN ?", orderIDs).
Group("order_id")
}
func ownerWalletIncomeSubquery(db *gorm.DB) *gorm.DB {
func ownerWalletIncomeForOrdersSubquery(db *gorm.DB, orderIDs []uint64) *gorm.DB {
return db.Table("wallet_ledger").
Select("order_id, COALESCE(SUM(amount_cent), 0) AS owner_wallet_income_amount_cent").
Where("direction = ? AND biz_type IN ? AND order_id IS NOT NULL", "in", []string{"owner_income", "deposit_compensation", "arbitration_owner_income"}).
Where("direction = ? AND biz_type IN ? AND order_id IN ?", "in", []string{"owner_income", "deposit_compensation", "arbitration_owner_income"}, orderIDs).
Group("order_id")
}
@@ -44,18 +47,6 @@ func ownerWalletIncomeForSettledOrdersSubquery(db *gorm.DB, query DashboardQuery
Group("scoped_order.id")
}
// orderPaymentForSettledOrdersSubquery 只聚合当前结算区间订单的退款状态,
// 供仪表盘异常数判断使用,避免 financeDetailBaseQuery 在首页扫描所有历史付款单。
func orderPaymentForSettledOrdersSubquery(db *gorm.DB, query DashboardQuery) *gorm.DB {
return db.Table("rental_orders AS scoped_order").
Select(`scoped_order.id AS order_id,
COALESCE(SUM(CASE WHEN payment.biz_type IN ? AND payment.status = 'refunding' THEN payment.amount_cent ELSE 0 END), 0) AS refunding_amount_cent,
COALESCE(SUM(CASE WHEN payment.biz_type IN ? AND payment.status = 'failed' THEN payment.amount_cent ELSE 0 END), 0) AS failed_refund_amount_cent`, refundBizTypes(), refundBizTypes()).
Joins("LEFT JOIN payment_orders AS payment ON payment.order_id = scoped_order.id AND payment.biz_type IN ?", refundBizTypes()).
Where("scoped_order.settled_at >= ? AND scoped_order.settled_at <= ?", query.StartDate, query.EndDate).
Group("scoped_order.id")
}
// paymentOriginalAmountForRefundsInRangeSubquery 仅为当前区间内的退款单回查原支付金额。
// 退款统计原先会对全部历史支付单按 order_id 聚合;数据增长后这部分即使只看一天也会很慢。
func paymentOriginalAmountForRefundsInRangeSubquery(db *gorm.DB, query DashboardQuery) *gorm.DB {