package repository import ( "github.com/topfans/backend/pkg/logger" "github.com/topfans/backend/services/taskService/model" "go.uber.org/zap" "gorm.io/gorm" ) type RevenueRepository interface { CreateRevenueRecord(record *model.ExhibitionRevenueRecord) (*model.ExhibitionRevenueRecord, error) GetRevenueRecord(id int64) (*model.ExhibitionRevenueRecord, error) ListRevenueByUser(userID, starID int64, status string, page, pageSize int) ([]*model.ExhibitionRevenueRecord, int64, error) ClaimRevenueRecord(id int64, userID int64) (bool, error) UpdateRevenueStatus(id int64, status string) error ListClaimableRevenue(limit int) ([]*model.ExhibitionRevenueRecord, error) } type revenueRepository struct { db *gorm.DB } func NewRevenueRepository(db *gorm.DB) RevenueRepository { return &revenueRepository{db: db} } func (r *revenueRepository) CreateRevenueRecord(record *model.ExhibitionRevenueRecord) (*model.ExhibitionRevenueRecord, error) { record.CreatedAt = gorm.NowFunc().Unix() if err := r.db.Create(record).Error; err != nil { logger.Logger.Error("Failed to CreateRevenueRecord", zap.Int64("user_id", record.UserID), zap.Error(err)) return nil, err } return record, nil } func (r *revenueRepository) GetRevenueRecord(id int64) (*model.ExhibitionRevenueRecord, error) { var record model.ExhibitionRevenueRecord if err := r.db.First(&record, id).Error; err != nil { return nil, err } return &record, nil } func (r *revenueRepository) ListRevenueByUser(userID, starID int64, status string, page, pageSize int) ([]*model.ExhibitionRevenueRecord, int64, error) { var records []*model.ExhibitionRevenueRecord var total int64 query := r.db.Model(&model.ExhibitionRevenueRecord{}).Where("user_id = ? AND star_id = ?", userID, starID) if status != "" { query = query.Where("status = ?", status) } if err := query.Count(&total).Error; err != nil { logger.Logger.Error("Failed to count revenue records", zap.Int64("user_id", userID), zap.Int64("star_id", starID), zap.Error(err)) return nil, 0, err } offset := (page - 1) * pageSize if err := query.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&records).Error; err != nil { logger.Logger.Error("Failed to ListRevenueByUser", zap.Int64("user_id", userID), zap.Int64("star_id", starID), zap.Error(err)) return nil, 0, err } return records, total, nil } func (r *revenueRepository) ClaimRevenueRecord(id int64, userID int64) (bool, error) { // 乐观锁:只有在 status='claimable' 时才更新 now := gorm.NowFunc().Unix() result := r.db.Model(&model.ExhibitionRevenueRecord{}). Where("id = ? AND user_id = ? AND status = ?", id, userID, "claimable"). Updates(map[string]interface{}{ "status": "claimed", "claimed_at": now, }) if result.Error != nil { logger.Logger.Error("Failed to ClaimRevenueRecord", zap.Int64("id", id), zap.Int64("user_id", userID), zap.Error(result.Error)) return false, result.Error } return result.RowsAffected > 0, nil } func (r *revenueRepository) UpdateRevenueStatus(id int64, status string) error { err := r.db.Model(&model.ExhibitionRevenueRecord{}).Where("id = ?", id).Update("status", status).Error if err != nil { logger.Logger.Error("Failed to UpdateRevenueStatus", zap.Int64("id", id), zap.String("status", status), zap.Error(err)) return err } return nil } func (r *revenueRepository) ListClaimableRevenue(limit int) ([]*model.ExhibitionRevenueRecord, error) { var records []*model.ExhibitionRevenueRecord err := r.db.Where("status = ?", "claimable").Limit(limit).Find(&records).Error if err != nil { logger.Logger.Error("Failed to ListClaimableRevenue", zap.Error(err)) return nil, err } return records, nil }