fix: 避免充值ID排序误用主键扫描历史流水

This commit is contained in:
Yvan
2026-11-05 01:57:06 +08:00
parent 10600d1bc9
commit 22d78b2dd6
+13 -2
View File
@@ -297,9 +297,20 @@ func (r *ledgerRepo) Spends(ctx context.Context, scope business.LedgerScope, fil
}
var pos []spendPO
// 先在窄查询中选出当前页主键,再读取明细列,避免为排序读取整段流水。
keysQuery := q.Select("r.id,r.source_db").Order(order).Order("r.id DESC,r.source_db ASC").Offset(options.Offset).Limit(options.Limit)
keysBase := q
tieOrder := "r.id DESC,r.source_db ASC"
if filter.SortField == "id" {
tieOrder = "r.source_db ASC"
if db.Dialector.Name() == "mysql" {
// LIMIT can make MySQL prefer scanning the primary key from its
// beginning, even when recent payments are near the end of history.
// Preserve selective time/scope indexes and sort the matching keys.
keysBase = q.Table("tab_spend r IGNORE INDEX FOR ORDER BY (PRIMARY)")
}
}
keysQuery := keysBase.Select("r.id,r.source_db").Order(order).Order(tieOrder).Offset(options.Offset).Limit(options.Limit)
pageQuery := db.Table("tab_spend r").Joins("JOIN (?) page_ids ON page_ids.id=r.id AND page_ids.source_db=r.source_db", keysQuery)
if err := pageQuery.Select("r.id,r.source_db,r.user_id,r.pay_order_number,r.game_id,r.game_name,r.server_id,r.server_name,r.game_player_name,r.pay_amount,r.pay_time,r.pay_way,r.pay_status,r.spend_ip,r.promote_id,r.promote_account").Order(order).Order("r.id DESC,r.source_db ASC").Scan(&pos).Error; err != nil {
if err := pageQuery.Select("r.id,r.source_db,r.user_id,r.pay_order_number,r.game_id,r.game_name,r.server_id,r.server_name,r.game_player_name,r.pay_amount,r.pay_time,r.pay_way,r.pay_status,r.spend_ip,r.promote_id,r.promote_account").Order(order).Order(tieOrder).Scan(&pos).Error; err != nil {
return nil, business.ErrStorage
}
meta := []ledgerMetaTarget{}