package postgres import ( "context" "time" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/redis/go-redis/v9" "gorm.io/gorm" ) type RechargeStore struct { db *gorm.DB redis *redis.Client } // NewRechargeStore 创建充值订单 Store 实例 func NewRechargeStore(db *gorm.DB, redis *redis.Client) *RechargeStore { return &RechargeStore{ db: db, redis: redis, } } // Create 创建充值订单 func (s *RechargeStore) Create(ctx context.Context, recharge *model.RechargeRecord) error { return s.db.WithContext(ctx).Create(recharge).Error } // GetByRechargeNo 根据充值订单号查询充值订单 // 不存在时返回 nil, nil func (s *RechargeStore) GetByRechargeNo(ctx context.Context, rechargeNo string) (*model.RechargeRecord, error) { var recharge model.RechargeRecord err := s.db.WithContext(ctx).Where("recharge_no = ?", rechargeNo).First(&recharge).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, nil } return nil, err } return &recharge, nil } // GetByID 根据 ID 查询充值订单 func (s *RechargeStore) GetByID(ctx context.Context, id uint) (*model.RechargeRecord, error) { var recharge model.RechargeRecord if err := s.db.WithContext(ctx).First(&recharge, id).Error; err != nil { return nil, err } return &recharge, nil } // ListRechargeParams 充值订单列表查询参数 type ListRechargeParams struct { Page int // 页码(从 1 开始) PageSize int // 每页数量 UserID *uint // 用户 ID 筛选 WalletID *uint // 钱包 ID 筛选 Status *int // 状态筛选 StartTime *time.Time // 开始时间 EndTime *time.Time // 结束时间 } // List 查询充值订单列表(支持分页和筛选) func (s *RechargeStore) List(ctx context.Context, params *ListRechargeParams) ([]*model.RechargeRecord, int64, error) { var recharges []*model.RechargeRecord var total int64 query := s.db.WithContext(ctx).Model(&model.RechargeRecord{}) // 应用筛选条件 if params.UserID != nil { query = query.Where("user_id = ?", *params.UserID) } if params.WalletID != nil { query = query.Where("wallet_id = ?", *params.WalletID) } if params.Status != nil { query = query.Where("status = ?", *params.Status) } if params.StartTime != nil { query = query.Where("created_at >= ?", *params.StartTime) } if params.EndTime != nil { query = query.Where("created_at <= ?", *params.EndTime) } // 统计总数 if err := query.Count(&total).Error; err != nil { return nil, 0, err } // 分页查询 page := params.Page if page < 1 { page = 1 } pageSize := params.PageSize if pageSize < 1 { pageSize = 20 } offset := (page - 1) * pageSize if err := query.Order("id DESC").Offset(offset).Limit(pageSize).Find(&recharges).Error; err != nil { return nil, 0, err } return recharges, total, nil } // UpdateStatus 更新充值订单状态(支持乐观锁检查) // oldStatus: 原状态(用于乐观锁检查,传 nil 则跳过检查) // newStatus: 新状态 // paidAt: 支付时间(状态变为已支付时传入) // completedAt: 完成时间(状态变为已完成时传入) func (s *RechargeStore) UpdateStatus(ctx context.Context, id uint, oldStatus *int, newStatus int, paidAt *time.Time, completedAt *time.Time) error { updates := map[string]interface{}{ "status": newStatus, } if paidAt != nil { updates["paid_at"] = paidAt } if completedAt != nil { updates["completed_at"] = completedAt } query := s.db.WithContext(ctx).Model(&model.RechargeRecord{}).Where("id = ?", id) // 乐观锁检查 if oldStatus != nil { query = query.Where("status = ?", *oldStatus) } result := query.Updates(updates) if result.Error != nil { return result.Error } if result.RowsAffected == 0 { return gorm.ErrRecordNotFound } return nil } // UpdatePaymentInfo 更新支付信息 func (s *RechargeStore) UpdatePaymentInfo(ctx context.Context, id uint, paymentChannel *string, paymentTransactionID *string) error { updates := map[string]interface{}{} if paymentChannel != nil { updates["payment_channel"] = paymentChannel } if paymentTransactionID != nil { updates["payment_transaction_id"] = paymentTransactionID } if len(updates) == 0 { return nil } result := s.db.WithContext(ctx).Model(&model.RechargeRecord{}).Where("id = ?", id).Updates(updates) if result.Error != nil { return result.Error } if result.RowsAffected == 0 { return gorm.ErrRecordNotFound } return nil }