Files
pay-bridge/backend/internal/repository/notify_log.go
2026-03-13 15:51:59 +08:00

76 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package repository
import (
"context"
"errors"
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"pay-bridge/internal/model"
)
// NotifyLogRepository 通知记录数据访问
type NotifyLogRepository struct {
db *gorm.DB
}
func NewNotifyLogRepository(db *gorm.DB) *NotifyLogRepository {
return &NotifyLogRepository{db: db}
}
// Upsert 创建或更新通知记录
func (r *NotifyLogRepository) Upsert(ctx context.Context, log *model.NotifyLog) error {
return r.db.WithContext(ctx).Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "trade_no"}, {Name: "notify_type"}},
DoUpdates: clause.AssignmentColumns([]string{"notify_url", "status", "retry_count", "next_retry_time", "last_response"}),
}).Create(log).Error
}
// GetByTradeNo 按 trade_no + notify_type 查询
func (r *NotifyLogRepository) GetByTradeNo(ctx context.Context, tradeNo string, notifyType model.NotifyType) (*model.NotifyLog, error) {
var log model.NotifyLog
err := r.db.WithContext(ctx).Where("trade_no = ? AND notify_type = ?", tradeNo, notifyType).First(&log).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return &log, err
}
// ListPendingRetry 查询到期需要重试的通知
func (r *NotifyLogRepository) ListPendingRetry(ctx context.Context, before time.Time, limit int) ([]*model.NotifyLog, error) {
var logs []*model.NotifyLog
err := r.db.WithContext(ctx).
Where("status IN ? AND next_retry_time <= ?",
[]model.NotifyStatus{model.NotifyStatusPending, model.NotifyStatusRetry},
before).
Order("next_retry_time ASC").
Limit(limit).
Find(&logs).Error
return logs, err
}
// IncrRetryCount 重试次数+1更新下次重试时间和最后响应
func (r *NotifyLogRepository) IncrRetryCount(ctx context.Context, id uint64, status model.NotifyStatus, nextRetryTime *time.Time, lastResponse string) error {
return r.db.WithContext(ctx).Model(&model.NotifyLog{}).Where("id = ?", id).Updates(map[string]any{
"retry_count": gorm.Expr("retry_count + 1"),
"status": status,
"next_retry_time": nextRetryTime,
"last_response": lastResponse,
}).Error
}
// MarkSuccess 标记通知成功
func (r *NotifyLogRepository) MarkSuccess(ctx context.Context, id uint64, lastResponse string) error {
return r.db.WithContext(ctx).Model(&model.NotifyLog{}).Where("id = ?", id).Updates(map[string]any{
"status": model.NotifyStatusSuccess,
"last_response": lastResponse,
}).Error
}
// MarkGiveup 标记放弃通知
func (r *NotifyLogRepository) MarkGiveup(ctx context.Context, id uint64) error {
return r.db.WithContext(ctx).Model(&model.NotifyLog{}).Where("id = ?", id).
Update("status", model.NotifyStatusGiveup).Error
}