{"record":{"id":"f8d4ecacb0727651","repo":"flipped-aurora/gin-vue-admin","slug":"error-f8d4ec","errorCode":null,"errorMessage":"该用户无此角色","messagePattern":"该用户无此角色","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_user.go","lineNumber":154,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\terr = db.Limit(limit).Offset(offset).Order(orderStr).Preload(\"Authorities\").Preload(\"Authority\").Preload(\"Departments\").Preload(\"Positions\").Preload(\"Dept\").Find(&userList).Error\n\treturn userList, total, err\n}\n\n//@author: [piexlmax](https://github.com/piexlmax)\n//@function: SetUserAuthority\n//@description: 设置一个用户的权限\n//@param: uuid uuid.UUID, authorityId string\n//@return: err error\n\nfunc (userService *UserService) SetUserAuthority(ctx context.Context, id uint, authorityId uint) (err error) {\n\n\tassignErr := global.GVA_DB.WithContext(ctx).Where(\"sys_user_id = ? AND sys_authority_authority_id = ?\", id, authorityId).First(&system.SysUserAuthority{}).Error\n\tif errors.Is(assignErr, gorm.ErrRecordNotFound) {\n\t\treturn errors.New(\"该用户无此角色\")\n\t}\n\n\tvar authority system.SysAuthority\n\terr = global.GVA_DB.WithContext(ctx).Where(\"authority_id = ?\", authorityId).First(&authority).Error\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar authorityMenu []system.SysAuthorityMenu\n\tvar authorityMenuIDs []string\n\terr = global.GVA_DB.WithContext(ctx).Where(\"sys_authority_authority_id = ?\", authorityId).Find(&authorityMenu).Error\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor i := range authorityMenu {\n\t\tauthorityMenuIDs = append(authorityMenuIDs, authorityMenu[i].MenuId)\n\t}\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_user.go#L136-L172","documentation":"SetUserAuthority only allows switching a user to an authority the user already holds in the sys_user_authority join table. If no row matches sys_user_id = id AND sys_authority_authority_id = authorityId, it returns errors.New(\"该用户无此角色\"). This is a guard ensuring the single authority_id can only be set to a role from the user's existing role set.","triggerScenarios":"Calling SetUserAuthority(sys_user.go:154) with an authorityId that is not linked to the user in system.SysUserAuthority — e.g. switching to a role never granted via SetUserAuthorities, or after that role was removed from the user.","commonSituations":"Front end showing role options not refreshed after roles were changed; attempting to switch to a newly created role before assigning it to the user; using a stale user detail page.","solutions":["First call SetUserAuthorities to add the target authority to the user's role set, then call SetUserAuthority to make it the active one.","Re-fetch the user's authorities before rendering the switch-role UI so only held roles are offered.","Confirm the authorityId passed is the role's authority_id (not menu id or row id)."],"exampleFix":"// before\nerr := userService.SetUserAuthority(ctx, userId, newAuthorityId) // role not yet granted\n// after\nif err := userService.SetUserAuthorities(ctx, adminAuthorityID, userId, []uint{newAuthorityId}); err != nil { return err }\nerr := userService.SetUserAuthority(ctx, userId, newAuthorityId)","handlingStrategy":"validation","validationCode":"// only offer roles the user already holds\nconst switchable = userAuthorities.filter(a => heldAuthorityIds.includes(a.authorityId))","typeGuard":null,"tryCatchPattern":"try {\n  await setUserAuthority({ id, authorityId })\n} catch (e) {\n  if (e.message === '该用户无此角色') ElMessage.error('请先为用户分配该角色')\n  else throw e\n}","preventionTips":["Render the switch-role dropdown only from the user's current authority list.","Re-fetch user authorities after any role change.","Assign roles via SetUserAuthorities before switching."],"tags":["auth","roles","authority","business-rule"],"backgroundTag":"role-not-assigned","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}