ycc-server/app/main/api/internal/logic/admin_role/updaterolelogic.go
2025-06-19 17:12:48 +08:00

149 lines
4.1 KiB
Go

package admin_role
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-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
}