@fudanda/admin-antd 2.20261107.1-beta.1 → 2.20261109.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/chunks/{App-BF96TQ_D.js → App-CfQx7jWq.js} +4 -4
  2. package/dist/chunks/{App-BF96TQ_D.js.map → App-CfQx7jWq.js.map} +1 -1
  3. package/dist/chunks/{AppModal-CLkMJ-96.js → AppModal-CVoUC2t3.js} +2 -2
  4. package/dist/chunks/{AppModal-CLkMJ-96.js.map → AppModal-CVoUC2t3.js.map} +1 -1
  5. package/dist/chunks/{ArcBaseAdmin--xQxd4tg.js → ArcBaseAdmin-DQyddbFC.js} +2 -2
  6. package/dist/chunks/{ArcBaseAdmin--xQxd4tg.js.map → ArcBaseAdmin-DQyddbFC.js.map} +1 -1
  7. package/dist/chunks/{DepartmentsPage-D6YVegPU.js → DepartmentsPage-CQx53QGE.js} +2 -2
  8. package/dist/chunks/{DepartmentsPage-D6YVegPU.js.map → DepartmentsPage-CQx53QGE.js.map} +1 -1
  9. package/dist/chunks/{DictsPage-uV3Uukwc.js → DictsPage-BGnamkWk.js} +2 -2
  10. package/dist/chunks/{DictsPage-uV3Uukwc.js.map → DictsPage-BGnamkWk.js.map} +1 -1
  11. package/dist/chunks/EntityContextRuntime-C9q95WDf.js +1 -0
  12. package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js → EntityContextRuntime-CbzeMNXR.js} +2 -2
  13. package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js.map → EntityContextRuntime-CbzeMNXR.js.map} +1 -1
  14. package/dist/chunks/{ExportButton-e2ybxuHb.js → ExportButton-sMPAV2hd.js} +2 -2
  15. package/dist/chunks/{ExportButton-e2ybxuHb.js.map → ExportButton-sMPAV2hd.js.map} +1 -1
  16. package/dist/chunks/{FileViewerPreviewPanel-BhI3pTi8.js → FileViewerPreviewPanel-Rti7pUhU.js} +3 -3
  17. package/dist/chunks/{FileViewerPreviewPanel-BhI3pTi8.js.map → FileViewerPreviewPanel-Rti7pUhU.js.map} +1 -1
  18. package/dist/chunks/{FilesPage-BI35mStl.js → FilesPage-D_iYsUwl.js} +3 -3
  19. package/dist/chunks/{FilesPage-BI35mStl.js.map → FilesPage-D_iYsUwl.js.map} +1 -1
  20. package/dist/chunks/IdentitySecurityPage-rDYX5ksX.js +9 -0
  21. package/dist/chunks/IdentitySecurityPage-rDYX5ksX.js.map +1 -0
  22. package/dist/chunks/{LogStatsScaffold-m0vVUXPh.js → LogStatsScaffold-CMIz4z0a.js} +2 -2
  23. package/dist/chunks/{LogStatsScaffold-m0vVUXPh.js.map → LogStatsScaffold-CMIz4z0a.js.map} +1 -1
  24. package/dist/chunks/{LoginLogsPage-BzBUR4Oo.js → LoginLogsPage-Bv5pPJb2.js} +2 -2
  25. package/dist/chunks/{LoginLogsPage-BzBUR4Oo.js.map → LoginLogsPage-Bv5pPJb2.js.map} +1 -1
  26. package/dist/chunks/{LoginLogsTable-BweUEjQX.js → LoginLogsTable-DYcTx2oR.js} +2 -2
  27. package/dist/chunks/{LoginLogsTable-BweUEjQX.js.map → LoginLogsTable-DYcTx2oR.js.map} +1 -1
  28. package/dist/chunks/{MarkdownPreviewPanel-C1OKSLmh.js → MarkdownPreviewPanel-lqs6AsoN.js} +2 -2
  29. package/dist/chunks/{MarkdownPreviewPanel-C1OKSLmh.js.map → MarkdownPreviewPanel-lqs6AsoN.js.map} +1 -1
  30. package/dist/chunks/{MasterDetailLayout-KVizcSNO.js → MasterDetailLayout-B5uqvh98.js} +2 -2
  31. package/dist/chunks/{MasterDetailLayout-KVizcSNO.js.map → MasterDetailLayout-B5uqvh98.js.map} +1 -1
  32. package/dist/chunks/{McpSettingsPage-Dhf0CbDN.js → McpSettingsPage-Cdej9Evi.js} +2 -2
  33. package/dist/chunks/{McpSettingsPage-Dhf0CbDN.js.map → McpSettingsPage-Cdej9Evi.js.map} +1 -1
  34. package/dist/chunks/{MemberAssignmentSheet-TYpnyA0z.js → MemberAssignmentSheet-AKvLbbYW.js} +2 -2
  35. package/dist/chunks/{MemberAssignmentSheet-TYpnyA0z.js.map → MemberAssignmentSheet-AKvLbbYW.js.map} +1 -1
  36. package/dist/chunks/{MenuCommandPalette-BcvpUfK7.js → MenuCommandPalette-ia0pSIFg.js} +2 -2
  37. package/dist/chunks/{MenuCommandPalette-BcvpUfK7.js.map → MenuCommandPalette-ia0pSIFg.js.map} +1 -1
  38. package/dist/chunks/{MenusPage-Dd7OLQYT.js → MenusPage-Bh55bvKH.js} +2 -2
  39. package/dist/chunks/{MenusPage-Dd7OLQYT.js.map → MenusPage-Bh55bvKH.js.map} +1 -1
  40. package/dist/chunks/{MonacoPreviewPanel-BW1j3ZTF.js → MonacoPreviewPanel-CT_sjf7Z.js} +2 -2
  41. package/dist/chunks/{MonacoPreviewPanel-BW1j3ZTF.js.map → MonacoPreviewPanel-CT_sjf7Z.js.map} +1 -1
  42. package/dist/chunks/{NavListPanel-Iz1RCkVw.js → NavListPanel-DMIUMh7q.js} +2 -2
  43. package/dist/chunks/{NavListPanel-Iz1RCkVw.js.map → NavListPanel-DMIUMh7q.js.map} +1 -1
  44. package/dist/chunks/{OperationLogsPage-Dt22tU4I.js → OperationLogsPage-7XVfmhxP.js} +2 -2
  45. package/dist/chunks/{OperationLogsPage-Dt22tU4I.js.map → OperationLogsPage-7XVfmhxP.js.map} +1 -1
  46. package/dist/chunks/{OperationLogsTable-B23Ry-2v.js → OperationLogsTable-gp-WZxiF.js} +3 -3
  47. package/dist/chunks/{OperationLogsTable-B23Ry-2v.js.map → OperationLogsTable-gp-WZxiF.js.map} +1 -1
  48. package/dist/chunks/{PDFPreviewPanel-kBPz5dQr.js → PDFPreviewPanel-CyfhyWav.js} +3 -3
  49. package/dist/chunks/{PDFPreviewPanel-kBPz5dQr.js.map → PDFPreviewPanel-CyfhyWav.js.map} +1 -1
  50. package/dist/chunks/{PositionsPage-BIKYQDB5.js → PositionsPage-Bwua1vNV.js} +2 -2
  51. package/dist/chunks/{PositionsPage-BIKYQDB5.js.map → PositionsPage-Bwua1vNV.js.map} +1 -1
  52. package/dist/chunks/{PreferencesSheetBody-D276rrp4.js → PreferencesSheetBody-C80D3dOM.js} +2 -2
  53. package/dist/chunks/{PreferencesSheetBody-D276rrp4.js.map → PreferencesSheetBody-C80D3dOM.js.map} +1 -1
  54. package/dist/chunks/{ProfilePage-DLftC6KZ.js → ProfilePage-DeTw-59a.js} +2 -2
  55. package/dist/chunks/{ProfilePage-DLftC6KZ.js.map → ProfilePage-DeTw-59a.js.map} +1 -1
  56. package/dist/chunks/{ProjectInfoPage-DkuBLC8t.js → ProjectInfoPage-Bqn3gfXa.js} +2 -2
  57. package/dist/chunks/{ProjectInfoPage-DkuBLC8t.js.map → ProjectInfoPage-Bqn3gfXa.js.map} +1 -1
  58. package/dist/chunks/{RelationPanel-B4BeO0Bz.js → RelationPanel-Bio-ig-l.js} +2 -2
  59. package/dist/chunks/{RelationPanel-B4BeO0Bz.js.map → RelationPanel-Bio-ig-l.js.map} +1 -1
  60. package/dist/chunks/{RolesPage-BhltU2Qm.js → RolesPage-fwUSs2HR.js} +2 -2
  61. package/dist/chunks/{RolesPage-BhltU2Qm.js.map → RolesPage-fwUSs2HR.js.map} +1 -1
  62. package/dist/chunks/{SessionConflictModal-3R8jdYkI.js → SessionConflictModal-Dw4opoNP.js} +2 -2
  63. package/dist/chunks/{SessionConflictModal-3R8jdYkI.js.map → SessionConflictModal-Dw4opoNP.js.map} +1 -1
  64. package/dist/chunks/{SettingModuleDetail-Dppk9An1.js → SettingModuleDetail-I9CSJ-fh.js} +2 -2
  65. package/dist/chunks/{SettingModuleDetail-Dppk9An1.js.map → SettingModuleDetail-I9CSJ-fh.js.map} +1 -1
  66. package/dist/chunks/{SettingsPage-DMzeDrnc.js → SettingsPage-Cy5-q-P6.js} +2 -2
  67. package/dist/chunks/{SettingsPage-DMzeDrnc.js.map → SettingsPage-Cy5-q-P6.js.map} +1 -1
  68. package/dist/chunks/{StatCard-C0xSZyiS.js → StatCard-BROG4NSp.js} +2 -2
  69. package/dist/chunks/{StatCard-C0xSZyiS.js.map → StatCard-BROG4NSp.js.map} +1 -1
  70. package/dist/chunks/{UserGroupsPage-DTJdszHl.js → UserGroupsPage-CsTBkUPy.js} +2 -2
  71. package/dist/chunks/{UserGroupsPage-DTJdszHl.js.map → UserGroupsPage-CsTBkUPy.js.map} +1 -1
  72. package/dist/chunks/{UserLogsPanels-z4UhQtgu.js → UserLogsPanels-3u8Z93YU.js} +2 -2
  73. package/dist/chunks/{UserLogsPanels-z4UhQtgu.js.map → UserLogsPanels-3u8Z93YU.js.map} +1 -1
  74. package/dist/chunks/{UserTransferSelect-BJNUXMhl.js → UserTransferSelect-ChLj4EkS.js} +2 -2
  75. package/dist/chunks/{UserTransferSelect-BJNUXMhl.js.map → UserTransferSelect-ChLj4EkS.js.map} +1 -1
  76. package/dist/chunks/{UsersPage--p68X2Yr.js → UsersPage-CfNnQJi4.js} +2 -2
  77. package/dist/chunks/{UsersPage--p68X2Yr.js.map → UsersPage-CfNnQJi4.js.map} +1 -1
  78. package/dist/chunks/{browser-BKLM0ThC-3Xar5rZw.js → browser-BKLM0ThC-D0TgzKTC.js} +1 -1
  79. package/dist/chunks/{code-P0HJS_q1.js → code-BkkeN2fd.js} +1 -1
  80. package/dist/chunks/{direct-engine-BYEscsGg.js → direct-engine-m32m22nx.js} +1 -1
  81. package/dist/chunks/{html-B__1Vr_C.js → html-BGNWR_Bp.js} +1 -1
  82. package/dist/chunks/{line-DzLRZVEq.js → line-CsTeuEcK.js} +1 -1
  83. package/dist/chunks/{lrc-kf-TilFB.js → lrc-D6gjnGZ5.js} +1 -1
  84. package/dist/chunks/{markdown-xIo-vnKK.js → markdown-BglUe9j8.js} +1 -1
  85. package/dist/chunks/{patch-BEaX-xYV.js → patch-C97Yl3jr.js} +1 -1
  86. package/dist/chunks/{worker-engine-FCdIQLzN.js → worker-engine-B7_3qQVS.js} +1 -1
  87. package/dist/core/hooks/queries/settings.d.ts +6 -0
  88. package/dist/core/hooks/queries/settings.d.ts.map +1 -1
  89. package/dist/core/hooks/queries/settings.js +34 -25
  90. package/dist/core/hooks/queries/settings.js.map +1 -1
  91. package/dist/core/hooks/useAuth.d.ts +2 -0
  92. package/dist/core/hooks/useAuth.d.ts.map +1 -1
  93. package/dist/core/hooks/useAuth.js.map +1 -1
  94. package/dist/core/index.js +7 -7
  95. package/dist/core/lib/go-auth-api.d.ts +1 -1
  96. package/dist/core/lib/go-auth-api.d.ts.map +1 -1
  97. package/dist/core/lib/go-auth-api.js +12 -8
  98. package/dist/core/lib/go-auth-api.js.map +1 -1
  99. package/dist/core/lib/native-operations.d.ts +85 -4
  100. package/dist/core/lib/native-operations.d.ts.map +1 -1
  101. package/dist/core/lib/native-operations.js +1 -0
  102. package/dist/core/lib/native-operations.js.map +1 -1
  103. package/dist/core/providers/GoAuthProvider.d.ts.map +1 -1
  104. package/dist/core/providers/GoAuthProvider.js +191 -142
  105. package/dist/core/providers/GoAuthProvider.js.map +1 -1
  106. package/dist/core/session-renewal.d.ts +15 -0
  107. package/dist/core/session-renewal.d.ts.map +1 -0
  108. package/dist/core/session-renewal.js +95 -0
  109. package/dist/core/session-renewal.js.map +1 -0
  110. package/dist/core/session-transition.d.ts +2 -0
  111. package/dist/core/session-transition.d.ts.map +1 -1
  112. package/dist/core/session-transition.js +20 -7
  113. package/dist/core/session-transition.js.map +1 -1
  114. package/dist/core/session.d.ts +4 -0
  115. package/dist/core/session.d.ts.map +1 -1
  116. package/dist/core/session.js +88 -61
  117. package/dist/core/session.js.map +1 -1
  118. package/dist/index.js +1 -1
  119. package/dist/{src-C8_bzBi4.js → src-DAkFn9SG.js} +2 -2
  120. package/dist/{src-C8_bzBi4.js.map → src-DAkFn9SG.js.map} +1 -1
  121. package/package.json +9 -9
  122. package/dist/chunks/EntityContextRuntime-BOJySc1D.js +0 -1
  123. package/dist/chunks/IdentitySecurityPage-DW5ybVL4.js +0 -9
  124. package/dist/chunks/IdentitySecurityPage-DW5ybVL4.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"UsersPage--p68X2Yr.js","mappings":"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","names":["__iconData","__iconData$3","createLucideIcon","__iconData$2","__iconData$1","batchStatusHandler","ids","selectedRowKeys","label","status","disableLabel","execute","run","clearSelection","Toast","successMessage","confirm","options","entity","confirmContent","danger","confirmDanger","Modal","SensitiveFormInput","inputProps","formApi","useFormApi","recordId","control","reveal","useRevealedValue","maskedValue","field","maskedText","EMPTY_PLACEHOLDER","text","Form","Space","Typography","Tooltip","Button","Eye","EyeOff","PencilLine","unlocked","Undo2","DirectorySyncControl","useDirectorySyncStatus","administrator","sync","useDirectorySync","DateTimeText","DirectoryAccountModal","sensitive","useSensitiveFormFields","directorySensitiveFields","user","create","useDirectoryCreate","update","useDirectoryUpdate","form","useRef","requestId","useState","uncertain","setUncertain","error","setError","provision","useDirectoryProvision","submit","input","values","body","identityDirectoryContract","profile","onClose","cause","AppModal","value","FormPasswordInput","data","UserMenuPermissionModal","directMenuIds","setDirectMenuIds","roleMenuIds","setRoleMenuIds","groupMenuIds","setGroupMenuIds","groups","setGroups","effectiveMenuIds","setEffectiveMenuIds","activeTab","setActiveTab","menuTreeQuery","useMenuTree","visible","permissionsQuery","useUserEffectivePermissions","userId","saveMenusMutation","useSaveUserMenus","useEffect","handleSave","effectiveSet","buildLabelSuffix","menuSources","result","id","tags","Tag","source","userName","ModalFooter","Tabs","TabPane","MenuPermissionPanel","_Fragment","g","scopeLabel","scope","DATA_SCOPE_OPTIONS","o","getMostPermissive","mostPermissiveDataScope","scopes","UserDataScopeModal","departmentTree","useMemo","buildTree","deptTree","item","userDataScope","setUserDataScope","deptScopeIds","setDeptScopeIds","roleDataScope","setRoleDataScope","roleDeptScopeIds","setRoleDeptScopeIds","groupDataScope","setGroupDataScope","groupDeptScopeIds","setGroupDeptScopeIds","permissionQuery","useUserDataPermission","saveMutation","useSaveUserDataPermission","enumValueOf","DATA_SCOPES","effectiveScope","effectiveDeptIds","Text","DataScopePanel","Divider","UserAvatarModal","updateAvatarMutation","useApiMutation","userContract","qc","userKeys","updateAvatar","avatar","api","handleSelect","onUpdated","url","err","handleRemoveAvatar","confirmDelete","AvatarSelectModal","uploadAvatarBlobToFileCenter","UserLogsSheet","firstTab","canViewLoginLogs","SideSheet","key","UserLoginLogsPanel","canViewOperationLogs","UserOperationLogsPanel","FoundationImportButton","dryRun","pending","setPending","duplicate","setDuplicate","setResult","setVisible","pick","beforeSubmit","dry","upload","response","goTransport","transferUsers","onFinished","template","blob","transferTemplate","downloadBlob","title","file","event","Dropdown","Select","Upload","ChevronDown","Table","ImportButton","props","SensitiveText","state","showToggle","Copy","copyTextWithToast","isAdminUser","UsersPage","usePermission","currentUser","useAuth","useListSearch","defaultSearchParams","useListDeepLink","applySearch","params","batchPasswordModalVisible","setBatchPasswordModalVisible","batchPasswordFormApi","menuPermUser","setMenuPermUser","menuPermVisible","setMenuPermVisible","dataPermUser","setDataPermUser","dataPermVisible","setDataPermVisible","roleAssignUser","setRoleAssignUser","roleAssignVisible","setRoleAssignVisible","roleAssignIds","setRoleAssignIds","avatarUser","setAvatarUser","avatarModalVisible","setAvatarModalVisible","logsUser","setLogsUser","logsVisible","setLogsVisible","externalIdentity","useIdentityCapabilities","directoryEditor","setDirectoryEditor","createPwdVal","setCreatePwdVal","editPwdVal","setEditPwdVal","batchPwdVal","setBatchPwdVal","statusItems","useDictItems","genderOptions","setSelectedRowKeys","deptTreeExpandedKeys","setDeptTreeExpandedKeys","canReadRoles","hasPermission","canReadDepartments","canReadPositions","allRolesQuery","useAllRoles","allDepartmentsQuery","useFlatDepartments","allPositionsQuery","useAllPositions","mySettingsQuery","useMySettings","allRoles","EMPTY_ROLES","allDepartments","EMPTY_DEPARTMENTS","allPositions","EMPTY_POSITIONS","passwordPolicy","filterQuery","useFilterQuery","submittedParams","USER_STATUSES","formatDateTimeRangeForApi","listQuery","useUserList","userList","EMPTY_USERS","useSaveUser","resetPasswordMutation","useResetUserPassword","deleteMutation","useDeleteUsers","unlockMutation","useUnlockUser","batchStatusMutation","useBatchUserStatus","toggleStatusMutation","batchPasswordMutation","useBatchUserPassword","assignRolesMutation","useAssignUserRoles","roleEffectivePermissionsQuery","kickSessionsMutation","useKickUserSessions","sensitiveFieldsRef","modal","useEditModal","formSaveMutation","useUserDetail","r","rawValues","clearFields","editing","payload","formatDateForApi","abortSubmit","editingUser","useStandardWebMcpCrudAdapter","action","record","isMaskedFieldValue","departmentContract","positionContract","roleContract","sensitiveFields","passwordModal","canViewUserLogs","selectedDeletableCount","selectedSet","selectedNonAdminIds","useStatusToggle","enabled","handleBatchStatus","handleBatchDelete","deletableIds","confirmAndDelete","departmentTreeData","departmentsToTreeData","departmentFilterTreeData","ALL_DEPARTMENTS_KEY","allDeptExpandedKeys","deptTreeExpandInitedRef","isAllDeptExpanded","isAllKeysExpanded","toggleDeptExpandAll","positionOptionList","openCreate","openEdit","openPassword","unlockUser","handleUnlock","useCallback","kickUserSessions","refetchUserList","columns","UserAvatar","v","renderEllipsis","overflowTagColumn","positions","roles","role","gender","DictTag","dateTimeColumn","EntityRelationButton","createdAtColumn","createOperationColumn","isAdmin","deleteAction","showDeptTree","setShowDeptTree","isLayoutNarrow","setIsLayoutNarrow","masterContent","MasterDetailLayout","jsx","ChevronsDownUp","ChevronsUpDown","Tree","draftParams","expandedKeys","newDeptId","selectedKey","newParams","renderDepartmentButton","Building2","forceVisible","renderBatchActions","BatchDeleteButton","BatchStatusButtons","KeyRound","renderImportButton","ConfigurableTable","buildTableSearch","KeywordInput","bindKeyword","StatusSelect","bind","DateRangeFilter","handleSearch","handleReset","CreateButton","ExportButton","listTableProps","buildPagination","nextKeys","keys","nextKeySet","adminIds","filtered","EditFormModal","Row","Col","PasswordStrengthMeter","i","formatPasswordPolicyHint","updated","updateUser"],"ignoreList":[0,1,2,3],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/building-complex.mjs","../../../../node_modules/lucide-react/dist/esm/icons/eye.mjs","../../../../node_modules/lucide-react/dist/esm/icons/pencil-line.mjs","../../../../node_modules/lucide-react/dist/esm/icons/undo-2.mjs","../../src/components/list-page/batchStatus.ts","../../src/components/sensitive/SensitiveFormInput.tsx","../../src/pages/users/IdentityDirectoryControls.tsx","../../src/pages/users/UserMenuPermissionModal.tsx","../../src/pages/users/UserDataScopeModal.tsx","../../src/pages/users/UserAvatarModal.tsx","../../src/pages/users/UserLogsSheet.tsx","../../src/components/FoundationImportButton.tsx","../../src/components/ImportButton.tsx","../../src/components/sensitive/SensitiveText.tsx","../../src/pages/users/UsersPage.tsx"],"sourcesContent":[null,null,null,null,"import type { ReactNode } from 'react';\nimport { Modal, Toast } from \"@/ui\";\nimport { confirmDanger } from \"@/utils/confirm\";\nexport type BatchStatus = 'enabled' | 'disabled';\nexport interface BatchStatusOptions<Id extends string | number = number> {\n /** 当前选中的行键(`useRowSelection().selectedRowKeys`) */\n readonly selectedRowKeys: readonly Id[];\n /** 成功后清空选中(`useRowSelection().clear`) */\n readonly clearSelection: () => void;\n /** 执行批量写入;载荷形状(`{ ids, status }` / `{ ids, enabled }`)由页面适配 */\n readonly run: (ids: Id[], status: BatchStatus) => Promise<unknown>;\n /** 停用侧文案:「停用」(默认)或「禁用」 */\n readonly disableLabel?: string;\n /**\n * 何时弹确认框:`'disable'`(默认,只有停用需要确认)/ `'always'` / `'never'`。\n * 标题缺省为「确认批量{启用 / 停用}选中的 N {entity}?」\n */\n readonly confirm?: 'disable' | 'always' | 'never';\n /** 确认标题里的量词 + 名词,如「个数据集」「条短链」;缺省「项」 */\n readonly entity?: string;\n readonly confirmContent?: (status: BatchStatus, count: number) => ReactNode | undefined;\n /** 停用是破坏性语义(如禁用账号)时确认按钮用红色实心 */\n readonly danger?: boolean;\n /** 成功提示,缺省「批量{启用 / 停用}成功」 */\n readonly successMessage?: (status: BatchStatus, count: number) => string;\n}\n/**\n * 「批量启用 / 停用」的统一流程:空选中直接返回 → 按策略确认 → 执行 → 清空选中 → 成功提示。\n * 返回 `handleBatchStatus(status)`,交给 `BatchEnableButton` / `BatchDisableButton` 的 `onClick`。\n *\n * @example\n * const handleBatchStatus = batchStatusHandler({\n * selectedRowKeys, clearSelection,\n * run: (ids, status) => batchStatusMutation.mutateAsync({ body: { ids, status } }),\n * confirm: 'always', entity: '个数据集',\n * });\n * <BatchEnableButton count={selectedRowKeys.length} onClick={() => handleBatchStatus('enabled')} />\n */\nexport function batchStatusHandler<Id extends string | number = number>({ selectedRowKeys, clearSelection, run, disableLabel = '停用', confirm = 'disable', entity = '项', confirmContent, danger = false, successMessage, }: BatchStatusOptions<Id>) {\n return async (status: BatchStatus): Promise<void> => {\n const ids = [...selectedRowKeys];\n if (ids.length === 0)\n return;\n const label = status === 'enabled' ? '启用' : disableLabel;\n const execute = async () => {\n await run(ids, status);\n clearSelection();\n Toast.success(successMessage?.(status, ids.length) ?? `批量${label}成功`);\n };\n const needConfirm = confirm === 'always' || (confirm === 'disable' && status === 'disabled');\n if (!needConfirm)\n return execute();\n const options = {\n title: `确认批量${label}选中的 ${ids.length} ${entity}?`,\n content: confirmContent?.(status, ids.length),\n onOk: execute,\n };\n // 停用是破坏性语义时用红色实心确认(confirmDanger),否则普通确认\n if (danger && status === 'disabled')\n confirmDanger(options);\n else\n Modal.confirm(options);\n };\n}\n","import type { ComponentProps } from 'react';\nimport { Button, Form, Space, Tooltip, Typography, useFormApi } from \"@/ui\";\nimport { Eye, EyeOff, PencilLine, Undo2 } from 'lucide-react';\nimport type { SensitiveFormFieldsControl } from \"@fudanda/react-core/hooks/useSensitiveFormFields\";\nimport { EMPTY_PLACEHOLDER } from \"@/utils/table-columns\";\nimport { useRevealedValue } from \"@fudanda/react-core/components/sensitive/useRevealedValue\";\ntype FormInputProps = ComponentProps<typeof Form.Input>;\nexport interface SensitiveFormInputProps extends Omit<FormInputProps, 'field' | 'label'> {\n /** `useSensitiveFormFields()` 的返回值 */\n control: SensitiveFormFieldsControl<{\n id: number;\n }>;\n field: string;\n label: string;\n}\n/**\n * 编辑表单里的敏感字段输入框。\n *\n * - 值对当前用户是掩码时默认**锁定**:展示掩码 + 「查看明文」(需权限,逐次审计)+ 「修改」\n * - 点「修改」后变成普通输入框(起始为空,若已查看明文则带入明文),可「取消修改」恢复锁定\n * - 新增、或用户本就能看到明文时,与普通 `Form.Input` 行为一致\n */\nexport function SensitiveFormInput({ control, field, label, ...inputProps }: SensitiveFormInputProps) {\n const formApi = useFormApi();\n const recordId = control.record?.id ?? 0;\n const reveal = useRevealedValue({ entity: control.entity, id: recordId, field });\n const maskedValue = (control.record as Record<string, unknown> | null)?.[field];\n const maskedText = typeof maskedValue === 'string' && maskedValue ? maskedValue : EMPTY_PLACEHOLDER;\n if (control.isLocked(field)) {\n const text = reveal.revealed ?? maskedText;\n return (<Form.Slot label={label}>\n <Space spacing={4} wrap className=\"sensitive-form-locked\">\n <Typography.Text className=\"sensitive-form-locked__value\">{text}</Typography.Text>\n {reveal.canReveal && (reveal.revealed === null ? (<Tooltip content=\"查看明文(记录审计)\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Eye size={14}/>} loading={reveal.revealing} aria-label=\"查看明文\" onClick={() => void reveal.show()}/>\n </Tooltip>) : (<Tooltip content=\"收起明文\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<EyeOff size={14}/>} aria-label=\"收起明文\" onClick={reveal.hide}/>\n </Tooltip>))}\n <Button size=\"small\" theme=\"borderless\" icon={<PencilLine size={14}/>} disabled={inputProps.disabled} onClick={() => {\n control.unlock(field);\n formApi.setValue(field, reveal.revealed ?? '');\n }}>\n 修改\n </Button>\n </Space>\n </Form.Slot>);\n }\n const unlocked = control.isUnlocked(field);\n return (<Form.Input {...inputProps} field={field} label={label} extraText={unlocked ? (<Space spacing={4}>\n <Typography.Text type=\"tertiary\" size=\"small\">留空则保持原值不变</Typography.Text>\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Undo2 size={12}/>} onClick={() => { control.relock(field); formApi.setValue(field, maskedValue); }}>取消修改</Button>\n </Space>) : inputProps.extraText}/>);\n}\n","import { useRef, useState } from 'react';\nimport { Button, Form, Space, Toast, Typography } from \"@/ui\";\nimport type { FormApi } from \"@/ui\";\nimport type { BodyOf } from '@fudanda/react-core/lib/contract-query';\nimport { type User } from '@fudanda/shared/identity';\nimport { identityDirectoryContract } from '@fudanda/react-core/lib/native-operations';\nimport { AppModal } from \"@/components/AppModal\";\nimport DateTimeText from \"@/components/DateTimeText\";\nimport { FormPasswordInput } from \"@/components/PasswordInput\";\nimport { SensitiveFormInput } from \"@/components/sensitive/SensitiveFormInput\";\nimport { useSensitiveFormFields } from \"@fudanda/react-core/hooks/useSensitiveFormFields\";\nimport { useDirectoryCreate, useDirectoryUpdate, useDirectorySync, useDirectorySyncStatus, useDirectoryProvision } from \"@fudanda/react-core/hooks/queries/identity-directory\";\nexport function DirectorySyncControl({ administrator }: {\n administrator: boolean;\n}) {\n const status = useDirectorySyncStatus(administrator);\n const sync = useDirectorySync();\n if (!administrator)\n return null;\n return <Space wrap>\n <Button loading={sync.isPending || status.data?.running} disabled={!status.data || status.data.running} onClick={() => { void sync.mutateAsync({}).catch(() => { }); }}>同步统一账户</Button>\n <Typography.Text type=\"tertiary\">最近成功同步:{status.data?.lastSuccessAt ? <DateTimeText value={status.data.lastSuccessAt} mode=\"absolute\"/> : '尚未完成'}</Typography.Text>\n {(status.isError || status.data?.error) && <Typography.Text type=\"danger\">{status.data?.error || '无法读取同步状态'}</Typography.Text>}\n </Space>;\n}\nconst directorySensitiveFields = ['email', 'phone'] as const;\nexport function DirectoryAccountModal({ user, onClose }: {\n user?: User;\n onClose: () => void;\n}) {\n const sensitive = useSensitiveFormFields({ entity: 'User', fields: directorySensitiveFields, record: user ?? null });\n const create = useDirectoryCreate();\n const update = useDirectoryUpdate();\n const form = useRef<FormApi | null>(null);\n const [requestId] = useState(() => crypto.randomUUID());\n const [uncertain, setUncertain] = useState(false);\n const [error, setError] = useState('');\n const provision = useDirectoryProvision(requestId, uncertain);\n const submit = async () => {\n if (!form.current || uncertain)\n return;\n let input: BodyOf<typeof identityDirectoryContract.create> | undefined;\n try {\n const values: unknown = await form.current.validate();\n if (user) {\n const body = identityDirectoryContract.update.input.shape.body.parse(sensitive.strip(values as Record<string, unknown>));\n await update.mutateAsync({ params: { id: user.id }, body });\n }\n else {\n const profile = values as Partial<BodyOf<typeof identityDirectoryContract.create>>;\n input = identityDirectoryContract.create.input.shape.body.parse({ ...profile, requestId, displayName: profile.displayName ?? '', email: profile.email ?? '', phone: profile.phone ?? '' });\n await create.mutateAsync({ body: input });\n }\n Toast.success(user ? '统一资料已更新' : '统一账户已创建,请在本应用分配权限');\n onClose();\n }\n catch (cause) {\n if (input)\n setUncertain(true);\n setError(cause instanceof Error ? cause.message : String(cause));\n }\n finally {\n form.current?.setValue('initialPassword', '');\n if (input)\n input.initialPassword = '';\n }\n };\n // A failed remote creation switches to reconciliation instead of another save.\n // This composite flow keeps its own form and query-result action.\n return <AppModal title={user ? '统一账户资料' : '创建统一账户'} visible onCancel={onClose} onOk={() => { void submit(); }} confirmLoading={create.isPending || update.isPending} okButtonProps={{ disabled: uncertain }}>\n <Form getFormApi={(value) => { form.current = value; }} initValues={{ displayName: user?.externalDisplayName || user?.nickname || '', email: user?.email || '', phone: user?.phone || '' }}>\n {!user && <Form.Input field=\"username\" label=\"统一用户名\" rules={[{ required: true }]}/>}\n <Form.Input field=\"displayName\" label=\"显示名\"/>\n <SensitiveFormInput control={sensitive} field=\"email\" label=\"邮箱\"/>\n <SensitiveFormInput control={sensitive} field=\"phone\" label=\"手机\"/>\n {!user && <FormPasswordInput field=\"initialPassword\" label=\"初始密码\" autoComplete=\"new-password\" rules={[{ required: true }]}/>}\n </Form>\n <p>角色、部门和本应用停用状态在“本应用权限”中设置。密码后续修改和 MFA 由 Casdoor 管理。</p>\n {error && <p role=\"alert\">{error}</p>}\n {uncertain && <Button loading={provision.isFetching} onClick={() => {\n void provision.refetch().then(({ data }) => {\n if (data?.status === 'complete') {\n Toast.success('开户已确认,请刷新用户列表');\n onClose();\n }\n else\n setError('开户结果尚未确认,请稍后再次查询。不会重新发送初始密码。');\n });\n }}>查询开户结果</Button>}\n </AppModal>;\n}\n","/**\n * 用户菜单权限弹窗\n *\n * Tabs:\n * 1. 直接授权 — 可编辑,显示用户直接授权的菜单\n * 2. 最终有效权限 — 只读,显示角色继承 ∪ 用户组继承 ∪ 直接授权,并用 Tag 标注来源\n */\nimport { useState, useEffect } from 'react';\nimport { Tabs, TabPane, Toast, Tag, Space } from \"@/ui\";\nimport AppModal from \"@/components/AppModal\";\nimport { MenuPermissionPanel } from \"@/components/permissions/MenuPermissionPanel\";\nimport { useMenuTree } from \"@fudanda/react-core/hooks/queries/menus\";\nimport ModalFooter from \"@/components/ModalFooter\";\nimport { useSaveUserMenus, useUserEffectivePermissions } from \"@fudanda/react-core/hooks/queries/users\";\ntype Props = Readonly<{\n userId: number;\n userName: string;\n visible: boolean;\n onClose: () => void;\n}>;\nexport function UserMenuPermissionModal({ userId, userName, visible, onClose }: Props) {\n const [directMenuIds, setDirectMenuIds] = useState<number[]>([]);\n const [roleMenuIds, setRoleMenuIds] = useState<number[]>([]);\n const [groupMenuIds, setGroupMenuIds] = useState<number[]>([]);\n const [groups, setGroups] = useState<Array<{\n id: number;\n name: string;\n }>>([]);\n const [effectiveMenuIds, setEffectiveMenuIds] = useState<number[]>([]);\n const [activeTab, setActiveTab] = useState('direct');\n const menuTreeQuery = useMenuTree({ enabled: visible });\n const permissionsQuery = useUserEffectivePermissions(userId, visible);\n const saveMenusMutation = useSaveUserMenus();\n useEffect(() => {\n if (!visible)\n return;\n setActiveTab('direct');\n }, [visible, userId]);\n useEffect(() => {\n if (!visible || !permissionsQuery.data)\n return;\n setDirectMenuIds(permissionsQuery.data.directMenuIds);\n setRoleMenuIds(permissionsQuery.data.roleMenuIds);\n setGroupMenuIds(permissionsQuery.data.groupMenuIds ?? []);\n setGroups(permissionsQuery.data.groups ?? []);\n setEffectiveMenuIds(permissionsQuery.data.effectiveMenuIds);\n }, [visible, permissionsQuery.data]);\n const handleSave = async () => {\n await saveMenusMutation.mutateAsync({ params: { id: userId }, body: { menuIds: directMenuIds } });\n Toast.success('菜单权限已更新');\n const effectiveSet = new Set([...directMenuIds, ...roleMenuIds, ...groupMenuIds]);\n setEffectiveMenuIds([...effectiveSet]);\n onClose();\n };\n /** 构造有效权限 Tab 里的具体来源 Tag(同一菜单可能有多个来源) */\n function buildLabelSuffix(): Record<string, React.ReactNode> {\n const menuSources = permissionsQuery.data?.menuSources ?? {};\n const result: Record<string, React.ReactNode> = {};\n for (const id of effectiveMenuIds) {\n const sources = menuSources[String(id)] ?? [];\n const tags = sources.map((source) => (<Tag key={source} size=\"small\" color={source === '用户直接授权' ? 'green' : source.includes('用户组:') ? 'orange' : 'blue'}>\n {source}\n </Tag>));\n result[String(id)] = <Space spacing={4} style={{ marginLeft: 4 }}>{tags}</Space>;\n }\n return result;\n }\n return (<AppModal title={`菜单权限 — ${userName}`} visible={visible} onCancel={onClose} footer={activeTab === 'effective' ? null : (<ModalFooter onCancel={onClose} onOk={handleSave} okText=\"保存\" loading={saveMenusMutation.isPending} disabled={!permissionsQuery.isSuccess}/>)} width={640}>\n <Tabs collapsible=\"auto\" activeKey={activeTab} onChange={setActiveTab}>\n <TabPane tab=\"直接授权\" itemKey=\"direct\">\n <MenuPermissionPanel allMenus={menuTreeQuery.data ?? []} checkedMenuIds={directMenuIds} onChange={setDirectMenuIds} loading={menuTreeQuery.isFetching || permissionsQuery.isFetching}/>\n </TabPane>\n <TabPane tab=\"最终有效权限\" itemKey=\"effective\">\n <div style={{ marginBottom: 8, fontSize: 12, color: 'var(--arc-antd-color-text-2)' }}>\n <div>最终权限 = 角色权限 ∪ 用户组继承 ∪ 用户直接授权,仅供预览</div>\n <div style={{ display: 'grid', gridTemplateColumns: '88px minmax(0, 1fr)', columnGap: 8, rowGap: 6, alignItems: 'start', marginTop: 6 }}>\n <span>权限来源:</span>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>\n {[...new Set(Object.values(permissionsQuery.data?.menuSources ?? {}).flat())].map((source) => (<Tag key={source} size=\"small\" color={source === '用户直接授权' ? 'green' : source.includes('用户组:') ? 'orange' : 'blue'}>\n {source}\n </Tag>))}\n </div>\n {groups.length > 0 && (<>\n <span>继承自用户组:</span>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>\n {groups.map((g) => <Tag key={g.id} size=\"small\" color=\"orange\">{g.name}</Tag>)}\n </div>\n </>)}\n </div>\n </div>\n <MenuPermissionPanel allMenus={menuTreeQuery.data ?? []} checkedMenuIds={effectiveMenuIds} loading={menuTreeQuery.isFetching || permissionsQuery.isFetching} readonly labelSuffix={buildLabelSuffix()}/>\n </TabPane>\n </Tabs>\n </AppModal>);\n}\n","/**\n * 用户数据权限弹窗\n *\n * 布局:\n * - 角色数据权限(只读):显示角色最宽松数据权限及自定义部门列表\n * - 用户组继承权限(只读):显示用户组绑定角色继承的最宽松数据权限\n * - 用户直接数据权限(可编辑):可选「跟随角色」(null) 或单独指定\n * - 最终有效权限(只读):取三者中最宽松的\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport { Typography, Divider, Toast, Tag } from \"@/ui\";\nimport AppModal from \"@/components/AppModal\";\nimport { DATA_SCOPES, mostPermissiveDataScope, type Department } from '@fudanda/shared/identity';\nimport { buildTree, enumValueOf } from '@fudanda/shared/core';\nimport type { ApiDepartment } from '@fudanda/shared/api/departments';\nimport { DataScopePanel, DATA_SCOPE_OPTIONS } from \"@/components/permissions/DataScopePanel\";\nimport { useSaveUserDataPermission, useUserDataPermission } from \"@fudanda/react-core/hooks/queries/users\";\nconst { Text } = Typography;\ntype Props = Readonly<{\n userId: number;\n userName: string;\n visible: boolean;\n deptTree: ApiDepartment[];\n onClose: () => void;\n}>;\nfunction scopeLabel(scope: string | null): string {\n if (scope === null)\n return '未设置';\n return DATA_SCOPE_OPTIONS.find((o) => o.value === scope)?.label ?? scope;\n}\nfunction getMostPermissive(scopes: Array<string | null>): string {\n return mostPermissiveDataScope(scopes) ?? 'self';\n}\nexport function UserDataScopeModal({ userId, userName, visible, deptTree, onClose }: Props) {\n const departmentTree = useMemo(() => buildTree<Department>(deptTree.map(item => ({ ...item, children: [] })), { keepEmptyChildren: true }), [deptTree]);\n const [userDataScope, setUserDataScope] = useState<string | null>(null);\n const [deptScopeIds, setDeptScopeIds] = useState<number[]>([]);\n const [roleDataScope, setRoleDataScope] = useState<string | null>(null);\n const [roleDeptScopeIds, setRoleDeptScopeIds] = useState<number[]>([]);\n const [groupDataScope, setGroupDataScope] = useState<string | null>(null);\n const [groupDeptScopeIds, setGroupDeptScopeIds] = useState<number[]>([]);\n const [groups, setGroups] = useState<Array<{\n id: number;\n name: string;\n }>>([]);\n const permissionQuery = useUserDataPermission(userId, visible);\n const saveMutation = useSaveUserDataPermission();\n useEffect(() => {\n if (!visible || !permissionQuery.data)\n return;\n setUserDataScope(permissionQuery.data.userDataScope ?? null);\n setDeptScopeIds(permissionQuery.data.deptScopeIds);\n setRoleDataScope(permissionQuery.data.roleDataScope ?? null);\n setRoleDeptScopeIds(permissionQuery.data.roleDeptScopeIds);\n setGroupDataScope(permissionQuery.data.groupDataScope ?? null);\n setGroupDeptScopeIds(permissionQuery.data.groupDeptScopeIds ?? []);\n setGroups(permissionQuery.data.groups ?? []);\n }, [visible, permissionQuery.data]);\n const handleSave = async () => {\n await saveMutation.mutateAsync({\n params: { id: userId },\n body: {\n // 面板以宽 string 维护选中值,提交前收窄为数据范围枚举;未设置(跟随角色)在完整替换文档中省略\n dataScope: enumValueOf(DATA_SCOPES, userDataScope),\n deptScopeIds: userDataScope === 'custom' ? deptScopeIds : [],\n },\n });\n Toast.success('数据权限已更新');\n onClose();\n };\n const effectiveScope = getMostPermissive([userDataScope, roleDataScope, groupDataScope]);\n const effectiveDeptIds = effectiveScope === 'custom'\n ? [...new Set([...(userDataScope === 'custom' ? deptScopeIds : []), ...roleDeptScopeIds, ...groupDeptScopeIds])]\n : [];\n return (<AppModal title={`数据权限 — ${userName}`} visible={visible} onCancel={onClose} onOk={handleSave} okButtonProps={{ disabled: !permissionQuery.isSuccess }} confirmLoading={saveMutation.isPending} width={440}>\n {/* 角色数据权限(只读) */}\n <div style={{ marginBottom: 12 }}>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>角色数据权限(只读)</Text>\n <DataScopePanel dataScope={roleDataScope ?? 'self'} deptScopeIds={roleDeptScopeIds} deptTree={departmentTree} loading={permissionQuery.isFetching} readonly/>\n </div>\n\n {/* 用户组继承权限(只读,仅在有绑定角色的组时展示) */}\n {groups.length > 0 && (<>\n <Divider margin={12}/>\n <div style={{ marginBottom: 12 }}>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>\n 用户组继承权限(只读)\n {groups.map((g) => <Tag key={g.id} size=\"small\" color=\"orange\" style={{ marginLeft: 6 }}>{g.name}</Tag>)}\n </Text>\n <DataScopePanel dataScope={groupDataScope ?? 'self'} deptScopeIds={groupDeptScopeIds} deptTree={departmentTree} loading={permissionQuery.isFetching} readonly/>\n </div>\n </>)}\n\n <Divider margin={12}/>\n\n {/* 用户直接数据权限(可编辑) */}\n <div style={{ marginBottom: 12 }}>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>用户直接权限</Text>\n <DataScopePanel dataScope={userDataScope} deptScopeIds={deptScopeIds} deptTree={departmentTree} onScopeChange={setUserDataScope} onDeptIdsChange={setDeptScopeIds} loading={permissionQuery.isFetching} nullable/>\n </div>\n\n <Divider margin={12}/>\n\n {/* 最终有效权限(只读) */}\n <div>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>\n 最终有效权限:\n <Text type=\"secondary\" style={{ fontWeight: 'normal', marginLeft: 8 }}>\n {scopeLabel(effectiveScope)}\n </Text>\n </Text>\n <DataScopePanel dataScope={effectiveScope} deptScopeIds={effectiveDeptIds} deptTree={departmentTree} loading={permissionQuery.isFetching} readonly/>\n </div>\n </AppModal>);\n}\n","import { userKeys } from '@fudanda/react-core/hooks/queries/users';\nimport { Toast } from \"@/ui\";\nimport { AvatarSelectModal } from \"@/components/AvatarSelectModal\";\nimport { uploadAvatarBlobToFileCenter } from \"@fudanda/react-core/utils/avatar-upload\";\nimport { type User } from '@fudanda/shared/identity';\nimport { userContract } from '@fudanda/react-core/lib/native-operations';\nimport { api, useApiMutation } from \"@fudanda/react-core/lib/contract-query\";\nimport { confirmDelete } from \"@/utils/confirm\";\ninterface UserAvatarModalProps {\n readonly visible: boolean;\n readonly user: User;\n readonly onClose: () => void;\n readonly onUpdated: (user: User) => void;\n}\nexport function UserAvatarModal({ visible, user, onClose, onUpdated }: UserAvatarModalProps) {\n // 失败提示由调用处按场景给出,请求层静默;code !== 0 由 api() 抛 GoaError\n const updateAvatarMutation = useApiMutation(userContract.update, { requestOptions: { silent: true }, invalidate: qc => {\n void qc.invalidateQueries({ queryKey: userKeys.lists });\n void qc.invalidateQueries({ queryKey: userKeys.detail(user.id) });\n } });\n const updateAvatar = async (avatar: string | null) => {\n await updateAvatarMutation.mutateAsync({ params: { id: user.id }, body: avatar === null ? { clearFields: ['avatar'] } : { avatar } });\n return api(userContract.detail, { params: { id: user.id } });\n };\n async function handleSelect(url: string) {\n try {\n onUpdated(await updateAvatar(url));\n Toast.success('头像已更新');\n onClose();\n }\n catch (err) {\n Toast.error(err instanceof Error && err.message ? err.message : '头像更新失败');\n }\n }\n function handleRemoveAvatar() {\n confirmDelete({\n title: '确定要移除该用户头像吗?',\n content: '移除后将使用昵称缩写作为默认头像。',\n onOk: async () => {\n try {\n onUpdated(await updateAvatar(null));\n // eslint-disable-next-line no-restricted-syntax -- 头像弹窗使用静默请求并在本地 catch 展示失败\n Toast.success('头像已移除');\n onClose();\n }\n catch (err) {\n Toast.error(err instanceof Error && err.message ? err.message : '移除失败');\n }\n },\n });\n }\n return (<AvatarSelectModal visible={visible} currentAvatar={user.avatar} confirmLoading={updateAvatarMutation.isPending} uploadBlob={uploadAvatarBlobToFileCenter} onCancel={onClose} onSelect={(url) => void handleSelect(url)} onRemove={user.avatar ? handleRemoveAvatar : undefined}/>);\n}\n","/**\n * 用户管理 → 「登录与操作记录」抽屉:把某个用户的登录记录与操作记录并排在一个抽屉里两个 tab。\n *\n * 两个 tab 的内容就是个人中心那两个 tab 抽出来的 `UserLoginLogsPanel` / `UserOperationLogsPanel`,\n * 只把 scope 从「本人」换成「指定 userId」,筛选条、分页、表格(含各自的详情弹窗)与列设置全部复用。\n *\n * tab 只读用户有权限的那几个(登录日志 / 操作日志是两个独立权限码),未激活的 tab 不发请求。\n */\nimport { useEffect, useState } from 'react';\nimport { SideSheet, TabPane, Tabs } from \"@/ui\";\nimport { UserLoginLogsPanel, UserOperationLogsPanel } from \"@/components/logs/UserLogsPanels\";\ntype LogsTab = 'login' | 'operation';\ninterface UserLogsSheetProps {\n /** 目标用户 ID(列表行) */\n readonly userId: number;\n /** 目标用户展示名(昵称(用户名)),仅用于标题 */\n readonly userName: string;\n readonly visible: boolean;\n /** 是否有权限看该用户的登录记录(system:log:login) */\n readonly canViewLoginLogs: boolean;\n /** 是否有权限看该用户的操作记录(system:log:operation) */\n readonly canViewOperationLogs: boolean;\n readonly onClose: () => void;\n}\nexport function UserLogsSheet({ userId, userName, visible, canViewLoginLogs, canViewOperationLogs, onClose, }: UserLogsSheetProps) {\n const firstTab: LogsTab = canViewLoginLogs ? 'login' : 'operation';\n const [activeTab, setActiveTab] = useState<LogsTab>(firstTab);\n // 关闭后回到首个可用 tab:下次打开总是从「登录记录」开始,不会停在上次看过的那一屏\n useEffect(() => {\n if (!visible)\n setActiveTab(firstTab);\n }, [visible, firstTab]);\n return (<SideSheet title={`登录与操作记录 · ${userName}`} visible={visible} onCancel={onClose} width={1180} bodyStyle={{ padding: '0 16px 16px' }} closeOnEsc>\n <Tabs collapsible=\"auto\" type=\"line\" activeKey={activeTab} onChange={(key) => setActiveTab(key as LogsTab)}>\n {canViewLoginLogs && (<TabPane tab=\"登录记录\" itemKey=\"login\">\n <UserLoginLogsPanel scope={{ kind: 'user', userId }} enabled={visible && activeTab === 'login'} columnSettingsKey=\"user-logs-login-logs\"/>\n </TabPane>)}\n {canViewOperationLogs && (<TabPane tab=\"操作记录\" itemKey=\"operation\">\n <UserOperationLogsPanel scope={{ kind: 'user', userId }} enabled={visible && activeTab === 'operation'} columnSettingsKey=\"user-logs-operation-logs\"/>\n </TabPane>)}\n </Tabs>\n </SideSheet>);\n}\nexport default UserLogsSheet;\n","import { useRef, useState } from 'react';\nimport { Button, Dropdown, Modal, Select, Table, Tag, Typography, Toast } from \"@/ui\";\nimport { ChevronDown, Upload } from 'lucide-react';\nimport { transferUsers, transferTemplate, type ApiTransferImportResult as SyncImportResult } from '@fudanda/shared/api/transfers';\nimport { goTransport } from \"@fudanda/react-core/lib/go-transport\";\nimport { downloadBlob } from \"@fudanda/react-core/utils/download\";\ninterface Props {\n entity: string;\n title: string;\n label?: string;\n beforeSubmit?: () => boolean;\n onFinished?: () => void;\n}\nexport default function FoundationImportButton({ entity, title, label = '导入', beforeSubmit, onFinished }: Readonly<Props>) {\n const input = useRef<HTMLInputElement>(null);\n const dryRun = useRef(false);\n const [pending, setPending] = useState(false);\n const [duplicate, setDuplicate] = useState<'error' | 'skip' | 'update'>('error');\n const [result, setResult] = useState<SyncImportResult | null>(null);\n const [visible, setVisible] = useState(false);\n const pick = (dry: boolean) => {\n if (beforeSubmit && !beforeSubmit())\n return;\n dryRun.current = dry;\n input.current?.click();\n };\n const upload = async (file: File) => {\n setVisible(true);\n setPending(true);\n setResult(null);\n try {\n const response = await goTransport.upload(transferUsers, { body: { file, dryRun: dryRun.current ? 'true' : 'false', duplicate } });\n setResult(response);\n if (!dryRun.current)\n onFinished?.();\n }\n catch (error) {\n Toast.error(error instanceof Error ? error.message : '导入失败');\n setVisible(false);\n }\n finally {\n setPending(false);\n }\n };\n const template = async () => { const response = await goTransport.download(transferTemplate); const blob = await response.blob(); downloadBlob(blob, `${title}导入模板.xlsx`); };\n if (entity !== 'identity.users')\n return null;\n return <>\n <input ref={input} type=\"file\" accept=\".xlsx\" style={{ display: 'none' }} onChange={event => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (file)\n void upload(file);\n }}/>\n <Dropdown trigger=\"click\" position=\"bottomLeft\" clickToHide render={<Dropdown.Menu>\n <Dropdown.Item onClick={() => pick(false)}>上传文件导入</Dropdown.Item>\n <Dropdown.Item onClick={() => pick(true)}>预检文件(仅校验不落库)</Dropdown.Item>\n <Dropdown.Item onClick={() => void template()}>下载导入模板</Dropdown.Item>\n <Dropdown.Item><Select aria-label=\"重复数据处理\" value={duplicate} onChange={value => setDuplicate(value as typeof duplicate)} optionList={[{ value: 'error', label: '重复时报错' }, { value: 'skip', label: '跳过重复用户' }, { value: 'update', label: '更新已有用户' }]}/></Dropdown.Item>\n </Dropdown.Menu>}><Button icon={<Upload size={14}/>} loading={pending}>{label} <ChevronDown size={12}/></Button></Dropdown>\n <Modal title={`${title}导入`} visible={visible} maskClosable={false} closable={!pending} onCancel={() => setVisible(false)} width={640} footer={<Button type=\"primary\" disabled={pending} onClick={() => setVisible(false)}>完成</Button>}>\n {pending ? <Typography.Text>正在同步处理,请等待当前请求完成。</Typography.Text> : result && <>\n {result.dryRun && <Typography.Text type=\"warning\">预检模式:仅校验数据,不写入任何记录。</Typography.Text>}\n <Typography.Paragraph>共 {result.total} 行,成功 {result.success},失败 {result.failed},跳过 {result.skipped}</Typography.Paragraph>\n <Table rowKey=\"row\" size=\"small\" dataSource={result.rows} columns={[{ title: '行', dataIndex: 'row', width: 70 }, { title: '内容', dataIndex: 'label' }, { title: '结果', dataIndex: 'status', width: 80, render: (status: string) => <Tag color={status === 'failed' ? 'red' : status === 'success' ? 'green' : 'grey'}>{status === 'failed' ? '失败' : status === 'success' ? '成功' : '跳过'}</Tag> }, { title: '说明', dataIndex: 'message' }]} pagination={{ pageSize: 8 }}/>\n </>}\n </Modal>\n </>;\n}\n","import type { ComponentProps } from 'react';\nimport FoundationImportButton from './FoundationImportButton';\n\nexport function ImportButton(props: ComponentProps<typeof FoundationImportButton>) {\n return <FoundationImportButton {...props}/>;\n}\nexport default ImportButton;\n","import { Button, Tooltip, Typography } from \"@/ui\";\nimport { Copy, Eye, EyeOff } from 'lucide-react';\nimport { copyTextWithToast } from \"@/utils/clipboard\";\nimport { EMPTY_PLACEHOLDER } from \"@/utils/table-columns\";\nimport { useRevealedValue } from \"@fudanda/react-core/components/sensitive/useRevealedValue\";\nexport interface SensitiveTextProps {\n /** 契约实体名(schema meta.id),如 `User` */\n entity: string;\n /** 记录主键 */\n id: number;\n /** 实体内字段名,如 `phone` */\n field: string;\n /** 服务端返回的值(对当前用户可能已是掩码) */\n value: string | null | undefined;\n}\n/**\n * 表格 / 详情里的敏感字段文本:原样展示服务端给的值(明文或掩码);\n * 值被打码且用户拥有「按需查看明文」权限时附带查看按钮,明文展示 30 秒后自动恢复掩码。\n */\nexport function SensitiveText({ entity, id, field, value }: SensitiveTextProps) {\n const state = useRevealedValue({ entity, id, field });\n if (value == null || value === '')\n return <Typography.Text type=\"quaternary\">{EMPTY_PLACEHOLDER}</Typography.Text>;\n const showToggle = state.isMasked && state.canReveal;\n const text = state.revealed ?? value;\n return (<span className=\"sensitive-text\">\n <Typography.Text ellipsis={{ showTooltip: true }} style={{ minWidth: 0 }}>{text}</Typography.Text>\n {showToggle && (state.revealed === null ? (<Tooltip content=\"查看明文(记录审计)\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Eye size={14}/>} loading={state.revealing} aria-label=\"查看明文\" onClick={() => void state.show()}/>\n </Tooltip>) : (<>\n <Tooltip content=\"复制明文\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Copy size={14}/>} aria-label=\"复制明文\" onClick={() => void copyTextWithToast(state.revealed ?? '')}/>\n </Tooltip>\n <Tooltip content=\"收起\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<EyeOff size={14}/>} aria-label=\"收起明文\" onClick={state.hide}/>\n </Tooltip>\n </>))}\n </span>);\n}\n","import { DirectoryAccountModal, DirectorySyncControl } from \"@/pages/users/IdentityDirectoryControls\";\nimport { useIdentityCapabilities } from \"@fudanda/react-core/hooks/queries/auth-public\";\nimport { FormPasswordInput } from \"@/components/PasswordInput\";\nimport EntityRelationButton from \"@/components/entity-relations/EntityRelationButton\";\nimport { useState, useEffect, useCallback, useMemo, useRef } from 'react';\nimport { Button, Select, Space, Form, Toast, Tag, Row, Col, Tree } from \"@/ui\";\nimport type { FormApi } from \"@/ui\";\nimport { ChevronsUpDown, ChevronsDownUp, Building2, KeyRound } from 'lucide-react';\nimport type { CreateUserInput, User, Role, Department, Position } from '@fudanda/shared/identity';\nimport { USER_STATUSES, enumValueOf } from '@fudanda/shared/core';\nimport type { BodyOf } from '@fudanda/react-core/lib/contract-query';\nimport { userContract, departmentContract, positionContract, roleContract } from '@fudanda/react-core/lib/native-operations';\nimport { UserAvatar } from \"@/components/UserAvatar\";\nimport { formatDateForApi, formatDateTimeRangeForApi } from \"@fudanda/react-core/utils/date\";\nimport { formatPasswordPolicyHint, type PasswordRules as PasswordPolicy } from '@fudanda/shared/settings';\nimport { PasswordStrengthMeter } from \"@/components/PasswordStrengthMeter\";\nimport DictTag from \"@/components/DictTag\";\nimport { useDictItems } from \"@fudanda/react-core/hooks/useDictItems\";\nimport type { ColumnProps } from \"@/ui\";\nimport type { TreeNodeData } from \"@/ui\";\nimport { usePermission } from \"@fudanda/react-core/hooks/usePermission\";\nimport { isAllKeysExpanded } from \"@fudanda/react-core/hooks/useTreeExpansion\";\nimport { useAuth } from \"@fudanda/react-core/hooks/useAuth\";\nimport { AppModal } from \"@/components/AppModal\";\nimport ConfigurableTable from \"@/components/ConfigurableTable\";\nimport { MasterDetailLayout } from \"@/components/MasterDetailLayout\";\nimport { createOperationColumn } from \"@/components/ResponsiveTableActions\";\nimport \"@/pages/users/UsersPage.css\";\nimport { createdAtColumn, dateTimeColumn, overflowTagColumn, renderEllipsis } from \"@/utils/table-columns\";\nimport { UserMenuPermissionModal } from \"@/pages/users/UserMenuPermissionModal\";\nimport { UserDataScopeModal } from \"@/pages/users/UserDataScopeModal\";\nimport { UserAvatarModal } from \"@/pages/users/UserAvatarModal\";\nimport { UserLogsSheet } from \"@/pages/users/UserLogsSheet\";\nimport ExportButton from \"@/components/ExportButton\";\nimport ImportButton from \"@/components/ImportButton\";\nimport { useAllRoles } from \"@fudanda/react-core/hooks/queries/roles\";\nimport { departmentsToTreeData, useFlatDepartments } from \"@fudanda/react-core/hooks/queries/departments\";\nimport { useAllPositions } from \"@fudanda/react-core/hooks/queries/positions\";\nimport { useMySettings } from \"@fudanda/react-core/hooks/queries/settings\";\nimport { useListSearch } from \"@fudanda/react-core/hooks/useListSearch\";\nimport { useListDeepLink } from \"@fudanda/react-core/hooks/useListDeepLink\";\nimport { useAssignUserRoles, useBatchUserPassword, useBatchUserStatus, useDeleteUsers, useKickUserSessions, useResetUserPassword, useSaveUser, useUnlockUser, useUserDetail, useUserEffectivePermissions, useUserList, userKeys } from \"@fudanda/react-core/hooks/queries/users\";\nimport { BatchDeleteButton, BatchStatusButtons, CreateButton } from \"@/components/toolbar-controls\";\nimport { DateRangeFilter, KeywordInput, StatusSelect } from \"@/components/search-filters\";\nimport { confirmDanger } from \"@/utils/confirm\";\n\nimport { batchStatusHandler, confirmAndDelete, deleteAction, buildTableSearch, listTableProps, useStatusToggle } from \"@/components/list-page/index\";\nimport { useEditModal, formSaveMutation } from \"@/hooks/useEditModal\";\nimport { useSensitiveFormFields } from \"@fudanda/react-core/hooks/useSensitiveFormFields\";\nimport { isMaskedFieldValue } from '@fudanda/react-core/hooks/queries/data-mask';\nimport { SensitiveFormInput, SensitiveText } from \"@/components/sensitive/index\";\nimport { abortSubmit } from \"@fudanda/react-core/lib/abort-submit\";\nimport { useFilterQuery } from \"@fudanda/react-core/hooks/useFilterQuery\";\nimport { EditFormModal } from \"@/components/EditFormModal\";\nimport { useStandardWebMcpCrudAdapter } from '@/webmcp-crud';\ninterface SearchParams {\n keyword: string;\n phone: string;\n status?: string;\n timeRange: [\n Date,\n Date\n ] | null;\n /** 部门树选中的部门;undefined = 全部部门 */\n departmentId?: number;\n}\n/** 用户表单值:记录里的 null 在提交时归一为未填 / null,与创建入参对齐 */\ninterface UserFormValues extends Partial<Omit<CreateUserInput, 'email' | 'phone' | 'gender' | 'birthDate'>> {\n email?: string | null;\n phone?: string | null;\n gender?: string | null;\n birthDate?: Date | string | null;\n}\ntype UserSavePayload = Partial<BodyOf<typeof userContract.create>> & BodyOf<typeof userContract.update>;\ninterface ResetPasswordFormValues {\n password: string;\n confirmPassword: string;\n}\nconst defaultSearchParams: SearchParams = { keyword: '', phone: '', status: undefined, timeRange: null, departmentId: undefined };\nconst ALL_DEPARTMENTS_KEY = 'all-departments';\nconst EMPTY_USERS: User[] = [];\nconst EMPTY_ROLES: Role[] = [];\nconst EMPTY_DEPARTMENTS: Department[] = [];\nconst EMPTY_POSITIONS: Position[] = [];\nfunction isAdminUser(user: Pick<User, 'username'>) {\n return user.username.trim().toLowerCase() === 'admin';\n}\nexport default function UsersPage() {\n const { hasPermission } = usePermission();\n const { updateUser, user: currentUser } = useAuth();\n const { page, pageSize, buildPagination, draftParams, bind, bindKeyword, submittedParams, handleSearch, applySearch, handleReset } = useListSearch<SearchParams>({ defaults: defaultSearchParams, listKey: userKeys.lists });\n useListDeepLink(['keyword'], (params) => applySearch({ ...defaultSearchParams, keyword: params.keyword ?? '' }));\n const [batchPasswordModalVisible, setBatchPasswordModalVisible] = useState(false);\n // useEditModal 例外:批量重置密码对话框(针对选中用户的动作表单,非新增 / 编辑)\n const batchPasswordFormApi = useRef<FormApi | null>(null);\n const [menuPermUser, setMenuPermUser] = useState<User | null>(null);\n const [menuPermVisible, setMenuPermVisible] = useState(false);\n const [dataPermUser, setDataPermUser] = useState<User | null>(null);\n const [dataPermVisible, setDataPermVisible] = useState(false);\n const [roleAssignUser, setRoleAssignUser] = useState<User | null>(null);\n const [roleAssignVisible, setRoleAssignVisible] = useState(false);\n const [roleAssignIds, setRoleAssignIds] = useState<number[]>([]);\n const [avatarUser, setAvatarUser] = useState<User | null>(null);\n const [avatarModalVisible, setAvatarModalVisible] = useState(false);\n const [logsUser, setLogsUser] = useState<User | null>(null);\n const [logsVisible, setLogsVisible] = useState(false);\n const identityQuery = useIdentityCapabilities();\n const externalIdentity = identityQuery.data?.externalLogin === true;\n const [directoryEditor, setDirectoryEditor] = useState<User | true | null>(null);\n const [createPwdVal, setCreatePwdVal] = useState('');\n const [editPwdVal, setEditPwdVal] = useState('');\n const [batchPwdVal, setBatchPwdVal] = useState('');\n const { items: statusItems } = useDictItems('common_status');\n const { options: genderOptions } = useDictItems('user_gender');\n const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);\n const [deptTreeExpandedKeys, setDeptTreeExpandedKeys] = useState<string[]>([]);\n const canReadRoles = hasPermission('system:role:list');\n const canReadDepartments = hasPermission('system:department:list');\n const canReadPositions = hasPermission('system:position:list');\n const allRolesQuery = useAllRoles({ enabled: canReadRoles });\n const allDepartmentsQuery = useFlatDepartments({ enabled: canReadDepartments });\n const allPositionsQuery = useAllPositions({ enabled: canReadPositions });\n const mySettingsQuery = useMySettings();\n const allRoles = allRolesQuery.data ?? EMPTY_ROLES;\n const allDepartments = allDepartmentsQuery.data ?? EMPTY_DEPARTMENTS;\n const allPositions = allPositionsQuery.data ?? EMPTY_POSITIONS;\n const passwordPolicy: PasswordPolicy | null = mySettingsQuery.data?.identitySecurity.password ?? null;\n // 已提交筛选 → 契约查询参数:列表与导出共用同一份映射\n const filterQuery = useFilterQuery({\n keyword: submittedParams.keyword,\n phone: submittedParams.phone,\n departmentId: submittedParams.departmentId,\n status: enumValueOf(USER_STATUSES, submittedParams.status),\n ...formatDateTimeRangeForApi(submittedParams.timeRange),\n });\n const listQuery = useUserList({ page, pageSize, ...filterQuery });\n const userList = listQuery.data?.list ?? EMPTY_USERS;\n const saveMutation = useSaveUser();\n const resetPasswordMutation = useResetUserPassword();\n const deleteMutation = useDeleteUsers();\n const unlockMutation = useUnlockUser();\n const batchStatusMutation = useBatchUserStatus();\n const toggleStatusMutation = useBatchUserStatus();\n const batchPasswordMutation = useBatchUserPassword();\n const assignRolesMutation = useAssignUserRoles();\n const roleEffectivePermissionsQuery = useUserEffectivePermissions(roleAssignUser?.id, roleAssignVisible);\n const kickSessionsMutation = useKickUserSessions();\n // 敏感字段(手机号 / 邮箱)对非豁免用户是掩码:编辑时锁定,提交前剔除未修改的锁定字段\n const sensitiveFieldsRef = useRef<ReturnType<typeof useSensitiveFormFields<User>> | null>(null);\n const modal = useEditModal<User, UserFormValues, UserSavePayload>({\n entityName: '用户',\n save: formSaveMutation(saveMutation, { create: userContract.create.input.shape.body, update: userContract.update.input.shape.body }),\n useDetail: useUserDetail,\n defaults: {\n positionIds: [],\n roleIds: [],\n status: 'enabled',\n },\n toValues: (user) => ({\n username: user.username,\n nickname: user.nickname,\n email: user.email ?? undefined,\n phone: user.phone ?? undefined,\n gender: user.gender ?? undefined,\n birthDate: user.birthDate ?? undefined,\n departmentId: user.departmentId ?? undefined,\n positionIds: user.positionIds ?? user.positions?.map((item) => item.id) ?? [],\n roleIds: user.roles.map((r) => r.id),\n status: user.status,\n }),\n beforeSave: (rawValues, { editing }) => {\n const control = sensitiveFieldsRef.current;\n const values = (control ? control.strip(rawValues as unknown as Record<string, unknown>) : rawValues) as UserFormValues;\n const clearFields: NonNullable<BodyOf<typeof userContract.update>['clearFields']> = [];\n if (editing) {\n if (values.departmentId == null) clearFields.push('departmentId');\n if ('email' in values && !values.email) clearFields.push('email');\n if ('phone' in values && !values.phone) clearFields.push('phone');\n if (!values.gender) clearFields.push('gender');\n if (!values.birthDate) clearFields.push('birthDate');\n }\n const payload: UserSavePayload = {\n username: values.username, nickname: values.nickname,\n email: values.email || undefined, phone: values.phone || undefined,\n departmentId: values.departmentId ?? undefined,\n gender: values.gender || undefined,\n birthDate: values.birthDate ? formatDateForApi(values.birthDate) : undefined,\n positionIds: values.positionIds ?? [], roleIds: values.roleIds ?? [], status: values.status,\n ...(editing ? { clearFields } : { password: values.password }),\n };\n // 被剔除的锁定字段不出现在载荷里(服务端只更新提交了的字段)\n if (!('email' in values))\n delete payload.email;\n if (!('phone' in values))\n delete payload.phone;\n if (editing && isAdminUser(editing) && values.status === 'disabled') {\n Toast.warning('admin 账号不允许禁用');\n abortSubmit('admin_status_forbidden');\n }\n if (externalIdentity)\n return { departmentId: payload.departmentId, positionIds: payload.positionIds, roleIds: payload.roleIds, status: payload.status, clearFields: values.departmentId == null ? ['departmentId'] : [] };\n return payload;\n },\n labelWidth: 72,\n });\n const editingUser = modal.editing;\n useStandardWebMcpCrudAdapter({ resource: 'users', title: '用户', permission: 'system:user', hasPermission, modal,\n list: userContract.list, detail: userContract.detail, create: userContract.create.input.shape.body, update: userContract.update.input.shape.body,\n updateFields: ['nickname', 'email', 'phone', 'departmentId', 'positionIds', 'roleIds', 'gender', 'birthDate', 'status', 'clearFields'], updateClearFields: ['email', 'phone', 'departmentId', 'gender', 'birthDate'],\n fields: ['id', 'username', 'nickname', 'email', 'phone', 'gender', 'birthDate', 'departmentId', 'departmentName', 'status', 'createdAt', 'updatedAt'],\n filters: filterQuery, selectedIds: selectedRowKeys, canCreate: !externalIdentity, remove: id => deleteMutation.mutateAsync([id]), onDeleted: () => setSelectedRowKeys([]), busy: batchPasswordModalVisible || menuPermVisible || dataPermVisible || roleAssignVisible || avatarModalVisible || logsVisible || directoryEditor !== null,\n guardRecord: (record, action) => { if (action === 'delete' && isAdminUser(record)) throw new Error('admin 账号不允许删除'); },\n guardValues: (values, record) => {\n if (record && 'username' in values) throw new Error('编辑时不能修改用户名');\n if (record && ['email', 'phone'].some(field => field in values && isMaskedFieldValue(record[field as 'email' | 'phone']))) throw new Error('敏感字段处于锁定状态,请在页面处理');\n if (externalIdentity && ['username', 'nickname', 'email', 'phone', 'gender', 'birthDate'].some(field => field in values)) throw new Error('外部身份字段由身份目录维护');\n if (!canReadDepartments && 'departmentId' in values || !canReadPositions && Array.isArray(values.positionIds) && values.positionIds.length > 0 || !canReadRoles && Array.isArray(values.roleIds) && values.roleIds.length > 0) throw new Error('缺少关联字段的读取权限');\n },\n lookups: [{ name: 'departments', title: '部门', operation: departmentContract.flat, permission: 'system:department:list', fields: ['id', 'name', 'parentId'] },\n { name: 'positions', title: '岗位', operation: positionContract.all, permission: 'system:position:list', fields: ['id', 'name', 'code'] },\n { name: 'roles', title: '角色', operation: roleContract.all, permission: 'system:role:list', fields: ['id', 'name', 'code'] }] });\n const sensitiveFields = useSensitiveFormFields<User>({ entity: 'User', fields: ['email', 'phone'], record: editingUser });\n sensitiveFieldsRef.current = sensitiveFields;\n const passwordModal = useEditModal<User, ResetPasswordFormValues>({\n save: {\n mutateAsync: async ({ id, values }) => {\n if (id == null)\n abortSubmit('missing_user');\n await resetPasswordMutation.mutateAsync({ params: { id }, body: { password: values.password } });\n return {} as User;\n },\n isPending: false,\n },\n beforeSave: (values) => {\n if (values.password !== values.confirmPassword) {\n Toast.error('两次密码输入不一致');\n abortSubmit('password_not_match');\n }\n return values;\n },\n successMessage: () => '密码修改成功',\n onSaved: () => setEditPwdVal(''),\n });\n /** 记录抽屉的入口条件:登录日志 / 操作日志两个权限至少有一个 */\n const canViewLoginLogs = hasPermission('system:log:login');\n const canViewOperationLogs = hasPermission('system:log:operation');\n const canViewUserLogs = canViewLoginLogs || canViewOperationLogs;\n const selectedDeletableCount = useMemo(() => {\n if (!userList.length)\n return 0;\n const selectedSet = new Set(selectedRowKeys);\n return userList.filter((item) => selectedSet.has(item.id) && !isAdminUser(item)).length;\n }, [userList, selectedRowKeys]);\n const selectedNonAdminIds = useMemo(() => {\n if (!userList.length)\n return [];\n const selectedSet = new Set(selectedRowKeys);\n return userList.filter((item) => selectedSet.has(item.id) && !isAdminUser(item)).map((item) => item.id);\n }, [userList, selectedRowKeys]);\n const status = useStatusToggle<User>({\n toggle: (user, enabled) => toggleStatusMutation.mutateAsync({ body: { ids: [user.id], status: enabled ? 'enabled' : 'disabled' } }),\n confirmDisable: (user) => ({ danger: true, title: `确认停用用户「${user.nickname ?? user.username}」?`, content: '停用后该用户将无法登录。', okText: '确认停用' }),\n disabled: (user) => isAdminUser(user) || !hasPermission('system:user:update'),\n });\n // 启用 / 停用都需确认(停用后无法登录,红色实心确认);admin 账号不在选中集里\n const handleBatchStatus = batchStatusHandler({\n selectedRowKeys: selectedNonAdminIds,\n clearSelection: () => setSelectedRowKeys([]),\n run: (ids, status) => batchStatusMutation.mutateAsync({ body: { ids, status } }),\n confirm: 'always',\n entity: '个用户',\n confirmContent: (status) => (status === 'disabled' ? '停用后该用户将无法登录。' : '启用后该用户可正常登录。'),\n danger: true,\n });\n const handleBatchDelete = () => {\n const deletableIds = userList\n .filter((item) => selectedRowKeys.includes(item.id) && !isAdminUser(item))\n .map((item) => item.id);\n if (deletableIds.length === 0) {\n Toast.warning('admin 账号不允许删除');\n return;\n }\n confirmAndDelete({\n title: `确认删除选中的 ${deletableIds.length} 个用户?`,\n content: '删除后无法恢复,请谨慎操作。',\n run: () => deleteMutation.mutateAsync(deletableIds),\n successMessage: '批量删除成功',\n onDeleted: () => setSelectedRowKeys([]),\n });\n };\n const departmentTreeData = useMemo<TreeNodeData[]>(() => departmentsToTreeData(allDepartments, { keepEmptyChildren: true }), [allDepartments]);\n const departmentFilterTreeData = useMemo<TreeNodeData[]>(() => [{ key: ALL_DEPARTMENTS_KEY, value: ALL_DEPARTMENTS_KEY, label: '全部部门' }, ...departmentTreeData], [departmentTreeData]);\n const allDeptExpandedKeys = useMemo(() => allDepartments.map((item) => String(item.id)), [allDepartments]);\n // 首次加载完成后默认全展开;此后(keepAlive 页签切回 / 数据刷新触发 effect 重放)保持用户手动展开/折叠状态\n const deptTreeExpandInitedRef = useRef(false);\n useEffect(() => {\n if (deptTreeExpandInitedRef.current || allDepartments.length === 0)\n return;\n deptTreeExpandInitedRef.current = true;\n setDeptTreeExpandedKeys(allDeptExpandedKeys);\n }, [allDeptExpandedKeys, allDepartments.length]);\n const isAllDeptExpanded = isAllKeysExpanded(deptTreeExpandedKeys, allDeptExpandedKeys);\n function toggleDeptExpandAll() {\n setDeptTreeExpandedKeys(isAllDeptExpanded ? [] : allDeptExpandedKeys);\n }\n const positionOptionList = useMemo(() => allPositions.map((item) => ({ value: item.id, label: item.name })), [allPositions]);\n const openCreate = modal.openCreate;\n const openEdit = modal.openEdit;\n const openPassword = passwordModal.openEdit;\n const { mutateAsync: unlockUser } = unlockMutation;\n const handleUnlock = useCallback(async (id: number) => {\n await unlockUser({ params: { id } });\n Toast.success('已清除登录验证码要求');\n }, [unlockUser]);\n const { mutateAsync: kickUserSessions } = kickSessionsMutation;\n const { refetch: refetchUserList } = listQuery;\n // 列定义 memo 化:搜索框每次击键都会触发页面重渲染,\n // 若每次都重建 columns(含所有 render 闭包),表格会整体重渲染所有行\n const columns: ColumnProps<User>[] = useMemo(() => [\n {\n title: '用户',\n dataIndex: 'nickname',\n minWidth: 260,\n ellipsis: { showTitle: false },\n render: (_: unknown, record: User) => (<div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n <span title={record.isOnline ? '在线' : '离线'} style={{\n flexShrink: 0,\n width: 8,\n height: 8,\n borderRadius: '50%',\n background: record.isOnline ? 'var(--arc-antd-color-success)' : 'var(--arc-antd-color-fill-2)',\n display: 'inline-block',\n boxShadow: record.isOnline ? '0 0 0 2px color-mix(in srgb, var(--arc-antd-color-success) 20%, transparent)' : undefined,\n }}/>\n <UserAvatar name={record.nickname || record.username} avatar={record.avatar} size={24}/>\n <span className=\"table-cell-ellipsis\" title={`${record.externalDisplayName || record.nickname}(${record.externalUsername || record.username})`}>\n {record.externalDisplayName || record.nickname}({record.externalUsername || record.username}){record.accountSource === \"casdoor\" && <Tag size=\"small\">Casdoor · {record.remoteStatus === \"active\" ? \"有效\" : \"停用或删除\"}</Tag>}\n </span>\n {record.loginChallengeRequired && (<Tag size=\"small\" color=\"orange\" style={{ flexShrink: 0 }}>需验证码</Tag>)}\n </div>),\n },\n {\n title: '手机号码',\n dataIndex: 'phone',\n width: 150,\n render: (v: string | null | undefined, record: User) => <SensitiveText entity=\"User\" id={record.id} field=\"phone\" value={v}/>,\n },\n {\n title: '邮箱',\n dataIndex: 'email',\n defaultHidden: true,\n width: 240,\n render: (v: string | null | undefined, record: User) => <SensitiveText entity=\"User\" id={record.id} field=\"email\" value={v}/>,\n },\n {\n title: '部门',\n dataIndex: 'departmentName',\n width: 140,\n render: renderEllipsis,\n },\n { ...overflowTagColumn<User>({\n title: '岗位',\n dataIndex: 'positions',\n width: 160,\n contentWidth: 128,\n getItems: (positions) => ((positions as Position[] | undefined) ?? [])\n .map((item) => ({ key: String(item.id), label: item.name })),\n tagColor: 'purple',\n popoverWidth: 200,\n empty: <Tag color=\"grey\">无岗位</Tag>,\n }), defaultHidden: true },\n overflowTagColumn<User>({\n title: '角色',\n dataIndex: 'roles',\n width: 180,\n contentWidth: 148,\n getItems: (roles) => (roles as Role[]).map((role) => ({ key: String(role.id), label: role.name })),\n tagColor: 'blue',\n popoverWidth: 240,\n empty: <Tag color=\"grey\">无角色</Tag>,\n }),\n {\n title: '性别',\n dataIndex: 'gender',\n defaultHidden: true,\n width: 80,\n render: (gender: string | null | undefined) => gender ? <DictTag dictCode=\"user_gender\" value={gender}/> : null,\n },\n dateTimeColumn('最近登录', 'lastLoginAt', { defaultHidden: true }),\n dateTimeColumn('最近活跃', 'lastActiveAt', { defaultHidden: true }),\n { title: '关联信息', key: 'relations', defaultHidden: true, width: 120, render: (_: unknown, record: User) => <EntityRelationButton entityRef={{ type: 'identity.user', key: String(record.id) }}/> },\n { ...createdAtColumn, defaultHidden: true },\n status.column(),\n createOperationColumn<User>({\n width: 180,\n desktopInlineKeys: ['edit', 'delete'],\n actions: (record) => {\n const isAdmin = isAdminUser(record);\n return [\n {\n key: 'edit',\n label: externalIdentity ? '本应用权限' : '编辑',\n hidden: !hasPermission('system:user:update'),\n onClick: () => {\n openEdit(record);\n },\n },\n { key: 'directory-profile', label: '统一账户资料', hidden: !externalIdentity || !hasPermission('system:user:update'), onClick: () => setDirectoryEditor(record) },\n deleteAction({\n hidden: externalIdentity || !hasPermission('system:user:delete'),\n disabled: isAdmin,\n disabledReason: 'admin 账号不允许删除',\n title: '确定要删除该用户吗?',\n run: () => deleteMutation.mutateAsync([record.id]),\n }),\n {\n key: 'avatar',\n label: '管理头像',\n hidden: externalIdentity || !hasPermission('system:user:update'),\n onClick: () => {\n setAvatarUser(record);\n setAvatarModalVisible(true);\n },\n },\n {\n key: 'password',\n label: '修改密码',\n hidden: externalIdentity || !hasPermission('system:user:update'),\n onClick: () => {\n openPassword(record);\n },\n },\n {\n key: 'unlock',\n label: '清除登录验证码要求',\n hidden: !record.loginChallengeRequired || !hasPermission('system:user:update'),\n onClick: () => handleUnlock(record.id),\n },\n {\n key: 'logs',\n label: '登录与操作记录',\n // 两个日志权限任一即可打开抽屉(只有权限的那个 tab 会渲染)\n hidden: !canViewUserLogs,\n onClick: () => {\n setLogsUser(record);\n setLogsVisible(true);\n },\n },\n {\n key: 'menu-permission',\n label: '菜单权限',\n hidden: !hasPermission('system:user:assign'),\n onClick: () => {\n setMenuPermUser(record);\n setMenuPermVisible(true);\n },\n },\n {\n key: 'assign-role',\n label: '分配角色',\n hidden: !hasPermission('system:user:assign'),\n onClick: () => {\n setRoleAssignUser(record);\n setRoleAssignIds(record.roles.map((r) => r.id));\n setRoleAssignVisible(true);\n },\n },\n {\n key: 'data-permission',\n label: '数据权限',\n hidden: !hasPermission('system:user:assign'),\n onClick: () => {\n setDataPermUser(record);\n setDataPermVisible(true);\n },\n },\n {\n key: 'force-logout',\n label: '强制下线',\n danger: true,\n dividerBefore: true,\n // 离线用户仍展示入口(便于发现该能力),但不可点击\n hidden: !hasPermission('system:session:forceLogout'),\n disabled: !record.isOnline,\n disabledReason: '该用户当前不在线',\n onClick: () => {\n confirmDanger({\n title: '强制下线',\n content: `确定要强制下线用户「${record.nickname}(${record.username})」的全部会话吗?`,\n onOk: async () => {\n await kickUserSessions({ params: { id: record.id } });\n Toast.success('已强制下线');\n void refetchUserList();\n },\n });\n },\n },\n ];\n },\n }),\n ], [externalIdentity, hasPermission, status, deleteMutation, handleUnlock, kickUserSessions, refetchUserList, openEdit, openPassword, canViewUserLogs]);\n const [showDeptTree, setShowDeptTree] = useState(false);\n const [isLayoutNarrow, setIsLayoutNarrow] = useState(false);\n const masterContent = (<div className=\"users-dept-sidebar\">\n <MasterDetailLayout.Header className=\"users-dept-sidebar-title\" style={{ padding: '10px 12px', minHeight: 44, marginBottom: 4 }} extra={(<Button className=\"users-dept-tree-action\" theme=\"borderless\" size=\"small\" icon={isAllDeptExpanded ? <ChevronsDownUp size={14}/> : <ChevronsUpDown size={14}/>} onClick={toggleDeptExpandAll}>\n {isAllDeptExpanded ? '全部折叠' : '全部展开'}\n </Button>)}>\n <span className=\"users-dept-sidebar-title-text\">组织架构</span>\n </MasterDetailLayout.Header>\n <Tree blockNode treeData={departmentFilterTreeData} expandedKeys={deptTreeExpandedKeys} value={draftParams.departmentId === undefined ? ALL_DEPARTMENTS_KEY : String(draftParams.departmentId)} filterTreeNode={(input, _node, data) => data.key === ALL_DEPARTMENTS_KEY || String(data.label ?? '').toLocaleLowerCase().includes(input.toLocaleLowerCase())} showFilteredOnly searchPlaceholder=\"搜索部门\" onExpand={(expandedKeys) => {\n setDeptTreeExpandedKeys((expandedKeys as Array<string | number>).map(String));\n }} onSelect={(selectedKey) => {\n const newDeptId = selectedKey === ALL_DEPARTMENTS_KEY ? undefined : Number(selectedKey);\n const newParams = { ...draftParams, departmentId: newDeptId };\n applySearch(newParams);\n setShowDeptTree(false);\n }} style={{ width: '100%' }}/>\n </div>);\n const renderDepartmentButton = (forceVisible = false) => (<Button theme=\"borderless\" icon={<Building2 size={14}/>} onClick={() => setShowDeptTree(true)} style={{ display: forceVisible || isLayoutNarrow ? undefined : 'none' }}>\n 按部门\n </Button>);\n const renderBatchActions = () => (<>\n {!externalIdentity && selectedDeletableCount > 0 && hasPermission('system:user:delete') && (<BatchDeleteButton count={selectedDeletableCount} onClick={handleBatchDelete}/>)}\n {selectedNonAdminIds.length > 0 && hasPermission('system:user:update') && (<>\n <BatchStatusButtons count={selectedNonAdminIds.length} onChange={handleBatchStatus} danger/>\n {!externalIdentity && <Button theme=\"light\" icon={<KeyRound size={14}/>} onClick={() => setBatchPasswordModalVisible(true)}>\n 批量修改密码 ({selectedNonAdminIds.length})\n </Button>}\n </>)}\n </>);\n const renderImportButton = () => !externalIdentity && hasPermission('system:user:import') ? (<ImportButton entity=\"identity.users\" title=\"用户\" onFinished={() => void refetchUserList()}/>) : null;\n return (<div className=\"page-container page-container--stretch\">\n <MasterDetailLayout master={masterContent} detail={<div className=\"users-content\">\n\n\n <ConfigurableTable<User> searchConfig={buildTableSearch({\n keyword: (<KeywordInput placeholder=\"搜索用户名/昵称/邮箱\" {...bindKeyword('keyword')} width={260}/>),\n filters: ((<>\n <KeywordInput placeholder=\"搜索手机号码\" {...bindKeyword('phone')} width={180}/>\n <StatusSelect items={statusItems} {...bind('status')}/>\n <DateRangeFilter placeholder={[\"开始时间\", \"结束时间\"]} {...bind('timeRange')}/>\n </>)),\n onSearch: (handleSearch),\n onReset: (handleReset),\n create: (<CreateButton permission=\"system:user:create\" onClick={() => externalIdentity ? setDirectoryEditor(true) : openCreate()}/>),\n actions: ((<>\n {renderDepartmentButton()}\n {renderBatchActions()}\n <ExportButton entity=\"system.users\" query={filterQuery} watermark={false} permission=\"system:user:export\"/>\n {renderImportButton()}\n {externalIdentity && <DirectorySyncControl administrator={currentUser?.roles.some(role => role.code === \"super_admin\") ?? false}/>}\n </>)),\n filterTitle: \"用户筛选\",\n actionTitle: \"用户操作\"\n })} columns={columns} {...listTableProps(listQuery, {\n pagination: buildPagination,\n empty: '暂无数据',\n rowSelection: {\n selectedRowKeys,\n onChange: (keys) => {\n const nextKeys = (keys ?? []).map(Number);\n const nextKeySet = new Set(nextKeys);\n const adminIds = userList.filter((item) => isAdminUser(item)).map((item) => item.id);\n const filtered = nextKeys.filter((id) => !adminIds.includes(id));\n if (filtered.length < nextKeys.length && adminIds.some((id) => nextKeySet.has(id))) {\n Toast.warning('admin 账号不支持批量删除');\n }\n setSelectedRowKeys(filtered);\n },\n },\n })}/>\n </div>} defaultSize={220} minSize={160} maxSize={400} showDetail={!showDeptTree} onMasterBack={() => setShowDeptTree(false)} masterBackLabel=\"返回用户列表\" onResponsiveChange={setIsLayoutNarrow} persistKey=\"users\" style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}/>\n\n {directoryEditor && <DirectoryAccountModal user={directoryEditor === true ? undefined : directoryEditor} onClose={() => { setDirectoryEditor(null); void refetchUserList(); }}/>}\n <EditFormModal modal={modal} okButtonProps={{ disabled: modal.detailLoading }} width={660}>\n {editingUser ? (<>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Input field=\"username\" label=\"用户名\" disabled/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"nickname\" label=\"昵称\" disabled={externalIdentity} placeholder=\"请输入昵称\" rules={[{ required: true, message: '请输入昵称' }]}/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <SensitiveFormInput control={sensitiveFields} disabled={externalIdentity} field=\"phone\" label=\"手机号码\" placeholder=\"请输入手机号码\" rules={[{ pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号码' }]}/>\n </Col>\n </Row>\n </>) : (<>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Input field=\"username\" label=\"用户名\" placeholder=\"请输入用户名\" rules={[{ required: true, message: '请输入用户名' }]}/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"nickname\" label=\"昵称\" disabled={externalIdentity} placeholder=\"请输入昵称\" rules={[{ required: true, message: '请输入昵称' }]}/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <FormPasswordInput field=\"password\" label=\"密码\" placeholder=\"请输入密码\" rules={[{ required: true, message: '请输入密码' }]} onChange={(v) => setCreatePwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={createPwdVal} policy={passwordPolicy}/>}/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"phone\" label=\"手机号码\" placeholder=\"请输入手机号码\" rules={[{ pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号码' }]}/>\n </Col>\n </Row>\n </>)}\n <Row gutter={16}>\n <Col span={12}>\n <SensitiveFormInput control={sensitiveFields} field=\"email\" disabled={externalIdentity} label=\"邮箱\" placeholder=\"请输入邮箱\" rules={[{ type: 'email', message: '邮箱格式不正确' }]}/>\n </Col>\n <Col span={12}>\n <Form.TreeSelect field=\"departmentId\" label=\"所属部门\" disabled={!canReadDepartments} style={{ width: '100%' }} treeData={departmentTreeData} placeholder=\"请选择所属部门\" filterTreeNode showClear/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Select field=\"positionIds\" label=\"岗位\" disabled={!canReadPositions} style={{ width: '100%' }} multiple filter showClear optionList={positionOptionList} placeholder=\"请选择岗位\"/>\n </Col>\n <Col span={12}>\n <Form.Select field=\"roleIds\" label=\"角色\" disabled={!canReadRoles} style={{ width: '100%' }} multiple filter optionList={allRoles.map((r) => ({ value: r.id, label: r.name }))} placeholder=\"请选择角色\"/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Select field=\"gender\" disabled={externalIdentity} label=\"性别\" style={{ width: '100%' }} showClear optionList={genderOptions} placeholder=\"请选择性别\"/>\n </Col>\n <Col span={12}>\n <Form.DatePicker field=\"birthDate\" disabled={externalIdentity} label=\"出生日期\" type=\"date\" style={{ width: '100%' }} placeholder=\"请选择出生日期\" showClear/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Select field=\"status\" label=\"状态\" style={{ width: '100%' }} optionList={statusItems.map((i) => ({\n value: i.value,\n label: i.label,\n disabled: editingUser ? (isAdminUser(editingUser) && i.value === 'disabled') : false,\n }))} placeholder=\"请选择状态\"/>\n </Col>\n </Row>\n </EditFormModal>\n\n <EditFormModal modal={passwordModal} title={passwordModal.editing ? `修改密码 - ${passwordModal.editing.nickname}` : '修改密码'} onCancel={() => { passwordModal.close(); setEditPwdVal(''); }} width={420}>\n <FormPasswordInput field=\"password\" label=\"新密码\" placeholder=\"请输入新密码\" rules={[\n { required: true, message: '请输入新密码' },\n { min: 6, message: '密码至少 6 个字符' },\n ]} onChange={(v) => setEditPwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={editPwdVal} policy={passwordPolicy}/>}/>\n <FormPasswordInput field=\"confirmPassword\" label=\"确认密码\" placeholder=\"请再次输入新密码\" rules={[{ required: true, message: '请确认新密码' }]}/>\n </EditFormModal>\n\n {false}\n\n {/* 批量修改密码 */}\n <AppModal title={`批量修改密码(共 ${selectedNonAdminIds.length} 个用户)`} visible={batchPasswordModalVisible} onCancel={() => { setBatchPasswordModalVisible(false); batchPasswordFormApi.current?.setValues({ password: '', confirmPassword: '' }); setBatchPwdVal(''); }} confirmLoading={batchPasswordMutation.isPending} onOk={async () => {\n if (!batchPasswordFormApi.current)\n return;\n try {\n const values = await batchPasswordFormApi.current.validate() as unknown as {\n password: string;\n confirmPassword: string;\n };\n if (values.password !== values.confirmPassword) {\n batchPasswordFormApi.current.setError('confirmPassword', '两次密码输入不一致');\n return;\n }\n await batchPasswordMutation.mutateAsync({ body: { ids: selectedNonAdminIds, password: values.password } });\n Toast.success('密码修改成功');\n setBatchPasswordModalVisible(false);\n batchPasswordFormApi.current.setValues({ password: '', confirmPassword: '' });\n setBatchPwdVal('');\n setSelectedRowKeys([]);\n }\n catch { /* No additional action. */ } /* No additional action. */ /* No additional action. */ /* No additional action. */ /* No additional action. */ /* No additional action. */\n }}>\n <Form getFormApi={(api) => { batchPasswordFormApi.current = api; }} labelPosition=\"left\" labelWidth={90}>\n <FormPasswordInput field=\"password\" label=\"新密码\" placeholder={passwordPolicy ? formatPasswordPolicyHint(passwordPolicy) : '请输入新密码'} rules={[{ required: true, message: '请输入新密码' }]} onChange={(v) => setBatchPwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={batchPwdVal} policy={passwordPolicy}/>}/>\n <FormPasswordInput field=\"confirmPassword\" label=\"确认密码\" placeholder=\"请再次输入新密码\" rules={[{ required: true, message: '请确认密码' }]}/>\n </Form>\n </AppModal>\n\n {/* 管理头像 */}\n {avatarUser && (<UserAvatarModal visible={avatarModalVisible} user={avatarUser} onClose={() => setAvatarModalVisible(false)} onUpdated={(updated) => {\n void listQuery.refetch();\n setAvatarUser(updated);\n updateUser(updated);\n }}/>)}\n\n {/* 登录与操作记录 */}\n {logsUser && (<UserLogsSheet visible={logsVisible} userId={logsUser.id} userName={`${logsUser.nickname || logsUser.username}(${logsUser.username})`} canViewLoginLogs={canViewLoginLogs} canViewOperationLogs={canViewOperationLogs} onClose={() => setLogsVisible(false)}/>)}\n\n {/* 用户菜单权限 */}\n {menuPermUser && (<UserMenuPermissionModal userId={menuPermUser.id} userName={menuPermUser.nickname || menuPermUser.username} visible={menuPermVisible} onClose={() => setMenuPermVisible(false)}/>)}\n\n {/* 用户数据权限 */}\n {dataPermUser && (<UserDataScopeModal userId={dataPermUser.id} userName={dataPermUser.nickname || dataPermUser.username} visible={dataPermVisible} deptTree={allDepartments} onClose={() => setDataPermVisible(false)}/>)}\n\n {/* 分配角色 */}\n <AppModal title={`分配角色——${roleAssignUser?.nickname || roleAssignUser?.username || ''}`} visible={roleAssignVisible} onCancel={() => setRoleAssignVisible(false)} confirmLoading={assignRolesMutation.isPending} onOk={async () => {\n if (!roleAssignUser)\n return;\n await assignRolesMutation.mutateAsync({ params: { id: roleAssignUser.id }, body: { roleIds: roleAssignIds } });\n Toast.success('角色分配成功');\n setRoleAssignVisible(false);\n }} okText=\"保存\" cancelText=\"取消\" width={480}>\n <div>\n <div style={{ marginBottom: 6, fontSize: 13, fontWeight: 600 }}>直接分配角色</div>\n <Select multiple filter showClear style={{ width: '100%' }} value={roleAssignIds} onChange={(v) => setRoleAssignIds((v as number[]) ?? [])} optionList={allRoles.map((r) => ({ value: r.id, label: r.name }))} placeholder=\"请选择要分配的角色\"/>\n </div>\n <div style={{ marginTop: 18, paddingTop: 14, borderTop: '1px solid var(--arc-antd-color-border)' }}>\n <div style={{ marginBottom: 6, fontSize: 13, fontWeight: 600 }}>用户组继承角色</div>\n <div style={{ marginBottom: 8, fontSize: 12, color: 'var(--arc-antd-color-text-2)' }}>\n 以下角色由用户组自动继承,只能在用户组中调整。\n </div>\n {roleEffectivePermissionsQuery.isFetching ? (<div style={{ color: 'var(--arc-antd-color-text-2)', fontSize: 12 }}>正在加载继承关系…</div>) : roleEffectivePermissionsQuery.data?.inheritedRoles.length ? (<Space spacing={6} wrap>\n {roleEffectivePermissionsQuery.data.inheritedRoles.map((role) => (<Tag key={role.id} color=\"orange\" style={{ marginBottom: 4 }}>\n {role.name}(来自:{role.groupNames.join('、')})\n </Tag>))}\n </Space>) : (<div style={{ color: 'var(--arc-antd-color-text-2)', fontSize: 12 }}>暂无用户组继承角色</div>)}\n </div>\n </AppModal>\n </div>);\n}\n"]}
