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

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
}