Browse Source

清理权限模型

master
hejl 10 hours ago
parent
commit
a2629fdea8
  1. 2
      gofaster/app/src/renderer/modules/route-sync/direct-route-mappings.js
  2. 259
      gofaster/backend/internal/auth/controller/permission_controller.go
  3. 272
      gofaster/backend/internal/auth/controller/resource_controller.go
  4. 168
      gofaster/backend/internal/auth/controller/route_sync_controller.go
  5. 43
      gofaster/backend/internal/auth/migration/create_route_tables.go
  6. 142
      gofaster/backend/internal/auth/migration/migration.go
  7. 9
      gofaster/backend/internal/auth/model/permission.go
  8. 39
      gofaster/backend/internal/auth/model/resource.go
  9. 10
      gofaster/backend/internal/auth/module.go
  10. 102
      gofaster/backend/internal/auth/repository/permission_repo.go
  11. 214
      gofaster/backend/internal/auth/repository/resource_repo.go
  12. 22
      gofaster/backend/internal/auth/repository/user_repo.go
  13. 3
      gofaster/backend/internal/auth/routes/auth_routes.go
  14. 22
      gofaster/backend/internal/auth/routes/permission_routes.go
  15. 42
      gofaster/backend/internal/auth/routes/resource_routes.go
  16. 22
      gofaster/backend/internal/auth/routes/route_sync_routes.go
  17. 4
      gofaster/backend/internal/auth/service/frontend_route_service.go
  18. 195
      gofaster/backend/internal/auth/service/permission_service.go
  19. 195
      gofaster/backend/internal/auth/service/resource_service.go
  20. 314
      gofaster/backend/internal/auth/service/route_sync_service.go
  21. 111
      gofaster/backend/internal/auth/service/route_sync_service_enhanced.go
  22. 53
      gofaster/backend/internal/shared/middleware/permission_middleware.go

2
gofaster/app/src/renderer/modules/route-sync/direct-route-mappings.js

@ -252,7 +252,7 @@ export default { @@ -252,7 +252,7 @@ export default {
"id": 15,
"component": "PasswordChangeModal",
"module": "user-management",
"triggerName": "passwordchangemodal-input-8m1x12",
"triggerName": "passwordchangemodal-input-sa0y29",
"triggerType": "input"
}
]

259
gofaster/backend/internal/auth/controller/permission_controller.go

@ -4,7 +4,6 @@ import ( @@ -4,7 +4,6 @@ import (
"net/http"
"strconv"
"gofaster/internal/auth/model"
"gofaster/internal/auth/service"
"gofaster/internal/shared/response"
@ -21,98 +20,9 @@ func NewPermissionController(permissionService *service.PermissionService) *Perm @@ -21,98 +20,9 @@ func NewPermissionController(permissionService *service.PermissionService) *Perm
}
}
// CreatePermission 创建权限
// @Summary 创建权限
// @Description 创建新的权限记录
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param permission body model.Permission true "权限信息"
// @Success 200 {object} response.Response{data=model.Permission}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions [post]
func (c *PermissionController) CreatePermission(ctx *gin.Context) {
var permission model.Permission
if err := ctx.ShouldBindJSON(&permission); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
if err := c.permissionService.CreatePermission(ctx.Request.Context(), &permission); err != nil {
response.Error(ctx, http.StatusInternalServerError, "创建权限失败", err.Error())
return
}
response.Success(ctx, "权限创建成功", permission)
}
// UpdatePermission 更新权限
// @Summary 更新权限
// @Description 更新指定ID的权限信息
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param id path int true "权限ID"
// @Param permission body model.Permission true "权限信息"
// @Success 200 {object} response.Response{data=model.Permission}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions/{id} [put]
func (c *PermissionController) UpdatePermission(ctx *gin.Context) {
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的权限ID")
return
}
var permission model.Permission
if err := ctx.ShouldBindJSON(&permission); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
permission.ID = uint(id)
if err := c.permissionService.UpdatePermission(ctx.Request.Context(), &permission); err != nil {
response.Error(ctx, http.StatusInternalServerError, "更新权限失败", err.Error())
return
}
response.Success(ctx, "权限更新成功", permission)
}
// DeletePermission 删除权限
// @Summary 删除权限
// @Description 删除指定ID的权限记录
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param id path int true "权限ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions/{id} [delete]
func (c *PermissionController) DeletePermission(ctx *gin.Context) {
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的权限ID")
return
}
if err := c.permissionService.DeletePermission(ctx.Request.Context(), uint(id)); err != nil {
response.Error(ctx, http.StatusInternalServerError, "删除权限失败", err.Error())
return
}
response.Success(ctx, "权限删除成功", nil)
}
// GetPermission 获取权限详情
// @Summary 获取权限详情
// @Description 根据ID获取权限的详细信息
// @Description 根据ID获取权限详情
// @Tags 权限管理
// @Accept json
// @Produce json
@ -125,11 +35,11 @@ func (c *PermissionController) GetPermission(ctx *gin.Context) { @@ -125,11 +35,11 @@ func (c *PermissionController) GetPermission(ctx *gin.Context) {
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的权限ID")
response.Error(ctx, http.StatusBadRequest, "无效的权限ID", err.Error())
return
}
permission, err := c.permissionService.GetPermission(ctx.Request.Context(), uint(id))
permission, err := c.permissionService.GetPermissionByID(ctx.Request.Context(), uint(id))
if err != nil {
response.Error(ctx, http.StatusNotFound, "权限不存在", err.Error())
return
@ -140,168 +50,147 @@ func (c *PermissionController) GetPermission(ctx *gin.Context) { @@ -140,168 +50,147 @@ func (c *PermissionController) GetPermission(ctx *gin.Context) {
// ListPermissions 获取权限列表
// @Summary 获取权限列表
// @Description 分页获取权限列表信息
// @Description 分页获取权限列表
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param pageSize query int false "每页数量" default(10)
// @Success 200 {object} response.Response{data=object}
// @Failure 500 {object} response.Response
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Failure 400 {object} response.Response
// @Router /api/auth/permissions [get]
func (c *PermissionController) ListPermissions(ctx *gin.Context) {
pageStr := ctx.DefaultQuery("page", "1")
pageSizeStr := ctx.DefaultQuery("pageSize", "10")
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))
page, err := strconv.Atoi(pageStr)
if err != nil || page < 1 {
if page < 1 {
page = 1
}
pageSize, err := strconv.Atoi(pageSizeStr)
if err != nil || pageSize < 1 || pageSize > 100 {
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
permissions, total, err := c.permissionService.ListPermissions(ctx.Request.Context(), page, pageSize)
offset := (page - 1) * pageSize
permissions, total, err := c.permissionService.ListPermissions(ctx.Request.Context(), offset, pageSize)
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取权限列表失败", err.Error())
return
}
response.Success(ctx, "获取权限列表成功", gin.H{
"data": permissions,
"page": page,
"size": pageSize,
"total": total,
})
result := map[string]interface{}{
"list": permissions,
"total": total,
"page": page,
"pageSize": pageSize,
}
response.Success(ctx, "获取权限列表成功", result)
}
// GetPermissionsByResource 根据资源获取权限列表
// @Summary 根据资源获取权限列表
// @Description 根据资源名称获取相关的权限列表
// GetPermissionsByBackendRoute 根据后端路由获取权限
// @Summary 根据后端路由获取权限
// @Description 根据后端路由获取相关权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param resource path string true "资源名称"
// @Param backendRoute query string true "后端路由"
// @Success 200 {object} response.Response{data=[]model.Permission}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions/resource/{resource} [get]
func (c *PermissionController) GetPermissionsByResource(ctx *gin.Context) {
resource := ctx.Param("resource")
if resource == "" {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "资源名称不能为空")
// @Router /api/auth/permissions/backend-route [get]
func (c *PermissionController) GetPermissionsByBackendRoute(ctx *gin.Context) {
backendRoute := ctx.Query("backendRoute")
if backendRoute == "" {
response.Error(ctx, http.StatusBadRequest, "后端路由不能为空", "")
return
}
permissions, err := c.permissionService.GetPermissionsByResource(ctx.Request.Context(), resource)
permissions, err := c.permissionService.GetPermissionsByBackendRoute(ctx.Request.Context(), backendRoute)
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取资源权限失败", err.Error())
response.Error(ctx, http.StatusInternalServerError, "获取权限失败", err.Error())
return
}
response.Success(ctx, "获取资源权限成功", permissions)
response.Success(ctx, "获取权限成功", permissions)
}
// AssignPermissionsToRole 为角色分配权限
// @Summary 为角色分配权限
// @Description 为指定角色分配多个权限
// GetPermissionsByFrontendRouteID 根据前端路由ID获取权限
// @Summary 根据前端路由ID获取权限
// @Description 根据前端路由ID获取相关权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param roleId path int true "角色ID"
// @Param request body object{permission_ids=[]int} true "权限ID列表"
// @Success 200 {object} response.Response
// @Param frontendRouteId path int true "前端路由ID"
// @Success 200 {object} response.Response{data=[]model.Permission}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions/roles/{roleId}/assign [post]
func (c *PermissionController) AssignPermissionsToRole(ctx *gin.Context) {
roleIDStr := ctx.Param("roleId")
roleID, err := strconv.ParseUint(roleIDStr, 10, 32)
// @Router /api/auth/permissions/frontend-route/{frontendRouteId} [get]
func (c *PermissionController) GetPermissionsByFrontendRouteID(ctx *gin.Context) {
idStr := ctx.Param("frontendRouteId")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的角色ID")
response.Error(ctx, http.StatusBadRequest, "无效的前端路由ID", err.Error())
return
}
var request struct {
PermissionIDs []uint `json:"permission_ids" binding:"required"`
}
if err := ctx.ShouldBindJSON(&request); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
if err := c.permissionService.AssignPermissionsToRole(ctx.Request.Context(), uint(roleID), request.PermissionIDs); err != nil {
response.Error(ctx, http.StatusInternalServerError, "分配权限失败", err.Error())
permissions, err := c.permissionService.GetPermissionsByFrontendRouteID(ctx.Request.Context(), uint(id))
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取权限失败", err.Error())
return
}
response.Success(ctx, "权限分配成功", nil)
response.Success(ctx, "获取权限成功", permissions)
}
// GetRolePermissions 获取角色的权限列表
// @Summary 获取角色的权限列表
// @Description 获取指定角色拥有的所有权限列表
// GetPermissionsByMenuGroupID 根据菜单分组ID获取权限
// @Summary 根据菜单分组ID获取权限
// @Description 根据菜单分组ID获取相关权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param roleId path int true "角色ID"
// @Param menuGroupId path int true "菜单分组ID"
// @Success 200 {object} response.Response{data=[]model.Permission}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions/roles/{roleId} [get]
func (c *PermissionController) GetRolePermissions(ctx *gin.Context) {
roleIDStr := ctx.Param("roleId")
roleID, err := strconv.ParseUint(roleIDStr, 10, 32)
// @Router /api/auth/permissions/menu-group/{menuGroupId} [get]
func (c *PermissionController) GetPermissionsByMenuGroupID(ctx *gin.Context) {
idStr := ctx.Param("menuGroupId")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的角色ID")
response.Error(ctx, http.StatusBadRequest, "无效的菜单分组ID", err.Error())
return
}
permissions, err := c.permissionService.GetRolePermissions(ctx.Request.Context(), uint(roleID))
permissions, err := c.permissionService.GetPermissionsByMenuGroupID(ctx.Request.Context(), uint(id))
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取角色权限失败", err.Error())
response.Error(ctx, http.StatusInternalServerError, "获取权限失败", err.Error())
return
}
response.Success(ctx, "获取角色权限成功", permissions)
response.Success(ctx, "获取权限成功", permissions)
}
// RemovePermissionsFromRole 从角色移除权限
// @Summary 从角色移除权限
// @Description 从指定角色中移除多个权限
// GetUserPermissions 获取用户权限
// @Summary 获取用户权限
// @Description 根据用户ID获取用户的所有权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param roleId path int true "角色ID"
// @Param request body object{permission_ids=[]int} true "权限ID列表"
// @Success 200 {object} response.Response
// @Param userId path int true "用户ID"
// @Success 200 {object} response.Response{data=[]model.Permission}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/permissions/roles/{roleId}/remove [delete]
func (c *PermissionController) RemovePermissionsFromRole(ctx *gin.Context) {
roleIDStr := ctx.Param("roleId")
roleID, err := strconv.ParseUint(roleIDStr, 10, 32)
// @Router /api/auth/permissions/user/{userId} [get]
func (c *PermissionController) GetUserPermissions(ctx *gin.Context) {
idStr := ctx.Param("userId")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的角色ID")
response.Error(ctx, http.StatusBadRequest, "无效的用户ID", err.Error())
return
}
var request struct {
PermissionIDs []uint `json:"permission_ids" binding:"required"`
}
if err := ctx.ShouldBindJSON(&request); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
if err := c.permissionService.RemovePermissionsFromRole(ctx.Request.Context(), uint(roleID), request.PermissionIDs); err != nil {
response.Error(ctx, http.StatusInternalServerError, "移除权限失败", err.Error())
permissions, err := c.permissionService.GetUserPermissions(ctx.Request.Context(), uint(id))
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取用户权限失败", err.Error())
return
}
response.Success(ctx, "权限移除成功", nil)
}
response.Success(ctx, "获取用户权限成功", permissions)
}

272
gofaster/backend/internal/auth/controller/resource_controller.go

@ -1,272 +0,0 @@ @@ -1,272 +0,0 @@
package controller
import (
"net/http"
"strconv"
"gofaster/internal/auth/model"
"gofaster/internal/auth/repository"
"gofaster/internal/auth/service"
"gofaster/internal/shared/response"
"github.com/gin-gonic/gin"
)
type ResourceController struct {
resourceService *service.ResourceService
routeMappingRepo *repository.RouteMappingRepository
}
func NewResourceController(resourceService *service.ResourceService, routeMappingRepo *repository.RouteMappingRepository) *ResourceController {
return &ResourceController{
resourceService: resourceService,
routeMappingRepo: routeMappingRepo,
}
}
// CreateResource 创建资源
// @Summary 创建资源
// @Description 创建新的资源记录
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param resource body model.Resource true "资源信息"
// @Success 200 {object} response.Response{data=model.Resource}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/resources [post]
func (c *ResourceController) CreateResource(ctx *gin.Context) {
var resource model.Resource
if err := ctx.ShouldBindJSON(&resource); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
if err := c.resourceService.CreateResource(ctx.Request.Context(), &resource); err != nil {
response.Error(ctx, http.StatusInternalServerError, "创建资源失败", err.Error())
return
}
response.Success(ctx, "资源创建成功", resource)
}
// UpdateResource 更新资源
// @Summary 更新资源
// @Description 更新指定ID的资源信息
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param id path int true "资源ID"
// @Param resource body model.Resource true "资源信息"
// @Success 200 {object} response.Response{data=model.Resource}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/resources/{id} [put]
func (c *ResourceController) UpdateResource(ctx *gin.Context) {
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的资源ID")
return
}
var resource model.Resource
if err := ctx.ShouldBindJSON(&resource); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
resource.ID = uint(id)
if err := c.resourceService.UpdateResource(ctx.Request.Context(), &resource); err != nil {
response.Error(ctx, http.StatusInternalServerError, "更新资源失败", err.Error())
return
}
response.Success(ctx, "资源更新成功", resource)
}
// DeleteResource 删除资源
// @Summary 删除资源
// @Description 删除指定ID的资源记录
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param id path int true "资源ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/resources/{id} [delete]
func (c *ResourceController) DeleteResource(ctx *gin.Context) {
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的资源ID")
return
}
if err := c.resourceService.DeleteResource(ctx.Request.Context(), uint(id)); err != nil {
response.Error(ctx, http.StatusInternalServerError, "删除资源失败", err.Error())
return
}
response.Success(ctx, "资源删除成功", nil)
}
// GetResource 获取资源详情
// @Summary 获取资源详情
// @Description 根据ID获取资源的详细信息
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param id path int true "资源ID"
// @Success 200 {object} response.Response{data=model.Resource}
// @Failure 400 {object} response.Response
// @Failure 404 {object} response.Response
// @Router /api/auth/resources/{id} [get]
func (c *ResourceController) GetResource(ctx *gin.Context) {
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "无效的资源ID")
return
}
resource, err := c.resourceService.GetResource(ctx.Request.Context(), uint(id))
if err != nil {
response.Error(ctx, http.StatusNotFound, "资源不存在", err.Error())
return
}
response.Success(ctx, "获取资源成功", resource)
}
// ListResources 获取资源列表
// @Summary 获取资源列表
// @Description 分页获取资源列表信息
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param pageSize query int false "每页数量" default(10)
// @Success 200 {object} response.Response{data=object}
// @Failure 500 {object} response.Response
// @Router /api/auth/resources [get]
func (c *ResourceController) ListResources(ctx *gin.Context) {
pageStr := ctx.DefaultQuery("page", "1")
pageSizeStr := ctx.DefaultQuery("pageSize", "10")
page, err := strconv.Atoi(pageStr)
if err != nil || page < 1 {
page = 1
}
pageSize, err := strconv.Atoi(pageSizeStr)
if err != nil || pageSize < 1 || pageSize > 100 {
pageSize = 10
}
resources, total, err := c.resourceService.ListResources(ctx.Request.Context(), page, pageSize)
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取资源列表失败", err.Error())
return
}
response.Success(ctx, "获取资源列表成功", gin.H{
"data": resources,
"page": page,
"size": pageSize,
"total": total,
})
}
// GetResourceTree 获取资源树
// @Summary 获取资源树
// @Description 获取层级结构的资源树
// @Tags 资源管理
// @Accept json
// @Produce json
// @Success 200 {object} response.Response{data=[]model.Resource}
// @Failure 500 {object} response.Response
// @Router /api/auth/resources/tree [get]
func (c *ResourceController) GetResourceTree(ctx *gin.Context) {
resources, err := c.resourceService.GetResourceTree(ctx.Request.Context())
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取资源树失败", err.Error())
return
}
response.Success(ctx, "获取资源树成功", resources)
}
// SyncResources 同步资源
// @Summary 同步资源
// @Description 从路由映射同步资源信息
// @Tags 资源管理
// @Accept json
// @Produce json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/resources/sync [post]
func (c *ResourceController) SyncResources(ctx *gin.Context) {
if err := c.resourceService.SyncResourcesFromRoutes(ctx.Request.Context()); err != nil {
response.Error(ctx, http.StatusInternalServerError, "同步资源失败", err.Error())
return
}
response.Success(ctx, "资源同步成功", nil)
}
// ListResourcesByModule 根据模块获取资源列表
// @Summary 根据模块获取资源列表
// @Description 根据模块名称获取相关资源列表
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param module path string true "模块名称"
// @Success 200 {object} response.Response{data=[]model.Resource}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/resources/module/{module} [get]
func (c *ResourceController) ListResourcesByModule(ctx *gin.Context) {
module := ctx.Param("module")
if module == "" {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "模块名称不能为空")
return
}
resources, err := c.resourceService.ListResourcesByModule(ctx.Request.Context(), module)
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取模块资源失败", err.Error())
return
}
response.Success(ctx, "获取模块资源成功", resources)
}
// ListResourcesByType 根据类型获取资源列表
// @Summary 根据类型获取资源列表
// @Description 根据资源类型获取相关资源列表
// @Tags 资源管理
// @Accept json
// @Produce json
// @Param type path string true "资源类型"
// @Success 200 {object} response.Response{data=[]model.Resource}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/auth/resources/type/{type} [get]
func (c *ResourceController) ListResourcesByType(ctx *gin.Context) {
resourceType := ctx.Param("type")
if resourceType == "" {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", "资源类型不能为空")
return
}
resources, err := c.resourceService.ListResourcesByType(ctx.Request.Context(), resourceType)
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取类型资源失败", err.Error())
return
}
response.Success(ctx, "获取类型资源成功", resources)
}

