{"record":{"id":"c999e9a55a306a60","repo":"flipped-aurora/gin-vue-admin","slug":"error-c999e9","errorCode":null,"errorMessage":"添加失败,请勿跨级操作","messagePattern":"添加失败,请勿跨级操作","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_menu.go","lineNumber":276,"sourceCode":"\t\tvar authorityMenus []system.SysAuthorityMenu\n\t\terr = global.GVA_DB.WithContext(ctx).Where(\"sys_authority_authority_id = ?\", adminAuthorityID).Find(&authorityMenus).Error\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor i := range authorityMenus {\n\t\t\tmenuIds = append(menuIds, authorityMenus[i].MenuId)\n\t\t}\n\n\t\tfor i := range menus {\n\t\t\thasMenu := false\n\t\t\tfor j := range menuIds {\n\t\t\t\tidStr := strconv.Itoa(int(menus[i].ID))\n\t\t\t\tif idStr == menuIds[j] {\n\t\t\t\t\thasMenu = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !hasMenu {\n\t\t\t\treturn errors.New(\"添加失败,请勿跨级操作\")\n\t\t\t}\n\t\t}\n\t}\n\n\terr = AuthorityServiceApp.SetMenuAuthority(ctx, &auth)\n\treturn err\n}\n\n//@author: [piexlmax](https://github.com/piexlmax)\n//@function: GetMenuAuthority\n//@description: 查看当前角色树\n//@param: info *request.GetAuthorityId\n//@return: menus []system.SysMenu, err error\n\nfunc (menuService *MenuService) GetMenuAuthority(ctx context.Context, info *request.GetAuthorityId) (menus []system.SysMenu, err error) {\n\tvar baseMenu []system.SysBaseMenu\n\tvar SysAuthorityMenus []system.SysAuthorityMenu\n\terr = global.GVA_DB.WithContext(ctx).Where(\"sys_authority_authority_id = ?\", info.AuthorityId).Find(&SysAuthorityMenus).Error","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_menu.go#L258-L294","documentation":"Raised by MenuService.AddMenuAuthority when assigning a menu tree to an authority: for each selected top-level menu, the service verifies the caller's own authority actually contains that menu ID. If a selected menu is not within the caller's assigned menus, the operation is rejected as an illegal cross-level grant and the transaction aborts before SetMenuAuthority runs.","triggerScenarios":"Calling AddMenuAuthority (POST /menu/MenuAuthority) with authorityMenus containing menu IDs that the current (privileged) authority does not itself possess — e.g. hand-crafted requests or stale frontend state selecting menus outside the admin's own scope.","commonSituations":"Manually constructed API requests trying to grant menus beyond the operator's rights; frontend sending full menu tree IDs instead of only the authority's assignable subset; data drift where the operator role lost menus it previously could assign.","solutions":["Ensure the request only includes menu IDs that belong to the calling authority's menu set.","Re-login / refresh the menu list so the frontend uses current authority menus.","Use a super-admin (authority 888) account to assign top-level or newly created menus.","Check sys_authority_menus for the operator role to confirm which IDs are legal."],"exampleFix":"// before (hand-crafted request granting unowned menu 42)\nawait setMenuAuthority({ authorityId: '9528', authorityMenus: [{ menuId: 42 }] })\n// after: only pass menus from the caller's own assignment\nconst own = ownAuthorityMenus.map(m => m.menuId)\nconst legal = targets.filter(id => own.includes(id))\nawait setMenuAuthority({ authorityId: '9528', authorityMenus: legal.map(id => ({ menuId: id })) })","handlingStrategy":"validation","validationCode":"const ownIds = new Set(ownAuthorityMenus.map(m => m.menuId))\nconst illegal = selectedMenuIds.filter(id => !ownIds.has(id))\nif (illegal.length) {\n  alert(`以下菜单超出当前账号可分配范围: ${illegal.join(',')}`)\n  return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await menuApi.setMenuAuthority(payload)\n} catch (e) {\n  if (String(e.msg).includes('请勿跨级操作')) {\n    await reloadAssignableMenus() // resync to caller's legal menu set\n  } else throw e\n}","preventionTips":["Only send menu IDs sourced from the operator's own authority menu list.","Use a super-admin account to assign newly created or top-level menus.","Re-login after your own role's menus change to avoid stale client state."],"tags":["go","gin-vue-admin","menu","authority","permission"],"backgroundTag":"unauthorized-menu-assignment","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}