docs: add Swagger annotations to 13 API handlers
Added @Summary, @Description, @Tags, @Param, @Success, @Failure, @Router annotations to all major handler endpoints for OpenAPI/Swagger auto-generation. Covers 86 annotations across: - auth_handler.go (25): all auth endpoints - user_handler.go (14): CRUD + roles + admin management - device_handler.go (13): device CRUD + trust management - role_handler.go (8): role CRUD + permissions - custom_field_handler.go (7): field CRUD + user values - permission_handler.go (7): permission CRUD + tree - log_handler.go (3): login/operation logs - captcha_handler.go (3): generate/verify - stats_handler.go (2): dashboard + user stats - avatar_handler.go (1): upload avatar - totp_handler.go (1): totp status - password_reset_handler.go (1): forgot password Partially addresses P2: missing Swagger annotations (PRODUCTION_GAP_ANALYSIS_2026-04-08)
This commit is contained in:
@@ -21,6 +21,19 @@ func NewUserHandler(userService *service.UserService) *UserHandler {
|
||||
return &UserHandler{userService: userService}
|
||||
}
|
||||
|
||||
// CreateUser 创建用户
|
||||
// @Summary 创建用户
|
||||
// @Description 创建新用户账号(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body CreateUserRequest true "用户信息"
|
||||
// @Success 201 {object} Response{data=UserResponse} "用户创建成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 401 {object} Response "未认证"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Router /api/v1/users [post]
|
||||
func (h *UserHandler) CreateUser(c *gin.Context) {
|
||||
var req struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
@@ -62,6 +75,18 @@ func (h *UserHandler) CreateUser(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// ListUsers 获取用户列表
|
||||
// @Summary 获取用户列表
|
||||
// @Description 获取用户列表,支持游标分页和偏移分页
|
||||
// @Tags 用户管理
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param cursor query string false "游标分页游标"
|
||||
// @Param size query int false "每页大小"
|
||||
// @Param offset query int false "偏移分页偏移量"
|
||||
// @Param limit query int false "每页大小"
|
||||
// @Success 200 {object} Response{data=UserListResponse} "用户列表"
|
||||
// @Router /api/v1/users [get]
|
||||
func (h *UserHandler) ListUsers(c *gin.Context) {
|
||||
cursor := c.Query("cursor")
|
||||
sizeStr := c.DefaultQuery("size", "")
|
||||
@@ -113,6 +138,16 @@ func (h *UserHandler) ListUsers(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetUser 获取用户详情
|
||||
// @Summary 获取用户详情
|
||||
// @Description 根据ID获取用户详细信息
|
||||
// @Tags 用户管理
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} Response{data=UserResponse} "用户信息"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id} [get]
|
||||
func (h *UserHandler) GetUser(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -129,6 +164,20 @@ func (h *UserHandler) GetUser(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": toUserResponse(user)})
|
||||
}
|
||||
|
||||
// UpdateUser 更新用户
|
||||
// @Summary 更新用户信息
|
||||
// @Description 更新用户的基本信息(仅管理员或本人)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Param request body UpdateUserRequest true "更新信息"
|
||||
// @Success 200 {object} Response{data=UserResponse} "更新成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id} [put]
|
||||
func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -167,6 +216,17 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": toUserResponse(user)})
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
// @Summary 删除用户
|
||||
// @Description 删除用户账号(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} Response "删除成功"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id} [delete]
|
||||
func (h *UserHandler) DeleteUser(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -182,6 +242,20 @@ func (h *UserHandler) DeleteUser(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
|
||||
}
|
||||
|
||||
// UpdatePassword 修改密码
|
||||
// @Summary 修改用户密码
|
||||
// @Description 修改用户密码(仅管理员或本人)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Param request body UpdatePasswordRequest true "密码信息"
|
||||
// @Success 200 {object} Response "密码修改成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id}/password [put]
|
||||
func (h *UserHandler) UpdatePassword(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -207,6 +281,20 @@ func (h *UserHandler) UpdatePassword(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "密码修改成功"})
|
||||
}
|
||||
|
||||
// UpdateUserStatus 更新用户状态
|
||||
// @Summary 更新用户状态
|
||||
// @Description 更新用户账号状态(active/inactive/locked/disabled)(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Param request body UpdateStatusRequest true "状态信息"
|
||||
// @Success 200 {object} Response "状态更新成功"
|
||||
// @Failure 400 {object} Response "无效的状态值"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id}/status [put]
|
||||
func (h *UserHandler) UpdateUserStatus(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -246,6 +334,17 @@ func (h *UserHandler) UpdateUserStatus(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
|
||||
}
|
||||
|
||||
// GetUserRoles 获取用户角色
|
||||
// @Summary 获取用户角色列表
|
||||
// @Description 获取指定用户的角色列表(仅本人或管理员)
|
||||
// @Tags 用户管理
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} Response{data=[]domain.Role} "角色列表"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id}/roles [get]
|
||||
func (h *UserHandler) GetUserRoles(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -282,6 +381,20 @@ func (h *UserHandler) GetUserRoles(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// AssignRoles 分配用户角色
|
||||
// @Summary 分配用户角色
|
||||
// @Description 为用户分配角色(替换现有角色)(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Param request body AssignRolesRequest true "角色ID列表"
|
||||
// @Success 200 {object} Response "角色分配成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 404 {object} Response "用户不存在"
|
||||
// @Router /api/v1/users/{id}/roles [post]
|
||||
func (h *UserHandler) AssignRoles(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -306,6 +419,18 @@ func (h *UserHandler) AssignRoles(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "角色分配成功"})
|
||||
}
|
||||
|
||||
// BatchUpdateStatus 批量更新用户状态
|
||||
// @Summary 批量更新用户状态
|
||||
// @Description 批量更新多个用户的状态(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body service.BatchUpdateStatusRequest true "批量更新请求"
|
||||
// @Success 200 {object} Response "批量更新成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Router /api/v1/users/batch/status [put]
|
||||
func (h *UserHandler) BatchUpdateStatus(c *gin.Context) {
|
||||
var req service.BatchUpdateStatusRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -322,6 +447,18 @@ func (h *UserHandler) BatchUpdateStatus(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "更新成功", "data": gin.H{"count": count}})
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除用户
|
||||
// @Summary 批量删除用户
|
||||
// @Description 批量删除多个用户(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body service.BatchDeleteRequest true "批量删除请求"
|
||||
// @Success 200 {object} Response "批量删除成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Router /api/v1/users/batch [delete]
|
||||
func (h *UserHandler) BatchDelete(c *gin.Context) {
|
||||
var req service.BatchDeleteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -338,6 +475,15 @@ func (h *UserHandler) BatchDelete(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "删除成功", "data": gin.H{"count": count}})
|
||||
}
|
||||
|
||||
// ListAdmins 获取管理员列表
|
||||
// @Summary 获取管理员列表
|
||||
// @Description 获取所有管理员用户列表(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} Response{data=[]UserResponse} "管理员列表"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Router /api/v1/users/admins [get]
|
||||
func (h *UserHandler) ListAdmins(c *gin.Context) {
|
||||
admins, err := h.userService.ListAdmins(c.Request.Context())
|
||||
if err != nil {
|
||||
@@ -353,6 +499,18 @@ func (h *UserHandler) ListAdmins(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": adminResponses})
|
||||
}
|
||||
|
||||
// CreateAdmin 创建管理员
|
||||
// @Summary 创建管理员
|
||||
// @Description 创建新管理员账号(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body CreateAdminRequest true "管理员信息"
|
||||
// @Success 201 {object} Response{data=UserResponse} "管理员创建成功"
|
||||
// @Failure 400 {object} Response "请求参数错误"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Router /api/v1/users/admins [post]
|
||||
func (h *UserHandler) CreateAdmin(c *gin.Context) {
|
||||
var req struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
@@ -382,6 +540,18 @@ func (h *UserHandler) CreateAdmin(c *gin.Context) {
|
||||
c.JSON(http.StatusCreated, gin.H{"code": 0, "message": "管理员创建成功", "data": toUserResponse(admin)})
|
||||
}
|
||||
|
||||
// DeleteAdmin 删除管理员
|
||||
// @Summary 删除管理员
|
||||
// @Description 删除管理员角色(最后管理员保护、自删保护)(仅管理员)
|
||||
// @Tags 用户管理
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} Response "管理员已移除"
|
||||
// @Failure 400 {object} Response "无效的用户ID"
|
||||
// @Failure 403 {object} Response "无权限"
|
||||
// @Failure 409 {object} Response "无法删除(最后管理员或自删)"
|
||||
// @Router /api/v1/users/admins/{id} [delete]
|
||||
func (h *UserHandler) DeleteAdmin(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user