168
gofaster/backend/internal/auth/controller/route_sync_controller.go

@ -1,168 +0,0 @@ @@ -1,168 +0,0 @@
package controller
import (
"net/http"
"gofaster/internal/auth/model"
"gofaster/internal/auth/service"
"gofaster/internal/shared/response"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// RouteSyncController 路由同步控制器
type RouteSyncController struct {
routeSyncService *service.RouteSyncService
log *zap.Logger
}
// NewRouteSyncController 创建路由同步控制器
func NewRouteSyncController(routeSyncService *service.RouteSyncService, log *zap.Logger) *RouteSyncController {
return &RouteSyncController{
routeSyncService: routeSyncService,
log: log,
}
}
// SyncRouteMapping 同步路由映射
// @Summary 同步前端路由映射
// @Description 接收前端路由信息并同步到数据库
// @Tags 路由同步
// @Accept json
// @Produce json
// @Param routeMapping body model.RouteMapping true "路由映射信息"
// @Success 200 {object} response.Response{data=model.RouteMapping}
// @Failure 400 {object} response.Response
// @Router /api/route-mappings/sync [post]
func (c *RouteSyncController) SyncRouteMapping(ctx *gin.Context) {
var routeMapping model.RouteMapping
if err := ctx.ShouldBindJSON(&routeMapping); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
// 验证必填字段
if routeMapping.BackendRoute == "" {
response.Error(ctx, http.StatusBadRequest, "后端路由不能为空", "")
return
}
if routeMapping.HTTPMethod == "" {
response.Error(ctx, http.StatusBadRequest, "HTTP方法不能为空", "")
return
}
// 设置默认值
if routeMapping.Module == "" {
routeMapping.Module = "unknown"
}
if routeMapping.Description == "" {
routeMapping.Description = "路由映射"
}
if routeMapping.Status == 0 {
routeMapping.Status = 1
}
// 同步到数据库
if err := c.routeSyncService.SyncRouteMapping(&routeMapping); err != nil {
c.log.Error("同步路由失败",
zap.String("backendRoute", routeMapping.BackendRoute),
zap.Error(err))
response.Error(ctx, http.StatusInternalServerError, "同步前端路由失败", err.Error())
return
}
c.log.Info("路由同步成功",
zap.String("backendRoute", routeMapping.BackendRoute),
zap.String("module", routeMapping.Module))
response.Success(ctx, "路由同步成功", routeMapping)
}
// BatchSyncRouteMappings 批量同步路由映射
// @Summary 批量同步前端路由
// @Description 批量接收前端路由信息并同步到数据库
// @Tags 路由同步
// @Accept json
// @Produce json
// @Param routeMappings body []model.RouteMapping true "路由映射信息列表"
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Failure 400 {object} response.Response
// @Router /api/route-mappings/batch-sync [post]
func (c *RouteSyncController) BatchSyncRouteMappings(ctx *gin.Context) {
var routeMappings []model.RouteMapping
if err := ctx.ShouldBindJSON(&routeMappings); err != nil {
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
return
}
if len(routeMappings) == 0 {
response.Error(ctx, http.StatusBadRequest, "路由映射列表不能为空", "")
return
}
// 批量同步
successCount, errorCount, errors := c.routeSyncService.BatchSyncRouteMappings(routeMappings)
result := map[string]interface{}{
"total": len(routeMappings),
"successCount": successCount,
"errorCount": errorCount,
"errors": errors,
}
if errorCount > 0 {
c.log.Warn("批量同步前端路由完成,存在部分错误",
zap.Int("total", len(routeMappings)),
zap.Int("success", successCount),
zap.Int("errors", errorCount))
response.Success(ctx, "批量同步完成,存在部分错误", result)
} else {
c.log.Info("批量同步前端路由成功",
zap.Int("total", len(routeMappings)),
zap.Int("success", successCount))
response.Success(ctx, "批量同步前端路由成功", result)
}
}
// GetSyncStatus 获取同步状态
// @Summary 获取同步状态
// @Description 获取路由同步的状态信息
// @Tags 路由同步
// @Accept json
// @Produce json
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Failure 400 {object} response.Response
// @Router /api/route-mappings/sync-status [get]
func (c *RouteSyncController) GetSyncStatus(ctx *gin.Context) {
status, err := c.routeSyncService.GetSyncStatus()
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取同步状态失败", err.Error())
return
}
response.Success(ctx, "获取同步状态成功", status)
}
// GetRouteMappings 获取路由映射列表
// @Summary 获取前端路由列表
// @Description 获取所有前端路由映射信息
// @Tags 路由同步
// @Accept json
// @Produce json
// @Param module query string false "模块名称"
// @Param authGroup query string false "权限分组"
// @Success 200 {object} response.Response{data=[]model.RouteMapping}
// @Failure 400 {object} response.Response
// @Router /api/route-mappings/frontend [get]
func (c *RouteSyncController) GetRouteMappings(ctx *gin.Context) {
module := ctx.Query("module")
routes, err := c.routeSyncService.GetRouteMappings(module)
if err != nil {
response.Error(ctx, http.StatusInternalServerError, "获取前端路由失败", err.Error())
return
}
response.Success(ctx, "获取前端路由成功", routes)
}

