package repository import ( "errors" "fmt" "gorm.io/gorm" "wx_service/internal/marketing/model" ) var ErrDownloadNotFound = errors.New("marketing download not found") type DownloadRepository struct { db *gorm.DB } func NewDownloadRepository(db *gorm.DB) *DownloadRepository { return &DownloadRepository{db: db} } func (r *DownloadRepository) Create(dl *model.MarketingDownload) error { if err := r.db.Create(dl).Error; err != nil { return fmt.Errorf("create marketing download: %w", err) } return nil } func (r *DownloadRepository) FindByID(id uint) (*model.MarketingDownload, error) { var dl model.MarketingDownload err := r.db.First(&dl, id).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrDownloadNotFound } return nil, fmt.Errorf("find marketing download: %w", err) } return &dl, nil } func (r *DownloadRepository) MarkAdCompleted(id uint) error { tx := r.db.Model(&model.MarketingDownload{}).Where("id = ?", id).Update("ad_completed", true) if tx.Error != nil { return fmt.Errorf("mark ad completed: %w", tx.Error) } if tx.RowsAffected == 0 { return ErrDownloadNotFound } return nil } func (r *DownloadRepository) FindByUser(userID uint, page, pageSize int) ([]model.MarketingDownload, int64, error) { if page <= 0 { page = 1 } if pageSize <= 0 { pageSize = 20 } if pageSize > 100 { pageSize = 100 } query := r.db.Model(&model.MarketingDownload{}).Where("user_id = ?", userID) var total int64 if err := query.Count(&total).Error; err != nil { return nil, 0, fmt.Errorf("count marketing downloads: %w", err) } var downloads []model.MarketingDownload offset := (page - 1) * pageSize if err := query.Preload("Template").Order("id DESC").Offset(offset).Limit(pageSize).Find(&downloads).Error; err != nil { return nil, 0, fmt.Errorf("list marketing downloads: %w", err) } return downloads, total, nil } type DownloadStats struct { TotalDownloads int64 TodayDownloads int64 } func (r *DownloadRepository) GetStats() (*DownloadStats, error) { var total int64 if err := r.db.Model(&model.MarketingDownload{}).Count(&total).Error; err != nil { return nil, fmt.Errorf("count total downloads: %w", err) } var today int64 if err := r.db.Model(&model.MarketingDownload{}). Where("DATE(created_at) = CURDATE()"). Count(&today).Error; err != nil { return nil, fmt.Errorf("count today downloads: %w", err) } return &DownloadStats{TotalDownloads: total, TodayDownloads: today}, nil }