Files
photography/backend-old/internal/service/category_service.go
xujiang 010fe2a8c7
Some checks failed
部署后端服务 / 🧪 测试后端 (push) Failing after 5m8s
部署后端服务 / 🚀 构建并部署 (push) Has been skipped
部署后端服务 / 🔄 回滚部署 (push) Has been skipped
fix
2025-07-10 18:09:11 +08:00

233 lines
6.2 KiB
Go
Raw 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 (
"context"
"errors"
"photography-backend/internal/model/entity"
"photography-backend/internal/repository/interfaces"
"go.uber.org/zap"
)
type CategoryService struct {
categoryRepo interfaces.CategoryRepository
logger *zap.Logger
}
func NewCategoryService(categoryRepo interfaces.CategoryRepository, logger *zap.Logger) *CategoryService {
return &CategoryService{
categoryRepo: categoryRepo,
logger: logger,
}
}
// GetCategories 获取分类列表
func (s *CategoryService) GetCategories(ctx context.Context, parentID *uint) ([]*entity.Category, error) {
categories, err := s.categoryRepo.List(ctx, parentID)
if err != nil {
s.logger.Error("Failed to get categories", zap.Error(err))
return nil, err
}
return categories, nil
}
// GetCategoryTree 获取分类树
func (s *CategoryService) GetCategoryTree(ctx context.Context) ([]*entity.CategoryTree, error) {
tree, err := s.categoryRepo.GetTree(ctx)
if err != nil {
s.logger.Error("Failed to get category tree", zap.Error(err))
return nil, err
}
return tree, nil
}
// GetCategoryByID 根据ID获取分类
func (s *CategoryService) GetCategoryByID(ctx context.Context, id uint) (*entity.Category, error) {
category, err := s.categoryRepo.GetByID(ctx, id)
if err != nil {
s.logger.Error("Failed to get category by ID", zap.Error(err), zap.Uint("id", id))
return nil, err
}
return category, nil
}
// GetCategoryBySlug 根据slug获取分类
func (s *CategoryService) GetCategoryBySlug(ctx context.Context, slug string) (*entity.Category, error) {
category, err := s.categoryRepo.GetBySlug(ctx, slug)
if err != nil {
s.logger.Error("Failed to get category by slug", zap.Error(err), zap.String("slug", slug))
return nil, err
}
return category, nil
}
// CreateCategory 创建分类
func (s *CategoryService) CreateCategory(ctx context.Context, req *entity.CreateCategoryRequest) (*entity.Category, error) {
// 验证slug唯一性
if err := s.categoryRepo.ValidateSlugUnique(ctx, req.Slug, 0); err != nil {
return nil, err
}
// 验证父分类存在性
if req.ParentID != nil {
if err := s.categoryRepo.ValidateParentCategory(ctx, 0, *req.ParentID); err != nil {
return nil, err
}
}
// 获取排序顺序
sortOrder, err := s.categoryRepo.GetNextSortOrder(ctx, req.ParentID)
if err != nil {
return nil, err
}
category := &entity.Category{
Name: req.Name,
Slug: req.Slug,
Description: req.Description,
ParentID: req.ParentID,
SortOrder: sortOrder,
IsActive: true,
}
if err := s.categoryRepo.Create(ctx, category); err != nil {
s.logger.Error("Failed to create category", zap.Error(err))
return nil, err
}
s.logger.Info("Category created successfully", zap.Uint("id", category.ID))
return category, nil
}
// UpdateCategory 更新分类
func (s *CategoryService) UpdateCategory(ctx context.Context, id uint, req *entity.UpdateCategoryRequest) (*entity.Category, error) {
// 检查分类是否存在
category, err := s.categoryRepo.GetByID(ctx, id)
if err != nil {
s.logger.Error("Failed to get category", zap.Error(err), zap.Uint("id", id))
return nil, err
}
// 验证slug唯一性
if req.Slug != nil && *req.Slug != category.Slug {
if err := s.categoryRepo.ValidateSlugUnique(ctx, *req.Slug, id); err != nil {
return nil, err
}
}
// 验证父分类(防止循环引用)
if req.ParentID != nil {
// 检查是否有变更
if (category.ParentID == nil && *req.ParentID != 0) || (category.ParentID != nil && *req.ParentID != *category.ParentID) {
if err := s.categoryRepo.ValidateParentCategory(ctx, id, *req.ParentID); err != nil {
return nil, err
}
}
}
// 更新字段
if req.Name != nil {
category.Name = *req.Name
}
if req.Slug != nil {
category.Slug = *req.Slug
}
if req.Description != nil {
category.Description = *req.Description
}
if req.ParentID != nil {
if *req.ParentID == 0 {
category.ParentID = nil
} else {
category.ParentID = req.ParentID
}
}
if req.SortOrder != nil {
category.SortOrder = *req.SortOrder
}
if req.IsActive != nil {
category.IsActive = *req.IsActive
}
// 保存更新
if err := s.categoryRepo.Update(ctx, category); err != nil {
s.logger.Error("Failed to update category", zap.Error(err))
return nil, err
}
s.logger.Info("Category updated successfully", zap.Uint("id", id))
return category, nil
}
// DeleteCategory 删除分类
func (s *CategoryService) DeleteCategory(ctx context.Context, id uint) error {
// 检查分类是否存在
_, err := s.categoryRepo.GetByID(ctx, id)
if err != nil {
s.logger.Error("Failed to get category", zap.Error(err), zap.Uint("id", id))
return err
}
// 检查是否有子分类
children, err := s.categoryRepo.GetChildren(ctx, id)
if err != nil {
return err
}
if len(children) > 0 {
return errors.New("cannot delete category with subcategories")
}
// 直接删除分类在Repository层检查照片关联
if err := s.categoryRepo.Delete(ctx, id); err != nil {
s.logger.Error("Failed to delete category", zap.Error(err))
return err
}
s.logger.Info("Category deleted successfully", zap.Uint("id", id))
return nil
}
// ReorderCategories 重新排序分类
func (s *CategoryService) ReorderCategories(ctx context.Context, parentID *uint, categoryIDs []uint) error {
if len(categoryIDs) == 0 {
return nil
}
// 重新排序分类
if err := s.categoryRepo.Reorder(ctx, parentID, categoryIDs); err != nil {
s.logger.Error("Failed to reorder categories", zap.Error(err))
return err
}
s.logger.Info("Categories reordered successfully", zap.Int("count", len(categoryIDs)))
return nil
}
// GetCategoryStats 获取分类统计信息
func (s *CategoryService) GetCategoryStats(ctx context.Context) (*entity.CategoryStats, error) {
stats, err := s.categoryRepo.GetStats(ctx)
if err != nil {
s.logger.Error("Failed to get category stats", zap.Error(err))
return nil, err
}
return stats, nil
}
// GenerateSlug 生成唯一slug
func (s *CategoryService) GenerateSlug(ctx context.Context, name string) (string, error) {
slug, err := s.categoryRepo.GenerateUniqueSlug(ctx, name)
if err != nil {
s.logger.Error("Failed to generate unique slug", zap.Error(err))
return "", err
}
return slug, nil
}