Files
photography/backend-old/internal/model/dto/category_dto.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

143 lines
6.1 KiB
Go

package dto
import (
"time"
"photography-backend/internal/model/entity"
)
// CreateCategoryRequest 创建分类请求
type CreateCategoryRequest struct {
Name string `json:"name" binding:"required,min=1,max=100" validate:"required,min=1,max=100"`
Description string `json:"description" binding:"omitempty,max=1000" validate:"omitempty,max=1000"`
Slug string `json:"slug" binding:"omitempty,min=1,max=100" validate:"omitempty,min=1,max=100"`
ParentID *uint `json:"parent_id" binding:"omitempty,min=1" validate:"omitempty,min=1"`
Color string `json:"color" binding:"omitempty,len=7" validate:"omitempty,len=7"`
CoverImage string `json:"cover_image" binding:"omitempty,url" validate:"omitempty,url"`
SortOrder int `json:"sort_order" binding:"omitempty,min=0" validate:"omitempty,min=0"`
}
// UpdateCategoryRequest 更新分类请求
type UpdateCategoryRequest struct {
Name *string `json:"name" binding:"omitempty,min=1,max=100" validate:"omitempty,min=1,max=100"`
Description *string `json:"description" binding:"omitempty,max=1000" validate:"omitempty,max=1000"`
Slug *string `json:"slug" binding:"omitempty,min=1,max=100" validate:"omitempty,min=1,max=100"`
ParentID *uint `json:"parent_id" binding:"omitempty,min=0" validate:"omitempty,min=0"`
Color *string `json:"color" binding:"omitempty,len=7" validate:"omitempty,len=7"`
CoverImage *string `json:"cover_image" binding:"omitempty,url" validate:"omitempty,url"`
SortOrder *int `json:"sort_order" binding:"omitempty,min=0" validate:"omitempty,min=0"`
IsActive *bool `json:"is_active" binding:"omitempty"`
}
// CategoryResponse 分类响应
type CategoryResponse struct {
ID uint `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Slug string `json:"slug"`
ParentID *uint `json:"parent_id"`
Color string `json:"color"`
CoverImage string `json:"cover_image"`
Sort int `json:"sort"`
IsActive bool `json:"is_active"`
PhotoCount int64 `json:"photo_count"`
AlbumCount int64 `json:"album_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// CategoryTreeResponse 分类树响应
type CategoryTreeResponse struct {
ID uint `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Slug string `json:"slug"`
ParentID *uint `json:"parent_id"`
Color string `json:"color"`
CoverImage string `json:"cover_image"`
Sort int `json:"sort"`
IsActive bool `json:"is_active"`
PhotoCount int64 `json:"photo_count"`
AlbumCount int64 `json:"album_count"`
Children []CategoryTreeResponse `json:"children"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// ListCategoriesOptions 分类列表查询选项
type ListCategoriesOptions struct {
Page int `json:"page" form:"page" binding:"omitempty,min=1" validate:"omitempty,min=1"`
Limit int `json:"limit" form:"limit" binding:"omitempty,min=1,max=100" validate:"omitempty,min=1,max=100"`
Sort string `json:"sort" form:"sort" binding:"omitempty,oneof=id name sort created_at updated_at" validate:"omitempty,oneof=id name sort created_at updated_at"`
Order string `json:"order" form:"order" binding:"omitempty,oneof=asc desc" validate:"omitempty,oneof=asc desc"`
ParentID *uint `json:"parent_id" form:"parent_id" binding:"omitempty,min=0" validate:"omitempty,min=0"`
IsActive *bool `json:"is_active" form:"is_active" binding:"omitempty"`
Search string `json:"search" form:"search" binding:"omitempty,max=100" validate:"omitempty,max=100"`
WithCount bool `json:"with_count" form:"with_count" binding:"omitempty"`
}
// CategoryListResponse 分类列表响应
type CategoryListResponse struct {
Categories []CategoryResponse `json:"categories"`
Total int64 `json:"total"`
Page int `json:"page"`
Limit int `json:"limit"`
}
// ReorderCategoriesRequest 重新排序分类请求
type ReorderCategoriesRequest struct {
ParentID *uint `json:"parent_id" binding:"omitempty,min=0" validate:"omitempty,min=0"`
CategoryIDs []uint `json:"category_ids" binding:"required,min=1" validate:"required,min=1"`
}
// CategoryStatsResponse 分类统计响应
type CategoryStatsResponse struct {
Total int64 `json:"total"`
Active int64 `json:"active"`
TopLevel int64 `json:"top_level"`
PhotoCounts map[string]int64 `json:"photo_counts"`
Popular []CategoryResponse `json:"popular"`
}
// ConvertToCategoryResponse 将分类实体转换为响应DTO
func ConvertToCategoryResponse(category *entity.Category) *CategoryResponse {
if category == nil {
return nil
}
return &CategoryResponse{
ID: category.ID,
Name: category.Name,
Description: category.Description,
ParentID: category.ParentID,
Color: category.Color,
CoverImage: category.CoverImage,
Sort: category.Sort,
IsActive: category.IsActive,
PhotoCount: category.PhotoCount,
CreatedAt: category.CreatedAt,
UpdatedAt: category.UpdatedAt,
}
}
// ConvertToCategoryTreeResponse 将分类树转换为响应DTO
func ConvertToCategoryTreeResponse(tree []entity.CategoryTree) []CategoryTreeResponse {
result := make([]CategoryTreeResponse, len(tree))
for i, category := range tree {
result[i] = CategoryTreeResponse{
ID: category.ID,
Name: category.Name,
Description: category.Description,
ParentID: category.ParentID,
Color: category.Color,
CoverImage: category.CoverImage,
Sort: category.Sort,
IsActive: category.IsActive,
PhotoCount: category.PhotoCount,
Children: ConvertToCategoryTreeResponse(category.Children),
CreatedAt: category.CreatedAt,
UpdatedAt: category.UpdatedAt,
}
}
return result
}