- 将 admin 相关服务移动到 internal/service/admin 目录下 - 更新控制器中的服务导入路径引用 - 移除已合并的服务文件 - 添加统一工作约定文档 - 更新 API 接口定义的包路径
129 lines
4.1 KiB
Go
129 lines
4.1 KiB
Go
package role
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
|
|
"service.xpcool.com/internal/consts"
|
|
"service.xpcool.com/internal/dao"
|
|
"service.xpcool.com/internal/library/response"
|
|
"service.xpcool.com/internal/model/do"
|
|
"service.xpcool.com/internal/model/dto"
|
|
"service.xpcool.com/internal/model/entity"
|
|
)
|
|
|
|
// IRoleManage 管理角色及其菜单绑定。
|
|
type IRoleManage interface {
|
|
List(context.Context, dto.PageQuery) ([]*dto.RoleItem, int, error)
|
|
Create(context.Context, dto.RoleCreateInput) (uint64, error)
|
|
Update(context.Context, dto.RoleUpdateInput) error
|
|
Delete(context.Context, uint64) error
|
|
}
|
|
|
|
type roleManage struct{}
|
|
|
|
var localRoleManage IRoleManage
|
|
|
|
func NewRoleManage() IRoleManage { return &roleManage{} }
|
|
|
|
func RoleManage() IRoleManage {
|
|
if localRoleManage == nil {
|
|
panic("RoleManage implementation not registered")
|
|
}
|
|
return localRoleManage
|
|
}
|
|
func RegisterRoleManage(i IRoleManage) { localRoleManage = i }
|
|
|
|
// ---------------------- Role manage ----------------------
|
|
|
|
func (s *roleManage) List(ctx context.Context, q dto.PageQuery) ([]*dto.RoleItem, int, error) {
|
|
total, err := dao.AdminRole.Ctx(ctx).Count()
|
|
if err != nil {
|
|
return nil, 0, gerror.Wrap(err, "count roles")
|
|
}
|
|
if total == 0 {
|
|
return nil, 0, nil
|
|
}
|
|
var list []entity.AdminRole
|
|
if err = dao.AdminRole.Ctx(ctx).Page(q.Page, q.Size).OrderAsc("id").Scan(&list); err != nil {
|
|
return nil, 0, gerror.Wrap(err, "query roles")
|
|
}
|
|
items := make([]*dto.RoleItem, 0, len(list))
|
|
for i := range list {
|
|
r := &list[i]
|
|
menuIds, err := roleMenuIDs(ctx, r.Id)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
items = append(items, &dto.RoleItem{
|
|
Id: r.Id, Code: r.Code, Name: r.Name, Status: r.Status, MenuIds: menuIds,
|
|
CreatedAt: r.CreatedAt.Layout("2006-01-02 15:04:05"),
|
|
})
|
|
}
|
|
return items, total, nil
|
|
}
|
|
|
|
func (s *roleManage) Create(ctx context.Context, in dto.RoleCreateInput) (uint64, error) {
|
|
count, err := dao.AdminRole.Ctx(ctx).Where(do.AdminRole{Code: in.Code}).Count()
|
|
if err != nil {
|
|
return 0, gerror.Wrap(err, "check role code")
|
|
}
|
|
if count > 0 {
|
|
return 0, response.Error(consts.CodeInvalidParam, "role code already exists")
|
|
}
|
|
id, err := dao.AdminRole.Ctx(ctx).Data(do.AdminRole{Code: in.Code, Name: in.Name, Status: in.Status}).InsertAndGetId()
|
|
if err != nil {
|
|
return 0, gerror.Wrap(err, "insert role")
|
|
}
|
|
if err = bindRoleMenus(ctx, uint64(id), in.MenuIds); err != nil {
|
|
return 0, err
|
|
}
|
|
return uint64(id), nil
|
|
}
|
|
|
|
func (s *roleManage) Update(ctx context.Context, in dto.RoleUpdateInput) error {
|
|
if _, err := dao.AdminRole.Ctx(ctx).Where(do.AdminRole{Id: in.Id}).Data(do.AdminRole{Name: in.Name, Status: in.Status}).Update(); err != nil {
|
|
return gerror.Wrap(err, "update role")
|
|
}
|
|
return bindRoleMenus(ctx, in.Id, in.MenuIds)
|
|
}
|
|
|
|
func (s *roleManage) Delete(ctx context.Context, id uint64) error {
|
|
if _, err := dao.AdminRole.Ctx(ctx).Where(do.AdminRole{Id: id}).Delete(); err != nil {
|
|
return gerror.Wrap(err, "delete role")
|
|
}
|
|
if _, err := dao.AdminRoleMenu.Ctx(ctx).Unscoped().Where(do.AdminRoleMenu{RoleId: id}).Delete(); err != nil {
|
|
return gerror.Wrap(err, "delete role menu bindings")
|
|
}
|
|
if _, err := dao.AdminUserRole.Ctx(ctx).Unscoped().Where(do.AdminUserRole{RoleId: id}).Delete(); err != nil {
|
|
return gerror.Wrap(err, "delete user role bindings")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func roleMenuIDs(ctx context.Context, roleID uint64) ([]uint64, error) {
|
|
var rels []entity.AdminRoleMenu
|
|
if err := dao.AdminRoleMenu.Ctx(ctx).Where(do.AdminRoleMenu{RoleId: roleID}).Scan(&rels); err != nil {
|
|
return nil, gerror.Wrap(err, "query role menus")
|
|
}
|
|
ids := make([]uint64, 0, len(rels))
|
|
for _, r := range rels {
|
|
ids = append(ids, r.MenuId)
|
|
}
|
|
return ids, nil
|
|
}
|
|
|
|
// bindRoleMenus 全量重绑角色-菜单关系。
|
|
func bindRoleMenus(ctx context.Context, roleID uint64, menuIds []uint64) error {
|
|
if _, err := dao.AdminRoleMenu.Ctx(ctx).Unscoped().Where(do.AdminRoleMenu{RoleId: roleID}).Delete(); err != nil {
|
|
return gerror.Wrap(err, "clear role menus")
|
|
}
|
|
for _, mid := range menuIds {
|
|
if _, err := dao.AdminRoleMenu.Ctx(ctx).Data(do.AdminRoleMenu{RoleId: roleID, MenuId: mid}).Insert(); err != nil {
|
|
return gerror.Wrap(err, "bind role menu")
|
|
}
|
|
}
|
|
return nil
|
|
}
|