rbac
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user