43
gofaster/backend/internal/auth/migration/create_route_tables.go

@ -32,49 +32,6 @@ func CreateRouteTables(db *gorm.DB, log *zap.Logger) error { @@ -32,49 +32,6 @@ func CreateRouteTables(db *gorm.DB, log *zap.Logger) error {
}
log.Info("✅ 前后台路由关系表创建完成")
// 为现有Resource表添加菜单相关字段
if err := addMenuFieldsToResource(db, log); err != nil {
log.Error("为Resource表添加菜单字段失败", zap.Error(err))
return err
}
log.Info("✅ Resource表菜单字段添加完成")
log.Info("路由相关表创建完成")
return nil
}
// addMenuFieldsToResource 为Resource表添加菜单相关字段
func addMenuFieldsToResource(db *gorm.DB, log *zap.Logger) error {
// 检查IsMenu字段是否存在
var hasIsMenu bool
err := db.Raw("SELECT COUNT(*) > 0 FROM information_schema.columns WHERE table_name = 'resources' AND column_name = 'is_menu'").Scan(&hasIsMenu).Error
if err != nil {
return err
}
if !hasIsMenu {
// 添加IsMenu字段
if err := db.Exec("ALTER TABLE resources ADD COLUMN is_menu BOOLEAN DEFAULT FALSE").Error; err != nil {
return err
}
log.Info("添加is_menu字段到resources表")
}
// 移除旧的MenuID字段(如果存在)
var hasMenuID bool
err = db.Raw("SELECT COUNT(*) > 0 FROM information_schema.columns WHERE table_name = 'resources' AND column_name = 'menu_id'").Scan(&hasMenuID).Error
if err != nil {
return err
}
if hasMenuID {
// 删除MenuID字段
if err := db.Exec("ALTER TABLE resources DROP COLUMN menu_id").Error; err != nil {
log.Warn("删除menu_id字段失败,可能已被删除", zap.Error(err))
} else {
log.Info("删除menu_id字段从resources表")
}
}
return nil
}

142
gofaster/backend/internal/auth/migration/migration.go

