优化财务仪表盘查询性能

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
@@ -19,11 +19,23 @@ func (r *Repository) Details(ctx context.Context, query DetailQuery) (*Paginated
return &PaginatedResult{Items: []FinanceDetailDTO{}, Total: 0, Page: query.Page, PageSize: query.PageSize}, nil
}
// 明细行查询保留完整 JOIN,仅对当前分页命中的订单做金额聚合。
db := r.financeDetailBaseQuery(ctx, query)
offset := (query.Page - 1) * query.PageSize
orderIDs := make([]uint64, 0, query.PageSize)
if err := r.applyDetailFilters(r.db.WithContext(ctx).Table("rental_orders AS ro"), query).
Order("ro.id DESC").
Offset(offset).
Limit(query.PageSize).
Pluck("ro.id", &orderIDs).Error; err != nil {
return nil, err
}
if len(orderIDs) == 0 {
return &PaginatedResult{Items: []FinanceDetailDTO{}, Total: total, Page: query.Page, PageSize: query.PageSize}, nil
}
// 先取当前页 ID,再只为这些订单聚合结账、支付和钱包详情。
db := r.financeDetailBaseQuery(ctx, query, orderIDs).Where("ro.id IN ?", orderIDs)
rows := make([]financeDetailRow, 0, query.PageSize)
if err := db.Order("ro.id DESC").Offset(offset).Limit(query.PageSize).Scan(&rows).Error; err != nil {
if err := db.Order("ro.id DESC").Scan(&rows).Error; err != nil {
return nil, err
}
items := make([]FinanceDetailDTO, 0, len(rows))
@@ -67,7 +79,7 @@ func (r *Repository) applyDetailFilters(db *gorm.DB, query DetailQuery) *gorm.DB
return db
}
func (r *Repository) financeDetailBaseQuery(ctx context.Context, query DetailQuery) *gorm.DB {
func (r *Repository) financeDetailBaseQuery(ctx context.Context, query DetailQuery, orderIDs []uint64) *gorm.DB {
db := r.db.WithContext(ctx).Table("rental_orders AS ro").
Select(`ro.id AS order_id, ro.order_no, ro.status AS order_status, ro.settlement_status, ro.refund_status,
ro.handoff_mode, ro.settlement_mode,
@@ -113,9 +125,9 @@ func (r *Repository) financeDetailBaseQuery(ctx context.Context, query DetailQue
ro.created_at, ro.settled_at, ro.offline_settled_at`, settlementDiffThresholdCent).
Joins("LEFT JOIN users AS ru ON ru.id = ro.renter_id").
Joins("LEFT JOIN users AS ou ON ou.id = ro.owner_id").
Joins("LEFT JOIN (?) AS oc ON oc.order_id = ro.id", acceptedCheckoutSubquery(r.db.WithContext(ctx))).
Joins("LEFT JOIN (?) AS p ON p.order_id = ro.id", orderPaymentSubquery(r.db.WithContext(ctx))).
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(r.db.WithContext(ctx)))
Joins("LEFT JOIN (?) AS oc ON oc.order_id = ro.id", acceptedCheckoutForOrdersSubquery(r.db.WithContext(ctx), orderIDs)).
Joins("LEFT JOIN (?) AS p ON p.order_id = ro.id", orderPaymentForOrdersSubquery(r.db.WithContext(ctx), orderIDs)).
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeForOrdersSubquery(r.db.WithContext(ctx), orderIDs))
return r.applyDetailFilters(db, query)
}