package service import ( "errors" "wx_service/internal/marketing/model" "wx_service/internal/marketing/repository" ) var ( ErrDownloadTemplateRequired = errors.New("请选择模板") ErrDownloadTemplateDisabled = errors.New("模板已禁用") ) type DownloadService struct { downloadRepo *repository.DownloadRepository templateRepo *repository.TemplateRepository } func NewDownloadService(downloadRepo *repository.DownloadRepository, templateRepo *repository.TemplateRepository) *DownloadService { return &DownloadService{ downloadRepo: downloadRepo, templateRepo: templateRepo, } } type CreateDownloadRequest struct { TemplateID uint `json:"template_id"` LogoURL string `json:"logo_url"` LogoX float64 `json:"logo_x"` LogoY float64 `json:"logo_y"` LogoW float64 `json:"logo_w"` LogoH float64 `json:"logo_h"` } type DownloadListResponse struct { Downloads []model.MarketingDownload `json:"downloads"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } func (s *DownloadService) Create(userID uint, req CreateDownloadRequest) (*model.MarketingDownload, error) { if req.TemplateID == 0 { return nil, ErrDownloadTemplateRequired } tpl, err := s.templateRepo.FindByID(req.TemplateID) if err != nil { return nil, err } if tpl.Status != 1 { return nil, ErrDownloadTemplateDisabled } dl := &model.MarketingDownload{ UserID: userID, TemplateID: req.TemplateID, LogoURL: req.LogoURL, LogoX: req.LogoX, LogoY: req.LogoY, LogoW: req.LogoW, LogoH: req.LogoH, } if err := s.downloadRepo.Create(dl); err != nil { return nil, err } if err := s.templateRepo.IncrementDownloadCount(req.TemplateID); err != nil { return nil, err } return dl, nil } func (s *DownloadService) MarkAdCompleted(downloadID uint) error { return s.downloadRepo.MarkAdCompleted(downloadID) } func (s *DownloadService) ListByUser(userID uint, page, pageSize int) (*DownloadListResponse, error) { downloads, total, err := s.downloadRepo.FindByUser(userID, page, pageSize) if err != nil { return nil, err } return &DownloadListResponse{ Downloads: downloads, Total: total, Page: page, PageSize: pageSize, }, nil } func (s *DownloadService) GetStats() (*repository.DownloadStats, error) { return s.downloadRepo.GetStats() } // IsBadRequestError checks if the error is a client-side validation error. func IsBadRequestError(err error) bool { return errors.Is(err, ErrDownloadTemplateRequired) || errors.Is(err, ErrDownloadTemplateDisabled) || errors.Is(err, ErrCategoryNameRequired) || errors.Is(err, ErrCategoryNameTooLong) || errors.Is(err, ErrCategoryHasTemplates) || errors.Is(err, ErrTemplateTitleRequired) || errors.Is(err, ErrTemplateTitleTooLong) || errors.Is(err, ErrTemplateImageRequired) || errors.Is(err, ErrTemplateCategoryRequired) } // IsNotFoundError checks if the error is a not-found error. func IsNotFoundError(err error) bool { return errors.Is(err, repository.ErrCategoryNotFound) || errors.Is(err, repository.ErrTemplateNotFound) || errors.Is(err, repository.ErrDownloadNotFound) }