1
+ {"version":3,"file":"UsersPage-CfNnQJi4.js","mappings":";;;;;;;IASMA,GAAa,CACjB,KAAM,mBACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,4BAA6B,IAAK,QAAS,CAAC,EAC1D,CACE,OACA,CACE,EAAG,4EACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAS,CAAC,CAC3E,EACA,QAAS,CAAC,YAAY,CACxB,EACAC,GAAW,KACL,GAAkBC,EAAiBF,EAAU,C;;;;;;;ICnB7CA,EAAa,CACjB,KAAM,MACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,wGACH,IAAK,QACP,CACF,EACA,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAS,CAAC,CAC1D,CACF,EACAG,EAAW,KACL,GAAMD,EAAiBF,CAAU,C;;;;;;;ICfjCA,GAAa,CACjB,KAAM,cACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CACE,OACA,CACE,EAAG,mIACH,IAAK,QACP,CACF,CACF,CACF,EACAI,GAAW,KACL,GAAaF,EAAiBF,EAAU,C;;;;;;;IChBxC,EAAa,CACjB,KAAM,SACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAS,CAAC,EAC9C,CAAC,OAAQ,CAAE,EAAG,2DAA4D,IAAK,QAAS,CAAC,CAC3F,CACF,EACAA,EAAW,KACL,GAAQE,EAAiBF,CAAU,C,OCoBzC,SAAgBK,GAAwD,CAAE,kBAAiB,iBAAgB,MAAK,eAAe,KAAM,UAAU,UAAW,SAAS,IAAK,iBAAgB,SAAS,GAAO,kBAA2C,CAC/O,OAAO,KAAO,IAAuC,CACjD,IAAMC,EAAM,CAAC,GAAGC,CAAe,EAC/B,GAAID,EAAI,SAAW,EACf,OACJ,IAAME,EAAQC,IAAW,UAAY,KAAOC,EACtCC,EAAU,SAAY,CACxB,MAAMC,EAAIN,EAAKG,CAAM,EACrBI,EAAe,EACfC,EAAM,QAAQC,IAAiBN,EAAQH,EAAI,MAAM,GAAK,KAAKE,EAAM,GAAG,CACxE,EAEA,GAAI,EADgBQ,IAAY,UAAaA,IAAY,WAAaP,IAAW,YAE7E,OAAOE,EAAQ,EACnB,IAAMM,EAAU,CACZ,MAAO,OAAOT,EAAM,MAAMF,EAAI,OAAO,GAAGY,EAAO,GAC/C,QAASC,IAAiBV,EAAQH,EAAI,MAAM,EAC5C,KAAMK,CACV,EAEIS,GAAUX,IAAW,WACrBY,GAAcJ,CAAO,EAErBK,GAAM,QAAQL,CAAO,CAC7B,CACJ,C,8CCzCA,SAAgBM,GAAmB,CAAE,UAAS,QAAO,QAAO,GAAGC,GAAuC,CAClG,IAAMC,EAAUC,EAAW,EACrBC,EAAWC,EAAQ,QAAQ,IAAM,EACjCC,EAASC,GAAiB,CAAE,OAAQF,EAAQ,OAAQ,GAAID,EAAU,OAAM,CAAC,EACzEI,EAAeH,EAAQ,SAA4CI,GACnEC,EAAa,OAAOF,GAAgB,UAAYA,EAAcA,EAAcG,GAClF,GAAIN,EAAQ,SAASI,CAAK,EAAG,CACzB,IAAMG,EAAON,EAAO,UAAYI,EAChC,MAAQ,kBAACG,EAAK,KAAN,CAAkB,QAC1B,2BAACC,EAAD,CAAO,QAAS,EAAG,QAAK,UAAU,wBAAlC,UACE,kBAACC,EAAW,KAAZ,CAAiB,UAAU,+BAAgC,SAAAH,CAAsB,GAChFN,EAAO,YAAcA,EAAO,WAAa,KAAQ,kBAACU,EAAD,CAAS,QAAQ,aAC7D,2BAACC,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAM,kBAACC,GAAD,CAAK,KAAM,EAAI,GAAG,QAASZ,EAAO,UAAW,aAAW,OAAO,YAAe,KAAKA,EAAO,KAAK,CAAG,EACzJ,GAAM,kBAACU,EAAD,CAAS,QAAQ,OAC9B,2BAACC,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAM,kBAACE,GAAD,CAAQ,KAAM,EAAI,GAAG,aAAW,OAAO,QAASb,EAAO,IAAM,EACpH,IACb,kBAACW,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAM,kBAACG,GAAD,CAAY,KAAM,EAAI,GAAG,SAAUnB,EAAW,SAAU,YAAe,CAC/GI,EAAQ,OAAOI,CAAK,EACpBP,EAAQ,SAASO,EAAOH,EAAO,UAAY,EAAE,CACjD,EAAG,aAEG,EACH,C,EACE,EACb,CACA,IAAMe,EAAWhB,EAAQ,WAAWI,CAAK,EACzC,MAAQ,kBAACI,EAAK,MAAN,CAAY,GAAIZ,EAAmB,QAAc,QAAO,UAAWoB,EAAY,kBAACP,EAAD,CAAO,QAAS,EAAhB,UACjF,kBAACC,EAAW,KAAZ,CAAiB,KAAK,WAAW,KAAK,QAAQ,oBAA0B,GACxE,kBAACE,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAM,kBAACK,GAAD,CAAO,KAAM,EAAI,GAAG,YAAe,CAAEjB,EAAQ,OAAOI,CAAK,EAAGP,EAAQ,SAASO,EAAOD,CAAW,CAAG,EAAG,eAAY,EAC1K,CAAK,GAAAP,EAAW,SAAW,EAC1C,C,kECxCA,SAAgBsB,GAAqB,CAAE,iBAEpC,CACC,IAAMrC,EAASsC,GAAuBC,CAAa,EAC7CC,EAAOC,GAAiB,EAG9B,OAFKF,EAEE,kBAACX,EAAD,CAAO,QAAP,UACP,kBAACG,EAAD,CAAQ,QAASS,EAAK,WAAaxC,EAAO,MAAM,QAAS,SAAU,CAACA,EAAO,MAAQA,EAAO,KAAK,QAAS,YAAe,CAAEwC,EAAU,YAAY,CAAC,CAAC,CAAC,CAAC,UAAY,CAAE,CAAC,CAAG,EAAG,iBAAc,GACtL,kBAACX,EAAW,KAAZ,CAAiB,KAAK,WAAtB,UAAiC,UAAQ7B,EAAO,MAAM,cAAgB,kBAAC0C,GAAD,CAAc,MAAO1C,EAAO,KAAK,cAAe,KAAK,UAAW,GAAI,MAAwB,C,IAChKA,EAAO,SAAWA,EAAO,MAAM,QAAU,kBAAC6B,EAAW,KAAZ,CAAiB,KAAK,SAAU,SAAA7B,EAAO,MAAM,OAAS,UAA4B,EACxH,C,GALM,IAMf,CAEA,SAAgB2C,GAAsB,CAAE,OAAM,WAG3C,CACC,IAAMC,EAAYC,GAAuB,CAAE,OAAQ,OAAQ,OAAQC,GAA0B,OAAQC,GAAQ,IAAK,CAAC,EAC7GC,EAASC,GAAmB,EAC5BC,EAASC,EAAmB,EAC5BC,EAAOC,EAAuB,IAAI,EAClC,CAACC,GAAaC,MAAe,OAAO,WAAW,CAAC,EAChD,CAACC,EAAWC,GAAgBF,EAAS,EAAK,EAC1C,CAACG,EAAOC,GAAYJ,EAAS,EAAE,EAC/BK,EAAYC,EAAsBP,EAAWE,CAAS,EACtDM,EAAS,SAAY,CACvB,GAAI,CAACV,EAAK,SAAWI,EACjB,OACJ,IAAIO,EACJ,GAAI,CACA,IAAMC,EAAkB,MAAMZ,EAAK,QAAQ,SAAS,EACpD,GAAIL,EAAM,CACN,IAAMkB,EAAOC,EAA0B,OAAO,MAAM,MAAM,KAAK,MAAMtB,EAAU,MAAMoB,CAAiC,CAAC,EACvH,MAAMd,EAAO,YAAY,CAAE,OAAQ,CAAE,GAAIH,EAAK,EAAG,EAAG,MAAK,CAAC,CAC9D,KACK,CACD,IAAMoB,EAAUH,EAChB,EAAQE,EAA0B,OAAO,MAAM,MAAM,KAAK,MAAM,CAAE,GAAGC,EAAS,YAAW,YAAaA,EAAQ,aAAe,GAAI,MAAOA,EAAQ,OAAS,GAAI,MAAOA,EAAQ,OAAS,EAAG,CAAC,EACzL,MAAMnB,EAAO,YAAY,CAAE,KAAMe,CAAM,CAAC,CAC5C,CACA1D,EAAM,QAAQ0C,EAAO,UAAY,mBAAmB,EACpDqB,EAAQ,CACZ,OACOC,EAAO,CACNN,GACAN,EAAa,EAAI,EACrBE,EAASU,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,CACnE,QACQ,CACJjB,EAAK,SAAS,SAAS,kBAAmB,EAAE,EACxCW,IACA,EAAM,gBAAkB,GAChC,CACJ,EAGA,MAAO,kBAACO,GAAD,CAAU,MAAOvB,EAAO,SAAW,SAAU,WAAQ,SAAUqB,EAAS,SAAY,CAAEN,EAAY,CAAG,EAAG,eAAgBd,EAAO,WAAaE,EAAO,UAAW,cAAe,CAAE,SAAUM,CAAU,EAAnM,UACP,kBAAC7B,EAAD,CAAM,WAAa,GAAU,CAAE,EAAK,QAAU4C,CAAO,EAAG,WAAY,CAAE,YAAaxB,GAAM,qBAAuBA,GAAM,UAAY,GAAI,MAAOA,GAAM,OAAS,GAAI,MAAOA,GAAM,OAAS,EAAG,EAAzL,UACG,CAACA,GAAQ,kBAACpB,EAAK,MAAN,CAAY,MAAM,WAAW,MAAM,QAAQ,MAAO,CAAC,CAAE,SAAU,EAAK,CAAC,CAAG,GAClF,kBAACA,EAAK,MAAN,CAAY,MAAM,cAAc,MAAM,KAAM,GAC5C,kBAACb,GAAD,CAAoB,QAAS8B,EAAW,MAAM,QAAQ,MAAM,IAAK,GACjE,kBAAC9B,GAAD,CAAoB,QAAS8B,EAAW,MAAM,QAAQ,MAAM,IAAK,GAChE,CAACG,GAAQ,kBAACyB,EAAD,CAAmB,MAAM,kBAAkB,MAAM,OAAO,aAAa,eAAe,MAAO,CAAC,CAAE,SAAU,EAAK,CAAC,CAAG,EACvH,C,GACN,kBAAC,IAAD,UAAG,oDAAqD,GACvDd,GAAS,kBAAC,IAAD,CAAG,KAAK,QAAS,SAAAA,CAAS,GACnCF,GAAa,kBAACzB,EAAD,CAAQ,QAAS6B,EAAU,WAAY,YAAe,CACxDA,EAAe,QAAQ,CAAC,CAAC,MAAM,CAAE,UAAW,CACpCa,GAAM,SAAW,YACjBpE,EAAM,QAAQ,eAAe,EAC7B+D,EAAQ,GAGRT,EAAS,8BAA8B,CAC/C,CAAC,CACL,EAAG,iBAAc,EACjB,C,EACZ,C,8DAjEM,GAA2B,CAAC,QAAS,OAAO,C,OCLlD,SAAgBe,GAAwB,CAAE,SAAQ,WAAU,UAAS,WAAkB,CACnF,GAAM,CAACC,EAAeC,GAAoBrB,EAAmB,CAAC,CAAC,EACzD,CAACsB,EAAaC,GAAkBvB,EAAmB,CAAC,CAAC,EACrD,CAACwB,EAAcC,GAAmBzB,EAAmB,CAAC,CAAC,EACvD,CAAC0B,EAAQC,GAAa3B,EAGxB,CAAC,CAAC,EACA,CAAC4B,EAAkBC,GAAuB7B,EAAmB,CAAC,CAAC,EAC/D,CAAC8B,EAAWC,GAAgB/B,EAAS,QAAQ,EAC7CgC,EAAgBC,GAAY,CAAE,QAASC,CAAQ,CAAC,EAChDC,EAAmBC,GAA4BC,EAAQH,CAAO,EAC9DI,EAAoBC,GAAiB,EAC3CC,OAAgB,CACPN,GAELH,EAAa,QAAQ,CACzB,EAAG,CAACG,EAASG,CAAM,CAAC,EACpBG,OAAgB,CACPN,GAAYC,EAAiB,OAElCd,EAAiBc,EAAiB,KAAK,aAAa,EACpDZ,EAAeY,EAAiB,KAAK,WAAW,EAChDV,EAAgBU,EAAiB,KAAK,cAAgB,CAAC,CAAC,EACxDR,EAAUQ,EAAiB,KAAK,QAAU,CAAC,CAAC,EAC5CN,EAAoBM,EAAiB,KAAK,gBAAgB,EAC9D,EAAG,CAACD,EAASC,EAAiB,IAAI,CAAC,EACnC,IAAMM,GAAa,SAAY,CAC3B,MAAMH,EAAkB,YAAY,CAAE,OAAQ,CAAE,GAAID,CAAO,EAAG,KAAM,CAAE,QAASjB,CAAc,CAAE,CAAC,EAChGtE,EAAM,QAAQ,SAAS,EACvB,IAAM4F,kBAAe,IAAI,IAAI,CAAC,GAAGtB,EAAe,GAAGE,EAAa,GAAGE,CAAY,CAAC,EAChFK,EAAoB,CAAC,GAAGa,CAAY,CAAC,EACrC7B,EAAQ,CACZ,EAEA,SAAS8B,IAAoD,CACzD,IAAMC,EAAcT,EAAiB,MAAM,aAAe,CAAC,EACrDU,EAA0C,CAAC,EACjD,IAAK,IAAMC,KAAMlB,EAAkB,CAE/B,IAAMmB,GADUH,EAAY,OAAOE,CAAE,IAAM,CAAC,GACvB,IAAK,GAAY,kBAACE,EAAD,CAAkB,KAAK,QAAQ,MAAOC,IAAW,SAAW,QAAUA,EAAO,SAAS,MAAM,EAAI,SAAW,OAClJ,SAAAA,CACE,EAF+CA,CAE/C,CAAE,EACH,EAAO,OAAOH,CAAE,GAAK,kBAACzE,EAAD,CAAO,QAAS,EAAG,MAAO,CAAE,WAAY,CAAE,EAAI,SAAA0E,CAAY,EACnF,CACA,OAAOF,CACX,CACA,MAAQ,kBAAC9B,GAAD,CAAU,MAAO,UAAUmC,IAAqB,UAAS,SAAUrC,EAAS,OAAQiB,IAAc,YAAc,KAAQ,kBAACqB,GAAD,CAAa,SAAUtC,EAAS,KAAM4B,GAAY,OAAO,KAAK,QAASH,EAAkB,UAAW,SAAU,CAACH,EAAiB,SAAW,GAAI,MAAO,IACpR,2BAACiB,EAAD,CAAM,YAAY,OAAO,UAAWtB,EAAW,SAAUC,EAAzD,UACE,kBAACsB,EAAD,CAAS,IAAI,OAAO,QAAQ,SAC1B,2BAACC,GAAD,CAAqB,SAAUtB,EAAc,MAAQ,CAAC,EAAG,eAAgBZ,EAAe,SAAUC,EAAkB,QAASW,EAAc,YAAcG,EAAiB,UAAY,EAC/K,GACT,kBAACkB,EAAD,CAAS,IAAI,SAAS,QAAQ,YAA9B,UACE,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,SAAU,GAAI,MAAO,8BAA+B,EAAnF,UACE,kBAAC,MAAD,UAAK,mCAAsC,GAC3C,kBAAC,MAAD,CAAK,MAAO,CAAE,QAAS,OAAQ,oBAAqB,sBAAuB,UAAW,EAAG,OAAQ,EAAG,WAAY,QAAS,UAAW,CAAE,EAAtI,UACE,kBAAC,OAAD,UAAM,OAAW,GACjB,kBAAC,MAAD,CAAK,MAAO,CAAE,QAAS,OAAQ,SAAU,OAAQ,IAAK,CAAE,EACrD,UAAC,GAAG,IAAI,IAAI,OAAO,OAAOlB,EAAiB,MAAM,aAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAK,GAAY,kBAACa,EAAD,CAAkB,KAAK,QAAQ,MAAOC,IAAW,SAAW,QAAUA,EAAO,SAAS,MAAM,EAAI,SAAW,OACrM,SAAAA,CACE,EAFkGA,CAElG,CAAE,CACN,GACJvB,EAAO,OAAS,GAAM,kBAAA6B,EAAA,WACnB,kBAAC,OAAD,UAAM,SAAa,GACnB,kBAAC,MAAD,CAAK,MAAO,CAAE,QAAS,OAAQ,SAAU,OAAQ,IAAK,CAAE,EACrD,SAAA7B,EAAO,IAAK,GAAM,kBAACsB,EAAD,CAAgB,KAAK,QAAQ,MAAM,SAAU,SAAAQ,EAAE,IAAU,EAA/CA,EAAE,EAA6C,CAAC,CAC1E,EACL,GACD,CACF,GACL,qBAACF,GAAD,CAAqB,SAAUtB,EAAc,MAAQ,CAAC,EAAG,eAAgBJ,EAAkB,QAASI,EAAc,YAAcG,EAAiB,WAAY,YAAS,YAAaQ,GAAiB,CAAG,EAChM,CACL,G,EACE,EACd,C,uDCrEA,SAASc,GAAW,EAA8B,CAG9C,OAFIC,IAAU,KACH,MACJC,GAAmB,KAAM,GAAMC,EAAE,QAAUF,CAAK,CAAC,EAAE,OAASA,CACvE,CACA,SAASG,GAAkB,EAAsC,CAC7D,OAAOC,GAAwBC,CAAM,GAAK,MAC9C,CACA,SAAgBC,GAAmB,CAAE,SAAQ,WAAU,UAAS,WAAU,WAAkB,CACxF,IAAMC,EAAiBC,MAAcC,EAAsBC,EAAS,IAAI,IAAS,CAAE,GAAGC,EAAM,SAAU,CAAC,CAAE,EAAE,EAAG,CAAE,kBAAmB,EAAK,CAAC,EAAG,CAACD,CAAQ,CAAC,EAChJ,CAACE,EAAeC,GAAoBvE,EAAwB,IAAI,EAChE,CAACwE,EAAcC,GAAmBzE,EAAmB,CAAC,CAAC,EACvD,CAAC0E,EAAeC,GAAoB3E,EAAwB,IAAI,EAChE,CAAC4E,EAAkBC,GAAuB7E,EAAmB,CAAC,CAAC,EAC/D,CAAC8E,EAAgBC,GAAqB/E,EAAwB,IAAI,EAClE,CAACgF,GAAmBC,GAAwBjF,EAAmB,CAAC,CAAC,EACjE,CAAC0B,EAAQC,GAAa3B,EAGxB,CAAC,CAAC,EACAkF,EAAkBC,GAAsB9C,EAAQH,CAAO,EACvDkD,EAAeC,GAA0B,EAC/C7C,OAAgB,CACPN,GAAYgD,EAAgB,OAEjCX,EAAiBW,EAAgB,KAAK,eAAiB,IAAI,EAC3DT,EAAgBS,EAAgB,KAAK,YAAY,EACjDP,EAAiBO,EAAgB,KAAK,eAAiB,IAAI,EAC3DL,EAAoBK,EAAgB,KAAK,gBAAgB,EACzDH,EAAkBG,EAAgB,KAAK,gBAAkB,IAAI,EAC7DD,EAAqBC,EAAgB,KAAK,mBAAqB,CAAC,CAAC,EACjEvD,EAAUuD,EAAgB,KAAK,QAAU,CAAC,CAAC,EAC/C,EAAG,CAAChD,EAASgD,EAAgB,IAAI,CAAC,EAClC,IAAMzC,EAAa,SAAY,CAC3B,MAAM2C,EAAa,YAAY,CAC3B,OAAQ,CAAE,GAAI/C,CAAO,EACrB,KAAM,CAEF,UAAWiD,GAAYC,GAAajB,CAAa,EACjD,aAAcA,IAAkB,SAAWE,EAAe,CAAC,CAC/D,CACJ,CAAC,EACD1H,EAAM,QAAQ,SAAS,EACvB+D,EAAQ,CACZ,EACM2E,GAAiB3B,GAAkB,CAACS,EAAeI,EAAeI,CAAc,CAAC,EACjFW,GAAmBD,KAAmB,SACtC,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAIlB,IAAkB,SAAWE,EAAe,CAAC,EAAI,GAAGI,EAAkB,GAAGI,EAAiB,CAAC,CAAC,EAC7G,CAAC,EACP,MAAQ,kBAACjE,GAAD,CAAU,MAAO,UAAUmC,IAAqB,UAAS,SAAUrC,EAAS,KAAM4B,EAAY,cAAe,CAAE,SAAU,CAACyC,EAAgB,SAAU,EAAG,eAAgBE,EAAa,UAAW,MAAO,IAAtM,UAEN,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,EAA/B,UACE,kBAACM,EAAD,CAAM,UAAO,MAAO,CAAE,QAAS,QAAS,aAAc,CAAE,EAAG,qBAAgB,GAC3E,kBAACC,EAAD,CAAgB,UAAWjB,GAAiB,OAAQ,aAAcE,EAAkB,SAAUX,EAAgB,QAASiB,EAAgB,WAAY,WAAS,EACzJ,C,GAGJxD,EAAO,OAAS,GAAM,kBAAA6B,EAAA,WACnB,kBAACqC,GAAD,CAAS,OAAQ,EAAI,GACrB,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,EAA/B,UACE,kBAACF,EAAD,CAAM,UAAO,MAAO,CAAE,QAAS,QAAS,aAAc,CAAE,EAAxD,UAA2D,cAExDhE,EAAO,IAAK,GAAM,kBAACsB,EAAD,CAAgB,KAAK,QAAQ,MAAM,SAAS,MAAO,CAAE,WAAY,CAAE,EAAI,SAAAQ,EAAE,IAAU,EAAzEA,EAAE,EAAuE,CAAC,CACnG,CACN,qBAACmC,EAAD,CAAgB,UAAWb,GAAkB,OAAQ,aAAcE,GAAmB,SAAUf,EAAgB,QAASiB,EAAgB,WAAY,WAAS,EAC3J,CACL,MAEJ,kBAACU,GAAD,CAAS,OAAQ,EAAI,GAGrB,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,EAA/B,UACE,kBAACF,EAAD,CAAM,UAAO,MAAO,CAAE,QAAS,QAAS,aAAc,CAAE,EAAG,iBAAY,GACvE,kBAACC,EAAD,CAAgB,UAAWrB,EAA6B,eAAc,SAAUL,EAAgB,cAAeM,EAAkB,gBAAiBE,EAAiB,QAASS,EAAgB,WAAY,WAAS,EAC9M,C,GAEL,kBAACU,GAAD,CAAS,OAAQ,EAAI,GAGrB,kBAAC,MAAD,WACE,kBAACF,EAAD,CAAM,UAAO,MAAO,CAAE,QAAS,QAAS,aAAc,CAAE,EAAxD,UAA2D,UAEzD,kBAACA,EAAD,CAAM,KAAK,YAAY,MAAO,CAAE,WAAY,SAAU,WAAY,CAAE,EACjE,SAAAjC,GAAW+B,EAAc,CACtB,EACF,CACN,qBAACG,EAAD,CAAgB,UAAWH,GAAgB,aAAcC,GAAkB,SAAUxB,EAAgB,QAASiB,EAAgB,WAAY,WAAS,EAChJ,GACG,C,EACd,C,kDAjGQ,SAAS5G,C,OCHjB,SAAgBuH,GAAgB,CAAE,UAAS,OAAM,UAAS,aAAmC,CAEzF,IAAMC,EAAuBC,GAAeC,EAAa,OAAQ,CAAE,eAAgB,CAAE,OAAQ,EAAK,EAAG,WAAY,GAAM,CACnHC,EAAQ,kBAAkB,CAAE,SAAUC,GAAS,KAAM,CAAC,EACtDD,EAAQ,kBAAkB,CAAE,SAAUC,GAAS,OAAO1G,EAAK,EAAE,CAAE,CAAC,CACpE,CAAE,CAAC,EACG2G,EAAe,KAAO,KACxB,MAAML,EAAqB,YAAY,CAAE,OAAQ,CAAE,GAAItG,EAAK,EAAG,EAAG,KAAM4G,IAAW,KAAO,CAAE,YAAa,CAAC,QAAQ,CAAE,EAAI,CAAE,QAAO,CAAE,CAAC,EAC7HC,EAAIL,EAAa,OAAQ,CAAE,OAAQ,CAAE,GAAIxG,EAAK,EAAG,CAAE,CAAC,GAE/D,eAAe8G,EAAa,EAAa,CACrC,GAAI,CACAC,EAAU,MAAMJ,EAAaK,CAAG,CAAC,EACjC1J,EAAM,QAAQ,OAAO,EACrB+D,EAAQ,CACZ,OACO4F,EAAK,CACR3J,EAAM,MAAM2J,aAAe,OAASA,EAAI,QAAUA,EAAI,QAAU,QAAQ,CAC5E,CACJ,CACA,SAASC,GAAqB,CAC1BC,EAAc,CACV,MAAO,eACP,QAAS,oBACT,KAAM,SAAY,CACd,GAAI,CACAJ,EAAU,MAAMJ,EAAa,IAAI,CAAC,EAElCrJ,EAAM,QAAQ,OAAO,EACrB+D,EAAQ,CACZ,OACO4F,EAAK,CACR3J,EAAM,MAAM2J,aAAe,OAASA,EAAI,QAAUA,EAAI,QAAU,MAAM,CAC1E,CACJ,CACJ,CAAC,CACL,CACA,MAAQ,kBAACG,GAAD,CAA4B,UAAS,cAAepH,EAAK,OAAQ,eAAgBsG,EAAqB,UAAW,WAAYe,GAA8B,SAAUhG,EAAS,SAAW,GAAQ,KAAKyF,EAAaE,CAAG,EAAG,SAAUhH,EAAK,OAASkH,EAAqB,MAAW,EAC7R,C,mDC5BA,SAAgBI,GAAc,CAAE,SAAQ,WAAU,UAAS,mBAAkB,uBAAsB,WAAgC,CAC/H,IAAMC,EAAoBC,EAAmB,QAAU,YACjD,CAAClF,EAAWC,GAAgB/B,EAAkB+G,CAAQ,EAM5D,OAJAvE,OAAgB,CACPN,GACDH,EAAagF,CAAQ,CAC7B,EAAG,CAAC7E,EAAS6E,CAAQ,CAAC,EACd,kBAACE,GAAD,CAAW,MAAO,aAAa/D,IAAqB,UAAS,SAAUrC,EAAS,MAAO,KAAM,UAAW,CAAE,QAAS,aAAc,EAAG,cAC1I,2BAACuC,EAAD,CAAM,YAAY,OAAO,KAAK,OAAO,UAAWtB,EAAW,SAAW,GAAQC,EAAamF,CAAc,EAAzG,UACGF,GAAqB,kBAAC3D,EAAD,CAAS,IAAI,OAAO,QAAQ,QAC9C,2BAAC8D,GAAD,CAAoB,MAAO,CAAE,KAAM,OAAQ,QAAO,EAAG,QAASjF,GAAWJ,IAAc,QAAS,kBAAkB,sBAAuB,EAClI,GACVsF,GAAyB,kBAAC/D,EAAD,CAAS,IAAI,OAAO,QAAQ,YAClD,2BAACgE,GAAD,CAAwB,MAAO,CAAE,KAAM,OAAQ,QAAO,EAAG,QAASnF,GAAWJ,IAAc,YAAa,kBAAkB,0BAA2B,EAC9I,EACP,C,EACG,EACf,C,+CC7BA,SAAwBwF,GAAuB,CAAE,SAAQ,QAAO,QAAQ,KAAM,eAAc,cAA+B,CACvH,IAAM9G,EAAQV,EAAyB,IAAI,EACrCyH,EAASzH,EAAO,EAAK,EACrB,CAAC0H,EAASC,GAAczH,EAAS,EAAK,EACtC,CAAC0H,EAAWC,GAAgB3H,EAAsC,OAAO,EACzE,CAAC6C,EAAQ+E,GAAa5H,EAAkC,IAAI,EAC5D,CAACkC,GAAS2F,GAAc7H,EAAS,EAAK,EACtC8H,EAAQ,GAAiB,EACvB,IAAiBC,EAAa,KAElC,EAAO,QAAUC,EACjBxH,EAAM,SAAS,MAAM,EACzB,EACMyH,EAAS,KAAO,IAAe,CACjCJ,EAAW,EAAI,EACfJ,EAAW,EAAI,EACfG,EAAU,IAAI,EACd,GAAI,CACA,IAAMM,EAAW,MAAMC,GAAY,OAAOC,GAAe,CAAE,KAAM,CAAE,OAAM,OAAQb,EAAO,QAAU,OAAS,QAAS,WAAU,CAAE,CAAC,EACjIK,EAAUM,CAAQ,EACbX,EAAO,SACRc,IAAa,CACrB,OACOlI,EAAO,CACVrD,EAAM,MAAMqD,aAAiB,MAAQA,EAAM,QAAU,MAAM,EAC3D0H,EAAW,EAAK,CACpB,QACQ,CACJJ,EAAW,EAAK,CACpB,CACJ,EACMa,EAAW,SAAY,CAAiE,IAAMC,EAAO,MAAM,MAA3DJ,GAAY,SAASK,EAAgB,GAA+B,KAAK,EAAGC,GAAaF,EAAM,GAAGG,EAAM,UAAU,CAAG,EAG3K,OAFIxL,IAAW,iBAER,kBAAAqG,EAAA,WACT,kBAAC,QAAD,CAAO,IAAK/C,EAAO,KAAK,OAAO,OAAO,QAAQ,MAAO,CAAE,QAAS,MAAO,EAAG,SAAU,GAAS,CACnF,IAAMmI,EAAOC,EAAM,OAAO,QAAQ,GAClC,EAAM,OAAO,MAAQ,GACjBD,GACAV,EAAYU,CAAI,CACxB,CAAG,GACT,kBAACE,EAAD,CAAU,QAAQ,QAAQ,SAAS,aAAa,eAAY,OAAQ,kBAACA,EAAS,KAAV,WACnE,kBAACA,EAAS,KAAV,CAAe,YAAef,EAAK,EAAK,EAAG,iBAAqB,GAChE,kBAACe,EAAS,KAAV,CAAe,YAAef,EAAK,EAAI,EAAG,uBAA2B,GACrE,kBAACe,EAAS,KAAV,CAAe,YAAe,KAAKP,EAAS,EAAG,iBAAqB,GACpE,kBAACO,EAAS,KAAV,UAAe,kBAACC,EAAD,CAAQ,aAAW,SAAS,MAAOpB,EAAW,SAAU,GAASC,EAAa3G,CAAyB,EAAG,WAAY,CAAC,CAAE,MAAO,QAAS,MAAO,OAAQ,EAAG,CAAE,MAAO,OAAQ,MAAO,QAAS,EAAG,CAAE,MAAO,SAAU,MAAO,QAAS,CAAC,CAAG,EAAgB,EACvP,IAAG,2BAACxC,EAAD,CAAQ,KAAM,kBAACuK,EAAD,CAAQ,KAAM,EAAI,GAAG,QAASvB,EAA5C,UAAsDhL,EAAM,IAAC,kBAACwM,GAAD,CAAa,KAAM,EAAI,EAAS,C,EAAW,GAC1H,kBAAC1L,GAAD,CAAO,MAAO,GAAGoL,EAAM,IAAc,WAAS,aAAc,GAAO,SAAU,CAAClB,EAAS,aAAgBK,EAAW,EAAK,EAAG,MAAO,IAAK,OAAQ,kBAACrJ,EAAD,CAAQ,KAAK,UAAU,SAAUgJ,EAAS,YAAeK,EAAW,EAAK,EAAG,aAAU,GAClO,SAAAL,EAAU,kBAAClJ,EAAW,KAAZ,UAAiB,mBAAkC,GAAIuE,GAAU,kBAAAU,EAAA,WAC1EV,EAAO,QAAU,kBAACvE,EAAW,KAAZ,CAAiB,KAAK,UAAU,8BAAoC,GACtF,kBAACA,EAAW,UAAZ,WAAsB,KAAGuE,EAAO,MAAM,SAAOA,EAAO,QAAQ,OAAKA,EAAO,OAAO,OAAKA,EAAO,OAA8B,IACzH,kBAACoG,EAAD,CAAO,OAAO,MAAM,KAAK,QAAQ,WAAYpG,EAAO,KAAM,QAAS,CAAC,CAAE,MAAO,IAAK,UAAW,MAAO,MAAO,EAAG,EAAG,CAAE,MAAO,KAAM,UAAW,OAAQ,EAAG,CAAE,MAAO,KAAM,UAAW,SAAU,MAAO,GAAI,OAAS,GAAmB,kBAACG,EAAD,CAAK,MAAOvG,IAAW,SAAW,MAAQA,IAAW,UAAY,QAAU,OAAS,SAAAA,IAAW,SAAW,KAAOA,IAAW,UAAY,KAAO,IAAU,EAAE,EAAG,CAAE,MAAO,KAAM,UAAW,SAAU,CAAC,EAAG,WAAY,CAAE,SAAU,CAAE,CAAG,EACnc,GACI,EACN,IArBY,IAsBf,C,mDCjEA,SAAgByM,GAAa,EAAsD,CAC/E,MAAO,kBAAC5B,GAAD,CAAwB,GAAI6B,CAAO,EAC9C,C,2CCcA,SAAgBC,GAAc,CAAE,SAAQ,KAAI,QAAO,SAA6B,CAC5E,IAAMC,EAAQvL,GAAiB,CAAE,SAAQ,KAAI,OAAM,CAAC,EACpD,GAAIkD,GAAS,MAAQA,IAAU,GAC3B,MAAO,kBAAC1C,EAAW,KAAZ,CAAiB,KAAK,aAAc,SAAAJ,EAAmC,GAClF,IAAMoL,EAAaD,EAAM,UAAYA,EAAM,UACrClL,EAAOkL,EAAM,UAAYrI,EAC/B,MAAQ,kBAAC,OAAD,CAAM,UAAU,iBAAhB,UACN,kBAAC1C,EAAW,KAAZ,CAAiB,SAAU,CAAE,YAAa,EAAK,EAAG,MAAO,CAAE,SAAU,CAAE,EAAI,SAAAH,CAAsB,GAChGmL,IAAeD,EAAM,WAAa,KAAQ,kBAAC9K,EAAD,CAAS,QAAQ,aACtD,2BAACC,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAM,kBAACC,GAAD,CAAK,KAAM,EAAI,GAAG,QAAS4K,EAAM,UAAW,aAAW,OAAO,YAAe,KAAKA,EAAM,KAAK,CAAG,EACvJ,GAAM,kBAAA9F,EAAA,WACb,kBAAChF,EAAD,CAAS,QAAQ,OACf,2BAACC,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAM,kBAAC+K,GAAD,CAAM,KAAM,EAAI,GAAG,aAAW,OAAO,YAAe,KAAKC,EAAkBH,EAAM,UAAY,EAAE,CAAG,EACzJ,GACT,kBAAC9K,EAAD,CAAS,QAAQ,KACf,2BAACC,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAM,kBAACE,GAAD,CAAQ,KAAM,EAAI,GAAG,aAAW,OAAO,QAAS2K,EAAM,IAAM,EACnH,EACT,IACF,C,EACV,C,iEC8CA,SAASI,EAAY,EAA8B,CAC/C,OAAOjK,EAAK,SAAS,KAAK,CAAC,CAAC,YAAY,IAAM,OAClD,CACA,SAAwBkK,IAAY,CAChC,GAAM,CAAE,iBAAkBC,GAAc,EAClC,CAAE,aAAY,KAAMC,GAAgBC,GAAQ,EAC5C,CAAE,OAAM,WAAU,kBAAiB,cAAa,OAAM,cAAa,kBAAiB,gBAAc,cAAa,eAAgBC,GAA4B,CAAE,SAAUC,GAAqB,QAAS7D,GAAS,KAAM,CAAC,EAC3N8D,GAAgB,CAAC,SAAS,EAAI,GAAWC,EAAY,CAAE,GAAGF,GAAqB,QAASG,EAAO,SAAW,EAAG,CAAC,CAAC,EAC/G,GAAM,CAACC,EAA2BC,GAAgCpK,EAAS,EAAK,EAE1EqK,EAAuBvK,EAAuB,IAAI,EAClD,CAACwK,GAAcC,IAAmBvK,EAAsB,IAAI,EAC5D,CAACwK,GAAiBC,GAAsBzK,EAAS,EAAK,EACtD,CAAC0K,EAAcC,IAAmB3K,EAAsB,IAAI,EAC5D,CAAC4K,GAAiBC,IAAsB7K,EAAS,EAAK,EACtD,CAAC8K,EAAgBC,IAAqB/K,EAAsB,IAAI,EAChE,CAACgL,GAAmBC,IAAwBjL,EAAS,EAAK,EAC1D,CAACkL,GAAeC,IAAoBnL,EAAmB,CAAC,CAAC,EACzD,CAACoL,GAAYC,IAAiBrL,EAAsB,IAAI,EACxD,CAACsL,GAAoBC,IAAyBvL,EAAS,EAAK,EAC5D,CAACwL,EAAUC,IAAezL,EAAsB,IAAI,EACpD,CAAC0L,GAAaC,IAAkB3L,EAAS,EAAK,EAE9C4L,EADgBC,GACG,EAAc,MAAM,gBAAkB,GACzD,CAACC,GAAiBC,IAAsB/L,EAA6B,IAAI,EACzE,CAACgM,GAAcC,IAAmBjM,EAAS,EAAE,EAC7C,CAACkM,GAAYC,IAAiBnM,EAAS,EAAE,EACzC,CAACoM,GAAaC,IAAkBrM,EAAS,EAAE,EAC3C,CAAE,MAAOsM,IAAgBC,GAAa,eAAe,EACrD,CAAE,QAASC,IAAkBD,GAAa,aAAa,EACvD,CAAChQ,EAAiBkQ,GAAsBzM,EAAmB,CAAC,CAAC,EAC7D,CAAC0M,GAAsBC,IAA2B3M,EAAmB,CAAC,CAAC,EACvE4M,EAAeC,EAAc,kBAAkB,EAC/CC,GAAqBD,EAAc,wBAAwB,EAC3DE,GAAmBF,EAAc,sBAAsB,EACvDG,GAAgBC,GAAY,CAAE,QAASL,CAAa,CAAC,EACrDM,GAAsBC,GAAmB,CAAE,QAASL,EAAmB,CAAC,EACxEM,GAAoBC,GAAgB,CAAE,QAASN,EAAiB,CAAC,EACjEO,GAAkBC,GAAc,EAChCC,EAAWR,GAAc,MAAQS,GACjCC,EAAiBR,GAAoB,MAAQS,GAC7CC,GAAeR,GAAkB,MAAQS,GACzCC,EAAwCR,GAAgB,MAAM,iBAAiB,UAAY,KAE3FS,GAAcC,GAAe,CAC/B,QAASC,EAAgB,QACzB,MAAOA,EAAgB,MACvB,aAAcA,EAAgB,aAC9B,OAAQ3I,GAAY4I,GAAeD,EAAgB,MAAM,EACzD,GAAGE,GAA0BF,EAAgB,SAAS,CAC1D,CAAC,EACKG,EAAYC,GAAY,CAAE,OAAM,WAAU,GAAGN,EAAY,CAAC,EAC1DO,EAAWF,EAAU,MAAM,MAAQG,GACnCnJ,GAAeoJ,GAAY,EAC3BC,GAAwBC,GAAqB,EAC7CC,GAAiBC,GAAe,EAChCC,GAAiBC,GAAc,EAC/BC,GAAsBC,GAAmB,EACzCC,GAAuBD,GAAmB,EAC1CE,GAAwBC,GAAqB,EAC7CC,GAAsBC,GAAmB,EACzCC,GAAgClN,GAA4B0I,GAAgB,GAAIE,EAAiB,EACjGuE,GAAuBC,GAAoB,EAE3CC,GAAqB3P,EAA+D,IAAI,EACxF4P,EAAQC,GAAoD,CAC9D,WAAY,KACZ,KAAMC,GAAiBxK,GAAc,CAAE,OAAQY,EAAa,OAAO,MAAM,MAAM,KAAM,OAAQA,EAAa,OAAO,MAAM,MAAM,IAAK,CAAC,EACnI,UAAW6J,GACX,SAAU,CACN,YAAa,CAAC,EACd,QAAS,CAAC,EACV,OAAQ,SACZ,EACA,SAAW,IAAU,CACjB,SAAUrQ,EAAK,SACf,SAAUA,EAAK,SACf,MAAOA,EAAK,OAAS,OACrB,MAAOA,EAAK,OAAS,OACrB,OAAQA,EAAK,QAAU,OACvB,UAAWA,EAAK,WAAa,OAC7B,aAAcA,EAAK,cAAgB,OACnC,YAAaA,EAAK,aAAeA,EAAK,WAAW,IAAK,GAAS6E,EAAK,EAAE,GAAK,CAAC,EAC5E,QAAS7E,EAAK,MAAM,IAAK,GAAMsQ,EAAE,EAAE,EACnC,OAAQtQ,EAAK,MACjB,GACA,YAAa,EAAW,CAAE,aAAc,CACpC,IAAM5B,EAAU6R,GAAmB,QAC7BhP,EAAU7C,EAAUA,EAAQ,MAAMmS,CAA+C,EAAIA,EACrFC,EAA8E,CAAC,EACjFC,IACIxP,EAAO,cAAsBuP,EAAY,KAAK,cAAc,EAC5D,UAAWvP,GAAU,CAACA,EAAO,OAAOuP,EAAY,KAAK,OAAO,EAC5D,UAAWvP,GAAU,CAACA,EAAO,OAAOuP,EAAY,KAAK,OAAO,EAC3DvP,EAAO,QAAQuP,EAAY,KAAK,QAAQ,EACxCvP,EAAO,WAAWuP,EAAY,KAAK,WAAW,GAEvD,IAAME,EAA2B,CAC7B,SAAUzP,EAAO,SAAU,SAAUA,EAAO,SAC5C,MAAOA,EAAO,OAAS,OAAW,MAAOA,EAAO,OAAS,OACzD,aAAcA,EAAO,cAAgB,OACrC,OAAQA,EAAO,QAAU,OACzB,UAAWA,EAAO,UAAY0P,GAAiB1P,EAAO,SAAS,EAAI,OACnE,YAAaA,EAAO,aAAe,CAAC,EAAG,QAASA,EAAO,SAAW,CAAC,EAAG,OAAQA,EAAO,OACrF,GAAIwP,EAAU,CAAE,aAAY,EAAI,CAAE,SAAUxP,EAAO,QAAS,CAChE,EAYA,MAVM,UAAWA,GACb,OAAOyP,EAAQ,MACb,UAAWzP,GACb,OAAOyP,EAAQ,MACfD,GAAWxG,EAAYwG,CAAO,GAAKxP,EAAO,SAAW,aACrD3D,EAAM,QAAQ,eAAe,EAC7BsT,GAAY,wBAAwB,GAEpCxE,EACO,CAAE,aAAcsE,EAAQ,aAAc,YAAaA,EAAQ,YAAa,QAASA,EAAQ,QAAS,OAAQA,EAAQ,OAAQ,YAAazP,EAAO,cAAgB,KAAO,CAAC,cAAc,EAAI,CAAC,CAAE,EAC/LyP,CACX,EACA,WAAY,EAChB,CAAC,EACKG,GAAcX,EAAM,QAC1BY,GAA6B,CAAE,SAAU,QAAS,MAAO,KAAM,WAAY,cAAe,gBAAe,QACrG,KAAMtK,EAAa,KAAM,OAAQA,EAAa,OAAQ,OAAQA,EAAa,OAAO,MAAM,MAAM,KAAM,OAAQA,EAAa,OAAO,MAAM,MAAM,KAC5I,aAAc,CAAC,WAAY,QAAS,QAAS,eAAgB,cAAe,UAAW,SAAU,YAAa,SAAU,aAAa,EAAG,kBAAmB,CAAC,QAAS,QAAS,eAAgB,SAAU,WAAW,EACnN,OAAQ,CAAC,KAAM,WAAY,WAAY,QAAS,QAAS,SAAU,YAAa,eAAgB,iBAAkB,SAAU,YAAa,WAAW,EACpJ,QAAS+H,GAAa,YAAaxR,EAAiB,UAAW,CAACqP,EAAkB,OAAQ,GAAM+C,GAAe,YAAY,CAAC7L,CAAE,CAAC,EAAG,cAAiB2J,EAAmB,CAAC,CAAC,EAAG,KAAMtC,GAA6BK,IAAmBI,IAAmBI,IAAqBM,IAAsBI,IAAeI,KAAoB,KAClU,aAAc,EAAQ,IAAW,CAAE,GAAIyE,IAAW,UAAY9G,EAAY+G,CAAM,EAAG,MAAU,MAAM,eAAe,CAAG,EACrH,aAAc,EAAQ,IAAW,CAC7B,GAAIA,GAAU,aAAc/P,EAAQ,MAAU,MAAM,YAAY,EAChE,GAAI+P,GAAU,CAAC,QAAS,OAAO,CAAC,CAAC,KAAK,GAASxS,KAASyC,GAAUgQ,GAAmBD,EAAOxS,EAA2B,CAAC,EAAG,MAAU,MAAM,mBAAmB,EAC9J,GAAI4N,GAAoB,CAAC,WAAY,WAAY,QAAS,QAAS,SAAU,WAAW,CAAC,CAAC,KAAK,GAAS5N,KAASyC,CAAM,EAAG,MAAU,MAAM,eAAe,EACzJ,GAAI,CAACqM,IAAsB,iBAAkBrM,GAAU,CAACsM,IAAoB,MAAM,QAAQtM,EAAO,WAAW,GAAKA,EAAO,YAAY,OAAS,GAAK,CAACmM,GAAgB,MAAM,QAAQnM,EAAO,OAAO,GAAKA,EAAO,QAAQ,OAAS,EAAG,MAAU,MAAM,aAAa,CAChQ,EACA,QAAS,CAAC,CAAE,KAAM,cAAe,MAAO,KAAM,UAAWiQ,GAAmB,KAAM,WAAY,yBAA0B,OAAQ,CAAC,KAAM,OAAQ,UAAU,CAAE,EACvJ,CAAE,KAAM,YAAa,MAAO,KAAM,UAAWC,GAAiB,IAAK,WAAY,uBAAwB,OAAQ,CAAC,KAAM,OAAQ,MAAM,CAAE,EACtI,CAAE,KAAM,QAAS,MAAO,KAAM,UAAWC,GAAa,IAAK,WAAY,mBAAoB,OAAQ,CAAC,KAAM,OAAQ,MAAM,CAAE,CAAC,CAAE,CAAC,EACtI,IAAMC,GAAkBvR,GAA6B,CAAE,OAAQ,OAAQ,OAAQ,CAAC,QAAS,OAAO,EAAG,OAAQ+Q,EAAY,CAAC,EACxH,GAAmB,QAAUQ,GAC7B,IAAMC,EAAgBnB,GAA4C,CAC9D,KAAM,CACF,YAAa,MAAO,CAAE,KAAI,aAClB7M,GACAsN,GAAY,cAAc,EAC9B,MAAM3B,GAAsB,YAAY,CAAE,OAAQ,CAAE,IAAG,EAAG,KAAM,CAAE,SAAUhO,EAAO,QAAS,CAAE,CAAC,EACxF,CAAC,GAEZ,UAAW,EACf,EACA,WAAa,IACLA,EAAO,WAAaA,EAAO,kBAC3B3D,EAAM,MAAM,WAAW,EACvBsT,GAAY,oBAAoB,GAE7B3P,GAEX,mBAAsB,SACtB,YAAe0L,GAAc,EAAE,CACnC,CAAC,EAEKnF,GAAmB6F,EAAc,kBAAkB,EACnDzF,GAAuByF,EAAc,sBAAsB,EAC3DkE,GAAkB/J,IAAoBI,GACtC4J,GAAyB9M,MAAc,CACzC,GAAI,CAACoK,EAAS,OACV,MAAO,GACX,IAAM2C,EAAc,IAAI,IAAI1U,CAAe,EAC3C,OAAO+R,EAAS,OAAQ,GAAS2C,EAAY,IAAI5M,EAAK,EAAE,GAAK,CAACoF,EAAYpF,CAAI,CAAC,CAAC,CAAC,MACrF,EAAG,CAACiK,EAAU/R,CAAe,CAAC,EACxB2U,EAAsBhN,MAAc,CACtC,GAAI,CAACoK,EAAS,OACV,MAAO,CAAC,EACZ,IAAM2C,EAAc,IAAI,IAAI1U,CAAe,EAC3C,OAAO+R,EAAS,OAAQ,GAAS2C,EAAY,IAAI5M,EAAK,EAAE,GAAK,CAACoF,EAAYpF,CAAI,CAAC,CAAC,CAAC,IAAK,GAASA,EAAK,EAAE,CAC1G,EAAG,CAACiK,EAAU/R,CAAe,CAAC,EACxBE,GAAS0U,GAAsB,CACjC,QAAS,EAAM,IAAYlC,GAAqB,YAAY,CAAE,KAAM,CAAE,IAAK,CAACzP,EAAK,EAAE,EAAG,OAAQ4R,EAAU,UAAY,UAAW,CAAE,CAAC,EAClI,eAAiB,IAAU,CAAE,OAAQ,GAAM,MAAO,UAAU5R,EAAK,UAAYA,EAAK,SAAS,IAAK,QAAS,eAAgB,OAAQ,MAAO,GACxI,SAAW,GAASiK,EAAYjK,CAAI,GAAK,CAACqN,EAAc,oBAAoB,CAChF,CAAC,EAEKwE,GAAoBhV,GAAmB,CACzC,gBAAiB6U,EACjB,mBAAsBzE,EAAmB,CAAC,CAAC,EAC3C,KAAM,EAAK,IAAWsC,GAAoB,YAAY,CAAE,KAAM,CAAE,MAAK,QAAO,CAAE,CAAC,EAC/E,QAAS,SACT,OAAQ,MACR,eAAiB,GAAYtS,IAAW,WAAa,eAAiB,eACtE,OAAQ,EACZ,CAAC,EACK6U,OAA0B,CAC5B,IAAMC,EAAejD,EAChB,OAAQ,GAAS/R,EAAgB,SAAS8H,EAAK,EAAE,GAAK,CAACoF,EAAYpF,CAAI,CAAC,CAAC,CACzE,IAAK,GAASA,EAAK,EAAE,EACtBkN,EAAa,SAAW,EACxBzU,EAAM,QAAQ,eAAe,EAGjC0U,GAAiB,CACb,MAAO,WAAWD,EAAa,OAAO,OACtC,QAAS,iBACT,QAAW5C,GAAe,YAAY4C,CAAY,EAClD,eAAgB,SAChB,cAAiB9E,EAAmB,CAAC,CAAC,CAC1C,CAAC,CACL,EACMgF,GAAqBvN,MAA8BwN,GAAsBhE,EAAgB,CAAE,kBAAmB,EAAK,CAAC,EAAG,CAACA,CAAc,CAAC,EACvIiE,GAA2BzN,MAA8B,CAAC,CAAE,IAAK0N,EAAqB,MAAOA,EAAqB,MAAO,MAAO,EAAG,GAAGH,EAAkB,EAAG,CAACA,EAAkB,CAAC,EAC/KI,EAAsB3N,MAAcwJ,EAAe,IAAK,GAAS,OAAOrJ,EAAK,EAAE,CAAC,EAAG,CAACqJ,CAAc,CAAC,EAEnGoE,GAA0BhS,EAAO,EAAK,EAC5C0C,OAAgB,CACRsP,GAAwB,SAAWpE,EAAe,SAAW,IAEjE,GAAwB,QAAU,GAClCf,GAAwBkF,CAAmB,EAC/C,EAAG,CAACA,EAAqBnE,EAAe,MAAM,CAAC,EAC/C,IAAMqE,GAAoBC,GAAkBtF,GAAsBmF,CAAmB,EACrF,SAASI,IAAsB,CAC3BtF,GAAwBoF,GAAoB,CAAC,EAAIF,CAAmB,CACxE,CACA,IAAMK,GAAqBhO,MAAc0J,GAAa,IAAK,IAAU,CAAE,MAAOvJ,EAAK,GAAI,MAAOA,EAAK,IAAK,EAAE,EAAG,CAACuJ,EAAY,CAAC,EACrHuE,GAAazC,EAAM,WACnB0C,GAAW1C,EAAM,SACjB2C,GAAevB,EAAc,SAC7B,CAAE,YAAawB,IAAezD,GAC9B0D,GAAeC,GAAY,KAAO,IAAe,CACnD,MAAMF,GAAW,CAAE,OAAQ,CAAE,IAAG,CAAE,CAAC,EACnCxV,EAAM,QAAQ,YAAY,CAC9B,EAAG,CAACwV,EAAU,CAAC,EACT,CAAE,YAAaG,GAAqBlD,GACpC,CAAE,QAASmD,IAAoBtE,EAG/BuE,GAA+BzO,MAAc,CAC/C,CACI,MAAO,KACP,UAAW,WACX,SAAU,IACV,SAAU,CAAE,UAAW,EAAM,EAC7B,QAAS,EAAY,IAAkB,kBAAC,MAAD,CAAK,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,SAAU,CAAE,EAAzE,UACzC,kBAAC,OAAD,CAAM,MAAOsM,EAAO,SAAW,KAAO,KAAM,MAAO,CACzC,WAAY,EACZ,MAAO,EACP,OAAQ,EACR,aAAc,MACd,WAAYA,EAAO,SAAW,gCAAkC,+BAChE,QAAS,eACT,UAAWA,EAAO,SAAW,+EAAiF,MAClH,CAAG,GACT,kBAACoC,GAAD,CAAY,KAAMpC,EAAO,UAAYA,EAAO,SAAU,OAAQA,EAAO,OAAQ,KAAM,EAAI,GACvF,kBAAC,OAAD,CAAM,UAAU,sBAAsB,MAAO,GAAGA,EAAO,qBAAuBA,EAAO,SAAS,GAAGA,EAAO,kBAAoBA,EAAO,SAAS,GAA5I,UACGA,EAAO,qBAAuBA,EAAO,SAAS,IAAEA,EAAO,kBAAoBA,EAAO,SAAS,IAAEA,EAAO,gBAAkB,WAAa,kBAACxN,EAAD,CAAK,KAAK,QAAV,UAAkB,aAAWwN,EAAO,eAAiB,SAAW,KAAO,OAAa,C,EACpN,C,GACLA,EAAO,wBAA2B,kBAACxN,EAAD,CAAK,KAAK,QAAQ,MAAM,SAAS,MAAO,CAAE,WAAY,CAAE,EAAG,eAAS,EACpG,C,EACL,EACA,CACI,MAAO,OACP,UAAW,QACX,MAAO,IACP,QAAS,EAA8B,IAAiB,kBAACoG,GAAD,CAAe,OAAO,OAAO,GAAIoH,EAAO,GAAI,MAAM,QAAQ,MAAOqC,CAAG,EAChI,EACA,CACI,MAAO,KACP,UAAW,QACX,cAAe,GACf,MAAO,IACP,QAAS,EAA8B,IAAiB,kBAACzJ,GAAD,CAAe,OAAO,OAAO,GAAIoH,EAAO,GAAI,MAAM,QAAQ,MAAOqC,CAAG,EAChI,EACA,CACI,MAAO,KACP,UAAW,iBACX,MAAO,IACP,OAAQC,EACZ,EACA,CAAE,GAAGC,GAAwB,CACrB,MAAO,KACP,UAAW,YACX,MAAO,IACP,aAAc,IACd,SAAW,IAAgBC,GAAwC,CAAC,GAC/D,IAAK,IAAU,CAAE,IAAK,OAAO3O,EAAK,EAAE,EAAG,MAAOA,EAAK,IAAK,EAAE,EAC/D,SAAU,SACV,aAAc,IACd,MAAO,kBAACrB,EAAD,CAAK,MAAM,OAAO,cAAQ,EACrC,CAAC,EAAG,cAAe,EAAK,EAC5B+P,GAAwB,CACpB,MAAO,KACP,UAAW,QACX,MAAO,IACP,aAAc,IACd,SAAW,GAAWE,EAAiB,IAAK,IAAU,CAAE,IAAK,OAAOC,EAAK,EAAE,EAAG,MAAOA,EAAK,IAAK,EAAE,EACjG,SAAU,OACV,aAAc,IACd,MAAO,kBAAClQ,EAAD,CAAK,MAAM,OAAO,cAAQ,EACrC,CAAC,EACD,CACI,MAAO,KACP,UAAW,SACX,cAAe,GACf,MAAO,GACP,OAAS,GAAsCmQ,EAAS,kBAACC,GAAD,CAAS,SAAS,cAAc,MAAOD,CAAQ,GAAI,IAC/G,EACAE,GAAe,OAAQ,cAAe,CAAE,cAAe,EAAK,CAAC,EAC7DA,GAAe,OAAQ,eAAgB,CAAE,cAAe,EAAK,CAAC,EAC9D,CAAE,MAAO,OAAQ,IAAK,YAAa,cAAe,GAAM,MAAO,IAAK,QAAS,EAAY,IAAiB,kBAACC,GAAD,CAAsB,UAAW,CAAE,KAAM,gBAAiB,IAAK,OAAO9C,EAAO,EAAE,CAAE,CAAG,EAAE,EAChM,CAAE,GAAG+C,GAAiB,cAAe,EAAK,EAC1C9W,GAAO,OAAO,EACd+W,GAA4B,CACxB,MAAO,IACP,kBAAmB,CAAC,OAAQ,QAAQ,EACpC,QAAU,GAAW,CACjB,IAAMC,EAAUhK,EAAY+G,CAAM,EAClC,MAAO,CACH,CACI,IAAK,OACL,MAAO5E,EAAmB,QAAU,KACpC,OAAQ,CAACiB,EAAc,oBAAoB,EAC3C,YAAe,CACXuF,GAAS5B,CAAM,CACnB,CACJ,EACA,CAAE,IAAK,oBAAqB,MAAO,SAAU,OAAQ,CAAC5E,GAAoB,CAACiB,EAAc,oBAAoB,EAAG,YAAed,GAAmByE,CAAM,CAAE,EAC1JkD,GAAa,CACT,OAAQ9H,GAAoB,CAACiB,EAAc,oBAAoB,EAC/D,SAAU4G,EACV,eAAgB,gBAChB,MAAO,aACP,QAAW9E,GAAe,YAAY,CAAC6B,EAAO,EAAE,CAAC,CACrD,CAAC,EACD,CACI,IAAK,SACL,MAAO,OACP,OAAQ5E,GAAoB,CAACiB,EAAc,oBAAoB,EAC/D,YAAe,CACXxB,GAAcmF,CAAM,EACpBjF,GAAsB,EAAI,CAC9B,CACJ,EACA,CACI,IAAK,WACL,MAAO,OACP,OAAQK,GAAoB,CAACiB,EAAc,oBAAoB,EAC/D,YAAe,CACXwF,GAAa7B,CAAM,CACvB,CACJ,EACA,CACI,IAAK,SACL,MAAO,YACP,OAAQ,CAACA,EAAO,wBAA0B,CAAC3D,EAAc,oBAAoB,EAC7E,YAAe0F,GAAa/B,EAAO,EAAE,CACzC,EACA,CACI,IAAK,OACL,MAAO,UAEP,OAAQ,CAACO,GACT,YAAe,CACXtF,GAAY+E,CAAM,EAClB7E,GAAe,EAAI,CACvB,CACJ,EACA,CACI,IAAK,kBACL,MAAO,OACP,OAAQ,CAACkB,EAAc,oBAAoB,EAC3C,YAAe,CACXtC,GAAgBiG,CAAM,EACtB/F,EAAmB,EAAI,CAC3B,CACJ,EACA,CACI,IAAK,cACL,MAAO,OACP,OAAQ,CAACoC,EAAc,oBAAoB,EAC3C,YAAe,CACX9B,GAAkByF,CAAM,EACxBrF,GAAiBqF,EAAO,MAAM,IAAK,GAAMV,EAAE,EAAE,CAAC,EAC9C7E,GAAqB,EAAI,CAC7B,CACJ,EACA,CACI,IAAK,kBACL,MAAO,OACP,OAAQ,CAAC4B,EAAc,oBAAoB,EAC3C,YAAe,CACXlC,GAAgB6F,CAAM,EACtB3F,GAAmB,EAAI,CAC3B,CACJ,EACA,CACI,IAAK,eACL,MAAO,OACP,OAAQ,GACR,cAAe,GAEf,OAAQ,CAACgC,EAAc,4BAA4B,EACnD,SAAU,CAAC2D,EAAO,SAClB,eAAgB,WAChB,YAAe,CACXnT,GAAc,CACV,MAAO,OACP,QAAS,aAAamT,EAAO,SAAS,GAAGA,EAAO,SAAS,WACzD,KAAM,SAAY,CACd,MAAMiC,EAAiB,CAAE,OAAQ,CAAE,GAAIjC,EAAO,EAAG,CAAE,CAAC,EACpD1T,EAAM,QAAQ,OAAO,EACrB4V,GAAqB,CACzB,CACJ,CAAC,CACL,CACJ,CACJ,CACJ,CACJ,CAAC,CACL,EAAG,CAAC9G,EAAkBiB,EAAepQ,GAAQkS,GAAgB4D,GAAcE,EAAkBC,GAAiBN,GAAUC,GAActB,EAAe,CAAC,EAChJ,CAAC4C,GAAcC,IAAmB5T,EAAS,EAAK,EAChD,CAAC6T,GAAgBC,IAAqB9T,EAAS,EAAK,EACpD+T,GAAiB,kBAAC,MAAD,CAAK,UAAU,qBAAf,UACrB,kBAACC,GAAmB,OAApB,CAA2B,UAAU,2BAA2B,MAAO,CAAE,QAAS,YAAa,UAAW,GAAI,aAAc,CAAE,EAAG,MAAQ,kBAACxV,EAAD,CAAQ,UAAU,yBAAyB,MAAM,aAAa,KAAK,QAAQ,KAA0ByV,EAApBlC,GAAqBmC,GAA8BC,GAA/B,CAAgB,KAAM,EAAI,CAA8B,EAAG,QAASlC,GAC3S,SAAAF,GAAoB,OAAS,MACxB,GACV,2BAAC,OAAD,CAAM,UAAU,gCAAgC,eAAU,EACjC,GAC3B,kBAACqC,EAAD,CAAM,aAAU,SAAUzC,GAA0B,aAAcjF,GAAsB,MAAO2H,EAAY,eAAiB,OAAYzC,EAAsB,OAAOyC,EAAY,YAAY,EAAG,gBAAiB,EAAO,EAAO,IAASnT,EAAK,MAAQ0Q,GAAuB,OAAO1Q,EAAK,OAAS,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,SAASV,EAAM,kBAAkB,CAAC,EAAG,oBAAiB,kBAAkB,OAAO,SAAW,GAAiB,CAC9ZmM,GAAyB2H,EAAwC,IAAI,MAAM,CAAC,CAChF,EAAG,SAAW,GAAgB,CAC1B,IAAMC,EAAYC,IAAgB5C,EAAsB,OAAY,OAAO4C,CAAW,EAChFC,EAAY,CAAE,GAAGJ,EAAa,aAAcE,CAAU,EAC5DtK,EAAYwK,CAAS,EACrBb,GAAgB,EAAK,CACzB,EAAG,MAAO,CAAE,MAAO,MAAO,CAAG,EAC5B,C,GACCc,IAA0B,EAAe,KAAW,kBAAClW,EAAD,CAAQ,MAAM,aAAa,KAAM,kBAACmW,GAAD,CAAW,KAAM,EAAI,GAAG,YAAef,GAAgB,EAAI,EAAG,MAAO,CAAE,QAASgB,GAAgBf,GAAiB,OAAY,MAAO,EAAG,cAE1N,GACFgB,OAA4B,kBAAAtR,EAAA,WAC/B,CAACqI,GAAoBoF,GAAyB,GAAKnE,EAAc,oBAAoB,GAAM,kBAACiI,GAAD,CAAmB,MAAO9D,GAAwB,QAASM,EAAmB,GACzKJ,EAAoB,OAAS,GAAKrE,EAAc,oBAAoB,GAAM,kBAAAtJ,EAAA,WACvE,kBAACwR,GAAD,CAAoB,MAAO7D,EAAoB,OAAQ,SAAUG,GAAmB,SAAO,GAC1F,CAACzF,GAAoB,kBAACpN,EAAD,CAAQ,MAAM,QAAQ,KAAM,kBAACwW,GAAD,CAAU,KAAM,EAAI,GAAG,YAAe5K,EAA6B,EAAI,EAAnG,UAAsG,WACjH8G,EAAoB,OAAO,GAC9B,CACR,KACJ,IACI+D,OAA2B,CAACrJ,GAAoBiB,EAAc,oBAAoB,EAAK,kBAAC3D,GAAD,CAAc,OAAO,iBAAiB,MAAM,KAAK,eAAkB,KAAKwJ,GAAgB,CAAG,GAAK,KAC7L,MAAQ,kBAAC,MAAD,CAAK,UAAU,yCAAf,UACN,kBAACsB,GAAD,CAAoB,OAAQD,GAAe,OAAQ,kBAAC,MAAD,CAAK,UAAU,gBAGlE,2BAACmB,GAAD,CAAyB,aAAcC,EAAiB,CAC9C,QAAU,kBAACC,EAAD,CAAc,YAAY,cAAc,GAAIC,EAAY,SAAS,EAAG,MAAO,GAAK,GAC1F,QAAW,kBAAA9R,EAAA,WACf,kBAAC6R,EAAD,CAAc,YAAY,SAAS,GAAIC,EAAY,OAAO,EAAG,MAAO,GAAK,GACzE,kBAACC,GAAD,CAAc,MAAOhJ,GAAa,GAAIiJ,EAAK,QAAQ,CAAG,GACtD,kBAACC,GAAD,CAAiB,YAAa,CAAC,OAAQ,MAAM,EAAG,GAAID,EAAK,WAAW,CAAG,EACvE,IACI,SAAWE,GACX,QAAUC,EACV,OAAS,kBAACC,GAAD,CAAc,WAAW,qBAAqB,YAAe/J,EAAmBG,GAAmB,EAAI,EAAIoG,GAAW,CAAG,GAClI,QAAW,kBAAA5O,EAAA,WACdmR,GAAuB,EACvBG,GAAmB,EACpB,kBAACe,GAAD,CAAc,OAAO,eAAe,MAAO7H,GAAa,UAAW,GAAO,WAAW,oBAAqB,GACzGkH,GAAmB,EACnBrJ,GAAoB,kBAAC9M,GAAD,CAAsB,cAAe8K,GAAa,MAAM,KAAK,GAAQsJ,EAAK,OAAS,aAAa,GAAK,EAAO,EACjI,IACI,YAAa,OACb,YAAa,MACjB,CAAC,EAAY,WAAS,GAAI2C,GAAezH,EAAW,CACpD,WAAY0H,EACZ,MAAO,OACP,aAAc,CACV,kBACA,SAAW,GAAS,CAChB,IAAMC,GAAYC,GAAQ,CAAC,GAAG,IAAI,MAAM,EAClCC,EAAa,IAAI,IAAIF,CAAQ,EAC7BG,EAAW5H,EAAS,OAAQ,GAAS7E,EAAYpF,CAAI,CAAC,CAAC,CAAC,IAAK,GAASA,EAAK,EAAE,EAC7E8R,EAAWJ,EAAS,OAAQ,GAAO,CAACG,EAAS,SAASpT,CAAE,CAAC,EAC3DqT,EAAS,OAASJ,EAAS,QAAUG,EAAS,KAAM,GAAOD,EAAW,IAAInT,CAAE,CAAC,GAC7EhG,EAAM,QAAQ,iBAAiB,EAEnC2P,EAAmB0J,CAAQ,CAC/B,CACJ,CACJ,CAAC,CAAG,EACC,GAAG,YAAa,IAAK,QAAS,IAAK,QAAS,IAAK,WAAY,CAACxC,GAAc,iBAAoBC,GAAgB,EAAK,EAAG,gBAAgB,SAAS,mBAAoBE,GAAmB,WAAW,QAAQ,MAAO,CAAE,KAAM,EAAG,UAAW,EAAG,SAAU,QAAS,CAAG,GAEvQhI,IAAmB,kBAAC1M,GAAD,CAAuB,KAAM0M,KAAoB,GAAO,OAAYA,GAAiB,YAAe,CAAEC,GAAmB,IAAI,EAAG2G,GAAqB,CAAG,CAAG,GAC/K,kBAAC0D,GAAD,CAAsB,QAAO,cAAe,CAAE,SAAU1G,EAAM,aAAc,EAAG,MAAO,IAAtF,UACGW,GAAe,kBAAA9M,EAAA,WACZ,kBAAC8S,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,MAAN,CAAY,MAAM,WAAW,MAAM,MAAM,WAAS,EAC/C,GACL,kBAACkY,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,MAAN,CAAY,MAAM,WAAW,MAAM,KAAK,SAAUwN,EAAkB,YAAY,QAAQ,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,OAAQ,CAAC,CAAG,EACpI,EACF,CACL,qBAACyK,EAAD,CAAK,OAAQ,GACX,2BAACC,EAAD,CAAK,KAAM,GACT,2BAAC/Y,GAAD,CAAoB,QAASsT,GAAiB,SAAUjF,EAAkB,MAAM,QAAQ,MAAM,OAAO,YAAY,UAAU,MAAO,CAAC,CAAE,QAAS,gBAAiB,QAAS,YAAa,CAAC,CAAG,EACtL,EACF,EACL,IAAM,kBAAArI,EAAA,WACN,kBAAC8S,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,MAAN,CAAY,MAAM,WAAW,MAAM,MAAM,YAAY,SAAS,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,QAAS,CAAC,CAAG,EAC3G,GACL,kBAACkY,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,MAAN,CAAY,MAAM,WAAW,MAAM,KAAK,SAAUwN,EAAkB,YAAY,QAAQ,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,OAAQ,CAAC,CAAG,EACpI,EACF,CACL,qBAACyK,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAACrV,EAAD,CAAmB,MAAM,WAAW,MAAM,KAAK,YAAY,QAAQ,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,OAAQ,CAAC,EAAG,SAAW,GAAMgL,GAAgB,OAAO4G,GAAK,EAAE,CAAC,EAAG,SAAU,kBAAC0D,GAAD,CAAuB,SAAUvK,GAAc,OAAQ8B,CAAgB,EAAG,EACtP,GACL,kBAACwI,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,MAAN,CAAY,MAAM,QAAQ,MAAM,OAAO,YAAY,UAAU,MAAO,CAAC,CAAE,QAAS,gBAAiB,QAAS,YAAa,CAAC,CAAG,EACxH,EACF,CACL,MACJ,kBAACiY,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAAC/Y,GAAD,CAAoB,QAASsT,GAAiB,MAAM,QAAQ,SAAUjF,EAAkB,MAAM,KAAK,YAAY,QAAQ,MAAO,CAAC,CAAE,KAAM,QAAS,QAAS,SAAU,CAAC,CAAG,EACpK,GACL,kBAAC0K,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,WAAN,CAAiB,MAAM,eAAe,MAAM,OAAO,SAAU,CAAC0O,GAAoB,MAAO,CAAE,MAAO,MAAO,EAAG,SAAU2E,GAAoB,YAAY,UAAU,kBAAe,YAAU,EACtL,EACF,C,GACL,kBAAC4E,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,OAAN,CAAa,MAAM,cAAc,MAAM,KAAK,SAAU,CAAC2O,GAAkB,MAAO,CAAE,MAAO,MAAO,EAAG,YAAS,UAAO,aAAU,WAAYmF,GAAoB,YAAY,OAAQ,EAC9K,GACL,kBAACoE,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,OAAN,CAAa,MAAM,UAAU,MAAM,KAAK,SAAU,CAACwO,EAAc,MAAO,CAAE,MAAO,MAAO,EAAG,YAAS,UAAO,WAAYY,EAAS,IAAK,IAAO,CAAE,MAAOsC,EAAE,GAAI,MAAOA,EAAE,IAAK,EAAE,EAAG,YAAY,OAAQ,EAC/L,EACF,C,GACL,kBAACuG,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,OAAN,CAAa,MAAM,SAAS,SAAUwN,EAAkB,MAAM,KAAK,MAAO,CAAE,MAAO,MAAO,EAAG,aAAU,WAAYY,GAAe,YAAY,OAAQ,EACnJ,GACL,kBAAC8J,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,WAAN,CAAiB,MAAM,YAAY,SAAUwN,EAAkB,MAAM,OAAO,KAAK,OAAO,MAAO,CAAE,MAAO,MAAO,EAAG,YAAY,UAAU,YAAU,EAC/I,EACF,C,GACL,kBAACyK,EAAD,CAAK,OAAQ,GACX,2BAACC,EAAD,CAAK,KAAM,GACT,2BAAClY,EAAK,OAAN,CAAa,MAAM,SAAS,MAAM,KAAK,MAAO,CAAE,MAAO,MAAO,EAAG,WAAYkO,GAAY,IAAK,IAAO,CACrG,MAAOkK,EAAE,MACT,MAAOA,EAAE,MACT,SAAUnG,GAAe5G,EAAY4G,EAAW,GAAKmG,EAAE,QAAU,WAAc,EACnF,EAAE,EAAG,YAAY,OAAQ,EAClB,EACF,EACQ,C,GAEf,kBAACJ,GAAD,CAAe,MAAOtF,EAAe,MAAOA,EAAc,QAAU,UAAUA,EAAc,QAAQ,WAAa,OAAQ,aAAgB,CAAEA,EAAc,MAAM,EAAG3E,GAAc,EAAE,CAAG,EAAG,MAAO,IAA/L,UACE,kBAAClL,EAAD,CAAmB,MAAM,WAAW,MAAM,MAAM,YAAY,SAAS,MAAO,CACxE,CAAE,SAAU,GAAM,QAAS,QAAS,EACpC,CAAE,IAAK,EAAG,QAAS,YAAa,CACpC,EAAG,SAAW,GAAMkL,GAAc,OAAO0G,GAAK,EAAE,CAAC,EAAG,SAAU,kBAAC0D,GAAD,CAAuB,SAAUrK,GAAY,OAAQ4B,CAAgB,EAAG,GACtI,kBAAC7M,EAAD,CAAmB,MAAM,kBAAkB,MAAM,OAAO,YAAY,WAAW,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,QAAS,CAAC,CAAG,EAClH,C,GAEd,GAGD,kBAACF,GAAD,CAAU,MAAO,YAAYmQ,EAAoB,OAAO,OAAQ,QAAS/G,EAA2B,aAAgB,CAAEC,EAA6B,EAAK,EAAGC,EAAqB,SAAS,UAAU,CAAE,SAAU,GAAI,gBAAiB,EAAG,CAAC,EAAGgC,GAAe,EAAE,CAAG,EAAG,eAAgB6C,GAAsB,UAAW,KAAM,SAAY,CAC/T,GAAK7E,EAAqB,QAE1B,GAAI,CACA,IAAM5J,EAAS,MAAM4J,EAAqB,QAAQ,SAAS,EAI3D,GAAI5J,EAAO,WAAaA,EAAO,gBAAiB,CAC5C4J,EAAqB,QAAQ,SAAS,kBAAmB,WAAW,EACpE,MACJ,CACA,MAAM6E,GAAsB,YAAY,CAAE,KAAM,CAAE,IAAKgC,EAAqB,SAAUzQ,EAAO,QAAS,CAAE,CAAC,EACzG3D,EAAM,QAAQ,QAAQ,EACtBsN,EAA6B,EAAK,EAClCC,EAAqB,QAAQ,UAAU,CAAE,SAAU,GAAI,gBAAiB,EAAG,CAAC,EAC5EgC,GAAe,EAAE,EACjBI,EAAmB,CAAC,CAAC,CACzB,MACM,CAA8B,CACxC,EACA,2BAACrO,EAAD,CAAM,WAAa,GAAQ,CAAE,EAAqB,QAAUiI,CAAK,EAAG,cAAc,OAAO,WAAY,GAArG,UACE,kBAACpF,EAAD,CAAmB,MAAM,WAAW,MAAM,MAAM,YAAa6M,EAAiB2I,GAAyB3I,CAAc,EAAI,SAAU,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,QAAS,CAAC,EAAG,SAAW,GAAMzB,GAAe,OAAOwG,GAAK,EAAE,CAAC,EAAG,SAAU,kBAAC0D,GAAD,CAAuB,SAAUnK,GAAa,OAAQ0B,CAAgB,EAAG,GACxT,kBAAC7M,EAAD,CAAmB,MAAM,kBAAkB,MAAM,OAAO,YAAY,WAAW,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,OAAQ,CAAC,CAAG,EAC1H,C,EACE,GAGTmK,IAAe,kBAACvF,GAAD,CAAiB,QAASyF,GAAoB,KAAMF,GAAY,YAAeG,GAAsB,EAAK,EAAG,UAAY,GAAY,CAC3I6C,EAAe,QAAQ,EACvB/C,GAAcqL,CAAO,EACrBC,EAAWD,CAAO,CACtB,CAAG,GAGRlL,GAAa,kBAAC1E,GAAD,CAAe,QAAS4E,GAAa,OAAQF,EAAS,GAAI,SAAU,GAAGA,EAAS,UAAYA,EAAS,SAAS,GAAGA,EAAS,SAAS,GAAsB,oBAAwC,wBAAsB,YAAeG,GAAe,EAAK,CAAG,GAG1QrB,IAAiB,kBAACnJ,GAAD,CAAyB,OAAQmJ,GAAa,GAAI,SAAUA,GAAa,UAAYA,GAAa,SAAU,QAASE,GAAiB,YAAeC,EAAmB,EAAK,CAAG,GAGjMC,GAAiB,kBAAC1G,GAAD,CAAoB,OAAQ0G,EAAa,GAAI,SAAUA,EAAa,UAAYA,EAAa,SAAU,QAASE,GAAiB,SAAU8C,EAAgB,YAAe7C,GAAmB,EAAK,CAAG,GAGvN,kBAAC9J,GAAD,CAAU,MAAO,SAAS+J,GAAgB,UAAYA,GAAgB,UAAY,KAAM,QAASE,GAAmB,aAAgBC,GAAqB,EAAK,EAAG,eAAgBmE,GAAoB,UAAW,KAAM,SAAY,CACvNtE,IAEL,MAAMsE,GAAoB,YAAY,CAAE,OAAQ,CAAE,GAAItE,EAAe,EAAG,EAAG,KAAM,CAAE,QAASI,EAAc,CAAE,CAAC,EAC7GpO,EAAM,QAAQ,QAAQ,EACtBmO,GAAqB,EAAK,EAC9B,EAAG,OAAO,KAAK,WAAW,KAAK,MAAO,IANxC,UAOE,kBAAC,MAAD,WACE,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,SAAU,GAAI,WAAY,GAAI,EAAG,iBAAW,GAC3E,kBAACnC,EAAD,CAAQ,YAAS,UAAO,aAAU,MAAO,CAAE,MAAO,MAAO,EAAG,MAAOoC,GAAe,SAAW,GAAMC,GAAkB0H,GAAkB,CAAC,CAAC,EAAG,WAAYrF,EAAS,IAAK,IAAO,CAAE,MAAOsC,EAAE,GAAI,MAAOA,EAAE,IAAK,EAAE,EAAG,YAAY,WAAY,EACpO,IACL,kBAAC,MAAD,CAAK,MAAO,CAAE,UAAW,GAAI,WAAY,GAAI,UAAW,wCAAyC,EAAjG,UACE,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,SAAU,GAAI,WAAY,GAAI,EAAG,kBAAY,GAC5E,kBAAC,MAAD,CAAK,MAAO,CAAE,aAAc,EAAG,SAAU,GAAI,MAAO,8BAA+B,EAAG,kCAEjF,GACJR,GAA8B,WAAc,kBAAC,MAAD,CAAK,MAAO,CAAE,MAAO,+BAAgC,SAAU,EAAG,EAAG,oBAAc,GAAKA,GAA8B,MAAM,eAAe,OAAU,kBAACjR,EAAD,CAAO,QAAS,EAAG,QAChN,SAAAiR,GAA8B,KAAK,eAAe,IAAK,GAAU,kBAACtM,EAAD,CAAmB,MAAM,SAAS,MAAO,CAAE,aAAc,CAAE,EAA3D,UAC7DkQ,EAAK,KAAK,OAAKA,EAAK,WAAW,KAAK,GAAG,EAAE,GACvC,CAFqE,EAAAA,EAAK,EAE1E,CAAE,CACJ,GAAM,kBAAC,MAAD,CAAK,MAAO,CAAE,MAAO,+BAAgC,SAAU,EAAG,EAAG,oBAAc,EAC/F,CACG,G,EACP,C,EACT,C,yNAnoBM,GAAoC,CAAE,QAAS,GAAI,MAAO,GAAI,OAAQ,OAAW,UAAW,KAAM,aAAc,MAAU,EAC1H,EAAsB,kBACtB,GAAsB,CAAC,EACvB,GAAsB,CAAC,EACvB,GAAkC,CAAC,EACnC,GAA8B,CAAC,C","names":["__iconData","__iconData$3","createLucideIcon","__iconData$2","__iconData$1","batchStatusHandler","ids","selectedRowKeys","label","status","disableLabel","execute","run","clearSelection","Toast","successMessage","confirm","options","entity","confirmContent","danger","confirmDanger","Modal","SensitiveFormInput","inputProps","formApi","useFormApi","recordId","control","reveal","useRevealedValue","maskedValue","field","maskedText","EMPTY_PLACEHOLDER","text","Form","Space","Typography","Tooltip","Button","Eye","EyeOff","PencilLine","unlocked","Undo2","DirectorySyncControl","useDirectorySyncStatus","administrator","sync","useDirectorySync","DateTimeText","DirectoryAccountModal","sensitive","useSensitiveFormFields","directorySensitiveFields","user","create","useDirectoryCreate","update","useDirectoryUpdate","form","useRef","requestId","useState","uncertain","setUncertain","error","setError","provision","useDirectoryProvision","submit","input","values","body","identityDirectoryContract","profile","onClose","cause","AppModal","value","FormPasswordInput","data","UserMenuPermissionModal","directMenuIds","setDirectMenuIds","roleMenuIds","setRoleMenuIds","groupMenuIds","setGroupMenuIds","groups","setGroups","effectiveMenuIds","setEffectiveMenuIds","activeTab","setActiveTab","menuTreeQuery","useMenuTree","visible","permissionsQuery","useUserEffectivePermissions","userId","saveMenusMutation","useSaveUserMenus","useEffect","handleSave","effectiveSet","buildLabelSuffix","menuSources","result","id","tags","Tag","source","userName","ModalFooter","Tabs","TabPane","MenuPermissionPanel","_Fragment","g","scopeLabel","scope","DATA_SCOPE_OPTIONS","o","getMostPermissive","mostPermissiveDataScope","scopes","UserDataScopeModal","departmentTree","useMemo","buildTree","deptTree","item","userDataScope","setUserDataScope","deptScopeIds","setDeptScopeIds","roleDataScope","setRoleDataScope","roleDeptScopeIds","setRoleDeptScopeIds","groupDataScope","setGroupDataScope","groupDeptScopeIds","setGroupDeptScopeIds","permissionQuery","useUserDataPermission","saveMutation","useSaveUserDataPermission","enumValueOf","DATA_SCOPES","effectiveScope","effectiveDeptIds","Text","DataScopePanel","Divider","UserAvatarModal","updateAvatarMutation","useApiMutation","userContract","qc","userKeys","updateAvatar","avatar","api","handleSelect","onUpdated","url","err","handleRemoveAvatar","confirmDelete","AvatarSelectModal","uploadAvatarBlobToFileCenter","UserLogsSheet","firstTab","canViewLoginLogs","SideSheet","key","UserLoginLogsPanel","canViewOperationLogs","UserOperationLogsPanel","FoundationImportButton","dryRun","pending","setPending","duplicate","setDuplicate","setResult","setVisible","pick","beforeSubmit","dry","upload","response","goTransport","transferUsers","onFinished","template","blob","transferTemplate","downloadBlob","title","file","event","Dropdown","Select","Upload","ChevronDown","Table","ImportButton","props","SensitiveText","state","showToggle","Copy","copyTextWithToast","isAdminUser","UsersPage","usePermission","currentUser","useAuth","useListSearch","defaultSearchParams","useListDeepLink","applySearch","params","batchPasswordModalVisible","setBatchPasswordModalVisible","batchPasswordFormApi","menuPermUser","setMenuPermUser","menuPermVisible","setMenuPermVisible","dataPermUser","setDataPermUser","dataPermVisible","setDataPermVisible","roleAssignUser","setRoleAssignUser","roleAssignVisible","setRoleAssignVisible","roleAssignIds","setRoleAssignIds","avatarUser","setAvatarUser","avatarModalVisible","setAvatarModalVisible","logsUser","setLogsUser","logsVisible","setLogsVisible","externalIdentity","useIdentityCapabilities","directoryEditor","setDirectoryEditor","createPwdVal","setCreatePwdVal","editPwdVal","setEditPwdVal","batchPwdVal","setBatchPwdVal","statusItems","useDictItems","genderOptions","setSelectedRowKeys","deptTreeExpandedKeys","setDeptTreeExpandedKeys","canReadRoles","hasPermission","canReadDepartments","canReadPositions","allRolesQuery","useAllRoles","allDepartmentsQuery","useFlatDepartments","allPositionsQuery","useAllPositions","mySettingsQuery","useMySettings","allRoles","EMPTY_ROLES","allDepartments","EMPTY_DEPARTMENTS","allPositions","EMPTY_POSITIONS","passwordPolicy","filterQuery","useFilterQuery","submittedParams","USER_STATUSES","formatDateTimeRangeForApi","listQuery","useUserList","userList","EMPTY_USERS","useSaveUser","resetPasswordMutation","useResetUserPassword","deleteMutation","useDeleteUsers","unlockMutation","useUnlockUser","batchStatusMutation","useBatchUserStatus","toggleStatusMutation","batchPasswordMutation","useBatchUserPassword","assignRolesMutation","useAssignUserRoles","roleEffectivePermissionsQuery","kickSessionsMutation","useKickUserSessions","sensitiveFieldsRef","modal","useEditModal","formSaveMutation","useUserDetail","r","rawValues","clearFields","editing","payload","formatDateForApi","abortSubmit","editingUser","useStandardWebMcpCrudAdapter","action","record","isMaskedFieldValue","departmentContract","positionContract","roleContract","sensitiveFields","passwordModal","canViewUserLogs","selectedDeletableCount","selectedSet","selectedNonAdminIds","useStatusToggle","enabled","handleBatchStatus","handleBatchDelete","deletableIds","confirmAndDelete","departmentTreeData","departmentsToTreeData","departmentFilterTreeData","ALL_DEPARTMENTS_KEY","allDeptExpandedKeys","deptTreeExpandInitedRef","isAllDeptExpanded","isAllKeysExpanded","toggleDeptExpandAll","positionOptionList","openCreate","openEdit","openPassword","unlockUser","handleUnlock","useCallback","kickUserSessions","refetchUserList","columns","UserAvatar","v","renderEllipsis","overflowTagColumn","positions","roles","role","gender","DictTag","dateTimeColumn","EntityRelationButton","createdAtColumn","createOperationColumn","isAdmin","deleteAction","showDeptTree","setShowDeptTree","isLayoutNarrow","setIsLayoutNarrow","masterContent","MasterDetailLayout","jsx","ChevronsDownUp","ChevronsUpDown","Tree","draftParams","expandedKeys","newDeptId","selectedKey","newParams","renderDepartmentButton","Building2","forceVisible","renderBatchActions","BatchDeleteButton","BatchStatusButtons","KeyRound","renderImportButton","ConfigurableTable","buildTableSearch","KeywordInput","bindKeyword","StatusSelect","bind","DateRangeFilter","handleSearch","handleReset","CreateButton","ExportButton","listTableProps","buildPagination","nextKeys","keys","nextKeySet","adminIds","filtered","EditFormModal","Row","Col","PasswordStrengthMeter","i","formatPasswordPolicyHint","updated","updateUser"],"ignoreList":[0,1,2,3],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/building-complex.mjs","../../../../node_modules/lucide-react/dist/esm/icons/eye.mjs","../../../../node_modules/lucide-react/dist/esm/icons/pencil-line.mjs","../../../../node_modules/lucide-react/dist/esm/icons/undo-2.mjs","../../src/components/list-page/batchStatus.ts","../../src/components/sensitive/SensitiveFormInput.tsx","../../src/pages/users/IdentityDirectoryControls.tsx","../../src/pages/users/UserMenuPermissionModal.tsx","../../src/pages/users/UserDataScopeModal.tsx","../../src/pages/users/UserAvatarModal.tsx","../../src/pages/users/UserLogsSheet.tsx","../../src/components/FoundationImportButton.tsx","../../src/components/ImportButton.tsx","../../src/components/sensitive/SensitiveText.tsx","../../src/pages/users/UsersPage.tsx"],"sourcesContent":[null,null,null,null,"import type { ReactNode } from 'react';\nimport { Modal, Toast } from \"@/ui\";\nimport { confirmDanger } from \"@/utils/confirm\";\nexport type BatchStatus = 'enabled' | 'disabled';\nexport interface BatchStatusOptions<Id extends string | number = number> {\n /** 当前选中的行键(`useRowSelection().selectedRowKeys`) */\n readonly selectedRowKeys: readonly Id[];\n /** 成功后清空选中(`useRowSelection().clear`) */\n readonly clearSelection: () => void;\n /** 执行批量写入;载荷形状(`{ ids, status }` / `{ ids, enabled }`)由页面适配 */\n readonly run: (ids: Id[], status: BatchStatus) => Promise<unknown>;\n /** 停用侧文案:「停用」(默认)或「禁用」 */\n readonly disableLabel?: string;\n /**\n * 何时弹确认框:`'disable'`(默认,只有停用需要确认)/ `'always'` / `'never'`。\n * 标题缺省为「确认批量{启用 / 停用}选中的 N {entity}?」\n */\n readonly confirm?: 'disable' | 'always' | 'never';\n /** 确认标题里的量词 + 名词,如「个数据集」「条短链」;缺省「项」 */\n readonly entity?: string;\n readonly confirmContent?: (status: BatchStatus, count: number) => ReactNode | undefined;\n /** 停用是破坏性语义(如禁用账号)时确认按钮用红色实心 */\n readonly danger?: boolean;\n /** 成功提示,缺省「批量{启用 / 停用}成功」 */\n readonly successMessage?: (status: BatchStatus, count: number) => string;\n}\n/**\n * 「批量启用 / 停用」的统一流程:空选中直接返回 → 按策略确认 → 执行 → 清空选中 → 成功提示。\n * 返回 `handleBatchStatus(status)`,交给 `BatchEnableButton` / `BatchDisableButton` 的 `onClick`。\n *\n * @example\n * const handleBatchStatus = batchStatusHandler({\n * selectedRowKeys, clearSelection,\n * run: (ids, status) => batchStatusMutation.mutateAsync({ body: { ids, status } }),\n * confirm: 'always', entity: '个数据集',\n * });\n * <BatchEnableButton count={selectedRowKeys.length} onClick={() => handleBatchStatus('enabled')} />\n */\nexport function batchStatusHandler<Id extends string | number = number>({ selectedRowKeys, clearSelection, run, disableLabel = '停用', confirm = 'disable', entity = '项', confirmContent, danger = false, successMessage, }: BatchStatusOptions<Id>) {\n return async (status: BatchStatus): Promise<void> => {\n const ids = [...selectedRowKeys];\n if (ids.length === 0)\n return;\n const label = status === 'enabled' ? '启用' : disableLabel;\n const execute = async () => {\n await run(ids, status);\n clearSelection();\n Toast.success(successMessage?.(status, ids.length) ?? `批量${label}成功`);\n };\n const needConfirm = confirm === 'always' || (confirm === 'disable' && status === 'disabled');\n if (!needConfirm)\n return execute();\n const options = {\n title: `确认批量${label}选中的 ${ids.length} ${entity}?`,\n content: confirmContent?.(status, ids.length),\n onOk: execute,\n };\n // 停用是破坏性语义时用红色实心确认(confirmDanger),否则普通确认\n if (danger && status === 'disabled')\n confirmDanger(options);\n else\n Modal.confirm(options);\n };\n}\n","import type { ComponentProps } from 'react';\nimport { Button, Form, Space, Tooltip, Typography, useFormApi } from \"@/ui\";\nimport { Eye, EyeOff, PencilLine, Undo2 } from 'lucide-react';\nimport type { SensitiveFormFieldsControl } from \"@fudanda/react-core/hooks/useSensitiveFormFields\";\nimport { EMPTY_PLACEHOLDER } from \"@/utils/table-columns\";\nimport { useRevealedValue } from \"@fudanda/react-core/components/sensitive/useRevealedValue\";\ntype FormInputProps = ComponentProps<typeof Form.Input>;\nexport interface SensitiveFormInputProps extends Omit<FormInputProps, 'field' | 'label'> {\n /** `useSensitiveFormFields()` 的返回值 */\n control: SensitiveFormFieldsControl<{\n id: number;\n }>;\n field: string;\n label: string;\n}\n/**\n * 编辑表单里的敏感字段输入框。\n *\n * - 值对当前用户是掩码时默认**锁定**:展示掩码 + 「查看明文」(需权限,逐次审计)+ 「修改」\n * - 点「修改」后变成普通输入框(起始为空,若已查看明文则带入明文),可「取消修改」恢复锁定\n * - 新增、或用户本就能看到明文时,与普通 `Form.Input` 行为一致\n */\nexport function SensitiveFormInput({ control, field, label, ...inputProps }: SensitiveFormInputProps) {\n const formApi = useFormApi();\n const recordId = control.record?.id ?? 0;\n const reveal = useRevealedValue({ entity: control.entity, id: recordId, field });\n const maskedValue = (control.record as Record<string, unknown> | null)?.[field];\n const maskedText = typeof maskedValue === 'string' && maskedValue ? maskedValue : EMPTY_PLACEHOLDER;\n if (control.isLocked(field)) {\n const text = reveal.revealed ?? maskedText;\n return (<Form.Slot label={label}>\n <Space spacing={4} wrap className=\"sensitive-form-locked\">\n <Typography.Text className=\"sensitive-form-locked__value\">{text}</Typography.Text>\n {reveal.canReveal && (reveal.revealed === null ? (<Tooltip content=\"查看明文(记录审计)\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Eye size={14}/>} loading={reveal.revealing} aria-label=\"查看明文\" onClick={() => void reveal.show()}/>\n </Tooltip>) : (<Tooltip content=\"收起明文\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<EyeOff size={14}/>} aria-label=\"收起明文\" onClick={reveal.hide}/>\n </Tooltip>))}\n <Button size=\"small\" theme=\"borderless\" icon={<PencilLine size={14}/>} disabled={inputProps.disabled} onClick={() => {\n control.unlock(field);\n formApi.setValue(field, reveal.revealed ?? '');\n }}>\n 修改\n </Button>\n </Space>\n </Form.Slot>);\n }\n const unlocked = control.isUnlocked(field);\n return (<Form.Input {...inputProps} field={field} label={label} extraText={unlocked ? (<Space spacing={4}>\n <Typography.Text type=\"tertiary\" size=\"small\">留空则保持原值不变</Typography.Text>\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Undo2 size={12}/>} onClick={() => { control.relock(field); formApi.setValue(field, maskedValue); }}>取消修改</Button>\n </Space>) : inputProps.extraText}/>);\n}\n","import { useRef, useState } from 'react';\nimport { Button, Form, Space, Toast, Typography } from \"@/ui\";\nimport type { FormApi } from \"@/ui\";\nimport type { BodyOf } from '@fudanda/react-core/lib/contract-query';\nimport { type User } from '@fudanda/shared/identity';\nimport { identityDirectoryContract } from '@fudanda/react-core/lib/native-operations';\nimport { AppModal } from \"@/components/AppModal\";\nimport DateTimeText from \"@/components/DateTimeText\";\nimport { FormPasswordInput } from \"@/components/PasswordInput\";\nimport { SensitiveFormInput } from \"@/components/sensitive/SensitiveFormInput\";\nimport { useSensitiveFormFields } from \"@fudanda/react-core/hooks/useSensitiveFormFields\";\nimport { useDirectoryCreate, useDirectoryUpdate, useDirectorySync, useDirectorySyncStatus, useDirectoryProvision } from \"@fudanda/react-core/hooks/queries/identity-directory\";\nexport function DirectorySyncControl({ administrator }: {\n administrator: boolean;\n}) {\n const status = useDirectorySyncStatus(administrator);\n const sync = useDirectorySync();\n if (!administrator)\n return null;\n return <Space wrap>\n <Button loading={sync.isPending || status.data?.running} disabled={!status.data || status.data.running} onClick={() => { void sync.mutateAsync({}).catch(() => { }); }}>同步统一账户</Button>\n <Typography.Text type=\"tertiary\">最近成功同步:{status.data?.lastSuccessAt ? <DateTimeText value={status.data.lastSuccessAt} mode=\"absolute\"/> : '尚未完成'}</Typography.Text>\n {(status.isError || status.data?.error) && <Typography.Text type=\"danger\">{status.data?.error || '无法读取同步状态'}</Typography.Text>}\n </Space>;\n}\nconst directorySensitiveFields = ['email', 'phone'] as const;\nexport function DirectoryAccountModal({ user, onClose }: {\n user?: User;\n onClose: () => void;\n}) {\n const sensitive = useSensitiveFormFields({ entity: 'User', fields: directorySensitiveFields, record: user ?? null });\n const create = useDirectoryCreate();\n const update = useDirectoryUpdate();\n const form = useRef<FormApi | null>(null);\n const [requestId] = useState(() => crypto.randomUUID());\n const [uncertain, setUncertain] = useState(false);\n const [error, setError] = useState('');\n const provision = useDirectoryProvision(requestId, uncertain);\n const submit = async () => {\n if (!form.current || uncertain)\n return;\n let input: BodyOf<typeof identityDirectoryContract.create> | undefined;\n try {\n const values: unknown = await form.current.validate();\n if (user) {\n const body = identityDirectoryContract.update.input.shape.body.parse(sensitive.strip(values as Record<string, unknown>));\n await update.mutateAsync({ params: { id: user.id }, body });\n }\n else {\n const profile = values as Partial<BodyOf<typeof identityDirectoryContract.create>>;\n input = identityDirectoryContract.create.input.shape.body.parse({ ...profile, requestId, displayName: profile.displayName ?? '', email: profile.email ?? '', phone: profile.phone ?? '' });\n await create.mutateAsync({ body: input });\n }\n Toast.success(user ? '统一资料已更新' : '统一账户已创建,请在本应用分配权限');\n onClose();\n }\n catch (cause) {\n if (input)\n setUncertain(true);\n setError(cause instanceof Error ? cause.message : String(cause));\n }\n finally {\n form.current?.setValue('initialPassword', '');\n if (input)\n input.initialPassword = '';\n }\n };\n // A failed remote creation switches to reconciliation instead of another save.\n // This composite flow keeps its own form and query-result action.\n return <AppModal title={user ? '统一账户资料' : '创建统一账户'} visible onCancel={onClose} onOk={() => { void submit(); }} confirmLoading={create.isPending || update.isPending} okButtonProps={{ disabled: uncertain }}>\n <Form getFormApi={(value) => { form.current = value; }} initValues={{ displayName: user?.externalDisplayName || user?.nickname || '', email: user?.email || '', phone: user?.phone || '' }}>\n {!user && <Form.Input field=\"username\" label=\"统一用户名\" rules={[{ required: true }]}/>}\n <Form.Input field=\"displayName\" label=\"显示名\"/>\n <SensitiveFormInput control={sensitive} field=\"email\" label=\"邮箱\"/>\n <SensitiveFormInput control={sensitive} field=\"phone\" label=\"手机\"/>\n {!user && <FormPasswordInput field=\"initialPassword\" label=\"初始密码\" autoComplete=\"new-password\" rules={[{ required: true }]}/>}\n </Form>\n <p>角色、部门和本应用停用状态在“本应用权限”中设置。密码后续修改和 MFA 由 Casdoor 管理。</p>\n {error && <p role=\"alert\">{error}</p>}\n {uncertain && <Button loading={provision.isFetching} onClick={() => {\n void provision.refetch().then(({ data }) => {\n if (data?.status === 'complete') {\n Toast.success('开户已确认,请刷新用户列表');\n onClose();\n }\n else\n setError('开户结果尚未确认,请稍后再次查询。不会重新发送初始密码。');\n });\n }}>查询开户结果</Button>}\n </AppModal>;\n}\n","/**\n * 用户菜单权限弹窗\n *\n * Tabs:\n * 1. 直接授权 — 可编辑,显示用户直接授权的菜单\n * 2. 最终有效权限 — 只读,显示角色继承 ∪ 用户组继承 ∪ 直接授权,并用 Tag 标注来源\n */\nimport { useState, useEffect } from 'react';\nimport { Tabs, TabPane, Toast, Tag, Space } from \"@/ui\";\nimport AppModal from \"@/components/AppModal\";\nimport { MenuPermissionPanel } from \"@/components/permissions/MenuPermissionPanel\";\nimport { useMenuTree } from \"@fudanda/react-core/hooks/queries/menus\";\nimport ModalFooter from \"@/components/ModalFooter\";\nimport { useSaveUserMenus, useUserEffectivePermissions } from \"@fudanda/react-core/hooks/queries/users\";\ntype Props = Readonly<{\n userId: number;\n userName: string;\n visible: boolean;\n onClose: () => void;\n}>;\nexport function UserMenuPermissionModal({ userId, userName, visible, onClose }: Props) {\n const [directMenuIds, setDirectMenuIds] = useState<number[]>([]);\n const [roleMenuIds, setRoleMenuIds] = useState<number[]>([]);\n const [groupMenuIds, setGroupMenuIds] = useState<number[]>([]);\n const [groups, setGroups] = useState<Array<{\n id: number;\n name: string;\n }>>([]);\n const [effectiveMenuIds, setEffectiveMenuIds] = useState<number[]>([]);\n const [activeTab, setActiveTab] = useState('direct');\n const menuTreeQuery = useMenuTree({ enabled: visible });\n const permissionsQuery = useUserEffectivePermissions(userId, visible);\n const saveMenusMutation = useSaveUserMenus();\n useEffect(() => {\n if (!visible)\n return;\n setActiveTab('direct');\n }, [visible, userId]);\n useEffect(() => {\n if (!visible || !permissionsQuery.data)\n return;\n setDirectMenuIds(permissionsQuery.data.directMenuIds);\n setRoleMenuIds(permissionsQuery.data.roleMenuIds);\n setGroupMenuIds(permissionsQuery.data.groupMenuIds ?? []);\n setGroups(permissionsQuery.data.groups ?? []);\n setEffectiveMenuIds(permissionsQuery.data.effectiveMenuIds);\n }, [visible, permissionsQuery.data]);\n const handleSave = async () => {\n await saveMenusMutation.mutateAsync({ params: { id: userId }, body: { menuIds: directMenuIds } });\n Toast.success('菜单权限已更新');\n const effectiveSet = new Set([...directMenuIds, ...roleMenuIds, ...groupMenuIds]);\n setEffectiveMenuIds([...effectiveSet]);\n onClose();\n };\n /** 构造有效权限 Tab 里的具体来源 Tag(同一菜单可能有多个来源) */\n function buildLabelSuffix(): Record<string, React.ReactNode> {\n const menuSources = permissionsQuery.data?.menuSources ?? {};\n const result: Record<string, React.ReactNode> = {};\n for (const id of effectiveMenuIds) {\n const sources = menuSources[String(id)] ?? [];\n const tags = sources.map((source) => (<Tag key={source} size=\"small\" color={source === '用户直接授权' ? 'green' : source.includes('用户组:') ? 'orange' : 'blue'}>\n {source}\n </Tag>));\n result[String(id)] = <Space spacing={4} style={{ marginLeft: 4 }}>{tags}</Space>;\n }\n return result;\n }\n return (<AppModal title={`菜单权限 — ${userName}`} visible={visible} onCancel={onClose} footer={activeTab === 'effective' ? null : (<ModalFooter onCancel={onClose} onOk={handleSave} okText=\"保存\" loading={saveMenusMutation.isPending} disabled={!permissionsQuery.isSuccess}/>)} width={640}>\n <Tabs collapsible=\"auto\" activeKey={activeTab} onChange={setActiveTab}>\n <TabPane tab=\"直接授权\" itemKey=\"direct\">\n <MenuPermissionPanel allMenus={menuTreeQuery.data ?? []} checkedMenuIds={directMenuIds} onChange={setDirectMenuIds} loading={menuTreeQuery.isFetching || permissionsQuery.isFetching}/>\n </TabPane>\n <TabPane tab=\"最终有效权限\" itemKey=\"effective\">\n <div style={{ marginBottom: 8, fontSize: 12, color: 'var(--arc-antd-color-text-2)' }}>\n <div>最终权限 = 角色权限 ∪ 用户组继承 ∪ 用户直接授权,仅供预览</div>\n <div style={{ display: 'grid', gridTemplateColumns: '88px minmax(0, 1fr)', columnGap: 8, rowGap: 6, alignItems: 'start', marginTop: 6 }}>\n <span>权限来源:</span>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>\n {[...new Set(Object.values(permissionsQuery.data?.menuSources ?? {}).flat())].map((source) => (<Tag key={source} size=\"small\" color={source === '用户直接授权' ? 'green' : source.includes('用户组:') ? 'orange' : 'blue'}>\n {source}\n </Tag>))}\n </div>\n {groups.length > 0 && (<>\n <span>继承自用户组:</span>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>\n {groups.map((g) => <Tag key={g.id} size=\"small\" color=\"orange\">{g.name}</Tag>)}\n </div>\n </>)}\n </div>\n </div>\n <MenuPermissionPanel allMenus={menuTreeQuery.data ?? []} checkedMenuIds={effectiveMenuIds} loading={menuTreeQuery.isFetching || permissionsQuery.isFetching} readonly labelSuffix={buildLabelSuffix()}/>\n </TabPane>\n </Tabs>\n </AppModal>);\n}\n","/**\n * 用户数据权限弹窗\n *\n * 布局:\n * - 角色数据权限(只读):显示角色最宽松数据权限及自定义部门列表\n * - 用户组继承权限(只读):显示用户组绑定角色继承的最宽松数据权限\n * - 用户直接数据权限(可编辑):可选「跟随角色」(null) 或单独指定\n * - 最终有效权限(只读):取三者中最宽松的\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport { Typography, Divider, Toast, Tag } from \"@/ui\";\nimport AppModal from \"@/components/AppModal\";\nimport { DATA_SCOPES, mostPermissiveDataScope, type Department } from '@fudanda/shared/identity';\nimport { buildTree, enumValueOf } from '@fudanda/shared/core';\nimport type { ApiDepartment } from '@fudanda/shared/api/departments';\nimport { DataScopePanel, DATA_SCOPE_OPTIONS } from \"@/components/permissions/DataScopePanel\";\nimport { useSaveUserDataPermission, useUserDataPermission } from \"@fudanda/react-core/hooks/queries/users\";\nconst { Text } = Typography;\ntype Props = Readonly<{\n userId: number;\n userName: string;\n visible: boolean;\n deptTree: ApiDepartment[];\n onClose: () => void;\n}>;\nfunction scopeLabel(scope: string | null): string {\n if (scope === null)\n return '未设置';\n return DATA_SCOPE_OPTIONS.find((o) => o.value === scope)?.label ?? scope;\n}\nfunction getMostPermissive(scopes: Array<string | null>): string {\n return mostPermissiveDataScope(scopes) ?? 'self';\n}\nexport function UserDataScopeModal({ userId, userName, visible, deptTree, onClose }: Props) {\n const departmentTree = useMemo(() => buildTree<Department>(deptTree.map(item => ({ ...item, children: [] })), { keepEmptyChildren: true }), [deptTree]);\n const [userDataScope, setUserDataScope] = useState<string | null>(null);\n const [deptScopeIds, setDeptScopeIds] = useState<number[]>([]);\n const [roleDataScope, setRoleDataScope] = useState<string | null>(null);\n const [roleDeptScopeIds, setRoleDeptScopeIds] = useState<number[]>([]);\n const [groupDataScope, setGroupDataScope] = useState<string | null>(null);\n const [groupDeptScopeIds, setGroupDeptScopeIds] = useState<number[]>([]);\n const [groups, setGroups] = useState<Array<{\n id: number;\n name: string;\n }>>([]);\n const permissionQuery = useUserDataPermission(userId, visible);\n const saveMutation = useSaveUserDataPermission();\n useEffect(() => {\n if (!visible || !permissionQuery.data)\n return;\n setUserDataScope(permissionQuery.data.userDataScope ?? null);\n setDeptScopeIds(permissionQuery.data.deptScopeIds);\n setRoleDataScope(permissionQuery.data.roleDataScope ?? null);\n setRoleDeptScopeIds(permissionQuery.data.roleDeptScopeIds);\n setGroupDataScope(permissionQuery.data.groupDataScope ?? null);\n setGroupDeptScopeIds(permissionQuery.data.groupDeptScopeIds ?? []);\n setGroups(permissionQuery.data.groups ?? []);\n }, [visible, permissionQuery.data]);\n const handleSave = async () => {\n await saveMutation.mutateAsync({\n params: { id: userId },\n body: {\n // 面板以宽 string 维护选中值,提交前收窄为数据范围枚举;未设置(跟随角色)在完整替换文档中省略\n dataScope: enumValueOf(DATA_SCOPES, userDataScope),\n deptScopeIds: userDataScope === 'custom' ? deptScopeIds : [],\n },\n });\n Toast.success('数据权限已更新');\n onClose();\n };\n const effectiveScope = getMostPermissive([userDataScope, roleDataScope, groupDataScope]);\n const effectiveDeptIds = effectiveScope === 'custom'\n ? [...new Set([...(userDataScope === 'custom' ? deptScopeIds : []), ...roleDeptScopeIds, ...groupDeptScopeIds])]\n : [];\n return (<AppModal title={`数据权限 — ${userName}`} visible={visible} onCancel={onClose} onOk={handleSave} okButtonProps={{ disabled: !permissionQuery.isSuccess }} confirmLoading={saveMutation.isPending} width={440}>\n {/* 角色数据权限(只读) */}\n <div style={{ marginBottom: 12 }}>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>角色数据权限(只读)</Text>\n <DataScopePanel dataScope={roleDataScope ?? 'self'} deptScopeIds={roleDeptScopeIds} deptTree={departmentTree} loading={permissionQuery.isFetching} readonly/>\n </div>\n\n {/* 用户组继承权限(只读,仅在有绑定角色的组时展示) */}\n {groups.length > 0 && (<>\n <Divider margin={12}/>\n <div style={{ marginBottom: 12 }}>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>\n 用户组继承权限(只读)\n {groups.map((g) => <Tag key={g.id} size=\"small\" color=\"orange\" style={{ marginLeft: 6 }}>{g.name}</Tag>)}\n </Text>\n <DataScopePanel dataScope={groupDataScope ?? 'self'} deptScopeIds={groupDeptScopeIds} deptTree={departmentTree} loading={permissionQuery.isFetching} readonly/>\n </div>\n </>)}\n\n <Divider margin={12}/>\n\n {/* 用户直接数据权限(可编辑) */}\n <div style={{ marginBottom: 12 }}>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>用户直接权限</Text>\n <DataScopePanel dataScope={userDataScope} deptScopeIds={deptScopeIds} deptTree={departmentTree} onScopeChange={setUserDataScope} onDeptIdsChange={setDeptScopeIds} loading={permissionQuery.isFetching} nullable/>\n </div>\n\n <Divider margin={12}/>\n\n {/* 最终有效权限(只读) */}\n <div>\n <Text strong style={{ display: 'block', marginBottom: 6 }}>\n 最终有效权限:\n <Text type=\"secondary\" style={{ fontWeight: 'normal', marginLeft: 8 }}>\n {scopeLabel(effectiveScope)}\n </Text>\n </Text>\n <DataScopePanel dataScope={effectiveScope} deptScopeIds={effectiveDeptIds} deptTree={departmentTree} loading={permissionQuery.isFetching} readonly/>\n </div>\n </AppModal>);\n}\n","import { userKeys } from '@fudanda/react-core/hooks/queries/users';\nimport { Toast } from \"@/ui\";\nimport { AvatarSelectModal } from \"@/components/AvatarSelectModal\";\nimport { uploadAvatarBlobToFileCenter } from \"@fudanda/react-core/utils/avatar-upload\";\nimport { type User } from '@fudanda/shared/identity';\nimport { userContract } from '@fudanda/react-core/lib/native-operations';\nimport { api, useApiMutation } from \"@fudanda/react-core/lib/contract-query\";\nimport { confirmDelete } from \"@/utils/confirm\";\ninterface UserAvatarModalProps {\n readonly visible: boolean;\n readonly user: User;\n readonly onClose: () => void;\n readonly onUpdated: (user: User) => void;\n}\nexport function UserAvatarModal({ visible, user, onClose, onUpdated }: UserAvatarModalProps) {\n // 失败提示由调用处按场景给出,请求层静默;code !== 0 由 api() 抛 GoaError\n const updateAvatarMutation = useApiMutation(userContract.update, { requestOptions: { silent: true }, invalidate: qc => {\n void qc.invalidateQueries({ queryKey: userKeys.lists });\n void qc.invalidateQueries({ queryKey: userKeys.detail(user.id) });\n } });\n const updateAvatar = async (avatar: string | null) => {\n await updateAvatarMutation.mutateAsync({ params: { id: user.id }, body: avatar === null ? { clearFields: ['avatar'] } : { avatar } });\n return api(userContract.detail, { params: { id: user.id } });\n };\n async function handleSelect(url: string) {\n try {\n onUpdated(await updateAvatar(url));\n Toast.success('头像已更新');\n onClose();\n }\n catch (err) {\n Toast.error(err instanceof Error && err.message ? err.message : '头像更新失败');\n }\n }\n function handleRemoveAvatar() {\n confirmDelete({\n title: '确定要移除该用户头像吗?',\n content: '移除后将使用昵称缩写作为默认头像。',\n onOk: async () => {\n try {\n onUpdated(await updateAvatar(null));\n // eslint-disable-next-line no-restricted-syntax -- 头像弹窗使用静默请求并在本地 catch 展示失败\n Toast.success('头像已移除');\n onClose();\n }\n catch (err) {\n Toast.error(err instanceof Error && err.message ? err.message : '移除失败');\n }\n },\n });\n }\n return (<AvatarSelectModal visible={visible} currentAvatar={user.avatar} confirmLoading={updateAvatarMutation.isPending} uploadBlob={uploadAvatarBlobToFileCenter} onCancel={onClose} onSelect={(url) => void handleSelect(url)} onRemove={user.avatar ? handleRemoveAvatar : undefined}/>);\n}\n","/**\n * 用户管理 → 「登录与操作记录」抽屉:把某个用户的登录记录与操作记录并排在一个抽屉里两个 tab。\n *\n * 两个 tab 的内容就是个人中心那两个 tab 抽出来的 `UserLoginLogsPanel` / `UserOperationLogsPanel`,\n * 只把 scope 从「本人」换成「指定 userId」,筛选条、分页、表格(含各自的详情弹窗)与列设置全部复用。\n *\n * tab 只读用户有权限的那几个(登录日志 / 操作日志是两个独立权限码),未激活的 tab 不发请求。\n */\nimport { useEffect, useState } from 'react';\nimport { SideSheet, TabPane, Tabs } from \"@/ui\";\nimport { UserLoginLogsPanel, UserOperationLogsPanel } from \"@/components/logs/UserLogsPanels\";\ntype LogsTab = 'login' | 'operation';\ninterface UserLogsSheetProps {\n /** 目标用户 ID(列表行) */\n readonly userId: number;\n /** 目标用户展示名(昵称(用户名)),仅用于标题 */\n readonly userName: string;\n readonly visible: boolean;\n /** 是否有权限看该用户的登录记录(system:log:login) */\n readonly canViewLoginLogs: boolean;\n /** 是否有权限看该用户的操作记录(system:log:operation) */\n readonly canViewOperationLogs: boolean;\n readonly onClose: () => void;\n}\nexport function UserLogsSheet({ userId, userName, visible, canViewLoginLogs, canViewOperationLogs, onClose, }: UserLogsSheetProps) {\n const firstTab: LogsTab = canViewLoginLogs ? 'login' : 'operation';\n const [activeTab, setActiveTab] = useState<LogsTab>(firstTab);\n // 关闭后回到首个可用 tab:下次打开总是从「登录记录」开始,不会停在上次看过的那一屏\n useEffect(() => {\n if (!visible)\n setActiveTab(firstTab);\n }, [visible, firstTab]);\n return (<SideSheet title={`登录与操作记录 · ${userName}`} visible={visible} onCancel={onClose} width={1180} bodyStyle={{ padding: '0 16px 16px' }} closeOnEsc>\n <Tabs collapsible=\"auto\" type=\"line\" activeKey={activeTab} onChange={(key) => setActiveTab(key as LogsTab)}>\n {canViewLoginLogs && (<TabPane tab=\"登录记录\" itemKey=\"login\">\n <UserLoginLogsPanel scope={{ kind: 'user', userId }} enabled={visible && activeTab === 'login'} columnSettingsKey=\"user-logs-login-logs\"/>\n </TabPane>)}\n {canViewOperationLogs && (<TabPane tab=\"操作记录\" itemKey=\"operation\">\n <UserOperationLogsPanel scope={{ kind: 'user', userId }} enabled={visible && activeTab === 'operation'} columnSettingsKey=\"user-logs-operation-logs\"/>\n </TabPane>)}\n </Tabs>\n </SideSheet>);\n}\nexport default UserLogsSheet;\n","import { useRef, useState } from 'react';\nimport { Button, Dropdown, Modal, Select, Table, Tag, Typography, Toast } from \"@/ui\";\nimport { ChevronDown, Upload } from 'lucide-react';\nimport { transferUsers, transferTemplate, type ApiTransferImportResult as SyncImportResult } from '@fudanda/shared/api/transfers';\nimport { goTransport } from \"@fudanda/react-core/lib/go-transport\";\nimport { downloadBlob } from \"@fudanda/react-core/utils/download\";\ninterface Props {\n entity: string;\n title: string;\n label?: string;\n beforeSubmit?: () => boolean;\n onFinished?: () => void;\n}\nexport default function FoundationImportButton({ entity, title, label = '导入', beforeSubmit, onFinished }: Readonly<Props>) {\n const input = useRef<HTMLInputElement>(null);\n const dryRun = useRef(false);\n const [pending, setPending] = useState(false);\n const [duplicate, setDuplicate] = useState<'error' | 'skip' | 'update'>('error');\n const [result, setResult] = useState<SyncImportResult | null>(null);\n const [visible, setVisible] = useState(false);\n const pick = (dry: boolean) => {\n if (beforeSubmit && !beforeSubmit())\n return;\n dryRun.current = dry;\n input.current?.click();\n };\n const upload = async (file: File) => {\n setVisible(true);\n setPending(true);\n setResult(null);\n try {\n const response = await goTransport.upload(transferUsers, { body: { file, dryRun: dryRun.current ? 'true' : 'false', duplicate } });\n setResult(response);\n if (!dryRun.current)\n onFinished?.();\n }\n catch (error) {\n Toast.error(error instanceof Error ? error.message : '导入失败');\n setVisible(false);\n }\n finally {\n setPending(false);\n }\n };\n const template = async () => { const response = await goTransport.download(transferTemplate); const blob = await response.blob(); downloadBlob(blob, `${title}导入模板.xlsx`); };\n if (entity !== 'identity.users')\n return null;\n return <>\n <input ref={input} type=\"file\" accept=\".xlsx\" style={{ display: 'none' }} onChange={event => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (file)\n void upload(file);\n }}/>\n <Dropdown trigger=\"click\" position=\"bottomLeft\" clickToHide render={<Dropdown.Menu>\n <Dropdown.Item onClick={() => pick(false)}>上传文件导入</Dropdown.Item>\n <Dropdown.Item onClick={() => pick(true)}>预检文件(仅校验不落库)</Dropdown.Item>\n <Dropdown.Item onClick={() => void template()}>下载导入模板</Dropdown.Item>\n <Dropdown.Item><Select aria-label=\"重复数据处理\" value={duplicate} onChange={value => setDuplicate(value as typeof duplicate)} optionList={[{ value: 'error', label: '重复时报错' }, { value: 'skip', label: '跳过重复用户' }, { value: 'update', label: '更新已有用户' }]}/></Dropdown.Item>\n </Dropdown.Menu>}><Button icon={<Upload size={14}/>} loading={pending}>{label} <ChevronDown size={12}/></Button></Dropdown>\n <Modal title={`${title}导入`} visible={visible} maskClosable={false} closable={!pending} onCancel={() => setVisible(false)} width={640} footer={<Button type=\"primary\" disabled={pending} onClick={() => setVisible(false)}>完成</Button>}>\n {pending ? <Typography.Text>正在同步处理,请等待当前请求完成。</Typography.Text> : result && <>\n {result.dryRun && <Typography.Text type=\"warning\">预检模式:仅校验数据,不写入任何记录。</Typography.Text>}\n <Typography.Paragraph>共 {result.total} 行,成功 {result.success},失败 {result.failed},跳过 {result.skipped}</Typography.Paragraph>\n <Table rowKey=\"row\" size=\"small\" dataSource={result.rows} columns={[{ title: '行', dataIndex: 'row', width: 70 }, { title: '内容', dataIndex: 'label' }, { title: '结果', dataIndex: 'status', width: 80, render: (status: string) => <Tag color={status === 'failed' ? 'red' : status === 'success' ? 'green' : 'grey'}>{status === 'failed' ? '失败' : status === 'success' ? '成功' : '跳过'}</Tag> }, { title: '说明', dataIndex: 'message' }]} pagination={{ pageSize: 8 }}/>\n </>}\n </Modal>\n </>;\n}\n","import type { ComponentProps } from 'react';\nimport FoundationImportButton from './FoundationImportButton';\n\nexport function ImportButton(props: ComponentProps<typeof FoundationImportButton>) {\n return <FoundationImportButton {...props}/>;\n}\nexport default ImportButton;\n","import { Button, Tooltip, Typography } from \"@/ui\";\nimport { Copy, Eye, EyeOff } from 'lucide-react';\nimport { copyTextWithToast } from \"@/utils/clipboard\";\nimport { EMPTY_PLACEHOLDER } from \"@/utils/table-columns\";\nimport { useRevealedValue } from \"@fudanda/react-core/components/sensitive/useRevealedValue\";\nexport interface SensitiveTextProps {\n /** 契约实体名(schema meta.id),如 `User` */\n entity: string;\n /** 记录主键 */\n id: number;\n /** 实体内字段名,如 `phone` */\n field: string;\n /** 服务端返回的值(对当前用户可能已是掩码) */\n value: string | null | undefined;\n}\n/**\n * 表格 / 详情里的敏感字段文本:原样展示服务端给的值(明文或掩码);\n * 值被打码且用户拥有「按需查看明文」权限时附带查看按钮,明文展示 30 秒后自动恢复掩码。\n */\nexport function SensitiveText({ entity, id, field, value }: SensitiveTextProps) {\n const state = useRevealedValue({ entity, id, field });\n if (value == null || value === '')\n return <Typography.Text type=\"quaternary\">{EMPTY_PLACEHOLDER}</Typography.Text>;\n const showToggle = state.isMasked && state.canReveal;\n const text = state.revealed ?? value;\n return (<span className=\"sensitive-text\">\n <Typography.Text ellipsis={{ showTooltip: true }} style={{ minWidth: 0 }}>{text}</Typography.Text>\n {showToggle && (state.revealed === null ? (<Tooltip content=\"查看明文(记录审计)\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Eye size={14}/>} loading={state.revealing} aria-label=\"查看明文\" onClick={() => void state.show()}/>\n </Tooltip>) : (<>\n <Tooltip content=\"复制明文\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<Copy size={14}/>} aria-label=\"复制明文\" onClick={() => void copyTextWithToast(state.revealed ?? '')}/>\n </Tooltip>\n <Tooltip content=\"收起\">\n <Button size=\"small\" theme=\"borderless\" type=\"tertiary\" icon={<EyeOff size={14}/>} aria-label=\"收起明文\" onClick={state.hide}/>\n </Tooltip>\n </>))}\n </span>);\n}\n","import { DirectoryAccountModal, DirectorySyncControl } from \"@/pages/users/IdentityDirectoryControls\";\nimport { useIdentityCapabilities } from \"@fudanda/react-core/hooks/queries/auth-public\";\nimport { FormPasswordInput } from \"@/components/PasswordInput\";\nimport EntityRelationButton from \"@/components/entity-relations/EntityRelationButton\";\nimport { useState, useEffect, useCallback, useMemo, useRef } from 'react';\nimport { Button, Select, Space, Form, Toast, Tag, Row, Col, Tree } from \"@/ui\";\nimport type { FormApi } from \"@/ui\";\nimport { ChevronsUpDown, ChevronsDownUp, Building2, KeyRound } from 'lucide-react';\nimport type { CreateUserInput, User, Role, Department, Position } from '@fudanda/shared/identity';\nimport { USER_STATUSES, enumValueOf } from '@fudanda/shared/core';\nimport type { BodyOf } from '@fudanda/react-core/lib/contract-query';\nimport { userContract, departmentContract, positionContract, roleContract } from '@fudanda/react-core/lib/native-operations';\nimport { UserAvatar } from \"@/components/UserAvatar\";\nimport { formatDateForApi, formatDateTimeRangeForApi } from \"@fudanda/react-core/utils/date\";\nimport { formatPasswordPolicyHint, type PasswordRules as PasswordPolicy } from '@fudanda/shared/settings';\nimport { PasswordStrengthMeter } from \"@/components/PasswordStrengthMeter\";\nimport DictTag from \"@/components/DictTag\";\nimport { useDictItems } from \"@fudanda/react-core/hooks/useDictItems\";\nimport type { ColumnProps } from \"@/ui\";\nimport type { TreeNodeData } from \"@/ui\";\nimport { usePermission } from \"@fudanda/react-core/hooks/usePermission\";\nimport { isAllKeysExpanded } from \"@fudanda/react-core/hooks/useTreeExpansion\";\nimport { useAuth } from \"@fudanda/react-core/hooks/useAuth\";\nimport { AppModal } from \"@/components/AppModal\";\nimport ConfigurableTable from \"@/components/ConfigurableTable\";\nimport { MasterDetailLayout } from \"@/components/MasterDetailLayout\";\nimport { createOperationColumn } from \"@/components/ResponsiveTableActions\";\nimport \"@/pages/users/UsersPage.css\";\nimport { createdAtColumn, dateTimeColumn, overflowTagColumn, renderEllipsis } from \"@/utils/table-columns\";\nimport { UserMenuPermissionModal } from \"@/pages/users/UserMenuPermissionModal\";\nimport { UserDataScopeModal } from \"@/pages/users/UserDataScopeModal\";\nimport { UserAvatarModal } from \"@/pages/users/UserAvatarModal\";\nimport { UserLogsSheet } from \"@/pages/users/UserLogsSheet\";\nimport ExportButton from \"@/components/ExportButton\";\nimport ImportButton from \"@/components/ImportButton\";\nimport { useAllRoles } from \"@fudanda/react-core/hooks/queries/roles\";\nimport { departmentsToTreeData, useFlatDepartments } from \"@fudanda/react-core/hooks/queries/departments\";\nimport { useAllPositions } from \"@fudanda/react-core/hooks/queries/positions\";\nimport { useMySettings } from \"@fudanda/react-core/hooks/queries/settings\";\nimport { useListSearch } from \"@fudanda/react-core/hooks/useListSearch\";\nimport { useListDeepLink } from \"@fudanda/react-core/hooks/useListDeepLink\";\nimport { useAssignUserRoles, useBatchUserPassword, useBatchUserStatus, useDeleteUsers, useKickUserSessions, useResetUserPassword, useSaveUser, useUnlockUser, useUserDetail, useUserEffectivePermissions, useUserList, userKeys } from \"@fudanda/react-core/hooks/queries/users\";\nimport { BatchDeleteButton, BatchStatusButtons, CreateButton } from \"@/components/toolbar-controls\";\nimport { DateRangeFilter, KeywordInput, StatusSelect } from \"@/components/search-filters\";\nimport { confirmDanger } from \"@/utils/confirm\";\n\nimport { batchStatusHandler, confirmAndDelete, deleteAction, buildTableSearch, listTableProps, useStatusToggle } from \"@/components/list-page/index\";\nimport { useEditModal, formSaveMutation } from \"@/hooks/useEditModal\";\nimport { useSensitiveFormFields } from \"@fudanda/react-core/hooks/useSensitiveFormFields\";\nimport { isMaskedFieldValue } from '@fudanda/react-core/hooks/queries/data-mask';\nimport { SensitiveFormInput, SensitiveText } from \"@/components/sensitive/index\";\nimport { abortSubmit } from \"@fudanda/react-core/lib/abort-submit\";\nimport { useFilterQuery } from \"@fudanda/react-core/hooks/useFilterQuery\";\nimport { EditFormModal } from \"@/components/EditFormModal\";\nimport { useStandardWebMcpCrudAdapter } from '@/webmcp-crud';\ninterface SearchParams {\n keyword: string;\n phone: string;\n status?: string;\n timeRange: [\n Date,\n Date\n ] | null;\n /** 部门树选中的部门;undefined = 全部部门 */\n departmentId?: number;\n}\n/** 用户表单值:记录里的 null 在提交时归一为未填 / null,与创建入参对齐 */\ninterface UserFormValues extends Partial<Omit<CreateUserInput, 'email' | 'phone' | 'gender' | 'birthDate'>> {\n email?: string | null;\n phone?: string | null;\n gender?: string | null;\n birthDate?: Date | string | null;\n}\ntype UserSavePayload = Partial<BodyOf<typeof userContract.create>> & BodyOf<typeof userContract.update>;\ninterface ResetPasswordFormValues {\n password: string;\n confirmPassword: string;\n}\nconst defaultSearchParams: SearchParams = { keyword: '', phone: '', status: undefined, timeRange: null, departmentId: undefined };\nconst ALL_DEPARTMENTS_KEY = 'all-departments';\nconst EMPTY_USERS: User[] = [];\nconst EMPTY_ROLES: Role[] = [];\nconst EMPTY_DEPARTMENTS: Department[] = [];\nconst EMPTY_POSITIONS: Position[] = [];\nfunction isAdminUser(user: Pick<User, 'username'>) {\n return user.username.trim().toLowerCase() === 'admin';\n}\nexport default function UsersPage() {\n const { hasPermission } = usePermission();\n const { updateUser, user: currentUser } = useAuth();\n const { page, pageSize, buildPagination, draftParams, bind, bindKeyword, submittedParams, handleSearch, applySearch, handleReset } = useListSearch<SearchParams>({ defaults: defaultSearchParams, listKey: userKeys.lists });\n useListDeepLink(['keyword'], (params) => applySearch({ ...defaultSearchParams, keyword: params.keyword ?? '' }));\n const [batchPasswordModalVisible, setBatchPasswordModalVisible] = useState(false);\n // useEditModal 例外:批量重置密码对话框(针对选中用户的动作表单,非新增 / 编辑)\n const batchPasswordFormApi = useRef<FormApi | null>(null);\n const [menuPermUser, setMenuPermUser] = useState<User | null>(null);\n const [menuPermVisible, setMenuPermVisible] = useState(false);\n const [dataPermUser, setDataPermUser] = useState<User | null>(null);\n const [dataPermVisible, setDataPermVisible] = useState(false);\n const [roleAssignUser, setRoleAssignUser] = useState<User | null>(null);\n const [roleAssignVisible, setRoleAssignVisible] = useState(false);\n const [roleAssignIds, setRoleAssignIds] = useState<number[]>([]);\n const [avatarUser, setAvatarUser] = useState<User | null>(null);\n const [avatarModalVisible, setAvatarModalVisible] = useState(false);\n const [logsUser, setLogsUser] = useState<User | null>(null);\n const [logsVisible, setLogsVisible] = useState(false);\n const identityQuery = useIdentityCapabilities();\n const externalIdentity = identityQuery.data?.externalLogin === true;\n const [directoryEditor, setDirectoryEditor] = useState<User | true | null>(null);\n const [createPwdVal, setCreatePwdVal] = useState('');\n const [editPwdVal, setEditPwdVal] = useState('');\n const [batchPwdVal, setBatchPwdVal] = useState('');\n const { items: statusItems } = useDictItems('common_status');\n const { options: genderOptions } = useDictItems('user_gender');\n const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);\n const [deptTreeExpandedKeys, setDeptTreeExpandedKeys] = useState<string[]>([]);\n const canReadRoles = hasPermission('system:role:list');\n const canReadDepartments = hasPermission('system:department:list');\n const canReadPositions = hasPermission('system:position:list');\n const allRolesQuery = useAllRoles({ enabled: canReadRoles });\n const allDepartmentsQuery = useFlatDepartments({ enabled: canReadDepartments });\n const allPositionsQuery = useAllPositions({ enabled: canReadPositions });\n const mySettingsQuery = useMySettings();\n const allRoles = allRolesQuery.data ?? EMPTY_ROLES;\n const allDepartments = allDepartmentsQuery.data ?? EMPTY_DEPARTMENTS;\n const allPositions = allPositionsQuery.data ?? EMPTY_POSITIONS;\n const passwordPolicy: PasswordPolicy | null = mySettingsQuery.data?.identitySecurity.password ?? null;\n // 已提交筛选 → 契约查询参数:列表与导出共用同一份映射\n const filterQuery = useFilterQuery({\n keyword: submittedParams.keyword,\n phone: submittedParams.phone,\n departmentId: submittedParams.departmentId,\n status: enumValueOf(USER_STATUSES, submittedParams.status),\n ...formatDateTimeRangeForApi(submittedParams.timeRange),\n });\n const listQuery = useUserList({ page, pageSize, ...filterQuery });\n const userList = listQuery.data?.list ?? EMPTY_USERS;\n const saveMutation = useSaveUser();\n const resetPasswordMutation = useResetUserPassword();\n const deleteMutation = useDeleteUsers();\n const unlockMutation = useUnlockUser();\n const batchStatusMutation = useBatchUserStatus();\n const toggleStatusMutation = useBatchUserStatus();\n const batchPasswordMutation = useBatchUserPassword();\n const assignRolesMutation = useAssignUserRoles();\n const roleEffectivePermissionsQuery = useUserEffectivePermissions(roleAssignUser?.id, roleAssignVisible);\n const kickSessionsMutation = useKickUserSessions();\n // 敏感字段(手机号 / 邮箱)对非豁免用户是掩码:编辑时锁定,提交前剔除未修改的锁定字段\n const sensitiveFieldsRef = useRef<ReturnType<typeof useSensitiveFormFields<User>> | null>(null);\n const modal = useEditModal<User, UserFormValues, UserSavePayload>({\n entityName: '用户',\n save: formSaveMutation(saveMutation, { create: userContract.create.input.shape.body, update: userContract.update.input.shape.body }),\n useDetail: useUserDetail,\n defaults: {\n positionIds: [],\n roleIds: [],\n status: 'enabled',\n },\n toValues: (user) => ({\n username: user.username,\n nickname: user.nickname,\n email: user.email ?? undefined,\n phone: user.phone ?? undefined,\n gender: user.gender ?? undefined,\n birthDate: user.birthDate ?? undefined,\n departmentId: user.departmentId ?? undefined,\n positionIds: user.positionIds ?? user.positions?.map((item) => item.id) ?? [],\n roleIds: user.roles.map((r) => r.id),\n status: user.status,\n }),\n beforeSave: (rawValues, { editing }) => {\n const control = sensitiveFieldsRef.current;\n const values = (control ? control.strip(rawValues as unknown as Record<string, unknown>) : rawValues) as UserFormValues;\n const clearFields: NonNullable<BodyOf<typeof userContract.update>['clearFields']> = [];\n if (editing) {\n if (values.departmentId == null) clearFields.push('departmentId');\n if ('email' in values && !values.email) clearFields.push('email');\n if ('phone' in values && !values.phone) clearFields.push('phone');\n if (!values.gender) clearFields.push('gender');\n if (!values.birthDate) clearFields.push('birthDate');\n }\n const payload: UserSavePayload = {\n username: values.username, nickname: values.nickname,\n email: values.email || undefined, phone: values.phone || undefined,\n departmentId: values.departmentId ?? undefined,\n gender: values.gender || undefined,\n birthDate: values.birthDate ? formatDateForApi(values.birthDate) : undefined,\n positionIds: values.positionIds ?? [], roleIds: values.roleIds ?? [], status: values.status,\n ...(editing ? { clearFields } : { password: values.password }),\n };\n // 被剔除的锁定字段不出现在载荷里(服务端只更新提交了的字段)\n if (!('email' in values))\n delete payload.email;\n if (!('phone' in values))\n delete payload.phone;\n if (editing && isAdminUser(editing) && values.status === 'disabled') {\n Toast.warning('admin 账号不允许禁用');\n abortSubmit('admin_status_forbidden');\n }\n if (externalIdentity)\n return { departmentId: payload.departmentId, positionIds: payload.positionIds, roleIds: payload.roleIds, status: payload.status, clearFields: values.departmentId == null ? ['departmentId'] : [] };\n return payload;\n },\n labelWidth: 72,\n });\n const editingUser = modal.editing;\n useStandardWebMcpCrudAdapter({ resource: 'users', title: '用户', permission: 'system:user', hasPermission, modal,\n list: userContract.list, detail: userContract.detail, create: userContract.create.input.shape.body, update: userContract.update.input.shape.body,\n updateFields: ['nickname', 'email', 'phone', 'departmentId', 'positionIds', 'roleIds', 'gender', 'birthDate', 'status', 'clearFields'], updateClearFields: ['email', 'phone', 'departmentId', 'gender', 'birthDate'],\n fields: ['id', 'username', 'nickname', 'email', 'phone', 'gender', 'birthDate', 'departmentId', 'departmentName', 'status', 'createdAt', 'updatedAt'],\n filters: filterQuery, selectedIds: selectedRowKeys, canCreate: !externalIdentity, remove: id => deleteMutation.mutateAsync([id]), onDeleted: () => setSelectedRowKeys([]), busy: batchPasswordModalVisible || menuPermVisible || dataPermVisible || roleAssignVisible || avatarModalVisible || logsVisible || directoryEditor !== null,\n guardRecord: (record, action) => { if (action === 'delete' && isAdminUser(record)) throw new Error('admin 账号不允许删除'); },\n guardValues: (values, record) => {\n if (record && 'username' in values) throw new Error('编辑时不能修改用户名');\n if (record && ['email', 'phone'].some(field => field in values && isMaskedFieldValue(record[field as 'email' | 'phone']))) throw new Error('敏感字段处于锁定状态,请在页面处理');\n if (externalIdentity && ['username', 'nickname', 'email', 'phone', 'gender', 'birthDate'].some(field => field in values)) throw new Error('外部身份字段由身份目录维护');\n if (!canReadDepartments && 'departmentId' in values || !canReadPositions && Array.isArray(values.positionIds) && values.positionIds.length > 0 || !canReadRoles && Array.isArray(values.roleIds) && values.roleIds.length > 0) throw new Error('缺少关联字段的读取权限');\n },\n lookups: [{ name: 'departments', title: '部门', operation: departmentContract.flat, permission: 'system:department:list', fields: ['id', 'name', 'parentId'] },\n { name: 'positions', title: '岗位', operation: positionContract.all, permission: 'system:position:list', fields: ['id', 'name', 'code'] },\n { name: 'roles', title: '角色', operation: roleContract.all, permission: 'system:role:list', fields: ['id', 'name', 'code'] }] });\n const sensitiveFields = useSensitiveFormFields<User>({ entity: 'User', fields: ['email', 'phone'], record: editingUser });\n sensitiveFieldsRef.current = sensitiveFields;\n const passwordModal = useEditModal<User, ResetPasswordFormValues>({\n save: {\n mutateAsync: async ({ id, values }) => {\n if (id == null)\n abortSubmit('missing_user');\n await resetPasswordMutation.mutateAsync({ params: { id }, body: { password: values.password } });\n return {} as User;\n },\n isPending: false,\n },\n beforeSave: (values) => {\n if (values.password !== values.confirmPassword) {\n Toast.error('两次密码输入不一致');\n abortSubmit('password_not_match');\n }\n return values;\n },\n successMessage: () => '密码修改成功',\n onSaved: () => setEditPwdVal(''),\n });\n /** 记录抽屉的入口条件:登录日志 / 操作日志两个权限至少有一个 */\n const canViewLoginLogs = hasPermission('system:log:login');\n const canViewOperationLogs = hasPermission('system:log:operation');\n const canViewUserLogs = canViewLoginLogs || canViewOperationLogs;\n const selectedDeletableCount = useMemo(() => {\n if (!userList.length)\n return 0;\n const selectedSet = new Set(selectedRowKeys);\n return userList.filter((item) => selectedSet.has(item.id) && !isAdminUser(item)).length;\n }, [userList, selectedRowKeys]);\n const selectedNonAdminIds = useMemo(() => {\n if (!userList.length)\n return [];\n const selectedSet = new Set(selectedRowKeys);\n return userList.filter((item) => selectedSet.has(item.id) && !isAdminUser(item)).map((item) => item.id);\n }, [userList, selectedRowKeys]);\n const status = useStatusToggle<User>({\n toggle: (user, enabled) => toggleStatusMutation.mutateAsync({ body: { ids: [user.id], status: enabled ? 'enabled' : 'disabled' } }),\n confirmDisable: (user) => ({ danger: true, title: `确认停用用户「${user.nickname ?? user.username}」?`, content: '停用后该用户将无法登录。', okText: '确认停用' }),\n disabled: (user) => isAdminUser(user) || !hasPermission('system:user:update'),\n });\n // 启用 / 停用都需确认(停用后无法登录,红色实心确认);admin 账号不在选中集里\n const handleBatchStatus = batchStatusHandler({\n selectedRowKeys: selectedNonAdminIds,\n clearSelection: () => setSelectedRowKeys([]),\n run: (ids, status) => batchStatusMutation.mutateAsync({ body: { ids, status } }),\n confirm: 'always',\n entity: '个用户',\n confirmContent: (status) => (status === 'disabled' ? '停用后该用户将无法登录。' : '启用后该用户可正常登录。'),\n danger: true,\n });\n const handleBatchDelete = () => {\n const deletableIds = userList\n .filter((item) => selectedRowKeys.includes(item.id) && !isAdminUser(item))\n .map((item) => item.id);\n if (deletableIds.length === 0) {\n Toast.warning('admin 账号不允许删除');\n return;\n }\n confirmAndDelete({\n title: `确认删除选中的 ${deletableIds.length} 个用户?`,\n content: '删除后无法恢复,请谨慎操作。',\n run: () => deleteMutation.mutateAsync(deletableIds),\n successMessage: '批量删除成功',\n onDeleted: () => setSelectedRowKeys([]),\n });\n };\n const departmentTreeData = useMemo<TreeNodeData[]>(() => departmentsToTreeData(allDepartments, { keepEmptyChildren: true }), [allDepartments]);\n const departmentFilterTreeData = useMemo<TreeNodeData[]>(() => [{ key: ALL_DEPARTMENTS_KEY, value: ALL_DEPARTMENTS_KEY, label: '全部部门' }, ...departmentTreeData], [departmentTreeData]);\n const allDeptExpandedKeys = useMemo(() => allDepartments.map((item) => String(item.id)), [allDepartments]);\n // 首次加载完成后默认全展开;此后(keepAlive 页签切回 / 数据刷新触发 effect 重放)保持用户手动展开/折叠状态\n const deptTreeExpandInitedRef = useRef(false);\n useEffect(() => {\n if (deptTreeExpandInitedRef.current || allDepartments.length === 0)\n return;\n deptTreeExpandInitedRef.current = true;\n setDeptTreeExpandedKeys(allDeptExpandedKeys);\n }, [allDeptExpandedKeys, allDepartments.length]);\n const isAllDeptExpanded = isAllKeysExpanded(deptTreeExpandedKeys, allDeptExpandedKeys);\n function toggleDeptExpandAll() {\n setDeptTreeExpandedKeys(isAllDeptExpanded ? [] : allDeptExpandedKeys);\n }\n const positionOptionList = useMemo(() => allPositions.map((item) => ({ value: item.id, label: item.name })), [allPositions]);\n const openCreate = modal.openCreate;\n const openEdit = modal.openEdit;\n const openPassword = passwordModal.openEdit;\n const { mutateAsync: unlockUser } = unlockMutation;\n const handleUnlock = useCallback(async (id: number) => {\n await unlockUser({ params: { id } });\n Toast.success('已清除登录验证码要求');\n }, [unlockUser]);\n const { mutateAsync: kickUserSessions } = kickSessionsMutation;\n const { refetch: refetchUserList } = listQuery;\n // 列定义 memo 化:搜索框每次击键都会触发页面重渲染,\n // 若每次都重建 columns(含所有 render 闭包),表格会整体重渲染所有行\n const columns: ColumnProps<User>[] = useMemo(() => [\n {\n title: '用户',\n dataIndex: 'nickname',\n minWidth: 260,\n ellipsis: { showTitle: false },\n render: (_: unknown, record: User) => (<div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n <span title={record.isOnline ? '在线' : '离线'} style={{\n flexShrink: 0,\n width: 8,\n height: 8,\n borderRadius: '50%',\n background: record.isOnline ? 'var(--arc-antd-color-success)' : 'var(--arc-antd-color-fill-2)',\n display: 'inline-block',\n boxShadow: record.isOnline ? '0 0 0 2px color-mix(in srgb, var(--arc-antd-color-success) 20%, transparent)' : undefined,\n }}/>\n <UserAvatar name={record.nickname || record.username} avatar={record.avatar} size={24}/>\n <span className=\"table-cell-ellipsis\" title={`${record.externalDisplayName || record.nickname}(${record.externalUsername || record.username})`}>\n {record.externalDisplayName || record.nickname}({record.externalUsername || record.username}){record.accountSource === \"casdoor\" && <Tag size=\"small\">Casdoor · {record.remoteStatus === \"active\" ? \"有效\" : \"停用或删除\"}</Tag>}\n </span>\n {record.loginChallengeRequired && (<Tag size=\"small\" color=\"orange\" style={{ flexShrink: 0 }}>需验证码</Tag>)}\n </div>),\n },\n {\n title: '手机号码',\n dataIndex: 'phone',\n width: 150,\n render: (v: string | null | undefined, record: User) => <SensitiveText entity=\"User\" id={record.id} field=\"phone\" value={v}/>,\n },\n {\n title: '邮箱',\n dataIndex: 'email',\n defaultHidden: true,\n width: 240,\n render: (v: string | null | undefined, record: User) => <SensitiveText entity=\"User\" id={record.id} field=\"email\" value={v}/>,\n },\n {\n title: '部门',\n dataIndex: 'departmentName',\n width: 140,\n render: renderEllipsis,\n },\n { ...overflowTagColumn<User>({\n title: '岗位',\n dataIndex: 'positions',\n width: 160,\n contentWidth: 128,\n getItems: (positions) => ((positions as Position[] | undefined) ?? [])\n .map((item) => ({ key: String(item.id), label: item.name })),\n tagColor: 'purple',\n popoverWidth: 200,\n empty: <Tag color=\"grey\">无岗位</Tag>,\n }), defaultHidden: true },\n overflowTagColumn<User>({\n title: '角色',\n dataIndex: 'roles',\n width: 180,\n contentWidth: 148,\n getItems: (roles) => (roles as Role[]).map((role) => ({ key: String(role.id), label: role.name })),\n tagColor: 'blue',\n popoverWidth: 240,\n empty: <Tag color=\"grey\">无角色</Tag>,\n }),\n {\n title: '性别',\n dataIndex: 'gender',\n defaultHidden: true,\n width: 80,\n render: (gender: string | null | undefined) => gender ? <DictTag dictCode=\"user_gender\" value={gender}/> : null,\n },\n dateTimeColumn('最近登录', 'lastLoginAt', { defaultHidden: true }),\n dateTimeColumn('最近活跃', 'lastActiveAt', { defaultHidden: true }),\n { title: '关联信息', key: 'relations', defaultHidden: true, width: 120, render: (_: unknown, record: User) => <EntityRelationButton entityRef={{ type: 'identity.user', key: String(record.id) }}/> },\n { ...createdAtColumn, defaultHidden: true },\n status.column(),\n createOperationColumn<User>({\n width: 180,\n desktopInlineKeys: ['edit', 'delete'],\n actions: (record) => {\n const isAdmin = isAdminUser(record);\n return [\n {\n key: 'edit',\n label: externalIdentity ? '本应用权限' : '编辑',\n hidden: !hasPermission('system:user:update'),\n onClick: () => {\n openEdit(record);\n },\n },\n { key: 'directory-profile', label: '统一账户资料', hidden: !externalIdentity || !hasPermission('system:user:update'), onClick: () => setDirectoryEditor(record) },\n deleteAction({\n hidden: externalIdentity || !hasPermission('system:user:delete'),\n disabled: isAdmin,\n disabledReason: 'admin 账号不允许删除',\n title: '确定要删除该用户吗?',\n run: () => deleteMutation.mutateAsync([record.id]),\n }),\n {\n key: 'avatar',\n label: '管理头像',\n hidden: externalIdentity || !hasPermission('system:user:update'),\n onClick: () => {\n setAvatarUser(record);\n setAvatarModalVisible(true);\n },\n },\n {\n key: 'password',\n label: '修改密码',\n hidden: externalIdentity || !hasPermission('system:user:update'),\n onClick: () => {\n openPassword(record);\n },\n },\n {\n key: 'unlock',\n label: '清除登录验证码要求',\n hidden: !record.loginChallengeRequired || !hasPermission('system:user:update'),\n onClick: () => handleUnlock(record.id),\n },\n {\n key: 'logs',\n label: '登录与操作记录',\n // 两个日志权限任一即可打开抽屉(只有权限的那个 tab 会渲染)\n hidden: !canViewUserLogs,\n onClick: () => {\n setLogsUser(record);\n setLogsVisible(true);\n },\n },\n {\n key: 'menu-permission',\n label: '菜单权限',\n hidden: !hasPermission('system:user:assign'),\n onClick: () => {\n setMenuPermUser(record);\n setMenuPermVisible(true);\n },\n },\n {\n key: 'assign-role',\n label: '分配角色',\n hidden: !hasPermission('system:user:assign'),\n onClick: () => {\n setRoleAssignUser(record);\n setRoleAssignIds(record.roles.map((r) => r.id));\n setRoleAssignVisible(true);\n },\n },\n {\n key: 'data-permission',\n label: '数据权限',\n hidden: !hasPermission('system:user:assign'),\n onClick: () => {\n setDataPermUser(record);\n setDataPermVisible(true);\n },\n },\n {\n key: 'force-logout',\n label: '强制下线',\n danger: true,\n dividerBefore: true,\n // 离线用户仍展示入口(便于发现该能力),但不可点击\n hidden: !hasPermission('system:session:forceLogout'),\n disabled: !record.isOnline,\n disabledReason: '该用户当前不在线',\n onClick: () => {\n confirmDanger({\n title: '强制下线',\n content: `确定要强制下线用户「${record.nickname}(${record.username})」的全部会话吗?`,\n onOk: async () => {\n await kickUserSessions({ params: { id: record.id } });\n Toast.success('已强制下线');\n void refetchUserList();\n },\n });\n },\n },\n ];\n },\n }),\n ], [externalIdentity, hasPermission, status, deleteMutation, handleUnlock, kickUserSessions, refetchUserList, openEdit, openPassword, canViewUserLogs]);\n const [showDeptTree, setShowDeptTree] = useState(false);\n const [isLayoutNarrow, setIsLayoutNarrow] = useState(false);\n const masterContent = (<div className=\"users-dept-sidebar\">\n <MasterDetailLayout.Header className=\"users-dept-sidebar-title\" style={{ padding: '10px 12px', minHeight: 44, marginBottom: 4 }} extra={(<Button className=\"users-dept-tree-action\" theme=\"borderless\" size=\"small\" icon={isAllDeptExpanded ? <ChevronsDownUp size={14}/> : <ChevronsUpDown size={14}/>} onClick={toggleDeptExpandAll}>\n {isAllDeptExpanded ? '全部折叠' : '全部展开'}\n </Button>)}>\n <span className=\"users-dept-sidebar-title-text\">组织架构</span>\n </MasterDetailLayout.Header>\n <Tree blockNode treeData={departmentFilterTreeData} expandedKeys={deptTreeExpandedKeys} value={draftParams.departmentId === undefined ? ALL_DEPARTMENTS_KEY : String(draftParams.departmentId)} filterTreeNode={(input, _node, data) => data.key === ALL_DEPARTMENTS_KEY || String(data.label ?? '').toLocaleLowerCase().includes(input.toLocaleLowerCase())} showFilteredOnly searchPlaceholder=\"搜索部门\" onExpand={(expandedKeys) => {\n setDeptTreeExpandedKeys((expandedKeys as Array<string | number>).map(String));\n }} onSelect={(selectedKey) => {\n const newDeptId = selectedKey === ALL_DEPARTMENTS_KEY ? undefined : Number(selectedKey);\n const newParams = { ...draftParams, departmentId: newDeptId };\n applySearch(newParams);\n setShowDeptTree(false);\n }} style={{ width: '100%' }}/>\n </div>);\n const renderDepartmentButton = (forceVisible = false) => (<Button theme=\"borderless\" icon={<Building2 size={14}/>} onClick={() => setShowDeptTree(true)} style={{ display: forceVisible || isLayoutNarrow ? undefined : 'none' }}>\n 按部门\n </Button>);\n const renderBatchActions = () => (<>\n {!externalIdentity && selectedDeletableCount > 0 && hasPermission('system:user:delete') && (<BatchDeleteButton count={selectedDeletableCount} onClick={handleBatchDelete}/>)}\n {selectedNonAdminIds.length > 0 && hasPermission('system:user:update') && (<>\n <BatchStatusButtons count={selectedNonAdminIds.length} onChange={handleBatchStatus} danger/>\n {!externalIdentity && <Button theme=\"light\" icon={<KeyRound size={14}/>} onClick={() => setBatchPasswordModalVisible(true)}>\n 批量修改密码 ({selectedNonAdminIds.length})\n </Button>}\n </>)}\n </>);\n const renderImportButton = () => !externalIdentity && hasPermission('system:user:import') ? (<ImportButton entity=\"identity.users\" title=\"用户\" onFinished={() => void refetchUserList()}/>) : null;\n return (<div className=\"page-container page-container--stretch\">\n <MasterDetailLayout master={masterContent} detail={<div className=\"users-content\">\n\n\n <ConfigurableTable<User> searchConfig={buildTableSearch({\n keyword: (<KeywordInput placeholder=\"搜索用户名/昵称/邮箱\" {...bindKeyword('keyword')} width={260}/>),\n filters: ((<>\n <KeywordInput placeholder=\"搜索手机号码\" {...bindKeyword('phone')} width={180}/>\n <StatusSelect items={statusItems} {...bind('status')}/>\n <DateRangeFilter placeholder={[\"开始时间\", \"结束时间\"]} {...bind('timeRange')}/>\n </>)),\n onSearch: (handleSearch),\n onReset: (handleReset),\n create: (<CreateButton permission=\"system:user:create\" onClick={() => externalIdentity ? setDirectoryEditor(true) : openCreate()}/>),\n actions: ((<>\n {renderDepartmentButton()}\n {renderBatchActions()}\n <ExportButton entity=\"system.users\" query={filterQuery} watermark={false} permission=\"system:user:export\"/>\n {renderImportButton()}\n {externalIdentity && <DirectorySyncControl administrator={currentUser?.roles.some(role => role.code === \"super_admin\") ?? false}/>}\n </>)),\n filterTitle: \"用户筛选\",\n actionTitle: \"用户操作\"\n })} columns={columns} {...listTableProps(listQuery, {\n pagination: buildPagination,\n empty: '暂无数据',\n rowSelection: {\n selectedRowKeys,\n onChange: (keys) => {\n const nextKeys = (keys ?? []).map(Number);\n const nextKeySet = new Set(nextKeys);\n const adminIds = userList.filter((item) => isAdminUser(item)).map((item) => item.id);\n const filtered = nextKeys.filter((id) => !adminIds.includes(id));\n if (filtered.length < nextKeys.length && adminIds.some((id) => nextKeySet.has(id))) {\n Toast.warning('admin 账号不支持批量删除');\n }\n setSelectedRowKeys(filtered);\n },\n },\n })}/>\n </div>} defaultSize={220} minSize={160} maxSize={400} showDetail={!showDeptTree} onMasterBack={() => setShowDeptTree(false)} masterBackLabel=\"返回用户列表\" onResponsiveChange={setIsLayoutNarrow} persistKey=\"users\" style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}/>\n\n {directoryEditor && <DirectoryAccountModal user={directoryEditor === true ? undefined : directoryEditor} onClose={() => { setDirectoryEditor(null); void refetchUserList(); }}/>}\n <EditFormModal modal={modal} okButtonProps={{ disabled: modal.detailLoading }} width={660}>\n {editingUser ? (<>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Input field=\"username\" label=\"用户名\" disabled/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"nickname\" label=\"昵称\" disabled={externalIdentity} placeholder=\"请输入昵称\" rules={[{ required: true, message: '请输入昵称' }]}/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <SensitiveFormInput control={sensitiveFields} disabled={externalIdentity} field=\"phone\" label=\"手机号码\" placeholder=\"请输入手机号码\" rules={[{ pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号码' }]}/>\n </Col>\n </Row>\n </>) : (<>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Input field=\"username\" label=\"用户名\" placeholder=\"请输入用户名\" rules={[{ required: true, message: '请输入用户名' }]}/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"nickname\" label=\"昵称\" disabled={externalIdentity} placeholder=\"请输入昵称\" rules={[{ required: true, message: '请输入昵称' }]}/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <FormPasswordInput field=\"password\" label=\"密码\" placeholder=\"请输入密码\" rules={[{ required: true, message: '请输入密码' }]} onChange={(v) => setCreatePwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={createPwdVal} policy={passwordPolicy}/>}/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"phone\" label=\"手机号码\" placeholder=\"请输入手机号码\" rules={[{ pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号码' }]}/>\n </Col>\n </Row>\n </>)}\n <Row gutter={16}>\n <Col span={12}>\n <SensitiveFormInput control={sensitiveFields} field=\"email\" disabled={externalIdentity} label=\"邮箱\" placeholder=\"请输入邮箱\" rules={[{ type: 'email', message: '邮箱格式不正确' }]}/>\n </Col>\n <Col span={12}>\n <Form.TreeSelect field=\"departmentId\" label=\"所属部门\" disabled={!canReadDepartments} style={{ width: '100%' }} treeData={departmentTreeData} placeholder=\"请选择所属部门\" filterTreeNode showClear/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Select field=\"positionIds\" label=\"岗位\" disabled={!canReadPositions} style={{ width: '100%' }} multiple filter showClear optionList={positionOptionList} placeholder=\"请选择岗位\"/>\n </Col>\n <Col span={12}>\n <Form.Select field=\"roleIds\" label=\"角色\" disabled={!canReadRoles} style={{ width: '100%' }} multiple filter optionList={allRoles.map((r) => ({ value: r.id, label: r.name }))} placeholder=\"请选择角色\"/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Select field=\"gender\" disabled={externalIdentity} label=\"性别\" style={{ width: '100%' }} showClear optionList={genderOptions} placeholder=\"请选择性别\"/>\n </Col>\n <Col span={12}>\n <Form.DatePicker field=\"birthDate\" disabled={externalIdentity} label=\"出生日期\" type=\"date\" style={{ width: '100%' }} placeholder=\"请选择出生日期\" showClear/>\n </Col>\n </Row>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Select field=\"status\" label=\"状态\" style={{ width: '100%' }} optionList={statusItems.map((i) => ({\n value: i.value,\n label: i.label,\n disabled: editingUser ? (isAdminUser(editingUser) && i.value === 'disabled') : false,\n }))} placeholder=\"请选择状态\"/>\n </Col>\n </Row>\n </EditFormModal>\n\n <EditFormModal modal={passwordModal} title={passwordModal.editing ? `修改密码 - ${passwordModal.editing.nickname}` : '修改密码'} onCancel={() => { passwordModal.close(); setEditPwdVal(''); }} width={420}>\n <FormPasswordInput field=\"password\" label=\"新密码\" placeholder=\"请输入新密码\" rules={[\n { required: true, message: '请输入新密码' },\n { min: 6, message: '密码至少 6 个字符' },\n ]} onChange={(v) => setEditPwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={editPwdVal} policy={passwordPolicy}/>}/>\n <FormPasswordInput field=\"confirmPassword\" label=\"确认密码\" placeholder=\"请再次输入新密码\" rules={[{ required: true, message: '请确认新密码' }]}/>\n </EditFormModal>\n\n {false}\n\n {/* 批量修改密码 */}\n <AppModal title={`批量修改密码(共 ${selectedNonAdminIds.length} 个用户)`} visible={batchPasswordModalVisible} onCancel={() => { setBatchPasswordModalVisible(false); batchPasswordFormApi.current?.setValues({ password: '', confirmPassword: '' }); setBatchPwdVal(''); }} confirmLoading={batchPasswordMutation.isPending} onOk={async () => {\n if (!batchPasswordFormApi.current)\n return;\n try {\n const values = await batchPasswordFormApi.current.validate() as unknown as {\n password: string;\n confirmPassword: string;\n };\n if (values.password !== values.confirmPassword) {\n batchPasswordFormApi.current.setError('confirmPassword', '两次密码输入不一致');\n return;\n }\n await batchPasswordMutation.mutateAsync({ body: { ids: selectedNonAdminIds, password: values.password } });\n Toast.success('密码修改成功');\n setBatchPasswordModalVisible(false);\n batchPasswordFormApi.current.setValues({ password: '', confirmPassword: '' });\n setBatchPwdVal('');\n setSelectedRowKeys([]);\n }\n catch { /* No additional action. */ } /* No additional action. */ /* No additional action. */ /* No additional action. */ /* No additional action. */ /* No additional action. */\n }}>\n <Form getFormApi={(api) => { batchPasswordFormApi.current = api; }} labelPosition=\"left\" labelWidth={90}>\n <FormPasswordInput field=\"password\" label=\"新密码\" placeholder={passwordPolicy ? formatPasswordPolicyHint(passwordPolicy) : '请输入新密码'} rules={[{ required: true, message: '请输入新密码' }]} onChange={(v) => setBatchPwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={batchPwdVal} policy={passwordPolicy}/>}/>\n <FormPasswordInput field=\"confirmPassword\" label=\"确认密码\" placeholder=\"请再次输入新密码\" rules={[{ required: true, message: '请确认密码' }]}/>\n </Form>\n </AppModal>\n\n {/* 管理头像 */}\n {avatarUser && (<UserAvatarModal visible={avatarModalVisible} user={avatarUser} onClose={() => setAvatarModalVisible(false)} onUpdated={(updated) => {\n void listQuery.refetch();\n setAvatarUser(updated);\n updateUser(updated);\n }}/>)}\n\n {/* 登录与操作记录 */}\n {logsUser && (<UserLogsSheet visible={logsVisible} userId={logsUser.id} userName={`${logsUser.nickname || logsUser.username}(${logsUser.username})`} canViewLoginLogs={canViewLoginLogs} canViewOperationLogs={canViewOperationLogs} onClose={() => setLogsVisible(false)}/>)}\n\n {/* 用户菜单权限 */}\n {menuPermUser && (<UserMenuPermissionModal userId={menuPermUser.id} userName={menuPermUser.nickname || menuPermUser.username} visible={menuPermVisible} onClose={() => setMenuPermVisible(false)}/>)}\n\n {/* 用户数据权限 */}\n {dataPermUser && (<UserDataScopeModal userId={dataPermUser.id} userName={dataPermUser.nickname || dataPermUser.username} visible={dataPermVisible} deptTree={allDepartments} onClose={() => setDataPermVisible(false)}/>)}\n\n {/* 分配角色 */}\n <AppModal title={`分配角色——${roleAssignUser?.nickname || roleAssignUser?.username || ''}`} visible={roleAssignVisible} onCancel={() => setRoleAssignVisible(false)} confirmLoading={assignRolesMutation.isPending} onOk={async () => {\n if (!roleAssignUser)\n return;\n await assignRolesMutation.mutateAsync({ params: { id: roleAssignUser.id }, body: { roleIds: roleAssignIds } });\n Toast.success('角色分配成功');\n setRoleAssignVisible(false);\n }} okText=\"保存\" cancelText=\"取消\" width={480}>\n <div>\n <div style={{ marginBottom: 6, fontSize: 13, fontWeight: 600 }}>直接分配角色</div>\n <Select multiple filter showClear style={{ width: '100%' }} value={roleAssignIds} onChange={(v) => setRoleAssignIds((v as number[]) ?? [])} optionList={allRoles.map((r) => ({ value: r.id, label: r.name }))} placeholder=\"请选择要分配的角色\"/>\n </div>\n <div style={{ marginTop: 18, paddingTop: 14, borderTop: '1px solid var(--arc-antd-color-border)' }}>\n <div style={{ marginBottom: 6, fontSize: 13, fontWeight: 600 }}>用户组继承角色</div>\n <div style={{ marginBottom: 8, fontSize: 12, color: 'var(--arc-antd-color-text-2)' }}>\n 以下角色由用户组自动继承,只能在用户组中调整。\n </div>\n {roleEffectivePermissionsQuery.isFetching ? (<div style={{ color: 'var(--arc-antd-color-text-2)', fontSize: 12 }}>正在加载继承关系…</div>) : roleEffectivePermissionsQuery.data?.inheritedRoles.length ? (<Space spacing={6} wrap>\n {roleEffectivePermissionsQuery.data.inheritedRoles.map((role) => (<Tag key={role.id} color=\"orange\" style={{ marginBottom: 4 }}>\n {role.name}(来自:{role.groupNames.join('、')})\n </Tag>))}\n </Space>) : (<div style={{ color: 'var(--arc-antd-color-text-2)', fontSize: 12 }}>暂无用户组继承角色</div>)}\n </div>\n </AppModal>\n </div>);\n}\n"]}