@ -47,14 +47,6 @@ func RunMigrations(db *gorm.DB) error { @@ -47,14 +47,6 @@ func RunMigrations(db *gorm.DB) error {
return err
}
// 自动迁移资源相关表
if err := db.AutoMigrate(
&model.Resource{},
&model.ResourcePermission{},
); err != nil {
return err
}
// 自动迁移权限相关表
if err := db.AutoMigrate(
&model.Permission{},
@ -98,10 +90,6 @@ func RunMigrations(db *gorm.DB) error { @@ -98,10 +90,6 @@ func RunMigrations(db *gorm.DB) error {
return err
}
// 创建默认权限
if err := createDefaultPermissions(db); err != nil {
return err
}
return nil
}
@ -231,133 +219,3 @@ func createDefaultPasswordPolicy(db *gorm.DB) error { @@ -231,133 +219,3 @@ func createDefaultPasswordPolicy(db *gorm.DB) error {
return nil
}
// createDefaultPermissions 创建默认权限
func createDefaultPermissions(db *gorm.DB) error {
// 检查是否已存在权限
var count int64
db.Model(&model.Permission{}).Count(&count)
if count > 0 {
return nil // 已存在权限,跳过
}
permissions := []model.Permission{
// 用户管理权限
{
Name: "查看用户列表",
Code: "user:list",
Description: "查看系统用户列表",
Resource: "user",
Action: "list",
},
{
Name: "创建用户",
Code: "user:create",
Description: "创建新用户",
Resource: "user",
Action: "create",
},
{
Name: "编辑用户",
Code: "user:update",
Description: "编辑用户信息",
Resource: "user",
Action: "update",
},
{
Name: "删除用户",
Code: "user:delete",
Description: "删除用户",
Resource: "user",
Action: "delete",
},
// 角色管理权限
{
Name: "查看角色列表",
Code: "role:list",
Description: "查看系统角色列表",
Resource: "role",
Action: "list",
},
{
Name: "创建角色",
Code: "role:create",
Description: "创建新角色",
Resource: "role",
Action: "create",
},
{
Name: "编辑角色",
Code: "role:update",
Description: "编辑角色信息",
Resource: "role",
Action: "update",
},
{
Name: "删除角色",
Code: "role:delete",
Description: "删除角色",
Resource: "role",
Action: "delete",
},
{
Name: "分配角色权限",
Code: "role:assign_permissions",
Description: "为角色分配权限",
Resource: "role",
Action: "assign_permissions",
},
// 权限管理权限
{
Name: "查看权限列表",
Code: "permission:list",
Description: "查看系统权限列表",
Resource: "permission",
Action: "list",
},
{
Name: "创建权限",
Code: "permission:create",
Description: "创建新权限",
Resource: "permission",
Action: "create",
},
{
Name: "编辑权限",
Code: "permission:update",
Description: "编辑权限信息",
Resource: "permission",
Action: "update",
},
{
Name: "删除权限",
Code: "permission:delete",
Description: "删除权限",
Resource: "permission",
Action: "delete",
},
// 系统管理权限
{
Name: "系统设置",
Code: "system:settings",
Description: "管理系统设置",
Resource: "system",
Action: "settings",
},
{
Name: "查看系统日志",
Code: "system:logs",
Description: "查看系统日志",
Resource: "system",
Action: "logs",
},
}
for _, permission := range permissions {
if err := db.Create(&permission).Error; err != nil {
return err
}
}
fmt.Println("✅ 默认权限创建完成")
return nil
}

9
gofaster/backend/internal/auth/model/permission.go

@ -6,9 +6,8 @@ import ( @@ -6,9 +6,8 @@ import (
type Permission struct {
model.BaseModel
Name string `gorm:"uniqueIndex;size:50" json:"name"`
Code string `gorm:"uniqueIndex;size:50" json:"code"`
Description string `gorm:"size:200" json:"description"`
Resource string `gorm:"size:100" json:"resource"`
Action string `gorm:"size:50" json:"action"` // create, read, update, delete等
Description string `gorm:"size:200" json:"description"` // 权限描述
BackendRoute string `gorm:"size:200" json:"backend_route"` // 后端路由
FrontendRouteID *uint `gorm:"index" json:"frontend_route_id"` // 前端路由ID
MenuGroupID *uint `gorm:"index" json:"menu_group_id"` // 菜单分组ID
}

39
gofaster/backend/internal/auth/model/resource.go

@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
package model
import (
"gofaster/internal/shared/model"
)
// Resource 权限资源模型
type Resource struct {
model.BaseModel
Name string `gorm:"uniqueIndex;size:100" json:"name"` // 资源名称,如 "用户管理"
Code string `gorm:"uniqueIndex;size:100" json:"code"` // 资源代码,如 "user:manage"
Type string `gorm:"size:50" json:"type"` // 资源类型:api, menu, button, data
Path string `gorm:"size:200" json:"path"` // 资源路径,如 "/api/users"
Method string `gorm:"size:20" json:"method"` // HTTP方法,如 "GET", "POST"
Description string `gorm:"size:200" json:"description"` // 资源描述
Module string `gorm:"size:50" json:"module"` // 所属模块,如 "auth", "workflow"
Status int `gorm:"default:1" json:"status"` // 状态:1-启用,0-禁用
Sort int `gorm:"default:0" json:"sort"` // 排序
ParentID *uint `gorm:"index" json:"parent_id"` // 父资源ID,用于层级结构
Icon string `gorm:"size:50" json:"icon"` // 图标(用于菜单)
IsPublic bool `gorm:"default:false" json:"is_public"` // 是否公开资源(无需权限验证)
IsMenu bool `gorm:"default:false" json:"is_menu"` // 是否为菜单资源
}
// ResourcePermission 资源权限关联表
type ResourcePermission struct {
ResourceID uint `gorm:"primaryKey"`
PermissionID uint `gorm:"primaryKey"`
}
// TableName 指定表名
func (Resource) TableName() string {
return "resources"
}
// TableName 指定表名
func (ResourcePermission) TableName() string {
return "resource_permissions"
}

10
gofaster/backend/internal/auth/module.go

@ -48,7 +48,6 @@ func (m *Module) Init(cfg *config.Config, logger *zap.Logger, db *gorm.DB, redis @@ -48,7 +48,6 @@ func (m *Module) Init(cfg *config.Config, logger *zap.Logger, db *gorm.DB, redis
passwordPolicyRepo := repository.NewPasswordPolicyRepository(db)
passwordHistoryRepo := repository.NewPasswordHistoryRepository(db)
passwordResetRepo := repository.NewPasswordResetRepository(db)
resourceRepo := repository.NewResourceRepository(db)
menuGroupRepo := repository.NewMenuGroupRepository(db)
frontendRouteRepo := repository.NewFrontendRouteRepository(db)
frontendBackendRouteRepo := repository.NewFrontendBackendRouteRepository(db)
@ -65,7 +64,7 @@ func (m *Module) Init(cfg *config.Config, logger *zap.Logger, db *gorm.DB, redis @@ -65,7 +64,7 @@ func (m *Module) Init(cfg *config.Config, logger *zap.Logger, db *gorm.DB, redis
)
menuGroupService := service.NewMenuGroupService(menuGroupRepo, logger)
frontendRouteService := service.NewFrontendRouteService(frontendRouteRepo, frontendBackendRouteRepo, logger)
m.routeSyncService = service.NewRouteSyncService(resourceRepo, frontendBackendRouteRepo, logger)
m.routeSyncService = service.NewRouteSyncService(frontendBackendRouteRepo, logger)
// 初始化控制器
m.userController = controller.NewUserController(userService)
@ -111,11 +110,10 @@ func (m *Module) RegisterRoutes(router *gin.RouterGroup) { @@ -111,11 +110,10 @@ func (m *Module) RegisterRoutes(router *gin.RouterGroup) {
routes.RegisterMenuGroupRoutes(router, m.db, m.logger)
}
// SyncRoutes 同步路由信息
// SyncRoutes 同步路由信息(已废弃,路由由前台同步)
func (m *Module) SyncRoutes(router *gin.Engine) error {
if m.routeSyncService != nil {
return m.routeSyncService.SyncRoutes(router)
}
// 路由同步功能已废弃,数据由前台同步
m.logger.Info("路由同步功能已废弃,数据由前台同步")
return nil
}

102
gofaster/backend/internal/auth/repository/permission_repo.go

@ -2,7 +2,6 @@ package repository @@ -2,7 +2,6 @@ package repository
import (
"context"
"fmt"
"gofaster/internal/auth/model"
"gofaster/internal/shared/repository"
@ -10,16 +9,12 @@ import ( @@ -10,16 +9,12 @@ import (
)
type PermissionRepository interface {
Create(ctx context.Context, permission *model.Permission) error
Update(ctx context.Context, permission *model.Permission) error
Delete(ctx context.Context, id uint) error
GetByID(ctx context.Context, id uint) (*model.Permission, error)
GetByName(ctx context.Context, name string) (*model.Permission, error)
GetByCode(ctx context.Context, code string) (*model.Permission, error)
List(ctx context.Context, offset, limit int) ([]*model.Permission, int64, error)
GetByResource(ctx context.Context, resource string) ([]*model.Permission, error)
GetByBackendRoute(ctx context.Context, backendRoute string) ([]*model.Permission, error)
GetByFrontendRouteID(ctx context.Context, frontendRouteID uint) ([]*model.Permission, error)
GetByMenuGroupID(ctx context.Context, menuGroupID uint) ([]*model.Permission, error)
GetByUserID(ctx context.Context, userID uint) ([]*model.Permission, error)
BatchCreate(ctx context.Context, permissions []*model.Permission) error
}
type permissionRepository struct {
@ -32,18 +27,6 @@ func NewPermissionRepository(db *gorm.DB) PermissionRepository { @@ -32,18 +27,6 @@ func NewPermissionRepository(db *gorm.DB) PermissionRepository {
}
}
func (r *permissionRepository) Create(ctx context.Context, permission *model.Permission) error {
return r.DB().WithContext(ctx).Create(permission).Error
}
func (r *permissionRepository) Update(ctx context.Context, permission *model.Permission) error {
return r.DB().WithContext(ctx).Save(permission).Error
}
func (r *permissionRepository) Delete(ctx context.Context, id uint) error {
return r.DB().WithContext(ctx).Delete(&model.Permission{}, id).Error
}
func (r *permissionRepository) GetByID(ctx context.Context, id uint) (*model.Permission, error) {
var permission model.Permission
err := r.DB().WithContext(ctx).First(&permission, id).Error
@ -53,68 +36,67 @@ func (r *permissionRepository) GetByID(ctx context.Context, id uint) (*model.Per @@ -53,68 +36,67 @@ func (r *permissionRepository) GetByID(ctx context.Context, id uint) (*model.Per
return &permission, nil
}
func (r *permissionRepository) GetByName(ctx context.Context, name string) (*model.Permission, error) {
var permission model.Permission
err := r.DB().WithContext(ctx).Where("name = ?", name).First(&permission).Error
if err != nil {
return nil, err
}
return &permission, nil
}
func (r *permissionRepository) GetByCode(ctx context.Context, code string) (*model.Permission, error) {
var permission model.Permission
err := r.DB().WithContext(ctx).Where("code = ?", code).First(&permission).Error
if err != nil {
return nil, err
}
return &permission, nil
}
func (r *permissionRepository) List(ctx context.Context, offset, limit int) ([]*model.Permission, int64, error) {
var permissions []*model.Permission
var total int64
// 添加调试日志
fmt.Printf("🔍 [权限查询] 开始查询权限列表,offset=%d, limit=%d\n", offset, limit)
err := r.DB().WithContext(ctx).Model(&model.Permission{}).Count(&total).Error
if err != nil {
fmt.Printf("🔍 [权限查询] 统计总数失败: %v\n", err)
return nil, 0, err
}
fmt.Printf("🔍 [权限查询] 数据库中共有 %d 条权限记录\n", total)
err = r.DB().WithContext(ctx).Offset(offset).Limit(limit).Order("id ASC").Find(&permissions).Error
err = r.DB().WithContext(ctx).
Offset(offset).
Limit(limit).
Find(&permissions).Error
if err != nil {
fmt.Printf("🔍 [权限查询] 查询权限列表失败: %v\n", err)
return nil, 0, err
}
fmt.Printf("🔍 [权限查询] 查询到 %d 条权限记录\n", len(permissions))
return permissions, total, nil
}
func (r *permissionRepository) GetByResource(ctx context.Context, resource string) ([]*model.Permission, error) {
func (r *permissionRepository) GetByBackendRoute(ctx context.Context, backendRoute string) ([]*model.Permission, error) {
var permissions []*model.Permission
err := r.DB().WithContext(ctx).Where("resource = ?", resource).Order("id ASC").Find(&permissions).Error
return permissions, err
err := r.DB().WithContext(ctx).Where("backend_route = ?", backendRoute).Find(&permissions).Error
if err != nil {
return nil, err
}
return permissions, nil
}
func (r *permissionRepository) GetByUserID(ctx context.Context, userID uint) ([]*model.Permission, error) {
func (r *permissionRepository) GetByFrontendRouteID(ctx context.Context, frontendRouteID uint) ([]*model.Permission, error) {
var permissions []*model.Permission
err := r.DB().WithContext(ctx).Where("frontend_route_id = ?", frontendRouteID).Find(&permissions).Error
if err != nil {
return nil, err
}
return permissions, nil
}
func (r *permissionRepository) GetByMenuGroupID(ctx context.Context, menuGroupID uint) ([]*model.Permission, error) {
var permissions []*model.Permission
err := r.DB().WithContext(ctx).Where("menu_group_id = ?", menuGroupID).Find(&permissions).Error
if err != nil {
return nil, err
}
return permissions, nil
}
// 通过用户角色关联查询权限
err := r.DB().WithContext(ctx).
func (r *permissionRepository) GetByUserID(ctx context.Context, userID uint) ([]*model.Permission, error) {
var permissions []*model.Permission
// 通过用户角色获取权限
err := r.DB().WithContext(ctx).Table("permissions").
Joins("JOIN role_permissions ON permissions.id = role_permissions.permission_id").
Joins("JOIN user_roles ON role_permissions.role_id = user_roles.role_id").
Where("user_roles.user_id = ?", userID).
Distinct().
Distinct("permissions.*").
Find(&permissions).Error
return permissions, err
}
func (r *permissionRepository) BatchCreate(ctx context.Context, permissions []*model.Permission) error {
return r.DB().WithContext(ctx).CreateInBatches(permissions, 100).Error
}
if err != nil {
return nil, err
}
return permissions, nil
}

214
gofaster/backend/internal/auth/repository/resource_repo.go

@ -1,214 +0,0 @@ @@ -1,214 +0,0 @@
package repository
import (
"context"
"fmt"
"gofaster/internal/auth/model"
"gofaster/internal/shared/repository"
"gorm.io/gorm"
)
type ResourceRepository interface {
Create(ctx context.Context, resource *model.Resource) error
Update(ctx context.Context, resource *model.Resource) error
Delete(ctx context.Context, id uint) error
GetByID(ctx context.Context, id uint) (*model.Resource, error)
GetByCode(ctx context.Context, code string) (*model.Resource, error)
List(ctx context.Context, offset, limit int) ([]*model.Resource, int64, error)
ListByModule(ctx context.Context, module string) ([]*model.Resource, error)
ListByType(ctx context.Context, resourceType string) ([]*model.Resource, error)
ListPublic(ctx context.Context) ([]*model.Resource, error)
GetTree(ctx context.Context) ([]*model.Resource, error)
BatchCreate(ctx context.Context, resources []*model.Resource) error
BatchUpdate(ctx context.Context, resources []*model.Resource) error
SyncFromRoutes(ctx context.Context, routes []RouteInfo) error
}
type resourceRepository struct {
*repository.BaseRepo
}
func NewResourceRepository(db *gorm.DB) ResourceRepository {
return &resourceRepository{
BaseRepo: repository.NewBaseRepo(db),
}
}
func (r *resourceRepository) Create(ctx context.Context, resource *model.Resource) error {
return r.DB().WithContext(ctx).Create(resource).Error
}
func (r *resourceRepository) Update(ctx context.Context, resource *model.Resource) error {
return r.DB().WithContext(ctx).Save(resource).Error
}
func (r *resourceRepository) Delete(ctx context.Context, id uint) error {
return r.DB().WithContext(ctx).Delete(&model.Resource{}, id).Error
}
func (r *resourceRepository) GetByID(ctx context.Context, id uint) (*model.Resource, error) {
var resource model.Resource
err := r.DB().WithContext(ctx).First(&resource, id).Error
if err != nil {
return nil, err
}
return &resource, nil
}
func (r *resourceRepository) GetByCode(ctx context.Context, code string) (*model.Resource, error) {
var resource model.Resource
err := r.DB().WithContext(ctx).Where("code = ?", code).First(&resource).Error
if err != nil {
return nil, err
}
return &resource, nil
}
func (r *resourceRepository) List(ctx context.Context, offset, limit int) ([]*model.Resource, int64, error) {
var resources []*model.Resource
var total int64
// 添加调试日志
fmt.Printf("🔍 [资源查询] 开始查询资源列表,offset=%d, limit=%d\n", offset, limit)
err := r.DB().WithContext(ctx).Model(&model.Resource{}).Count(&total).Error
if err != nil {
fmt.Printf("🔍 [资源查询] 统计总数失败: %v\n", err)
return nil, 0, err
}
fmt.Printf("🔍 [资源查询] 数据库中共有 %d 条资源记录\n", total)
err = r.DB().WithContext(ctx).Offset(offset).Limit(limit).Order("sort ASC, id ASC").Find(&resources).Error
if err != nil {
fmt.Printf("🔍 [资源查询] 查询资源列表失败: %v\n", err)
return nil, 0, err
}
fmt.Printf("🔍 [资源查询] 查询到 %d 条资源记录\n", len(resources))
return resources, total, nil
}
func (r *resourceRepository) ListByModule(ctx context.Context, module string) ([]*model.Resource, error) {
var resources []*model.Resource
err := r.DB().WithContext(ctx).Where("module = ? AND status = 1", module).Order("sort ASC, id ASC").Find(&resources).Error
return resources, err
}
func (r *resourceRepository) ListByType(ctx context.Context, resourceType string) ([]*model.Resource, error) {
var resources []*model.Resource
err := r.DB().WithContext(ctx).Where("type = ? AND status = 1", resourceType).Order("sort ASC, id ASC").Find(&resources).Error
return resources, err
}
func (r *resourceRepository) ListPublic(ctx context.Context) ([]*model.Resource, error) {
var resources []*model.Resource
err := r.DB().WithContext(ctx).Where("is_public = true AND status = 1").Order("sort ASC, id ASC").Find(&resources).Error
return resources, err
}
func (r *resourceRepository) GetTree(ctx context.Context) ([]*model.Resource, error) {
var resources []*model.Resource
err := r.DB().WithContext(ctx).Where("status = 1").Order("sort ASC, id ASC").Find(&resources).Error
if err != nil {
return nil, err
}
// 构建树形结构
return r.buildTree(resources), nil
}
func (r *resourceRepository) buildTree(resources []*model.Resource) []*model.Resource {
resourceMap := make(map[uint]*model.Resource)
var roots []*model.Resource
// 创建映射
for _, resource := range resources {
resourceMap[resource.ID] = resource
}
// 构建树形结构
for _, resource := range resources {
if resource.ParentID == nil {
roots = append(roots, resource)
} else {
if _, exists := resourceMap[*resource.ParentID]; exists {
// 这里需要添加Children字段到Resource模型中
// 暂时跳过,后续可以扩展
}
}
}
return roots
}
func (r *resourceRepository) BatchCreate(ctx context.Context, resources []*model.Resource) error {
return r.DB().WithContext(ctx).CreateInBatches(resources, 100).Error
}
func (r *resourceRepository) BatchUpdate(ctx context.Context, resources []*model.Resource) error {
return r.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
for _, resource := range resources {
if err := tx.Save(resource).Error; err != nil {
return err
}
}
return nil
})
}
// RouteInfo 路由信息
type RouteInfo struct {
Path string
Method string
Name string
Description string
Module string
IsPublic bool
}
func (r *resourceRepository) SyncFromRoutes(ctx context.Context, routes []RouteInfo) error {
return r.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
for _, route := range routes {
// 生成资源代码
code := fmt.Sprintf("%s:%s:%s", route.Module, route.Method, route.Path)
// 检查资源是否已存在
var existingResource model.Resource
err := tx.Where("code = ?", code).First(&existingResource).Error
if err == gorm.ErrRecordNotFound {
// 创建新资源
resource := &model.Resource{
Name: route.Name,
Code: code,
Type: "api",
Path: route.Path,
Method: route.Method,
Description: route.Description,
Module: route.Module,
Status: 1,
IsPublic: route.IsPublic,
}
if err := tx.Create(resource).Error; err != nil {
return fmt.Errorf("创建资源失败: %v", err)
}
fmt.Printf("✅ 创建资源: %s (%s %s)\n", route.Name, route.Method, route.Path)
} else if err != nil {
return fmt.Errorf("查询资源失败: %v", err)
} else {
// 更新现有资源
existingResource.Name = route.Name
existingResource.Description = route.Description
existingResource.IsPublic = route.IsPublic
if err := tx.Save(&existingResource).Error; err != nil {
return fmt.Errorf("更新资源失败: %v", err)
}
fmt.Printf("🔄 更新资源: %s (%s %s)\n", route.Name, route.Method, route.Path)
}
}
return nil
})
}

22
gofaster/backend/internal/auth/repository/user_repo.go

@ -22,6 +22,9 @@ type UserRepository interface { @@ -22,6 +22,9 @@ type UserRepository interface {
ResetPasswordError(ctx context.Context, userID uint) error
UpdateLastLogin(ctx context.Context, userID uint, ip string) error
GetUserWithRoles(ctx context.Context, userID uint) (*model.User, error)
// 权限相关方法
GetUserPermissions(userID uint) ([]model.Permission, error)
}
type userRepository struct {
@ -171,3 +174,22 @@ func (r *userRepository) GetUserWithRoles(ctx context.Context, userID uint) (*mo @@ -171,3 +174,22 @@ func (r *userRepository) GetUserWithRoles(ctx context.Context, userID uint) (*mo
}
return &user, nil
}
// GetUserPermissions 获取用户的所有权限
func (r *userRepository) GetUserPermissions(userID uint) ([]model.Permission, error) {
var permissions []model.Permission
// 通过用户角色获取权限
err := r.db.Table("permissions").
Joins("JOIN role_permissions ON permissions.id = role_permissions.permission_id").
Joins("JOIN user_roles ON role_permissions.role_id = user_roles.role_id").
Where("user_roles.user_id = ?", userID).
Distinct("permissions.*").
Find(&permissions).Error
if err != nil {
return nil, err
}
return permissions, nil
}

3
gofaster/backend/internal/auth/routes/auth_routes.go

@ -79,9 +79,6 @@ func RegisterAuthRoutes(router *gin.RouterGroup, db *gorm.DB, jwtSecret string) @@ -79,9 +79,6 @@ func RegisterAuthRoutes(router *gin.RouterGroup, db *gorm.DB, jwtSecret string)
testAdmin.GET("/users", userController.ListUsers)
}
// 注册资源管理路由
RegisterResourceRoutes(router, db, jwtSecret)
// 注册权限管理路由 - 注册到 /auth 组下
RegisterPermissionRoutes(auth, db, jwtSecret)

22
gofaster/backend/internal/auth/routes/permission_routes.go

@ -13,8 +13,7 @@ import ( @@ -13,8 +13,7 @@ import (
func RegisterPermissionRoutes(router *gin.RouterGroup, db *gorm.DB, jwtSecret string) {
// 初始化依赖
permissionRepo := repository.NewPermissionRepository(db)
roleRepo := repository.NewRoleRepository(db)
permissionService := service.NewPermissionService(permissionRepo, roleRepo)
permissionService := service.NewPermissionService(permissionRepo)
permissionController := controller.NewPermissionController(permissionService)
// 权限管理路由组
@ -23,18 +22,13 @@ func RegisterPermissionRoutes(router *gin.RouterGroup, db *gorm.DB, jwtSecret st @@ -23,18 +22,13 @@ func RegisterPermissionRoutes(router *gin.RouterGroup, db *gorm.DB, jwtSecret st
// 需要权限验证的路由
permissionGroup.Use(middleware.JWTAuth()) // 暂时只检查JWT,不检查权限
{
// 权限CRUD操作
permissionGroup.GET("", permissionController.ListPermissions) // 获取权限列表
permissionGroup.POST("", permissionController.CreatePermission) // 创建权限
permissionGroup.GET("/:id", permissionController.GetPermission) // 获取权限详情
permissionGroup.PUT("/:id", permissionController.UpdatePermission) // 更新权限
permissionGroup.DELETE("/:id", permissionController.DeletePermission) // 删除权限
// 权限分配相关
permissionGroup.GET("/resource/:resource", permissionController.GetPermissionsByResource) // 根据资源获取权限
permissionGroup.POST("/roles/:roleId/assign", permissionController.AssignPermissionsToRole) // 为角色分配权限
permissionGroup.GET("/roles/:roleId", permissionController.GetRolePermissions) // 获取角色的权限列表
permissionGroup.DELETE("/roles/:roleId/remove", permissionController.RemovePermissionsFromRole) // 从角色移除权限
// 权限查询操作
permissionGroup.GET("", permissionController.ListPermissions) // 获取权限列表
permissionGroup.GET("/:id", permissionController.GetPermission) // 获取权限详情
permissionGroup.GET("/backend-route", permissionController.GetPermissionsByBackendRoute) // 根据后端路由获取权限
permissionGroup.GET("/frontend-route/:frontendRouteId", permissionController.GetPermissionsByFrontendRouteID) // 根据前端路由ID获取权限
permissionGroup.GET("/menu-group/:menuGroupId", permissionController.GetPermissionsByMenuGroupID) // 根据菜单分组ID获取权限
permissionGroup.GET("/user/:userId", permissionController.GetUserPermissions) // 获取用户权限
}
}
}

42
gofaster/backend/internal/auth/routes/resource_routes.go

@ -1,42 +0,0 @@ @@ -1,42 +0,0 @@
package routes
import (
"gofaster/internal/auth/controller"
"gofaster/internal/auth/repository"
"gofaster/internal/auth/service"
"gofaster/internal/shared/middleware"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func RegisterResourceRoutes(router *gin.RouterGroup, db *gorm.DB, jwtSecret string) {
// 初始化依赖
resourceRepo := repository.NewResourceRepository(db)
routeMappingRepo := repository.NewRouteMappingRepository(db)
resourceService := service.NewResourceService(resourceRepo)
resourceController := controller.NewResourceController(resourceService, routeMappingRepo)
// 资源管理路由组
resourceGroup := router.Group("/resources")
{
// 需要权限验证的路由
resourceGroup.Use(middleware.JWTAuth()) // 暂时只检查JWT,不检查权限
{
// 资源CRUD操作
resourceGroup.GET("", resourceController.ListResources) // 获取资源列表
resourceGroup.POST("", resourceController.CreateResource) // 创建资源
resourceGroup.GET("/:id", resourceController.GetResource) // 获取资源详情
resourceGroup.PUT("/:id", resourceController.UpdateResource) // 更新资源
resourceGroup.DELETE("/:id", resourceController.DeleteResource) // 删除资源
// 资源树和同步
resourceGroup.GET("/tree", resourceController.GetResourceTree) // 获取资源树
resourceGroup.POST("/sync", resourceController.SyncResources) // 同步资源
// 按模块和类型查询
resourceGroup.GET("/module/:module", resourceController.ListResourcesByModule) // 按模块获取资源
resourceGroup.GET("/type/:type", resourceController.ListResourcesByType) // 按类型获取资源
}
}
}

22
gofaster/backend/internal/auth/routes/route_sync_routes.go

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
package routes
import (
"gofaster/internal/auth/controller"
"gofaster/internal/auth/repository"
"gofaster/internal/auth/service"
"net/http"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
@ -13,23 +13,25 @@ import ( @@ -13,23 +13,25 @@ import (
// RegisterRouteSyncRoutes 注册路由同步相关路由
func RegisterRouteSyncRoutes(router *gin.RouterGroup, db *gorm.DB, logger *zap.Logger) {
// 初始化依赖
resourceRepo := repository.NewResourceRepository(db)
frontendBackendRouteRepo := repository.NewFrontendBackendRouteRepository(db)
routeSyncService := service.NewRouteSyncService(resourceRepo, frontendBackendRouteRepo, logger)
routeSyncController := controller.NewRouteSyncController(routeSyncService, logger)
routeSyncService := service.NewRouteSyncService(frontendBackendRouteRepo, logger)
// 路由同步路由组
routeSyncGroup := router.Group("/route-mappings")
routeSyncGroup := router.Group("/route-sync")
{
// 临时移除认证要求,用于开发测试
// TODO: 后续添加认证逻辑
// routeSyncGroup.Use(middleware.JWTAuth())
{
// 路由映射同步
routeSyncGroup.POST("/sync", routeSyncController.SyncRouteMapping) // 同步单个路由映射
routeSyncGroup.POST("/batch-sync", routeSyncController.BatchSyncRouteMappings) // 批量同步路由映射
routeSyncGroup.GET("/sync-status", routeSyncController.GetSyncStatus) // 获取同步状态
routeSyncGroup.GET("/mappings", routeSyncController.GetRouteMappings) // 获取路由映射列表
// 路由同步状态查询
routeSyncGroup.GET("/status", func(c *gin.Context) {
status, err := routeSyncService.GetSyncStatus()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"data": status})
})
}
}
}

4
gofaster/backend/internal/auth/service/frontend_route_service.go

@ -30,7 +30,7 @@ func NewFrontendRouteService( @@ -30,7 +30,7 @@ func NewFrontendRouteService(
// SyncFrontendRoute 同步单个前台路由
func (s *FrontendRouteService) SyncFrontendRoute(routeData map[string]interface{}) error {
s.logger.Info("开始同步前台路由", zap.String("path", routeData["path"].(string)))
// s.logger.Info("开始同步前台路由", zap.String("path", routeData["path"].(string)))
// 1. 创建或更新前台路由
frontendRoute := &model.FrontendRoute{
@ -84,7 +84,7 @@ func (s *FrontendRouteService) SyncFrontendRoute(routeData map[string]interface{ @@ -84,7 +84,7 @@ func (s *FrontendRouteService) SyncFrontendRoute(routeData map[string]interface{
}
}
s.logger.Info("前台路由同步成功", zap.String("path", frontendRoute.Path))
// s.logger.Info("前台路由同步成功", zap.String("path", frontendRoute.Path))
return nil
}

195
gofaster/backend/internal/auth/service/permission_service.go

@ -2,209 +2,46 @@ package service @@ -2,209 +2,46 @@ package service
import (
"context"
"fmt"
"gofaster/internal/auth/model"
"gofaster/internal/auth/repository"
"gorm.io/gorm"
)
type PermissionService struct {
permissionRepo repository.PermissionRepository
roleRepo repository.RoleRepository
}
func NewPermissionService(permissionRepo repository.PermissionRepository, roleRepo repository.RoleRepository) *PermissionService {
func NewPermissionService(permissionRepo repository.PermissionRepository) *PermissionService {
return &PermissionService{
permissionRepo: permissionRepo,
roleRepo: roleRepo,
}
}
// CreatePermission 创建权限
func (s *PermissionService) CreatePermission(ctx context.Context, permission *model.Permission) error {
// 检查权限名称是否已存在
existing, err := s.permissionRepo.GetByName(ctx, permission.Name)
if err != nil && err != gorm.ErrRecordNotFound {
return fmt.Errorf("检查权限名称失败: %v", err)
}
if existing != nil {
return fmt.Errorf("权限名称 %s 已存在", permission.Name)
}
// 如果code为空,自动生成code
if permission.Code == "" {
permission.Code = fmt.Sprintf("%s:%s", permission.Resource, permission.Action)
}
// 检查权限代码是否已存在
existingCode, err := s.permissionRepo.GetByCode(ctx, permission.Code)
if err != nil && err != gorm.ErrRecordNotFound {
return fmt.Errorf("检查权限代码失败: %v", err)
}
if existingCode != nil {
return fmt.Errorf("权限代码 %s 已存在", permission.Code)
}
return s.permissionRepo.Create(ctx, permission)
}
// UpdatePermission 更新权限
func (s *PermissionService) UpdatePermission(ctx context.Context, permission *model.Permission) error {
// 检查权限是否存在
existing, err := s.permissionRepo.GetByID(ctx, permission.ID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("权限不存在")
}
return fmt.Errorf("查询权限失败: %v", err)
}
// 如果修改了名称,需要检查名称唯一性
if existing.Name != permission.Name {
nameExists, err := s.permissionRepo.GetByName(ctx, permission.Name)
if err != nil && err != gorm.ErrRecordNotFound {
return fmt.Errorf("检查权限名称失败: %v", err)
}
if nameExists != nil {
return fmt.Errorf("权限名称 %s 已存在", permission.Name)
}
}
return s.permissionRepo.Update(ctx, permission)
}
// DeletePermission 删除权限
func (s *PermissionService) DeletePermission(ctx context.Context, id uint) error {
// 检查权限是否存在
_, err := s.permissionRepo.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("权限不存在")
}
return fmt.Errorf("查询权限失败: %v", err)
}
// 检查是否有角色在使用此权限
roles, err := s.roleRepo.GetRolesByPermission(ctx, id)
if err != nil {
return fmt.Errorf("查询角色失败: %v", err)
}
if len(roles) > 0 {
return fmt.Errorf("无法删除正在使用的权限,有 %d 个角色在使用此权限", len(roles))
}
return s.permissionRepo.Delete(ctx, id)
}
// GetPermission 获取权限详情
func (s *PermissionService) GetPermission(ctx context.Context, id uint) (*model.Permission, error) {
// GetPermissionByID 根据ID获取权限
func (s *PermissionService) GetPermissionByID(ctx context.Context, id uint) (*model.Permission, error) {
return s.permissionRepo.GetByID(ctx, id)
}
// ListPermissions 获取权限列表
func (s *PermissionService) ListPermissions(ctx context.Context, page, pageSize int) ([]*model.Permission, int64, error) {
offset := (page - 1) * pageSize
return s.permissionRepo.List(ctx, offset, pageSize)
}
// GetPermissionsByResource 根据资源获取权限列表
func (s *PermissionService) GetPermissionsByResource(ctx context.Context, resource string) ([]*model.Permission, error) {
return s.permissionRepo.GetByResource(ctx, resource)
func (s *PermissionService) ListPermissions(ctx context.Context, offset, limit int) ([]*model.Permission, int64, error) {
return s.permissionRepo.List(ctx, offset, limit)
}
// AssignPermissionsToRole 为角色分配权限
func (s *PermissionService) AssignPermissionsToRole(ctx context.Context, roleID uint, permissionIDs []uint) error {
// 检查角色是否存在
_, err := s.roleRepo.GetByID(ctx, roleID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("角色不存在")
}
return fmt.Errorf("查询角色失败: %v", err)
}
// 检查权限是否都存在
for _, permissionID := range permissionIDs {
permission, err := s.permissionRepo.GetByID(ctx, permissionID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("权限ID %d 不存在", permissionID)
}
return fmt.Errorf("查询权限失败: %v", err)
}
if permission == nil {
return fmt.Errorf("权限ID %d 不存在", permissionID)
}
}
// 分配权限
return s.roleRepo.AssignPermissions(ctx, roleID, permissionIDs)
// GetPermissionsByBackendRoute 根据后端路由获取权限
func (s *PermissionService) GetPermissionsByBackendRoute(ctx context.Context, backendRoute string) ([]*model.Permission, error) {
return s.permissionRepo.GetByBackendRoute(ctx, backendRoute)
}
// GetRolePermissions 获取角色的权限列表
func (s *PermissionService) GetRolePermissions(ctx context.Context, roleID uint) ([]*model.Permission, error) {
// 检查角色是否存在
_, err := s.roleRepo.GetByID(ctx, roleID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("角色不存在")
}
return nil, fmt.Errorf("查询角色失败: %v", err)
}
return s.roleRepo.GetPermissions(ctx, roleID)
// GetPermissionsByFrontendRouteID 根据前端路由ID获取权限
func (s *PermissionService) GetPermissionsByFrontendRouteID(ctx context.Context, frontendRouteID uint) ([]*model.Permission, error) {
return s.permissionRepo.GetByFrontendRouteID(ctx, frontendRouteID)
}
// RemovePermissionsFromRole 从角色移除权限
func (s *PermissionService) RemovePermissionsFromRole(ctx context.Context, roleID uint, permissionIDs []uint) error {
// 检查角色是否存在
_, err := s.roleRepo.GetByID(ctx, roleID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("角色不存在")
}
return fmt.Errorf("查询角色失败: %v", err)
}
// 移除权限
return s.roleRepo.RemovePermissions(ctx, roleID, permissionIDs)
// GetPermissionsByMenuGroupID 根据菜单分组ID获取权限
func (s *PermissionService) GetPermissionsByMenuGroupID(ctx context.Context, menuGroupID uint) ([]*model.Permission, error) {
return s.permissionRepo.GetByMenuGroupID(ctx, menuGroupID)
}
// GetUserPermissions 获取用户权限列表
// GetUserPermissions 获取用户权限
func (s *PermissionService) GetUserPermissions(ctx context.Context, userID uint) ([]*model.Permission, error) {
return s.permissionRepo.GetByUserID(ctx, userID)
}
// CheckUserPermission 检查用户是否有指定权限
func (s *PermissionService) CheckUserPermission(ctx context.Context, userID uint, permissionName string) (bool, error) {
permissions, err := s.GetUserPermissions(ctx, userID)
if err != nil {
return false, fmt.Errorf("获取用户权限失败: %v", err)
}
for _, permission := range permissions {
if permission.Name == permissionName {
return true, nil
}
}
return false, nil
}
// CheckUserResourcePermission 检查用户是否有指定资源的指定操作权限
func (s *PermissionService) CheckUserResourcePermission(ctx context.Context, userID uint, resource, action string) (bool, error) {
permissions, err := s.GetUserPermissions(ctx, userID)
if err != nil {
return false, fmt.Errorf("获取用户权限失败: %v", err)
}
for _, permission := range permissions {
if permission.Resource == resource && permission.Action == action {
return true, nil
}
}
return false, nil
}
}

195
gofaster/backend/internal/auth/service/resource_service.go

@ -1,195 +0,0 @@ @@ -1,195 +0,0 @@
package service
import (
"context"
"fmt"
"gofaster/internal/auth/model"
"gofaster/internal/auth/repository"
"gorm.io/gorm"
)
type ResourceService struct {
resourceRepo repository.ResourceRepository
}
func NewResourceService(resourceRepo repository.ResourceRepository) *ResourceService {
return &ResourceService{
resourceRepo: resourceRepo,
}
}
// CreateResource 创建资源
func (s *ResourceService) CreateResource(ctx context.Context, resource *model.Resource) error {
// 检查资源代码是否已存在
existing, err := s.resourceRepo.GetByCode(ctx, resource.Code)
if err != nil && err != gorm.ErrRecordNotFound {
return fmt.Errorf("检查资源代码失败: %v", err)
}
if existing != nil {
return fmt.Errorf("资源代码 %s 已存在", resource.Code)
}
return s.resourceRepo.Create(ctx, resource)
}
// UpdateResource 更新资源
func (s *ResourceService) UpdateResource(ctx context.Context, resource *model.Resource) error {
// 检查资源是否存在
existing, err := s.resourceRepo.GetByID(ctx, resource.ID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("资源不存在")
}
return fmt.Errorf("查询资源失败: %v", err)
}
// 如果修改了代码,需要检查代码唯一性
if existing.Code != resource.Code {
codeExists, err := s.resourceRepo.GetByCode(ctx, resource.Code)
if err != nil && err != gorm.ErrRecordNotFound {
return fmt.Errorf("检查资源代码失败: %v", err)
}
if codeExists != nil {
return fmt.Errorf("资源代码 %s 已存在", resource.Code)
}
}
return s.resourceRepo.Update(ctx, resource)
}
// DeleteResource 删除资源
func (s *ResourceService) DeleteResource(ctx context.Context, id uint) error {
// 检查资源是否存在
existing, err := s.resourceRepo.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("资源不存在")
}
return fmt.Errorf("查询资源失败: %v", err)
}
// 检查是否有子资源
children, err := s.resourceRepo.ListByModule(ctx, existing.Module)
if err != nil {
return fmt.Errorf("查询子资源失败: %v", err)
}
for _, child := range children {
if child.ParentID != nil && *child.ParentID == id {
return fmt.Errorf("无法删除有子资源的资源")
}
}
return s.resourceRepo.Delete(ctx, id)
}
// GetResource 获取资源详情
func (s *ResourceService) GetResource(ctx context.Context, id uint) (*model.Resource, error) {
return s.resourceRepo.GetByID(ctx, id)
}
// ListResources 获取资源列表
func (s *ResourceService) ListResources(ctx context.Context, page, pageSize int) ([]*model.Resource, int64, error) {
offset := (page - 1) * pageSize
return s.resourceRepo.List(ctx, offset, pageSize)
}
// ListResourcesByModule 根据模块获取资源列表
func (s *ResourceService) ListResourcesByModule(ctx context.Context, module string) ([]*model.Resource, error) {
return s.resourceRepo.ListByModule(ctx, module)
}
// ListResourcesByType 根据类型获取资源列表
func (s *ResourceService) ListResourcesByType(ctx context.Context, resourceType string) ([]*model.Resource, error) {
return s.resourceRepo.ListByType(ctx, resourceType)
}
// GetResourceTree 获取资源树
func (s *ResourceService) GetResourceTree(ctx context.Context) ([]*model.Resource, error) {
return s.resourceRepo.GetTree(ctx)
}
// SyncResourcesFromRoutes 从路由同步资源
func (s *ResourceService) SyncResourcesFromRoutes(ctx context.Context) error {
// 定义系统中的所有路由
routes := []repository.RouteInfo{
// 认证模块
{Path: "/api/auth/login", Method: "POST", Name: "用户登录", Description: "用户登录接口", Module: "auth", IsPublic: true},
{Path: "/api/auth/logout", Method: "POST", Name: "用户登出", Description: "用户登出接口", Module: "auth", IsPublic: false},
{Path: "/api/auth/captcha", Method: "GET", Name: "获取验证码", Description: "获取登录验证码", Module: "auth", IsPublic: true},
{Path: "/api/auth/refresh", Method: "POST", Name: "刷新令牌", Description: "刷新访问令牌", Module: "auth", IsPublic: false},
{Path: "/api/auth/change-password", Method: "POST", Name: "修改密码", Description: "用户修改密码", Module: "auth", IsPublic: false},
{Path: "/api/auth/profile", Method: "GET", Name: "获取用户信息", Description: "获取当前用户信息", Module: "auth", IsPublic: false},
{Path: "/api/auth/profile", Method: "PUT", Name: "更新用户信息", Description: "更新当前用户信息", Module: "auth", IsPublic: false},
// 用户管理模块
{Path: "/api/users", Method: "GET", Name: "获取用户列表", Description: "分页获取用户列表", Module: "user", IsPublic: false},
{Path: "/api/users", Method: "POST", Name: "创建用户", Description: "创建新用户", Module: "user", IsPublic: false},
{Path: "/api/users/:id", Method: "GET", Name: "获取用户详情", Description: "根据ID获取用户详情", Module: "user", IsPublic: false},
{Path: "/api/users/:id", Method: "PUT", Name: "更新用户", Description: "更新用户信息", Module: "user", IsPublic: false},
{Path: "/api/users/:id", Method: "DELETE", Name: "删除用户", Description: "删除用户", Module: "user", IsPublic: false},
// 角色管理模块
{Path: "/api/roles", Method: "GET", Name: "获取角色列表", Description: "分页获取角色列表", Module: "role", IsPublic: false},
{Path: "/api/roles", Method: "POST", Name: "创建角色", Description: "创建新角色", Module: "role", IsPublic: false},
{Path: "/api/roles/:id", Method: "GET", Name: "获取角色详情", Description: "根据ID获取角色详情", Module: "role", IsPublic: false},
{Path: "/api/roles/:id", Method: "PUT", Name: "更新角色", Description: "更新角色信息", Module: "role", IsPublic: false},
{Path: "/api/roles/:id", Method: "DELETE", Name: "删除角色", Description: "删除角色", Module: "role", IsPublic: false},
// 权限管理模块
{Path: "/api/permissions", Method: "GET", Name: "获取权限列表", Description: "分页获取权限列表", Module: "permission", IsPublic: false},
{Path: "/api/permissions", Method: "POST", Name: "创建权限", Description: "创建新权限", Module: "permission", IsPublic: false},
{Path: "/api/permissions/:id", Method: "GET", Name: "获取权限详情", Description: "根据ID获取权限详情", Module: "permission", IsPublic: false},
{Path: "/api/permissions/:id", Method: "PUT", Name: "更新权限", Description: "更新权限信息", Module: "permission", IsPublic: false},
{Path: "/api/permissions/:id", Method: "DELETE", Name: "删除权限", Description: "删除权限", Module: "permission", IsPublic: false},
// 资源管理模块
{Path: "/api/resources", Method: "GET", Name: "获取资源列表", Description: "分页获取资源列表", Module: "resource", IsPublic: false},
{Path: "/api/resources", Method: "POST", Name: "创建资源", Description: "创建新资源", Module: "resource", IsPublic: false},
{Path: "/api/resources/:id", Method: "GET", Name: "获取资源详情", Description: "根据ID获取资源详情", Module: "resource", IsPublic: false},
{Path: "/api/resources/:id", Method: "PUT", Name: "更新资源", Description: "更新资源信息", Module: "resource", IsPublic: false},
{Path: "/api/resources/:id", Method: "DELETE", Name: "删除资源", Description: "删除资源", Module: "resource", IsPublic: false},
{Path: "/api/resources/sync", Method: "POST", Name: "同步资源", Description: "从路由同步资源", Module: "resource", IsPublic: false},
{Path: "/api/resources/tree", Method: "GET", Name: "获取资源树", Description: "获取资源树形结构", Module: "resource", IsPublic: false},
// 工作流模块
{Path: "/api/workflows", Method: "GET", Name: "获取工作流列表", Description: "分页获取工作流列表", Module: "workflow", IsPublic: false},
{Path: "/api/workflows", Method: "POST", Name: "创建工作流", Description: "创建新工作流", Module: "workflow", IsPublic: false},
{Path: "/api/workflows/:id", Method: "GET", Name: "获取工作流详情", Description: "根据ID获取工作流详情", Module: "workflow", IsPublic: false},
{Path: "/api/workflows/:id", Method: "PUT", Name: "更新工作流", Description: "更新工作流信息", Module: "workflow", IsPublic: false},
{Path: "/api/workflows/:id", Method: "DELETE", Name: "删除工作流", Description: "删除工作流", Module: "workflow", IsPublic: false},
{Path: "/api/workflows/:id/execute", Method: "POST", Name: "执行工作流", Description: "执行工作流", Module: "workflow", IsPublic: false},
}
fmt.Printf("🔄 开始同步资源,共 %d 个路由\n", len(routes))
return s.resourceRepo.SyncFromRoutes(ctx, routes)
}
// GetUserResources 获取用户可访问的资源
func (s *ResourceService) GetUserResources(ctx context.Context, userID uint) ([]*model.Resource, error) {
// 这里需要根据用户的角色和权限来获取可访问的资源
// 暂时返回所有启用的资源,后续可以优化
return s.resourceRepo.ListByType(ctx, "api")
}
// CheckResourcePermission 检查用户是否有访问资源的权限
func (s *ResourceService) CheckResourcePermission(ctx context.Context, userID uint, resourceCode string) (bool, error) {
// 获取资源信息
resource, err := s.resourceRepo.GetByCode(ctx, resourceCode)
if err != nil {
if err == gorm.ErrRecordNotFound {
return false, fmt.Errorf("资源不存在")
}
return false, fmt.Errorf("查询资源失败: %v", err)
}
// 如果是公开资源,直接返回true
if resource.IsPublic {
return true, nil
}
// 这里需要根据用户的角色和权限来检查
// 暂时返回true,后续实现完整的权限检查逻辑
return true, nil
}

314
gofaster/backend/internal/auth/service/route_sync_service.go

@ -1,292 +1,37 @@ @@ -1,292 +1,37 @@
package service
import (
"fmt"
"gofaster/internal/auth/model"
"gofaster/internal/auth/repository"
"reflect"
"regexp"
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"gorm.io/gorm"
)
// RouteInfo 路由信息结构
type RouteInfo struct {
Path string `json:"path"`
Method string `json:"method"`
Module string `json:"module"`
Description string `json:"description"`
}
// RouteSyncService 路由同步服务
type RouteSyncService struct {
resourceRepo repository.ResourceRepository
frontendBackendRouteRepo *repository.FrontendBackendRouteRepository
log *zap.Logger
swaggerParser *SwaggerParser
}
// NewRouteSyncService 创建路由同步服务实例
func NewRouteSyncService(
resourceRepo repository.ResourceRepository,
frontendBackendRouteRepo *repository.FrontendBackendRouteRepository,
log *zap.Logger,
) *RouteSyncService {
swaggerParser := NewSwaggerParser()
// 解析Controller目录中的Swagger注释
controllerDir := "./internal/auth/controller"
if err := swaggerParser.ParseControllerDirectory(controllerDir); err != nil {
log.Warn("解析Swagger注释失败", zap.Error(err))
// 尝试其他可能的路径
alternativePaths := []string{
"internal/auth/controller",
"backend/internal/auth/controller",
"./backend/internal/auth/controller",
}
for _, altPath := range alternativePaths {
if err := swaggerParser.ParseControllerDirectory(altPath); err == nil {
log.Info("成功解析Swagger注释", zap.String("path", altPath))
break
}
}
} else {
log.Info("成功解析Swagger注释", zap.String("path", controllerDir))
}
return &RouteSyncService{
resourceRepo: resourceRepo,
frontendBackendRouteRepo: frontendBackendRouteRepo,
log: log,
swaggerParser: swaggerParser,
}
}
// SyncRoutes 同步路由信息到数据库
func (s *RouteSyncService) SyncRoutes(router *gin.Engine) error {
s.log.Info("开始同步后台路由信息...")
// 收集所有路由信息
routes := s.collectRoutes(router)
// 同步到数据库
createdCount, updatedCount, err := s.syncToDatabase(routes)
if err != nil {
s.log.Error("路由同步失败", zap.Error(err))
return err
}
s.log.Info("路由同步完成",
zap.Int("总路由数", len(routes)),
zap.Int("新增数", createdCount),
zap.Int("更新数", updatedCount),
)
return nil
}
// collectRoutes 收集路由信息
func (s *RouteSyncService) collectRoutes(router *gin.Engine) []RouteInfo {
var routes []RouteInfo
// 遍历所有注册的路由
for _, route := range router.Routes() {
if route.Method != "" && route.Path != "" {
module := s.extractModuleFromPath(route.Path)
description := s.generateDescription(route.Method, route.Path)
routes = append(routes, RouteInfo{
Path: route.Path,
Method: route.Method,
Module: module,
Description: description,
})
}
}
return routes
}
// collectRoutesFromGroup 从路由组收集路由信息
func (s *RouteSyncService) collectRoutesFromGroup(group interface{}, routes *[]RouteInfo) {
// 使用反射获取路由组信息
val := reflect.ValueOf(group)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
// 尝试获取路由组的方法
if val.Kind() == reflect.Struct {
// 这里需要根据实际的gin路由组结构来提取路由信息
// 由于gin的路由组结构比较复杂,我们主要依赖Routes()方法
}
}
// extractModuleFromPath 从路径中提取模块名
func (s *RouteSyncService) extractModuleFromPath(path string) string {
// 移除开头的斜杠
path = strings.TrimPrefix(path, "/")
// 分割路径
parts := strings.Split(path, "/")
if len(parts) == 0 {
return "unknown"
}
// 第一个部分通常是模块名
module := parts[0]
// 映射常见的模块名
switch module {
case "api":
if len(parts) > 1 {
return parts[1] // 如 /api/auth -> auth
}
return "api"
case "auth":
return "auth"
case "workflow":
return "workflow"
case "user":
return "user"
case "role":
return "role"
case "permission":
return "permission"
case "resource":
return "resource"
default:
return module
}
}
// convertPathFormat 转换路径格式:将:var格式改为{var}格式
func (s *RouteSyncService) convertPathFormat(path string) string {
// 使用正则表达式替换:var格式为{var}格式
re := regexp.MustCompile(`:([a-zA-Z0-9_]+)`)
return re.ReplaceAllString(path, "{$1}")
}
// generateDescription 生成路由描述
func (s *RouteSyncService) generateDescription(method, path string) string {
// 优先从Swagger注释中获取@Summary
if s.swaggerParser != nil {
summary := s.swaggerParser.GetSummary(method, path)
if summary != "" {
return summary
}
}
// 回退到原有逻辑
module := s.extractModuleFromPath(path)
switch method {
case "GET":
if strings.Contains(path, "/:id") {
return fmt.Sprintf("获取%s详情", module)
}
return fmt.Sprintf("获取%s列表", module)
case "POST":
return fmt.Sprintf("创建%s", module)
case "PUT":
return fmt.Sprintf("更新%s", module)
case "DELETE":
return fmt.Sprintf("删除%s", module)
case "PATCH":
return fmt.Sprintf("部分更新%s", module)
default:
return fmt.Sprintf("%s操作", method)
}
}
// syncToDatabase 同步路由信息到数据库
func (s *RouteSyncService) syncToDatabase(routes []RouteInfo) (int, int, error) {
createdCount := 0
updatedCount := 0
for _, route := range routes {
// 检查是否已存在
existing, err := s.routeMappingRepo.FindByBackendRoute(route.Path, route.Method)
if err != nil && err != gorm.ErrRecordNotFound {
s.log.Error("查询路由映射失败",
zap.String("path", route.Path),
zap.String("method", route.Method),
zap.Error(err),
)
continue
}
// 转换路径格式:将:var格式改为{var}格式
convertedPath := s.convertPathFormat(route.Path)
s.log.Debug("🔄 路径格式转换",
zap.String("original", route.Path),
zap.String("converted", convertedPath))
// 创建或更新路由映射
mapping := &model.RouteMapping{
BackendRoute: convertedPath,
HTTPMethod: route.Method,
Module: route.Module,
Description: route.Description,
Status: 1,
}
s.log.Debug("📝 准备写入数据库",
zap.String("backend_route", mapping.BackendRoute),
zap.String("http_method", mapping.HTTPMethod),
zap.String("module", mapping.Module),
zap.String("description", mapping.Description),
zap.Int("status", mapping.Status))
if existing == nil {
// 创建新的路由映射
if err := s.routeMappingRepo.Create(mapping); err != nil {
s.log.Error("创建路由映射失败",
zap.String("path", route.Path),
zap.String("method", route.Method),
zap.Error(err),
)
continue
}
createdCount++
s.log.Debug("创建路由映射",
zap.String("path", route.Path),
zap.String("method", route.Method),
)
} else {
// 更新现有路由映射
mapping.ID = existing.ID
if err := s.routeMappingRepo.Update(mapping); err != nil {
s.log.Error("更新路由映射失败",
zap.String("path", route.Path),
zap.String("method", route.Method),
zap.Error(err),
)
continue
}
updatedCount++
s.log.Debug("更新路由映射",
zap.String("path", route.Path),
zap.String("method", route.Method),
)
}
}
return createdCount, updatedCount, nil
}
// GetSyncStatus 获取同步状态
func (s *RouteSyncService) GetSyncStatus() (map[string]interface{}, error) {
// 获取数据库中的路由映射总数
totalMappings, err := s.routeMappingRepo.FindAll()
totalMappings, err := s.frontendBackendRouteRepo.List()
if err != nil {
return nil, err
}
// 按模块统计
// 统计各模块的路由数量
moduleStats := make(map[string]int)
for _, mapping := range totalMappings {
moduleStats[mapping.Module]++
@ -295,59 +40,6 @@ func (s *RouteSyncService) GetSyncStatus() (map[string]interface{}, error) { @@ -295,59 +40,6 @@ func (s *RouteSyncService) GetSyncStatus() (map[string]interface{}, error) {
return map[string]interface{}{
"total_mappings": len(totalMappings),
"module_stats": moduleStats,
"last_sync": "应用启动时自动同步",
"last_sync": "前台同步",
}, nil
}
// SyncRouteMapping 同步路由映射
func (s *RouteSyncService) SyncRouteMapping(routeMapping *model.RouteMapping) error {
s.log.Info("同步路由映射",
zap.String("backendRoute", routeMapping.BackendRoute),
zap.String("httpMethod", routeMapping.HTTPMethod),
zap.String("module", routeMapping.Module))
// 检查是否已存在相同的路由
existing, err := s.routeMappingRepo.FindByBackendRoute(routeMapping.BackendRoute, routeMapping.HTTPMethod)
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
if existing != nil {
// 更新现有记录
routeMapping.ID = existing.ID
return s.routeMappingRepo.Update(routeMapping)
}
// 创建新记录
return s.routeMappingRepo.Create(routeMapping)
}
// BatchSyncRouteMappings 批量同步路由映射
func (s *RouteSyncService) BatchSyncRouteMappings(routeMappings []model.RouteMapping) (int, int, []string) {
successCount := 0
errorCount := 0
var errors []string
for _, mapping := range routeMappings {
if err := s.SyncRouteMapping(&mapping); err != nil {
errorCount++
errorMsg := fmt.Sprintf("同步路由失败 %s %s: %s",
mapping.HTTPMethod, mapping.BackendRoute, err.Error())
errors = append(errors, errorMsg)
s.log.Error("批量同步路由失败", zap.Error(err))
} else {
successCount++
}
}
return successCount, errorCount, errors
}
// GetRouteMappings 获取路由映射列表
func (s *RouteSyncService) GetRouteMappings(module string) ([]model.RouteMapping, error) {
if module != "" {
return s.routeMappingRepo.FindByModule(module)
} else {
return s.routeMappingRepo.FindAll()
}
}

111
gofaster/backend/internal/auth/service/route_sync_service_enhanced.go

@ -1,111 +0,0 @@ @@ -1,111 +0,0 @@
package service
import (
"fmt"
"gofaster/internal/auth/repository"
"reflect"
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// EnhancedRouteSyncService 增强版路由同步服务
type EnhancedRouteSyncService struct {
*RouteSyncService
}
// NewEnhancedRouteSyncService 创建增强版路由同步服务
func NewEnhancedRouteSyncService(
routeMappingRepo *repository.RouteMappingRepository,
resourceRepo repository.ResourceRepository,
log *zap.Logger,
) *EnhancedRouteSyncService {
return &EnhancedRouteSyncService{
RouteSyncService: NewRouteSyncService(routeMappingRepo, resourceRepo, log),
}
}
// generateDescriptionFromSwagger 从Swagger注释中生成描述
func (s *EnhancedRouteSyncService) generateDescriptionFromSwagger(method, path string, handler interface{}) string {
// 使用反射获取handler的注释信息
handlerType := reflect.TypeOf(handler)
if handlerType == nil {
return s.generateDescription(method, path)
}
// 尝试从方法注释中提取@Summary信息
// 这里需要结合AST解析来获取注释,暂时使用简化版本
return s.generateDescription(method, path)
}
// generateEnhancedDescription 生成增强版描述
func (s *EnhancedRouteSyncService) generateEnhancedDescription(method, path string) string {
// 定义更详细的描述映射
pathDescriptions := map[string]string{
"/auth/login": "用户登录",
"/auth/logout": "用户登出",
"/auth/captcha": "获取验证码",
"/auth/userinfo": "获取用户信息",
"/auth/change-password": "修改密码",
"/auth/password-policy": "获取密码策略",
"/auth/validate-password": "验证密码强度",
"/auth/admin/users": "用户管理",
"/auth/admin/users/:id": "用户详情操作",
"/auth/roles": "角色管理",
"/auth/roles/:id": "角色详情操作",
"/auth/permissions": "权限管理",
"/auth/permissions/:id": "权限详情操作",
"/auth/resources": "资源管理",
"/auth/resources/:id": "资源详情操作",
}
// 先尝试精确匹配
if desc, exists := pathDescriptions[path]; exists {
return desc
}
// 尝试模式匹配
for pattern, desc := range pathDescriptions {
if strings.Contains(path, strings.TrimSuffix(pattern, "/:id")) {
switch method {
case "GET":
if strings.Contains(path, "/:id") {
return fmt.Sprintf("获取%s详情", desc)
}
return fmt.Sprintf("获取%s列表", desc)
case "POST":
return fmt.Sprintf("创建%s", desc)
case "PUT":
return fmt.Sprintf("更新%s", desc)
case "DELETE":
return fmt.Sprintf("删除%s", desc)
}
}
}
// 回退到原始逻辑
return s.generateDescription(method, path)
}
// collectRoutesWithEnhancedDescription 收集路由信息并生成增强描述
func (s *EnhancedRouteSyncService) collectRoutesWithEnhancedDescription(router *gin.Engine) []RouteInfo {
var routes []RouteInfo
// 遍历所有注册的路由
for _, route := range router.Routes() {
if route.Method != "" && route.Path != "" {
module := s.extractModuleFromPath(route.Path)
description := s.generateEnhancedDescription(route.Method, route.Path)
routes = append(routes, RouteInfo{
Path: route.Path,
Method: route.Method,
Module: module,
Description: description,
})
}
}
return routes
}

53
gofaster/backend/internal/shared/middleware/permission_middleware.go

@ -24,19 +24,18 @@ func PermissionMiddleware(db *gorm.DB, jwtSecret string) gin.HandlerFunc { @@ -24,19 +24,18 @@ func PermissionMiddleware(db *gorm.DB, jwtSecret string) gin.HandlerFunc {
// 获取当前请求的路由信息
path := c.Request.URL.Path
method := c.Request.Method
// 检查路由映射
routeMappingRepo := repository.NewRouteMappingRepository(db)
routeMapping, err := routeMappingRepo.FindByBackendRoute(path, method)
if err != nil {
frontendBackendRouteRepo := repository.NewFrontendBackendRouteRepository(db)
routeMappings, err := frontendBackendRouteRepo.FindByBackendRoute(path)
if err != nil || len(routeMappings) == 0 {
// 如果找不到路由映射,允许通过(可能是公开接口)
c.Next()
return
}
// 检查用户是否有权限访问该路由
if err := checkUserPermission(db, userID, routeMapping); err != nil {
if err := checkUserPermission(db, userID, routeMappings[0]); err != nil {
c.JSON(http.StatusForbidden, gin.H{"error": fmt.Sprintf("权限不足: %s", err.Error())})
c.Abort()
return
@ -47,7 +46,7 @@ func PermissionMiddleware(db *gorm.DB, jwtSecret string) gin.HandlerFunc { @@ -47,7 +46,7 @@ func PermissionMiddleware(db *gorm.DB, jwtSecret string) gin.HandlerFunc {
}
// checkUserPermission 检查用户权限
func checkUserPermission(db *gorm.DB, userID uint, routeMapping *model.RouteMapping) error {
func checkUserPermission(db *gorm.DB, userID uint, routeMapping *model.FrontendBackendRoute) error {
// 这里实现三级权限检查逻辑
// 1. 菜单级别权限
// 2. 权限组级别权限
@ -58,53 +57,19 @@ func checkUserPermission(db *gorm.DB, userID uint, routeMapping *model.RouteMapp @@ -58,53 +57,19 @@ func checkUserPermission(db *gorm.DB, userID uint, routeMapping *model.RouteMapp
return nil
}
// OptionalPermissionMiddleware 可选的权限中间件(不强制要求权限)
func OptionalPermissionMiddleware(db *gorm.DB, jwtSecret string) gin.HandlerFunc {
return func(c *gin.Context) {
// 获取用户信息
userID := GetUserID(c)
if userID == 0 {
// 没有用户信息,继续处理请求
c.Next()
return
}
// 获取当前请求的路由信息
path := c.Request.URL.Path
method := c.Request.Method
// 检查路由映射
routeMappingRepo := repository.NewRouteMappingRepository(db)
routeMapping, err := routeMappingRepo.FindByBackendRoute(path, method)
if err != nil {
// 如果找不到路由映射,继续处理请求
c.Next()
return
}
// 检查用户是否有权限访问该路由
if err := checkUserPermission(db, userID, routeMapping); err != nil {
// 权限不足,但因为是可选权限,所以继续处理请求
c.Set("permission_warning", fmt.Sprintf("权限不足: %s", err.Error()))
}
c.Next()
}
}
// GetRouteAuthGroup 获取路由的权限分组
func GetRouteAuthGroup(c *gin.Context, db *gorm.DB) string {
path := c.Request.URL.Path
method := c.Request.Method
routeMappingRepo := repository.NewRouteMappingRepository(db)
routeMapping, err := routeMappingRepo.FindByBackendRoute(path, method)
if err != nil {
frontendBackendRouteRepo := repository.NewFrontendBackendRouteRepository(db)
routeMappings, err := frontendBackendRouteRepo.FindByBackendRoute(path)
if err != nil || len(routeMappings) == 0 {
return "Unknown"
}
// 根据模块和HTTP方法确定权限组
return getAuthGroupByMethod(routeMapping.Module, routeMapping.HTTPMethod)
return getAuthGroupByMethod(routeMappings[0].Module, method)
}
// getAuthGroupByMethod 根据模块和HTTP方法确定权限组

Loading…
Cancel
Save