You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
9.6 KiB
195 lines
9.6 KiB
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 |
|
}
|
|
|