package rbac import ( "context" "portal-mini-go/internal/model/admin" "portal-mini-go/internal/pkg/errors" adminrepo "portal-mini-go/internal/repository/admin" ) // RoleService 角色业务:CRUD 与权限分配。 type RoleService struct { repo RoleRepository invalidator CacheInvalidator } func NewRoleService(repo RoleRepository, invalidator CacheInvalidator) *RoleService { return &RoleService{repo: repo, invalidator: invalidator} } // CreateRoleReq 新建角色请求。 type CreateRoleReq struct { Code string `json:"code" binding:"required"` Name string `json:"name" binding:"required"` Description string `json:"description"` Status int8 `json:"status"` } // Create 新建角色,code 唯一。 func (s *RoleService) Create(ctx context.Context, req CreateRoleReq) (*admin.Role, error) { if req.Status == 0 { req.Status = admin.UserStatusEnabled } if req.Status != admin.UserStatusEnabled && req.Status != admin.UserStatusDisabled { return nil, errors.New(40000, "非法的角色状态") } if _, err := s.repo.GetByCode(ctx, req.Code); err == nil { return nil, errors.New(40900, "角色 code 已存在") } else if !errors.Is(err, errors.ErrNotFound) { return nil, err } r := &admin.Role{Code: req.Code, Name: req.Name, Description: req.Description, Status: req.Status} if err := s.repo.Create(ctx, r); err != nil { return nil, err } return r, nil } // RoleListReq 角色列表过滤条件。 type RoleListReq struct { Keyword string Status int8 Page int Size int } // List 分页查询角色。 func (s *RoleService) List(ctx context.Context, req RoleListReq) ([]admin.Role, int64, error) { page, size := req.Page, req.Size if page <= 0 { page = 1 } if size <= 0 { size = 20 } return s.repo.List(ctx, adminrepo.RoleListFilter{ Keyword: req.Keyword, Status: req.Status, Page: page, Size: size, }) } // GetByID 按 ID 查询角色。 func (s *RoleService) GetByID(ctx context.Context, id uint64) (*admin.Role, error) { return s.repo.GetByID(ctx, id) } // UpdateRoleReq 编辑角色请求;指针区分“未提供”与“置空”。 type UpdateRoleReq struct { Name *string `json:"name"` Description *string `json:"description"` Status *int8 `json:"status"` } // Update 局部更新角色。 func (s *RoleService) Update(ctx context.Context, id uint64, req UpdateRoleReq) (*admin.Role, error) { cols := map[string]interface{}{} if req.Name != nil { cols["name"] = *req.Name } if req.Description != nil { cols["description"] = *req.Description } if req.Status != nil { if *req.Status != admin.UserStatusEnabled && *req.Status != admin.UserStatusDisabled { return nil, errors.New(40000, "非法的角色状态") } cols["status"] = *req.Status } if len(cols) == 0 { return s.repo.GetByID(ctx, id) } if err := s.repo.Update(ctx, id, cols); err != nil { return nil, err } s.invalidator.InvalidateAll(ctx) return s.repo.GetByID(ctx, id) } // Delete 删除角色(清理关联并失效全部缓存)。 func (s *RoleService) Delete(ctx context.Context, id uint64) error { if err := s.repo.Delete(ctx, id); err != nil { return err } s.invalidator.InvalidateAll(ctx) return nil } // SetPermissions 为角色分配权限(全量替换)。 func (s *RoleService) SetPermissions(ctx context.Context, id uint64, permIDs []uint64) error { if err := s.repo.SetPermissions(ctx, id, permIDs); err != nil { return err } s.invalidator.InvalidateAll(ctx) return nil }