refactor: 重构后端架构为 go-zero 框架,优化项目结构
主要变更: - 采用 go-zero 框架替代 Gin,提升开发效率 - 重构项目结构,API 文件模块化组织 - 将 model 移至 api/internal/model 目录 - 移除 common 包,改为标准 pkg 目录结构 - 实现统一的仓储模式,支持配置驱动数据库切换 - 简化测试策略,专注 API 集成测试 - 更新 CLAUDE.md 文档,提供详细的开发指导 技术栈更新: - 框架: Gin → go-zero v1.6.0+ - 代码生成: 引入 goctl 工具 - 架构模式: 四层架构 → go-zero 三层架构 (Handler→Logic→Model) - 项目布局: 遵循 Go 社区标准和 go-zero 最佳实践
This commit is contained in:
@ -3,7 +3,8 @@ package handlers
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/gin-gonic/gin"
|
||||
"photography-backend/internal/models"
|
||||
"photography-backend/internal/model/entity"
|
||||
"photography-backend/internal/model/dto"
|
||||
"photography-backend/internal/service/auth"
|
||||
"photography-backend/internal/api/middleware"
|
||||
"photography-backend/pkg/response"
|
||||
@ -23,7 +24,7 @@ func NewAuthHandler(authService *auth.AuthService) *AuthHandler {
|
||||
|
||||
// Login 用户登录
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
var req models.LoginRequest
|
||||
var req dto.LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
@ -40,7 +41,7 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
||||
|
||||
// Register 用户注册
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
var req models.CreateUserRequest
|
||||
var req dto.CreateUserRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
@ -57,7 +58,7 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
||||
|
||||
// RefreshToken 刷新令牌
|
||||
func (h *AuthHandler) RefreshToken(c *gin.Context) {
|
||||
var req models.RefreshTokenRequest
|
||||
var req dto.RefreshTokenRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
@ -97,7 +98,7 @@ func (h *AuthHandler) UpdatePassword(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var req models.UpdatePasswordRequest
|
||||
var req dto.ChangePasswordRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
|
||||
@ -5,8 +5,10 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"photography-backend/internal/models"
|
||||
"photography-backend/internal/model/entity"
|
||||
"photography-backend/internal/model/dto"
|
||||
"photography-backend/internal/service"
|
||||
"photography-backend/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
@ -32,17 +34,14 @@ func NewCategoryHandler(categoryService *service.CategoryService, logger *zap.Lo
|
||||
// @Produce json
|
||||
// @Param parent_id query int false "父分类ID"
|
||||
// @Success 200 {array} models.Category
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories [get]
|
||||
func (h *CategoryHandler) GetCategories(c *gin.Context) {
|
||||
var parentID *uint
|
||||
if parentIDStr := c.Query("parent_id"); parentIDStr != "" {
|
||||
id, err := strconv.ParseUint(parentIDStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
Error: "Invalid parent_id",
|
||||
Message: "Parent ID must be a valid number",
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, "Parent ID must be a valid number"))
|
||||
return
|
||||
}
|
||||
parentIDUint := uint(id)
|
||||
@ -52,10 +51,7 @@ func (h *CategoryHandler) GetCategories(c *gin.Context) {
|
||||
categories, err := h.categoryService.GetCategories(c.Request.Context(), parentID)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get categories", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
Error: "Failed to get categories",
|
||||
Message: err.Error(),
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, response.Error(http.StatusInternalServerError, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@ -69,13 +65,13 @@ func (h *CategoryHandler) GetCategories(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} models.CategoryTree
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/tree [get]
|
||||
func (h *CategoryHandler) GetCategoryTree(c *gin.Context) {
|
||||
tree, err := h.categoryService.GetCategoryTree(c.Request.Context())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get category tree", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get category tree",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -93,15 +89,15 @@ func (h *CategoryHandler) GetCategoryTree(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "分类ID"
|
||||
// @Success 200 {object} models.Category
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/{id} [get]
|
||||
func (h *CategoryHandler) GetCategory(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid category ID",
|
||||
Message: "Category ID must be a valid number",
|
||||
})
|
||||
@ -111,7 +107,7 @@ func (h *CategoryHandler) GetCategory(c *gin.Context) {
|
||||
category, err := h.categoryService.GetCategoryByID(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "category not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Category not found",
|
||||
Message: "The requested category does not exist",
|
||||
})
|
||||
@ -119,7 +115,7 @@ func (h *CategoryHandler) GetCategory(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to get category", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get category",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -137,8 +133,8 @@ func (h *CategoryHandler) GetCategory(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param slug path string true "分类slug"
|
||||
// @Success 200 {object} models.Category
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/slug/{slug} [get]
|
||||
func (h *CategoryHandler) GetCategoryBySlug(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
@ -146,7 +142,7 @@ func (h *CategoryHandler) GetCategoryBySlug(c *gin.Context) {
|
||||
category, err := h.categoryService.GetCategoryBySlug(c.Request.Context(), slug)
|
||||
if err != nil {
|
||||
if err.Error() == "category not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Category not found",
|
||||
Message: "The requested category does not exist",
|
||||
})
|
||||
@ -154,7 +150,7 @@ func (h *CategoryHandler) GetCategoryBySlug(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to get category by slug", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get category",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -172,14 +168,14 @@ func (h *CategoryHandler) GetCategoryBySlug(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param category body models.CreateCategoryRequest true "分类信息"
|
||||
// @Success 201 {object} models.Category
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories [post]
|
||||
func (h *CategoryHandler) CreateCategory(c *gin.Context) {
|
||||
var req models.CreateCategoryRequest
|
||||
var req entity.CreateCategoryRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -188,7 +184,7 @@ func (h *CategoryHandler) CreateCategory(c *gin.Context) {
|
||||
|
||||
// 验证请求数据
|
||||
if err := h.validateCreateCategoryRequest(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request data",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -198,7 +194,7 @@ func (h *CategoryHandler) CreateCategory(c *gin.Context) {
|
||||
category, err := h.categoryService.CreateCategory(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to create category", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to create category",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -217,25 +213,25 @@ func (h *CategoryHandler) CreateCategory(c *gin.Context) {
|
||||
// @Param id path int true "分类ID"
|
||||
// @Param category body models.UpdateCategoryRequest true "分类信息"
|
||||
// @Success 200 {object} models.Category
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/{id} [put]
|
||||
func (h *CategoryHandler) UpdateCategory(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid category ID",
|
||||
Message: "Category ID must be a valid number",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req models.UpdateCategoryRequest
|
||||
var req entity.UpdateCategoryRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -245,7 +241,7 @@ func (h *CategoryHandler) UpdateCategory(c *gin.Context) {
|
||||
category, err := h.categoryService.UpdateCategory(c.Request.Context(), uint(id), &req)
|
||||
if err != nil {
|
||||
if err.Error() == "category not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Category not found",
|
||||
Message: "The requested category does not exist",
|
||||
})
|
||||
@ -253,7 +249,7 @@ func (h *CategoryHandler) UpdateCategory(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to update category", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to update category",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -271,15 +267,15 @@ func (h *CategoryHandler) UpdateCategory(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "分类ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/{id} [delete]
|
||||
func (h *CategoryHandler) DeleteCategory(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid category ID",
|
||||
Message: "Category ID must be a valid number",
|
||||
})
|
||||
@ -289,7 +285,7 @@ func (h *CategoryHandler) DeleteCategory(c *gin.Context) {
|
||||
err = h.categoryService.DeleteCategory(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "category not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Category not found",
|
||||
Message: "The requested category does not exist",
|
||||
})
|
||||
@ -297,7 +293,7 @@ func (h *CategoryHandler) DeleteCategory(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to delete category", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to delete category",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -315,14 +311,14 @@ func (h *CategoryHandler) DeleteCategory(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param request body models.ReorderCategoriesRequest true "排序请求"
|
||||
// @Success 200 {object} models.SuccessResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/reorder [post]
|
||||
func (h *CategoryHandler) ReorderCategories(c *gin.Context) {
|
||||
var req models.ReorderCategoriesRequest
|
||||
var req entity.ReorderCategoriesRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -330,7 +326,7 @@ func (h *CategoryHandler) ReorderCategories(c *gin.Context) {
|
||||
}
|
||||
|
||||
if len(req.CategoryIDs) == 0 {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request",
|
||||
Message: "No category IDs provided",
|
||||
})
|
||||
@ -340,14 +336,14 @@ func (h *CategoryHandler) ReorderCategories(c *gin.Context) {
|
||||
err := h.categoryService.ReorderCategories(c.Request.Context(), req.ParentID, req.CategoryIDs)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to reorder categories", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to reorder categories",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.SuccessResponse{
|
||||
c.JSON(http.StatusOK, entity.SuccessResponse{
|
||||
Message: "Categories reordered successfully",
|
||||
})
|
||||
}
|
||||
@ -359,13 +355,13 @@ func (h *CategoryHandler) ReorderCategories(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.CategoryStats
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/stats [get]
|
||||
func (h *CategoryHandler) GetCategoryStats(c *gin.Context) {
|
||||
stats, err := h.categoryService.GetCategoryStats(c.Request.Context())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get category stats", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get category stats",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -383,14 +379,14 @@ func (h *CategoryHandler) GetCategoryStats(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param request body models.GenerateSlugRequest true "生成slug请求"
|
||||
// @Success 200 {object} models.GenerateSlugResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /categories/generate-slug [post]
|
||||
func (h *CategoryHandler) GenerateSlug(c *gin.Context) {
|
||||
var req models.GenerateSlugRequest
|
||||
var req entity.GenerateSlugRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -398,7 +394,7 @@ func (h *CategoryHandler) GenerateSlug(c *gin.Context) {
|
||||
}
|
||||
|
||||
if req.Name == "" {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request",
|
||||
Message: "Name is required",
|
||||
})
|
||||
@ -408,14 +404,14 @@ func (h *CategoryHandler) GenerateSlug(c *gin.Context) {
|
||||
slug, err := h.categoryService.GenerateSlug(c.Request.Context(), req.Name)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to generate slug", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to generate slug",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.GenerateSlugResponse{
|
||||
c.JSON(http.StatusOK, entity.GenerateSlugResponse{
|
||||
Slug: slug,
|
||||
})
|
||||
}
|
||||
|
||||
@ -6,7 +6,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"photography-backend/internal/models"
|
||||
"photography-backend/internal/model/entity"
|
||||
"photography-backend/internal/model/dto"
|
||||
"photography-backend/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -42,8 +43,8 @@ func NewPhotoHandler(photoService *service.PhotoService, logger *zap.Logger) *Ph
|
||||
// @Param sort_by query string false "排序字段"
|
||||
// @Param sort_order query string false "排序方向"
|
||||
// @Success 200 {object} service.PhotoListResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos [get]
|
||||
func (h *PhotoHandler) GetPhotos(c *gin.Context) {
|
||||
var params service.PhotoListParams
|
||||
@ -51,7 +52,7 @@ func (h *PhotoHandler) GetPhotos(c *gin.Context) {
|
||||
// 解析查询参数
|
||||
if err := c.ShouldBindQuery(¶ms); err != nil {
|
||||
h.logger.Error("Failed to bind query params", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid query parameters",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -67,7 +68,7 @@ func (h *PhotoHandler) GetPhotos(c *gin.Context) {
|
||||
result, err := h.photoService.GetPhotos(c.Request.Context(), params)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get photos", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get photos",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -85,15 +86,15 @@ func (h *PhotoHandler) GetPhotos(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "照片ID"
|
||||
// @Success 200 {object} models.Photo
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/{id} [get]
|
||||
func (h *PhotoHandler) GetPhoto(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid photo ID",
|
||||
Message: "Photo ID must be a valid number",
|
||||
})
|
||||
@ -103,7 +104,7 @@ func (h *PhotoHandler) GetPhoto(c *gin.Context) {
|
||||
photo, err := h.photoService.GetPhotoByID(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "photo not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Photo not found",
|
||||
Message: "The requested photo does not exist",
|
||||
})
|
||||
@ -111,7 +112,7 @@ func (h *PhotoHandler) GetPhoto(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to get photo", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get photo",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -129,14 +130,14 @@ func (h *PhotoHandler) GetPhoto(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param photo body models.CreatePhotoRequest true "照片信息"
|
||||
// @Success 201 {object} models.Photo
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos [post]
|
||||
func (h *PhotoHandler) CreatePhoto(c *gin.Context) {
|
||||
var req models.CreatePhotoRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -145,7 +146,7 @@ func (h *PhotoHandler) CreatePhoto(c *gin.Context) {
|
||||
|
||||
// 验证请求数据
|
||||
if err := h.validateCreatePhotoRequest(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request data",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -155,7 +156,7 @@ func (h *PhotoHandler) CreatePhoto(c *gin.Context) {
|
||||
photo, err := h.photoService.CreatePhoto(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to create photo", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to create photo",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -174,15 +175,15 @@ func (h *PhotoHandler) CreatePhoto(c *gin.Context) {
|
||||
// @Param id path int true "照片ID"
|
||||
// @Param photo body models.UpdatePhotoRequest true "照片信息"
|
||||
// @Success 200 {object} models.Photo
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/{id} [put]
|
||||
func (h *PhotoHandler) UpdatePhoto(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid photo ID",
|
||||
Message: "Photo ID must be a valid number",
|
||||
})
|
||||
@ -192,7 +193,7 @@ func (h *PhotoHandler) UpdatePhoto(c *gin.Context) {
|
||||
var req models.UpdatePhotoRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -202,7 +203,7 @@ func (h *PhotoHandler) UpdatePhoto(c *gin.Context) {
|
||||
photo, err := h.photoService.UpdatePhoto(c.Request.Context(), uint(id), &req)
|
||||
if err != nil {
|
||||
if err.Error() == "photo not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Photo not found",
|
||||
Message: "The requested photo does not exist",
|
||||
})
|
||||
@ -210,7 +211,7 @@ func (h *PhotoHandler) UpdatePhoto(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to update photo", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to update photo",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -228,15 +229,15 @@ func (h *PhotoHandler) UpdatePhoto(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "照片ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/{id} [delete]
|
||||
func (h *PhotoHandler) DeletePhoto(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid photo ID",
|
||||
Message: "Photo ID must be a valid number",
|
||||
})
|
||||
@ -246,7 +247,7 @@ func (h *PhotoHandler) DeletePhoto(c *gin.Context) {
|
||||
err = h.photoService.DeletePhoto(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "photo not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Photo not found",
|
||||
Message: "The requested photo does not exist",
|
||||
})
|
||||
@ -254,7 +255,7 @@ func (h *PhotoHandler) DeletePhoto(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to delete photo", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to delete photo",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -277,14 +278,14 @@ func (h *PhotoHandler) DeletePhoto(c *gin.Context) {
|
||||
// @Param category_ids formData string false "分类ID列表(逗号分隔)"
|
||||
// @Param tag_ids formData string false "标签ID列表(逗号分隔)"
|
||||
// @Success 201 {object} models.Photo
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/upload [post]
|
||||
func (h *PhotoHandler) UploadPhoto(c *gin.Context) {
|
||||
// 获取上传的文件
|
||||
file, header, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "No file uploaded",
|
||||
Message: "Please select a file to upload",
|
||||
})
|
||||
@ -328,7 +329,7 @@ func (h *PhotoHandler) UploadPhoto(c *gin.Context) {
|
||||
photo, err := h.photoService.UploadPhoto(c.Request.Context(), file, header, req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to upload photo", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to upload photo",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -346,14 +347,14 @@ func (h *PhotoHandler) UploadPhoto(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param request body models.BatchUpdatePhotosRequest true "批量更新请求"
|
||||
// @Success 200 {object} models.SuccessResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/batch/update [post]
|
||||
func (h *PhotoHandler) BatchUpdatePhotos(c *gin.Context) {
|
||||
var req models.BatchUpdatePhotosRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -361,7 +362,7 @@ func (h *PhotoHandler) BatchUpdatePhotos(c *gin.Context) {
|
||||
}
|
||||
|
||||
if len(req.IDs) == 0 {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request",
|
||||
Message: "No photo IDs provided",
|
||||
})
|
||||
@ -371,7 +372,7 @@ func (h *PhotoHandler) BatchUpdatePhotos(c *gin.Context) {
|
||||
err := h.photoService.BatchUpdatePhotos(c.Request.Context(), req.IDs, &req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to batch update photos", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to batch update photos",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -391,14 +392,14 @@ func (h *PhotoHandler) BatchUpdatePhotos(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param request body models.BatchDeleteRequest true "批量删除请求"
|
||||
// @Success 200 {object} models.SuccessResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/batch/delete [post]
|
||||
func (h *PhotoHandler) BatchDeletePhotos(c *gin.Context) {
|
||||
var req models.BatchDeleteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -406,7 +407,7 @@ func (h *PhotoHandler) BatchDeletePhotos(c *gin.Context) {
|
||||
}
|
||||
|
||||
if len(req.IDs) == 0 {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request",
|
||||
Message: "No photo IDs provided",
|
||||
})
|
||||
@ -416,7 +417,7 @@ func (h *PhotoHandler) BatchDeletePhotos(c *gin.Context) {
|
||||
err := h.photoService.BatchDeletePhotos(c.Request.Context(), req.IDs)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to batch delete photos", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to batch delete photos",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -435,13 +436,13 @@ func (h *PhotoHandler) BatchDeletePhotos(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.PhotoStats
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /photos/stats [get]
|
||||
func (h *PhotoHandler) GetPhotoStats(c *gin.Context) {
|
||||
stats, err := h.photoService.GetPhotoStats(c.Request.Context())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get photo stats", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get photo stats",
|
||||
Message: err.Error(),
|
||||
})
|
||||
|
||||
@ -5,7 +5,8 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"photography-backend/internal/models"
|
||||
"photography-backend/internal/model/entity"
|
||||
"photography-backend/internal/model/dto"
|
||||
"photography-backend/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -37,8 +38,8 @@ func NewTagHandler(tagService *service.TagService, logger *zap.Logger) *TagHandl
|
||||
// @Param sort_by query string false "排序字段"
|
||||
// @Param sort_order query string false "排序方向"
|
||||
// @Success 200 {object} service.TagListResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags [get]
|
||||
func (h *TagHandler) GetTags(c *gin.Context) {
|
||||
var params service.TagListParams
|
||||
@ -46,7 +47,7 @@ func (h *TagHandler) GetTags(c *gin.Context) {
|
||||
// 解析查询参数
|
||||
if err := c.ShouldBindQuery(¶ms); err != nil {
|
||||
h.logger.Error("Failed to bind query params", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid query parameters",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -57,7 +58,7 @@ func (h *TagHandler) GetTags(c *gin.Context) {
|
||||
result, err := h.tagService.GetTags(c.Request.Context(), params)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get tags", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get tags",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -74,13 +75,13 @@ func (h *TagHandler) GetTags(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} models.Tag
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/all [get]
|
||||
func (h *TagHandler) GetAllTags(c *gin.Context) {
|
||||
tags, err := h.tagService.GetAllTags(c.Request.Context())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get all tags", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get all tags",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -98,15 +99,15 @@ func (h *TagHandler) GetAllTags(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "标签ID"
|
||||
// @Success 200 {object} models.Tag
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/{id} [get]
|
||||
func (h *TagHandler) GetTag(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid tag ID",
|
||||
Message: "Tag ID must be a valid number",
|
||||
})
|
||||
@ -116,7 +117,7 @@ func (h *TagHandler) GetTag(c *gin.Context) {
|
||||
tag, err := h.tagService.GetTagByID(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "tag not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Tag not found",
|
||||
Message: "The requested tag does not exist",
|
||||
})
|
||||
@ -124,7 +125,7 @@ func (h *TagHandler) GetTag(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to get tag", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get tag",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -142,8 +143,8 @@ func (h *TagHandler) GetTag(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param slug path string true "标签slug"
|
||||
// @Success 200 {object} models.Tag
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/slug/{slug} [get]
|
||||
func (h *TagHandler) GetTagBySlug(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
@ -151,7 +152,7 @@ func (h *TagHandler) GetTagBySlug(c *gin.Context) {
|
||||
tag, err := h.tagService.GetTagBySlug(c.Request.Context(), slug)
|
||||
if err != nil {
|
||||
if err.Error() == "tag not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Tag not found",
|
||||
Message: "The requested tag does not exist",
|
||||
})
|
||||
@ -159,7 +160,7 @@ func (h *TagHandler) GetTagBySlug(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to get tag by slug", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get tag",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -177,14 +178,14 @@ func (h *TagHandler) GetTagBySlug(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param tag body models.CreateTagRequest true "标签信息"
|
||||
// @Success 201 {object} models.Tag
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags [post]
|
||||
func (h *TagHandler) CreateTag(c *gin.Context) {
|
||||
var req models.CreateTagRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -193,7 +194,7 @@ func (h *TagHandler) CreateTag(c *gin.Context) {
|
||||
|
||||
// 验证请求数据
|
||||
if err := h.validateCreateTagRequest(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request data",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -203,7 +204,7 @@ func (h *TagHandler) CreateTag(c *gin.Context) {
|
||||
tag, err := h.tagService.CreateTag(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to create tag", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to create tag",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -222,15 +223,15 @@ func (h *TagHandler) CreateTag(c *gin.Context) {
|
||||
// @Param id path int true "标签ID"
|
||||
// @Param tag body models.UpdateTagRequest true "标签信息"
|
||||
// @Success 200 {object} models.Tag
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/{id} [put]
|
||||
func (h *TagHandler) UpdateTag(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid tag ID",
|
||||
Message: "Tag ID must be a valid number",
|
||||
})
|
||||
@ -240,7 +241,7 @@ func (h *TagHandler) UpdateTag(c *gin.Context) {
|
||||
var req models.UpdateTagRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -250,7 +251,7 @@ func (h *TagHandler) UpdateTag(c *gin.Context) {
|
||||
tag, err := h.tagService.UpdateTag(c.Request.Context(), uint(id), &req)
|
||||
if err != nil {
|
||||
if err.Error() == "tag not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Tag not found",
|
||||
Message: "The requested tag does not exist",
|
||||
})
|
||||
@ -258,7 +259,7 @@ func (h *TagHandler) UpdateTag(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to update tag", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to update tag",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -276,15 +277,15 @@ func (h *TagHandler) UpdateTag(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "标签ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/{id} [delete]
|
||||
func (h *TagHandler) DeleteTag(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid tag ID",
|
||||
Message: "Tag ID must be a valid number",
|
||||
})
|
||||
@ -294,7 +295,7 @@ func (h *TagHandler) DeleteTag(c *gin.Context) {
|
||||
err = h.tagService.DeleteTag(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "tag not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "Tag not found",
|
||||
Message: "The requested tag does not exist",
|
||||
})
|
||||
@ -302,7 +303,7 @@ func (h *TagHandler) DeleteTag(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to delete tag", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to delete tag",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -320,14 +321,14 @@ func (h *TagHandler) DeleteTag(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param request body models.BatchDeleteRequest true "批量删除请求"
|
||||
// @Success 200 {object} models.SuccessResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/batch/delete [post]
|
||||
func (h *TagHandler) BatchDeleteTags(c *gin.Context) {
|
||||
var req models.BatchDeleteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -335,7 +336,7 @@ func (h *TagHandler) BatchDeleteTags(c *gin.Context) {
|
||||
}
|
||||
|
||||
if len(req.IDs) == 0 {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request",
|
||||
Message: "No tag IDs provided",
|
||||
})
|
||||
@ -345,7 +346,7 @@ func (h *TagHandler) BatchDeleteTags(c *gin.Context) {
|
||||
err := h.tagService.BatchDeleteTags(c.Request.Context(), req.IDs)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to batch delete tags", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to batch delete tags",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -365,7 +366,7 @@ func (h *TagHandler) BatchDeleteTags(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param limit query int false "限制数量"
|
||||
// @Success 200 {array} models.TagWithCount
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/popular [get]
|
||||
func (h *TagHandler) GetPopularTags(c *gin.Context) {
|
||||
limit := 10
|
||||
@ -378,7 +379,7 @@ func (h *TagHandler) GetPopularTags(c *gin.Context) {
|
||||
tags, err := h.tagService.GetPopularTags(c.Request.Context(), limit)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get popular tags", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get popular tags",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -395,13 +396,13 @@ func (h *TagHandler) GetPopularTags(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} models.TagCloudItem
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/cloud [get]
|
||||
func (h *TagHandler) GetTagCloud(c *gin.Context) {
|
||||
cloud, err := h.tagService.GetTagCloud(c.Request.Context())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get tag cloud", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get tag cloud",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -418,13 +419,13 @@ func (h *TagHandler) GetTagCloud(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.TagStats
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/stats [get]
|
||||
func (h *TagHandler) GetTagStats(c *gin.Context) {
|
||||
stats, err := h.tagService.GetTagStats(c.Request.Context())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get tag stats", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get tag stats",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -443,13 +444,13 @@ func (h *TagHandler) GetTagStats(c *gin.Context) {
|
||||
// @Param q query string true "搜索关键词"
|
||||
// @Param limit query int false "限制数量"
|
||||
// @Success 200 {array} models.Tag
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/search [get]
|
||||
func (h *TagHandler) SearchTags(c *gin.Context) {
|
||||
query := c.Query("q")
|
||||
if query == "" {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid query",
|
||||
Message: "Search query is required",
|
||||
})
|
||||
@ -466,7 +467,7 @@ func (h *TagHandler) SearchTags(c *gin.Context) {
|
||||
tags, err := h.tagService.SearchTags(c.Request.Context(), query, limit)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to search tags", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to search tags",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -484,14 +485,14 @@ func (h *TagHandler) SearchTags(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param request body models.GenerateSlugRequest true "生成slug请求"
|
||||
// @Success 200 {object} models.GenerateSlugResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /tags/generate-slug [post]
|
||||
func (h *TagHandler) GenerateSlug(c *gin.Context) {
|
||||
var req models.GenerateSlugRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -499,7 +500,7 @@ func (h *TagHandler) GenerateSlug(c *gin.Context) {
|
||||
}
|
||||
|
||||
if req.Name == "" {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request",
|
||||
Message: "Name is required",
|
||||
})
|
||||
@ -509,7 +510,7 @@ func (h *TagHandler) GenerateSlug(c *gin.Context) {
|
||||
slug, err := h.tagService.GenerateSlug(c.Request.Context(), req.Name)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to generate slug", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to generate slug",
|
||||
Message: err.Error(),
|
||||
})
|
||||
|
||||
@ -5,7 +5,8 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"photography-backend/internal/models"
|
||||
"photography-backend/internal/model/entity"
|
||||
"photography-backend/internal/model/dto"
|
||||
"photography-backend/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -31,8 +32,8 @@ func NewUserHandler(userService *service.UserService, logger *zap.Logger) *UserH
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.UserResponse
|
||||
// @Failure 401 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 401 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /me [get]
|
||||
func (h *UserHandler) GetCurrentUser(c *gin.Context) {
|
||||
userID := c.GetUint("user_id")
|
||||
@ -40,7 +41,7 @@ func (h *UserHandler) GetCurrentUser(c *gin.Context) {
|
||||
user, err := h.userService.GetUserByID(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get current user", zap.Error(err), zap.Uint("user_id", userID))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get user information",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -68,8 +69,8 @@ func (h *UserHandler) GetCurrentUser(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param user body models.UpdateCurrentUserRequest true "用户信息"
|
||||
// @Success 200 {object} models.UserResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /me [put]
|
||||
func (h *UserHandler) UpdateCurrentUser(c *gin.Context) {
|
||||
userID := c.GetUint("user_id")
|
||||
@ -77,7 +78,7 @@ func (h *UserHandler) UpdateCurrentUser(c *gin.Context) {
|
||||
var req models.UpdateCurrentUserRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -87,7 +88,7 @@ func (h *UserHandler) UpdateCurrentUser(c *gin.Context) {
|
||||
user, err := h.userService.UpdateCurrentUser(c.Request.Context(), userID, &req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to update current user", zap.Error(err), zap.Uint("user_id", userID))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to update user information",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -117,8 +118,8 @@ func (h *UserHandler) UpdateCurrentUser(c *gin.Context) {
|
||||
// @Param limit query int false "每页数量"
|
||||
// @Param search query string false "搜索关键词"
|
||||
// @Success 200 {object} service.UserListResponse
|
||||
// @Failure 403 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 403 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /admin/users [get]
|
||||
func (h *UserHandler) GetUsers(c *gin.Context) {
|
||||
var params service.UserListParams
|
||||
@ -126,7 +127,7 @@ func (h *UserHandler) GetUsers(c *gin.Context) {
|
||||
// 解析查询参数
|
||||
if err := c.ShouldBindQuery(¶ms); err != nil {
|
||||
h.logger.Error("Failed to bind query params", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid query parameters",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -136,7 +137,7 @@ func (h *UserHandler) GetUsers(c *gin.Context) {
|
||||
result, err := h.userService.GetUsers(c.Request.Context(), params)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get users", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get users",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -154,15 +155,15 @@ func (h *UserHandler) GetUsers(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} models.UserResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /admin/users/{id} [get]
|
||||
func (h *UserHandler) GetUser(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid user ID",
|
||||
Message: "User ID must be a valid number",
|
||||
})
|
||||
@ -172,7 +173,7 @@ func (h *UserHandler) GetUser(c *gin.Context) {
|
||||
user, err := h.userService.GetUserByID(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "user not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "User not found",
|
||||
Message: "The requested user does not exist",
|
||||
})
|
||||
@ -180,7 +181,7 @@ func (h *UserHandler) GetUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to get user", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to get user",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -208,14 +209,14 @@ func (h *UserHandler) GetUser(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param user body models.CreateUserRequest true "用户信息"
|
||||
// @Success 201 {object} models.UserResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /admin/users [post]
|
||||
func (h *UserHandler) CreateUser(c *gin.Context) {
|
||||
var req models.CreateUserRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -224,7 +225,7 @@ func (h *UserHandler) CreateUser(c *gin.Context) {
|
||||
|
||||
// 验证请求数据
|
||||
if err := h.validateCreateUserRequest(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request data",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -234,7 +235,7 @@ func (h *UserHandler) CreateUser(c *gin.Context) {
|
||||
user, err := h.userService.CreateUser(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to create user", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to create user",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -263,15 +264,15 @@ func (h *UserHandler) CreateUser(c *gin.Context) {
|
||||
// @Param id path int true "用户ID"
|
||||
// @Param user body models.UpdateUserRequest true "用户信息"
|
||||
// @Success 200 {object} models.UserResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /admin/users/{id} [put]
|
||||
func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid user ID",
|
||||
Message: "User ID must be a valid number",
|
||||
})
|
||||
@ -281,7 +282,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
var req models.UpdateUserRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Error("Failed to bind JSON", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid request body",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -291,7 +292,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
user, err := h.userService.UpdateUser(c.Request.Context(), uint(id), &req)
|
||||
if err != nil {
|
||||
if err.Error() == "user not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "User not found",
|
||||
Message: "The requested user does not exist",
|
||||
})
|
||||
@ -299,7 +300,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to update user", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to update user",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@ -327,15 +328,15 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 404 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
// @Failure 400 {object} response.Error
|
||||
// @Failure 404 {object} response.Error
|
||||
// @Failure 500 {object} response.Error
|
||||
// @Router /admin/users/{id} [delete]
|
||||
func (h *UserHandler) DeleteUser(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Invalid user ID",
|
||||
Message: "User ID must be a valid number",
|
||||
})
|
||||
@ -345,7 +346,7 @@ func (h *UserHandler) DeleteUser(c *gin.Context) {
|
||||
// 防止删除自己
|
||||
currentUserID := c.GetUint("user_id")
|
||||
if uint(id) == currentUserID {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, response.Error{
|
||||
Error: "Cannot delete yourself",
|
||||
Message: "You cannot delete your own account",
|
||||
})
|
||||
@ -355,7 +356,7 @@ func (h *UserHandler) DeleteUser(c *gin.Context) {
|
||||
err = h.userService.DeleteUser(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
if err.Error() == "user not found" {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, response.Error{
|
||||
Error: "User not found",
|
||||
Message: "The requested user does not exist",
|
||||
})
|
||||
@ -363,7 +364,7 @@ func (h *UserHandler) DeleteUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.logger.Error("Failed to delete user", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
c.JSON(http.StatusInternalServerError, response.Error{
|
||||
Error: "Failed to delete user",
|
||||
Message: err.Error(),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user