Files
2025-11-17 13:32:54 +08:00

319 lines
7.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}