package service import ( "dianshang/internal/model" "dianshang/internal/repository" "errors" "fmt" "time" ) // BannerService 轮播图服务 type BannerService struct { bannerRepo *repository.BannerRepository } // NewBannerService 创建轮播图服务 func NewBannerService(bannerRepo *repository.BannerRepository) *BannerService { return &BannerService{ bannerRepo: bannerRepo, } } // GetActiveBanners 获取有效的轮播图 func (s *BannerService) GetActiveBanners() ([]model.Banner, error) { return s.bannerRepo.GetActiveBannersWithTimeRange() } // GetBannerList 获取轮播图列表(分页) func (s *BannerService) GetBannerList(page, pageSize int, status *int) ([]model.Banner, int64, error) { if page <= 0 { page = 1 } if pageSize <= 0 || pageSize > 100 { pageSize = 10 } return s.bannerRepo.GetBannerList(page, pageSize, status) } // GetBannerByID 根据ID获取轮播图 func (s *BannerService) GetBannerByID(id uint) (*model.Banner, error) { if id == 0 { return nil, errors.New("轮播图ID不能为空") } return s.bannerRepo.GetBannerByID(id) } // CreateBanner 创建轮播图 func (s *BannerService) CreateBanner(banner *model.Banner) error { // 验证必填字段 if err := s.validateBanner(banner); err != nil { return err } // 如果没有设置排序值,自动设置为最大值+10 if banner.Sort == 0 { maxSort, err := s.bannerRepo.GetMaxSort() if err != nil { return fmt.Errorf("获取最大排序值失败: %v", err) } banner.Sort = maxSort + 10 } // 设置默认状态 if banner.Status == 0 { banner.Status = 1 } return s.bannerRepo.CreateBanner(banner) } // UpdateBanner 更新轮播图 func (s *BannerService) UpdateBanner(id uint, banner *model.Banner) error { if id == 0 { return errors.New("轮播图ID不能为空") } // 检查轮播图是否存在 exists, err := s.bannerRepo.CheckBannerExists(id) if err != nil { return fmt.Errorf("检查轮播图是否存在失败: %v", err) } if !exists { return errors.New("轮播图不存在") } // 验证必填字段 if err := s.validateBanner(banner); err != nil { return err } banner.ID = id return s.bannerRepo.UpdateBanner(banner) } // DeleteBanner 删除轮播图 func (s *BannerService) DeleteBanner(id uint) error { if id == 0 { return errors.New("轮播图ID不能为空") } // 检查轮播图是否存在 exists, err := s.bannerRepo.CheckBannerExists(id) if err != nil { return fmt.Errorf("检查轮播图是否存在失败: %v", err) } if !exists { return errors.New("轮播图不存在") } return s.bannerRepo.DeleteBanner(id) } // BatchDeleteBanners 批量删除轮播图 func (s *BannerService) BatchDeleteBanners(ids []uint) error { if len(ids) == 0 { return errors.New("轮播图ID列表不能为空") } return s.bannerRepo.BatchDeleteBanners(ids) } // UpdateBannerStatus 更新轮播图状态 func (s *BannerService) UpdateBannerStatus(id uint, status int) error { if id == 0 { return errors.New("轮播图ID不能为空") } if status < 0 || status > 1 { return errors.New("状态值无效,只能是0或1") } // 检查轮播图是否存在 exists, err := s.bannerRepo.CheckBannerExists(id) if err != nil { return fmt.Errorf("检查轮播图是否存在失败: %v", err) } if !exists { return errors.New("轮播图不存在") } return s.bannerRepo.UpdateBannerStatus(id, status) } // BatchUpdateBannerStatus 批量更新轮播图状态 func (s *BannerService) BatchUpdateBannerStatus(ids []uint, status int) error { if len(ids) == 0 { return errors.New("轮播图ID列表不能为空") } if status < 0 || status > 1 { return errors.New("状态值无效,只能是0或1") } return s.bannerRepo.BatchUpdateBannerStatus(ids, status) } // UpdateBannerSort 更新轮播图排序 func (s *BannerService) UpdateBannerSort(id uint, sort int) error { if id == 0 { return errors.New("轮播图ID不能为空") } if sort < 0 { return errors.New("排序值不能为负数") } // 检查轮播图是否存在 exists, err := s.bannerRepo.CheckBannerExists(id) if err != nil { return fmt.Errorf("检查轮播图是否存在失败: %v", err) } if !exists { return errors.New("轮播图不存在") } return s.bannerRepo.UpdateBannerSort(id, sort) } // BatchUpdateBannerSort 批量更新轮播图排序 func (s *BannerService) BatchUpdateBannerSort(sortData []map[string]interface{}) error { if len(sortData) == 0 { return errors.New("排序数据不能为空") } // 验证排序数据 for _, data := range sortData { id, ok := data["id"] if !ok { return errors.New("排序数据中缺少ID字段") } sort, ok := data["sort"] if !ok { return errors.New("排序数据中缺少sort字段") } // 类型检查 if _, ok := id.(uint); !ok { if idFloat, ok := id.(float64); ok { data["id"] = uint(idFloat) } else { return errors.New("ID字段类型错误") } } if _, ok := sort.(int); !ok { if sortFloat, ok := sort.(float64); ok { data["sort"] = int(sortFloat) } else { return errors.New("sort字段类型错误") } } } return s.bannerRepo.BatchUpdateBannerSort(sortData) } // GetBannersByDateRange 根据日期范围获取轮播图 func (s *BannerService) GetBannersByDateRange(startDate, endDate time.Time) ([]model.Banner, error) { if startDate.After(endDate) { return nil, errors.New("开始日期不能晚于结束日期") } return s.bannerRepo.GetBannersByDateRange(startDate, endDate) } // GetBannersByStatus 根据状态获取轮播图 func (s *BannerService) GetBannersByStatus(status int) ([]model.Banner, error) { if status < 0 || status > 1 { return nil, errors.New("状态值无效,只能是0或1") } return s.bannerRepo.GetBannersByStatus(status) } // GetBannerStatistics 获取轮播图统计信息 func (s *BannerService) GetBannerStatistics() (map[string]interface{}, error) { // 获取总数 total, err := s.bannerRepo.GetBannerCount() if err != nil { return nil, fmt.Errorf("获取轮播图总数失败: %v", err) } // 获取启用数量 activeCount, err := s.bannerRepo.GetBannerCountByStatus(1) if err != nil { return nil, fmt.Errorf("获取启用轮播图数量失败: %v", err) } // 获取禁用数量 inactiveCount, err := s.bannerRepo.GetBannerCountByStatus(0) if err != nil { return nil, fmt.Errorf("获取禁用轮播图数量失败: %v", err) } // 获取过期轮播图 expiredBanners, err := s.bannerRepo.GetExpiredBanners() if err != nil { return nil, fmt.Errorf("获取过期轮播图失败: %v", err) } return map[string]interface{}{ "total": total, "active": activeCount, "inactive": inactiveCount, "expired": len(expiredBanners), "expired_list": expiredBanners, }, nil } // CleanExpiredBanners 清理过期轮播图 func (s *BannerService) CleanExpiredBanners() error { expiredBanners, err := s.bannerRepo.GetExpiredBanners() if err != nil { return fmt.Errorf("获取过期轮播图失败: %v", err) } if len(expiredBanners) == 0 { return nil } // 将过期轮播图状态设置为禁用 var ids []uint for _, banner := range expiredBanners { ids = append(ids, banner.ID) } return s.bannerRepo.BatchUpdateBannerStatus(ids, 0) } // validateBanner 验证轮播图数据 func (s *BannerService) validateBanner(banner *model.Banner) error { if banner.Title == "" { return errors.New("轮播图标题不能为空") } if banner.Image == "" { return errors.New("轮播图图片不能为空") } if banner.LinkType < 1 || banner.LinkType > 4 { return errors.New("链接类型无效,只能是1-4") } if banner.Sort < 0 { return errors.New("排序值不能为负数") } // 验证时间范围 if banner.StartTime != nil && banner.EndTime != nil { if banner.StartTime.After(*banner.EndTime) { return errors.New("开始时间不能晚于结束时间") } } return nil }