package interfaces import ( "strconv" "mengstack/internal/kernel/response" "mengstack/internal/modules/rbac/application" "mengstack/internal/modules/rbac/domain" "github.com/gin-gonic/gin" ) type Handler struct { svc *application.Service } func NewHandler(svc *application.Service) *Handler { return &Handler{svc: svc} } // ListPermissions godoc // @Summary 列出权限 // @Description 获取所有权限列表,可按模块筛选 // @Tags RBAC // @Produce json // @Param module query string false "按模块筛选" // @Success 200 {object} response.Response{data=[]domain.PermissionDTO} // @Failure 500 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/permissions [get] func (h *Handler) ListPermissions(c *gin.Context) { module := c.Query("module") var ( dtos []domain.PermissionDTO err error ) if module != "" { dtos, err = h.svc.ListPermissionsByModule(c.Request.Context(), module) } else { dtos, err = h.svc.ListPermissions(c.Request.Context()) } if err != nil { response.HandleError(c, err) return } response.Success(c, dtos) } // CreateRole godoc // @Summary 创建角色 // @Description 在当前租户下创建新角色 // @Tags RBAC // @Accept json // @Produce json // @Param request body domain.CreateRoleRequest true "角色信息" // @Success 200 {object} response.Response{data=domain.RoleDTO} // @Failure 400 {object} response.Response // @Failure 409 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles [post] func (h *Handler) CreateRole(c *gin.Context) { var req domain.CreateRoleRequest if err := c.ShouldBindJSON(&req); err != nil { response.Fail(c, response.NewBadRequest("invalid request body")) return } dto, err := h.svc.CreateRole(c.Request.Context(), req) if err != nil { response.HandleError(c, err) return } response.Success(c, dto) } // ListRoles godoc // @Summary 列出角色 // @Description 获取当前租户下的所有角色 // @Tags RBAC // @Produce json // @Success 200 {object} response.Response{data=[]domain.RoleDTO} // @Failure 500 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles [get] func (h *Handler) ListRoles(c *gin.Context) { dtos, err := h.svc.ListRoles(c.Request.Context()) if err != nil { response.HandleError(c, err) return } response.Success(c, dtos) } // GetRole godoc // @Summary 获取角色详情 // @Description 根据 ID 获取角色信息,包含权限列表 // @Tags RBAC // @Produce json // @Param id path int true "角色 ID" // @Success 200 {object} response.Response{data=domain.RoleDTO} // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles/{id} [get] func (h *Handler) GetRole(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid role id")) return } dto, err := h.svc.GetRole(c.Request.Context(), uint(id)) if err != nil { response.HandleError(c, err) return } response.Success(c, dto) } // UpdateRole godoc // @Summary 更新角色 // @Description 更新角色名称或描述 // @Tags RBAC // @Accept json // @Produce json // @Param id path int true "角色 ID" // @Param request body domain.UpdateRoleRequest true "更新内容" // @Success 200 {object} response.Response{data=domain.RoleDTO} // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles/{id} [put] func (h *Handler) UpdateRole(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid role id")) return } var req domain.UpdateRoleRequest if err := c.ShouldBindJSON(&req); err != nil { response.Fail(c, response.NewBadRequest("invalid request body")) return } dto, err := h.svc.UpdateRole(c.Request.Context(), uint(id), req) if err != nil { response.HandleError(c, err) return } response.Success(c, dto) } // DeleteRole godoc // @Summary 删除角色 // @Description 删除指定角色(系统角色不可删除) // @Tags RBAC // @Param id path int true "角色 ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 403 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles/{id} [delete] func (h *Handler) DeleteRole(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid role id")) return } if err := h.svc.DeleteRole(c.Request.Context(), uint(id)); err != nil { response.HandleError(c, err) return } response.Success(c, nil) } // SetRolePermissions godoc // @Summary 设置角色权限 // @Description 为角色批量设置权限(覆盖原有权限) // @Tags RBAC // @Accept json // @Produce json // @Param id path int true "角色 ID" // @Param request body domain.SetRolePermissionsRequest true "权限 ID 列表" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles/{id}/permissions [put] func (h *Handler) SetRolePermissions(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid role id")) return } var req domain.SetRolePermissionsRequest if err := c.ShouldBindJSON(&req); err != nil { response.Fail(c, response.NewBadRequest("invalid request body")) return } if err := h.svc.SetRolePermissions(c.Request.Context(), uint(id), req); err != nil { response.HandleError(c, err) return } response.Success(c, nil) } // GetRolePermissions godoc // @Summary 获取角色权限列表 // @Description 获取指定角色已分配的权限列表 // @Tags RBAC // @Produce json // @Param id path int true "角色 ID" // @Success 200 {object} response.Response{data=[]domain.PermissionDTO} // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/roles/{id}/permissions [get] func (h *Handler) GetRolePermissions(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid role id")) return } dto, err := h.svc.GetRole(c.Request.Context(), uint(id)) if err != nil { response.HandleError(c, err) return } response.Success(c, dto.Permissions) } // AssignRole godoc // @Summary 分配角色给用户 // @Description 为指定用户分配一个角色 // @Tags RBAC // @Accept json // @Produce json // @Param userId path int true "用户 ID" // @Param request body domain.AssignRoleRequest true "角色 ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 409 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/users/{userId}/roles [post] func (h *Handler) AssignRole(c *gin.Context) { userID, err := strconv.ParseUint(c.Param("userId"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid user id")) return } var req domain.AssignRoleRequest if err := c.ShouldBindJSON(&req); err != nil { response.Fail(c, response.NewBadRequest("invalid request body")) return } if err := h.svc.AssignRoleToUser(c.Request.Context(), uint(userID), req); err != nil { response.HandleError(c, err) return } response.Success(c, nil) } // RemoveRole godoc // @Summary 移除用户角色 // @Description 从指定用户移除一个角色 // @Tags RBAC // @Param userId path int true "用户 ID" // @Param roleId path int true "角色 ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/users/{userId}/roles/{roleId} [delete] func (h *Handler) RemoveRole(c *gin.Context) { userID, err := strconv.ParseUint(c.Param("userId"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid user id")) return } roleID, err := strconv.ParseUint(c.Param("roleId"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid role id")) return } if err := h.svc.RemoveRoleFromUser(c.Request.Context(), uint(userID), uint(roleID)); err != nil { response.HandleError(c, err) return } response.Success(c, nil) } // GetUserRoles godoc // @Summary 获取用户角色 // @Description 获取指定用户的所有角色及权限 // @Tags RBAC // @Produce json // @Param userId path int true "用户 ID" // @Success 200 {object} response.Response{data=[]domain.RoleDTO} // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/rbac/users/{userId}/roles [get] func (h *Handler) GetUserRoles(c *gin.Context) { userID, err := strconv.ParseUint(c.Param("userId"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid user id")) return } dtos, err := h.svc.GetUserPermissions(c.Request.Context(), uint(userID)) if err != nil { response.HandleError(c, err) return } response.Success(c, dtos) }