149 lines
4.1 KiB
Go
149 lines
4.1 KiB
Go
package admin_role
|
|
|
|
import (
|
|
"context"
|
|
|
|
"tydata-server/app/main/api/internal/svc"
|
|
"tydata-server/app/main/api/internal/types"
|
|
"tydata-server/app/main/model"
|
|
"tydata-server/common/xerr"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/samber/lo"
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
)
|
|
|
|
type UpdateRoleLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
func NewUpdateRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateRoleLogic {
|
|
return &UpdateRoleLogic{
|
|
Logger: logx.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *UpdateRoleLogic) UpdateRole(req *types.UpdateRoleReq) (resp *types.UpdateRoleResp, err error) {
|
|
// 检查角色是否存在
|
|
role, err := l.svcCtx.AdminRoleModel.FindOne(l.ctx, req.Id)
|
|
if err != nil {
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return nil, errors.Wrapf(xerr.NewErrMsg("角色不存在"), "更新角色失败, 角色不存在err: %v", err)
|
|
}
|
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新角色失败err: %v", err)
|
|
}
|
|
|
|
// 检查角色编码是否重复
|
|
if req.RoleCode != nil && *req.RoleCode != role.RoleCode {
|
|
roleModel, err := l.svcCtx.AdminRoleModel.FindOneByRoleCode(l.ctx, *req.RoleCode)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新角色失败err: %v", err)
|
|
}
|
|
if roleModel != nil {
|
|
return nil, errors.Wrapf(xerr.NewErrMsg("角色编码已存在"), "更新角色失败, 角色编码已存在err: %v", err)
|
|
}
|
|
}
|
|
|
|
// 更新角色信息
|
|
if req.RoleName != nil {
|
|
role.RoleName = *req.RoleName
|
|
}
|
|
if req.RoleCode != nil {
|
|
role.RoleCode = *req.RoleCode
|
|
}
|
|
if req.Description != nil {
|
|
role.Description = *req.Description
|
|
}
|
|
if req.Status != nil {
|
|
role.Status = *req.Status
|
|
}
|
|
if req.Sort != nil {
|
|
role.Sort = *req.Sort
|
|
}
|
|
|
|
// 使用事务更新角色和关联菜单
|
|
err = l.svcCtx.AdminRoleModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
// 更新角色
|
|
_, err = l.svcCtx.AdminRoleModel.Update(ctx, session, role)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if req.MenuIds != nil {
|
|
// 1. 获取当前关联的菜单ID
|
|
builder := l.svcCtx.AdminRoleMenuModel.SelectBuilder().
|
|
Where("role_id = ?", req.Id)
|
|
currentMenus, err := l.svcCtx.AdminRoleMenuModel.FindAll(ctx, builder, "id ASC")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 2. 转换为map便于查找
|
|
currentMenuMap := make(map[int64]*model.AdminRoleMenu)
|
|
for _, menu := range currentMenus {
|
|
currentMenuMap[menu.MenuId] = menu
|
|
}
|
|
|
|
// 3. 检查新的菜单ID是否存在
|
|
for _, menuId := range req.MenuIds {
|
|
exists, err := l.svcCtx.AdminMenuModel.FindOne(ctx, menuId)
|
|
if err != nil || exists == nil {
|
|
return errors.Wrapf(xerr.NewErrMsg("菜单不存在"), "菜单ID: %d", menuId)
|
|
}
|
|
}
|
|
|
|
// 4. 找出需要删除和新增的关联
|
|
var toDelete []*model.AdminRoleMenu
|
|
var toInsert []int64
|
|
|
|
// 需要删除的:当前存在但新列表中没有的
|
|
for menuId, roleMenu := range currentMenuMap {
|
|
if !lo.Contains(req.MenuIds, menuId) {
|
|
toDelete = append(toDelete, roleMenu)
|
|
}
|
|
}
|
|
|
|
// 需要新增的:新列表中有但当前不存在的
|
|
for _, menuId := range req.MenuIds {
|
|
if _, exists := currentMenuMap[menuId]; !exists {
|
|
toInsert = append(toInsert, menuId)
|
|
}
|
|
}
|
|
|
|
// 5. 删除需要移除的关联
|
|
for _, roleMenu := range toDelete {
|
|
err = l.svcCtx.AdminRoleMenuModel.Delete(ctx, session, roleMenu.Id)
|
|
if err != nil {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "删除角色菜单关联失败: %v", err)
|
|
}
|
|
}
|
|
|
|
// 6. 添加新的关联
|
|
for _, menuId := range toInsert {
|
|
roleMenu := &model.AdminRoleMenu{
|
|
RoleId: req.Id,
|
|
MenuId: menuId,
|
|
}
|
|
_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
|
|
if err != nil {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "添加角色菜单关联失败: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新角色失败err: %v", err)
|
|
}
|
|
|
|
return &types.UpdateRoleResp{
|
|
Success: true,
|
|
}, nil
|
|
}
|