package user import ( "context" "time" "perms-system-server/internal/consts" authHelper "perms-system-server/internal/logic/auth" "perms-system-server/internal/middleware" "perms-system-server/internal/model/userrole" "perms-system-server/internal/response" "perms-system-server/internal/svc" "perms-system-server/internal/types" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type BindRolesLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewBindRolesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BindRolesLogic { return &BindRolesLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *BindRolesLogic) BindRoles(req *types.BindRolesReq) error { if _, err := l.svcCtx.SysUserModel.FindOne(l.ctx, req.UserId); err != nil { return response.ErrNotFound("用户不存在") } productCode := middleware.GetProductCode(l.ctx) if err := authHelper.CheckManageAccess(l.ctx, l.svcCtx, req.UserId, productCode); err != nil { return err } if _, err := l.svcCtx.SysProductMemberModel.FindOneByProductCodeUserId(l.ctx, productCode, req.UserId); err != nil { return response.ErrBadRequest("目标用户不是当前产品的成员") } if len(req.RoleIds) > 0 { seen := make(map[int64]bool, len(req.RoleIds)) uniqueIds := make([]int64, 0, len(req.RoleIds)) for _, id := range req.RoleIds { if !seen[id] { seen[id] = true uniqueIds = append(uniqueIds, id) } } req.RoleIds = uniqueIds } caller := middleware.GetUserDetails(l.ctx) if len(req.RoleIds) > 0 { roles, err := l.svcCtx.SysRoleModel.FindByIds(l.ctx, req.RoleIds) if err != nil { return err } if int64(len(roles)) != int64(len(req.RoleIds)) { return response.ErrBadRequest("包含无效的角色ID") } for _, r := range roles { if r.ProductCode != productCode { return response.ErrBadRequest("不能绑定其他产品的角色") } if r.Status != consts.StatusEnabled { return response.ErrBadRequest("不能绑定已禁用的角色") } if caller != nil && !caller.IsSuperAdmin { if caller.MinPermsLevel == 0 || r.PermsLevel < caller.MinPermsLevel { return response.ErrForbidden("不能分配权限级别高于自身的角色") } } } } if err := l.svcCtx.SysUserRoleModel.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error { if err := l.svcCtx.SysUserRoleModel.DeleteByUserIdForProductTx(ctx, session, req.UserId, productCode); err != nil { return err } if len(req.RoleIds) == 0 { return nil } now := time.Now().Unix() data := make([]*userrole.SysUserRole, 0, len(req.RoleIds)) for _, roleId := range req.RoleIds { data = append(data, &userrole.SysUserRole{ UserId: req.UserId, RoleId: roleId, CreateTime: now, UpdateTime: now, }) } return l.svcCtx.SysUserRoleModel.BatchInsertWithTx(ctx, session, data) }); err != nil { return err } l.svcCtx.UserDetailsLoader.Clean(l.ctx, req.UserId) return nil }