319 lines
7.8 KiB
Go
319 lines
7.8 KiB
Go
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
|
||
} |