fix(v2): 退款自愈扫描加回溯窗(防 LIMIT 尾部饥饿)+ 清死行
RefundApplyTask 的候选查询按 out_trade_no ASC/id ASC 取前 200,succeeded 退款历史 只增不减、partially_refunded 长期驻留,超过 limit 后最新的崩溃窗口永远排在候选外 扫不到。两路查询都加 since 回溯窗:RefundStore.ListDistinctOutTradeNosByStatusSince (completed_at>=since)、OrderStore.ListOrdersByStatusSince(updated_at>=since),旧的 无窗方法原样保留。RefundApplyTask 新增 lookback/now 参数,config.ReconcileConfig 新增 RefundApplyLookbackMin(默认 48h)。顺带按 T6 复审补 OrderTTLMin 字段注释(须 ≫ crypto orderTTL 15min),清 sync_test.go 死行 `_ = time.Second`。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -175,6 +175,22 @@ func (s *OrderStore) ListOrdersByStatus(statuses []model.OrderStatusV2, limit in
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ListOrdersByStatusSince 同 ListOrdersByStatus,但加 updated_at>=since 回溯窗——
|
||||
// refunding/partially_refunded 是长期驻留态(订单进入后可能停留很久),不设窗口时
|
||||
// 会占满 limit 名额,把「近期才卡滞、需要自愈」的订单挤出候选(与
|
||||
// RefundStore.ListDistinctOutTradeNosByStatusSince 同一治法,同一 lookback 语义)。
|
||||
func (s *OrderStore) ListOrdersByStatusSince(statuses []model.OrderStatusV2, since time.Time, limit int) ([]model.OrderV2, error) {
|
||||
if limit <= 0 || limit > 500 {
|
||||
limit = 200
|
||||
}
|
||||
var out []model.OrderV2
|
||||
if err := s.db.Where("status IN ? AND updated_at >= ?", statuses, since).
|
||||
Order("id ASC").Limit(limit).Find(&out).Error; err != nil {
|
||||
return nil, fmt.Errorf("store.ListOrdersByStatusSince: %w", err)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ListAttemptsByChannelSince 列某渠道 created_at>=since 的 attempt(任意状态),
|
||||
// 供 orphan 扫描构造"已知期望金额集"(凡 pay 合法签发过的金额都不算孤儿)。
|
||||
func (s *OrderStore) ListAttemptsByChannelSince(channel string, since time.Time, limit int) ([]model.Attempt, error) {
|
||||
|
||||
Reference in New Issue
Block a user