Files
urldb/handlers/category_handler.go

190 lines
5.2 KiB
Go
Raw Permalink Normal View History

2025-07-10 13:58:28 +08:00
package handlers
import (
"net/http"
"strconv"
2025-07-18 09:42:07 +08:00
"github.com/ctwj/urldb/db/converter"
"github.com/ctwj/urldb/db/dto"
"github.com/ctwj/urldb/db/entity"
2025-08-03 10:50:25 +08:00
"github.com/ctwj/urldb/utils"
2025-07-10 13:58:28 +08:00
"github.com/gin-gonic/gin"
)
// GetCategories 获取分类列表
func GetCategories(c *gin.Context) {
2025-07-16 08:29:49 +08:00
// 获取分页参数
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
search := c.Query("search")
2025-08-03 10:50:25 +08:00
utils.Debug("获取分类列表 - 分页参数: page=%d, pageSize=%d, search=%s", page, pageSize, search)
2025-07-16 08:29:49 +08:00
var categories []entity.Category
var total int64
var err error
if search != "" {
// 搜索分类
categories, total, err = repoManager.CategoryRepository.Search(search, page, pageSize)
} else {
// 分页查询
categories, total, err = repoManager.CategoryRepository.FindWithPagination(page, pageSize)
}
2025-07-10 13:58:28 +08:00
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
2025-07-10 13:58:28 +08:00
return
}
2025-08-03 10:50:25 +08:00
utils.Debug("查询到分类数量: %d, 总数: %d", len(categories), total)
2025-07-16 11:03:55 +08:00
// 获取每个分类的资源数量和标签名称
2025-07-10 13:58:28 +08:00
resourceCounts := make(map[uint]int64)
2025-07-16 11:03:55 +08:00
tagNamesMap := make(map[uint][]string)
2025-07-10 13:58:28 +08:00
for _, category := range categories {
2025-07-16 10:54:00 +08:00
// 获取资源数量
resourceCount, err := repoManager.CategoryRepository.GetResourceCount(category.ID)
2025-07-10 13:58:28 +08:00
if err != nil {
continue
}
2025-07-16 10:54:00 +08:00
resourceCounts[category.ID] = resourceCount
2025-07-16 11:03:55 +08:00
// 获取标签名称
tagNames, err := repoManager.CategoryRepository.GetTagNames(category.ID)
2025-07-16 10:54:00 +08:00
if err != nil {
continue
}
2025-07-16 11:03:55 +08:00
tagNamesMap[category.ID] = tagNames
2025-07-10 13:58:28 +08:00
}
2025-07-16 11:03:55 +08:00
responses := converter.ToCategoryResponseList(categories, resourceCounts, tagNamesMap)
2025-07-16 08:29:49 +08:00
// 返回分页格式的响应
SuccessResponse(c, gin.H{
"items": responses,
"total": total,
"page": page,
"page_size": pageSize,
})
2025-07-10 13:58:28 +08:00
}
// CreateCategory 创建分类
func CreateCategory(c *gin.Context) {
var req dto.CreateCategoryRequest
if err := c.ShouldBindJSON(&req); err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, err.Error(), http.StatusBadRequest)
2025-07-10 13:58:28 +08:00
return
}
2025-08-03 10:50:25 +08:00
// 首先检查是否存在已删除的同名分类
deletedCategory, err := repoManager.CategoryRepository.FindByNameIncludingDeleted(req.Name)
if err == nil && deletedCategory.DeletedAt.Valid {
utils.Debug("找到已删除的分类: ID=%d, Name=%s", deletedCategory.ID, deletedCategory.Name)
// 如果存在已删除的同名分类,则恢复它
err = repoManager.CategoryRepository.RestoreDeletedCategory(deletedCategory.ID)
if err != nil {
ErrorResponse(c, "恢复已删除分类失败: "+err.Error(), http.StatusInternalServerError)
return
}
utils.Debug("分类恢复成功: ID=%d", deletedCategory.ID)
// 重新获取恢复后的分类
restoredCategory, err := repoManager.CategoryRepository.FindByID(deletedCategory.ID)
if err != nil {
ErrorResponse(c, "获取恢复的分类失败: "+err.Error(), http.StatusInternalServerError)
return
}
utils.Debug("重新获取到恢复的分类: ID=%d, Name=%s", restoredCategory.ID, restoredCategory.Name)
// 更新分类信息
restoredCategory.Description = req.Description
err = repoManager.CategoryRepository.Update(restoredCategory)
if err != nil {
ErrorResponse(c, "更新恢复的分类失败: "+err.Error(), http.StatusInternalServerError)
return
}
utils.Debug("分类信息更新成功: ID=%d, Description=%s", restoredCategory.ID, restoredCategory.Description)
SuccessResponse(c, gin.H{
"message": "分类恢复成功",
"category": converter.ToCategoryResponse(restoredCategory, 0, []string{}),
})
return
}
// 如果不存在已删除的同名分类,则创建新分类
2025-07-10 13:58:28 +08:00
category := &entity.Category{
Name: req.Name,
Description: req.Description,
}
2025-08-03 10:50:25 +08:00
err = repoManager.CategoryRepository.Create(category)
2025-07-10 13:58:28 +08:00
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
2025-07-10 13:58:28 +08:00
return
}
2025-07-11 17:45:16 +08:00
SuccessResponse(c, gin.H{
"message": "分类创建成功",
2025-07-16 11:03:55 +08:00
"category": converter.ToCategoryResponse(category, 0, []string{}),
2025-07-10 13:58:28 +08:00
})
}
// UpdateCategory 更新分类
func UpdateCategory(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
2025-07-10 13:58:28 +08:00
return
}
var req dto.UpdateCategoryRequest
if err := c.ShouldBindJSON(&req); err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, err.Error(), http.StatusBadRequest)
2025-07-10 13:58:28 +08:00
return
}
category, err := repoManager.CategoryRepository.FindByID(uint(id))
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, "分类不存在", http.StatusNotFound)
2025-07-10 13:58:28 +08:00
return
}
if req.Name != "" {
category.Name = req.Name
}
if req.Description != "" {
category.Description = req.Description
}
err = repoManager.CategoryRepository.Update(category)
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
2025-07-10 13:58:28 +08:00
return
}
2025-07-11 17:45:16 +08:00
SuccessResponse(c, gin.H{"message": "分类更新成功"})
2025-07-10 13:58:28 +08:00
}
// DeleteCategory 删除分类
func DeleteCategory(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
2025-07-10 13:58:28 +08:00
return
}
err = repoManager.CategoryRepository.Delete(uint(id))
if err != nil {
2025-07-11 17:45:16 +08:00
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
2025-07-10 13:58:28 +08:00
return
}
2025-07-11 17:45:16 +08:00
SuccessResponse(c, gin.H{"message": "分类删除成功"})
2025-07-10 13:58:28 +08:00
}