149 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package admin_role
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 
 | |
| 	"tyc-server/app/main/api/internal/svc"
 | |
| 	"tyc-server/app/main/api/internal/types"
 | |
| 	"tyc-server/app/main/model"
 | |
| 	"tyc-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
 | |
| }
 |