package service import ( "context" "errors" "server/internal/db" "server/internal/db/sqlc" "server/internal/model/common" "server/internal/model/enum" "server/internal/model/request" "server/internal/pkg/cache" "server/internal/pkg/cache/cachekey" "server/internal/pkg/dberr" "server/internal/pkg/errs" ) type SysRoleService struct { store *db.Store cache *cache.Caches } func NewSysRoleService(store *db.Store, cache *cache.Caches) *SysRoleService { return &SysRoleService{ store: store, cache: cache, } } // clearCache 清理所有api权限和用户信息 禁用角色/删除角色需要清理 func (s *SysRoleService) clearCache(ctx context.Context) error { if err := s.cache.DelByPrefix(ctx, cachekey.UserApiPermissionsPattern); err != nil { return err } if err := s.cache.DelByPrefix(ctx, cachekey.UserInfoPattern); err != nil { return err } return nil } func (s *SysRoleService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.SysRole, int64, error) { params := sqlc.ListSysRolesParams{ Limit: p.PageSize, Offset: (p.Page - 1) * p.PageSize, } total, err := s.store.CountSysRoles(ctx) if err != nil { return nil, 0, err } list, err := s.store.ListSysRoles(ctx, params) if err != nil { return nil, 0, err } return list, total, nil } func (s *SysRoleService) GetRoles(ctx context.Context) ([]sqlc.SysRole, error) { return s.store.GetAllSysRoles(ctx) } func (s *SysRoleService) GetRoleMenus(ctx context.Context, id int32) ([]sqlc.GetSysRoleMenusRow, error) { _, err := s.store.GetSysRoleByID(ctx, id) if err != nil { return nil, dberr.MapNoRows(err, errs.ErrSysRoleNotFound) } return s.store.GetSysRoleMenus(ctx, id) } func (s *SysRoleService) GetRoleApis(ctx context.Context, id int32) ([]sqlc.GetSysRoleApisRow, error) { _, err := s.store.GetSysRoleByID(ctx, id) if err != nil { return nil, dberr.MapNoRows(err, errs.ErrSysRoleNotFound) } return s.store.GetSysRoleApis(ctx, id) } func (s *SysRoleService) Create(ctx context.Context, req request.CreateSysRoleRequest) error { params := sqlc.CreateSysRoleParams{ Name: req.Name, Code: req.Code, Status: *req.Status, } err := s.store.CreateSysRole(ctx, params) if err != nil { return dberr.MapUniqueViolation(err, dberr.SysRoleCodeKey, errs.ErrCodeAlreadyExists) } return nil } func (s *SysRoleService) Update(ctx context.Context, id int32, req request.UpdateSysRoleRequest) error { params := sqlc.UpdateSysRoleParams{ ID: id, Name: req.Name, Status: req.Status, } rows, err := s.store.UpdateSysRole(ctx, params) err = dberr.MapRowsAffected(rows, err, errs.ErrSysRoleNotFound) if err != nil { if errors.Is(err, errs.ErrSysRoleNotFound) { } return err } // 清理缓存 无论启用禁用 启用时也需要清理缓存以刷新权限 _ = s.clearCache(ctx) return nil } func (s *SysRoleService) SetRoleMenus(ctx context.Context, roleID int32, req request.SetSysRoleMenusRequest) error { // 先检查角色是否存在 _, err := s.store.GetSysRoleByID(ctx, roleID) if err != nil { return dberr.MapNoRows(err, errs.ErrSysRoleNotFound) } err = s.store.WithTx(ctx, func(q *sqlc.Queries) error { // 1. 先删除所有关联表数据 if err = q.DeleteSysRolePermissionByType(ctx, sqlc.DeleteSysRolePermissionByTypeParams{ RoleID: roleID, Type: int16(enum.PermissionTypeMenu), }); err != nil { return err } // 2. 查出所有权限id并组装数据 permissionIds, err := q.GetSysPermissionIdsByMenuIDs(ctx, req.MenuIDs) if err != nil { return err } params := make([]sqlc.CreateSysRolePermissionParams, 0, len(permissionIds)) for _, id := range permissionIds { params = append(params, sqlc.CreateSysRolePermissionParams{ RoleID: roleID, PermissionID: id, }) } // 批量插入 _, err = q.CreateSysRolePermission(ctx, params) if err != nil { return err } return nil }) if err != nil { return err } // 清理缓存 这里只用清理用户信息 _ = s.cache.DelByPrefix(ctx, cachekey.UserInfoPattern) return nil } func (s *SysRoleService) SetRoleApis(ctx context.Context, roleID int32, req request.SetSysRoleApisRequest) error { _, err := s.store.GetSysRoleByID(ctx, roleID) if err != nil { return dberr.MapNoRows(err, errs.ErrSysRoleNotFound) } err = s.store.WithTx(ctx, func(q *sqlc.Queries) error { // 先删除所有旧权限数据 if err = q.DeleteSysRolePermissionByType(ctx, sqlc.DeleteSysRolePermissionByTypeParams{ RoleID: roleID, Type: int16(enum.PermissionTypeApi), }); err != nil { return err } // 查出数据并组装 permissionIds, err := q.GetSysPermissionIdsByApiIDs(ctx, req.ApiIDs) if err != nil { return err } params := make([]sqlc.CreateSysRolePermissionParams, 0, len(permissionIds)) for _, id := range permissionIds { params = append(params, sqlc.CreateSysRolePermissionParams{ RoleID: roleID, PermissionID: id, }) } // 批量插入 _, err = q.CreateSysRolePermission(ctx, params) if err != nil { return err } return nil }) if err != nil { return err } // 清理缓存 这里只用清理接口权限 _ = s.cache.DelByPrefix(ctx, cachekey.UserApiPermissionsPattern) return nil } func (s *SysRoleService) Delete(ctx context.Context, id int32) error { err := s.store.WithTx(ctx, func(q *sqlc.Queries) error { // 1.删除角色关联权限 err := q.DeleteSysRolePermissionByRoleID(ctx, id) if err != nil { return err } // 2. 根据角色id删除用户关联的角色 err = q.DeleteSysUserRoleByRoleID(ctx, id) if err != nil { return err } // 3. 删除角色信息 rows, err := q.DeleteSysRole(ctx, id) err = dberr.MapRowsAffected(rows, err, errs.ErrSysRoleNotFound) if err != nil { // 如果是数据库不存在这条数据 此时也执行清理 if errors.Is(err, errs.ErrSysRoleNotFound) { } return err } return nil }) if err != nil { return err } // 清理缓存 _ = s.clearCache(ctx) return nil }