Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -7,9 +7,6 @@ import (
|
||||
)
|
||||
|
||||
// HasRefundCommissionLog 判断指定订单号是否已写入 333 退款佣金日志。
|
||||
// 用于 refund 主流程做幂等校验,以及 stuck-order recovery / activate worker
|
||||
// 区分「已退款」(terminal)与「短暂 claimed」(transient)这两种共用 status=6
|
||||
// 的语义。
|
||||
//
|
||||
// 实现细节:
|
||||
// 1. type=33 + content LIKE '%"order_no":"<orderNo>"%' 先走索引粗筛;
|
||||
@@ -36,3 +33,26 @@ func HasRefundCommissionLog(tx *gorm.DB, orderNo string) (bool, error) {
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// HasOrderRefundLog 判断指定订单号是否已写入 24 订单退款审计日志。
|
||||
func HasOrderRefundLog(tx *gorm.DB, orderNo string) (bool, error) {
|
||||
if orderNo == "" {
|
||||
return false, nil
|
||||
}
|
||||
var logs []SystemLog
|
||||
if err := tx.Model(&SystemLog{}).
|
||||
Where("type = ? AND content LIKE ?", TypeOrderRefund.Uint8(), fmt.Sprintf("%%\"order_no\":\"%s\"%%", orderNo)).
|
||||
Find(&logs).Error; err != nil {
|
||||
return false, fmt.Errorf("query order refund log failed: %w", err)
|
||||
}
|
||||
for _, item := range logs {
|
||||
var content OrderRefund
|
||||
if err := content.Unmarshal([]byte(item.Content)); err != nil {
|
||||
continue
|
||||
}
|
||||
if content.OrderNo == orderNo {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -140,6 +140,62 @@ func TestHasRefundCommissionLog(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestHasOrderRefundLog(t *testing.T) {
|
||||
const orderNo = "ORD-REFUND-AUDIT-1"
|
||||
|
||||
t.Run("returns true when order refund audit log exists", func(t *testing.T) {
|
||||
db, mock, cleanup := newRefundLogTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(24), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}).
|
||||
AddRow(1, fmt.Sprintf(`{"order_id":100,"order_no":"%s","order_status_after":7}`, orderNo)))
|
||||
|
||||
got, err := HasOrderRefundLog(db, orderNo)
|
||||
if err != nil {
|
||||
t.Fatalf("HasOrderRefundLog error: %v", err)
|
||||
}
|
||||
if !got {
|
||||
t.Fatalf("HasOrderRefundLog = false, want true")
|
||||
}
|
||||
assertRefundLogExpectations(t, mock)
|
||||
})
|
||||
|
||||
t.Run("returns false when audit log order_no does not match", func(t *testing.T) {
|
||||
db, mock, cleanup := newRefundLogTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(24), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}).
|
||||
AddRow(1, `{"order_id":100,"order_no":"OTHER","order_status_after":7}`))
|
||||
|
||||
got, err := HasOrderRefundLog(db, orderNo)
|
||||
if err != nil {
|
||||
t.Fatalf("HasOrderRefundLog error: %v", err)
|
||||
}
|
||||
if got {
|
||||
t.Fatalf("HasOrderRefundLog = true, want false")
|
||||
}
|
||||
assertRefundLogExpectations(t, mock)
|
||||
})
|
||||
|
||||
t.Run("returns false for empty order_no without querying", func(t *testing.T) {
|
||||
db, mock, cleanup := newRefundLogTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
got, err := HasOrderRefundLog(db, "")
|
||||
if err != nil {
|
||||
t.Fatalf("HasOrderRefundLog error: %v", err)
|
||||
}
|
||||
if got {
|
||||
t.Fatalf("HasOrderRefundLog = true, want false")
|
||||
}
|
||||
assertRefundLogExpectations(t, mock)
|
||||
})
|
||||
}
|
||||
|
||||
func newRefundLogTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock, func()) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user