com-angel-authorization 1.0.16 → 1.0.17

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/context.tsx","../../src/core/store.ts","../../src/react/Can.tsx","../../src/react/ResourceManager.tsx","../../src/resources/types.ts","../../src/utils/snowflake.ts","../../src/resources/pagination.ts","../../src/resources/api.ts","../../src/react/MenuManager.tsx","../../src/react/RoleManager.tsx","../../src/roles/index.ts","../../src/react/SystemAdmin.tsx","../../src/admin/menu.ts"],"sourcesContent":["import {\n createContext,\n createElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n createPermissionStore,\n type CheckOptions,\n type PermissionCode,\n type PermissionState,\n type PermissionStoreAPI,\n type RoleCode,\n} from '../core';\n\nconst PermissionContext = createContext<PermissionStoreAPI | null>(null);\n\nexport interface PermissionProviderProps {\n children: ReactNode;\n /** Pass an existing store to share across trees, or omit to create one. */\n store?: PermissionStoreAPI;\n /** Initial state when the provider creates its own store. */\n initialState?: Partial<PermissionState>;\n}\n\nexport function PermissionProvider({\n children,\n store: externalStore,\n initialState,\n}: PermissionProviderProps) {\n const store = useMemo(\n () => externalStore ?? createPermissionStore(initialState),\n // store identity is intentional; initialState only applies on first create\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [externalStore],\n );\n\n return createElement(PermissionContext.Provider, { value: store }, children);\n}\n\nfunction useStore(): PermissionStoreAPI {\n const store = useContext(PermissionContext);\n if (!store) {\n throw new Error(\n '[com-angel-authorization/react] usePermission* hooks must be used within <PermissionProvider>.',\n );\n }\n return store;\n}\n\nfunction usePermissionSnapshot(store: PermissionStoreAPI): PermissionState {\n const [state, setState] = useState(() => store.getState());\n\n useEffect(() => {\n setState(store.getState());\n return store.subscribe(setState);\n }, [store]);\n\n return state;\n}\n\nexport interface UsePermissionResult {\n permissions: PermissionCode[];\n roles: RoleCode[];\n isSuperAdmin: boolean;\n hasPermission: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;\n can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n setPermissions: (permissions: PermissionCode[]) => void;\n setRoles: (roles: RoleCode[]) => void;\n setSuperAdmin: (isSuperAdmin: boolean) => void;\n hydrate: (payload: Partial<PermissionState>) => void;\n clear: () => void;\n store: PermissionStoreAPI;\n}\n\nexport function usePermission(): UsePermissionResult {\n const store = useStore();\n const state = usePermissionSnapshot(store);\n\n const hasPermission = useCallback(\n (codes: PermissionCode | PermissionCode[], options?: CheckOptions) =>\n store.hasPermission(codes, options),\n [store],\n );\n\n const hasRole = useCallback(\n (codes: RoleCode | RoleCode[], options?: CheckOptions) => store.hasRole(codes, options),\n [store],\n );\n\n const can = useCallback(\n (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => store.can(codes, options),\n [store],\n );\n\n return {\n permissions: state.permissions,\n roles: state.roles,\n isSuperAdmin: Boolean(state.isSuperAdmin),\n hasPermission,\n hasRole,\n can,\n setPermissions: store.setPermissions.bind(store),\n setRoles: store.setRoles.bind(store),\n setSuperAdmin: store.setSuperAdmin.bind(store),\n hydrate: store.hydrate.bind(store),\n clear: store.clear.bind(store),\n store,\n };\n}\n\n/** Returns whether the current user has the given permission(s). */\nexport function useHasPermission(\n codes: PermissionCode | PermissionCode[],\n options?: CheckOptions,\n): boolean {\n const { hasPermission, permissions, isSuperAdmin } = usePermission();\n // re-compute when permission list / super-admin changes\n void permissions;\n void isSuperAdmin;\n return hasPermission(codes, options);\n}\n\n/** Returns whether the current user has the given role(s). */\nexport function useHasRole(\n codes: RoleCode | RoleCode[],\n options?: CheckOptions,\n): boolean {\n const { hasRole, roles, isSuperAdmin } = usePermission();\n void roles;\n void isSuperAdmin;\n return hasRole(codes, options);\n}\n","import type {\n CheckOptions,\n MatchMode,\n PermissionCode,\n PermissionListener,\n PermissionState,\n PermissionStoreAPI,\n RoleCode,\n} from './types';\n\nconst DEFAULT_STATE: PermissionState = {\n permissions: [],\n roles: [],\n isSuperAdmin: false,\n};\n\nfunction toArray<T>(value: T | T[]): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nfunction matchCodes(\n owned: Set<string>,\n required: string[],\n mode: MatchMode,\n isSuperAdmin: boolean,\n): boolean {\n if (isSuperAdmin) return true;\n if (required.length === 0) return true;\n\n if (mode === 'all') {\n return required.every((code) => owned.has(code));\n }\n\n return required.some((code) => owned.has(code));\n}\n\n/**\n * Mutable permission store shared by React / Vue adapters.\n * Framework-agnostic — safe to use in Node, browser, or any UI lib.\n */\nexport class PermissionStore implements PermissionStoreAPI {\n private state: PermissionState;\n private permissionSet: Set<string>;\n private roleSet: Set<string>;\n private listeners = new Set<PermissionListener>();\n\n constructor(initial?: Partial<PermissionState>) {\n this.state = {\n ...DEFAULT_STATE,\n ...initial,\n permissions: initial?.permissions ?? [],\n roles: initial?.roles ?? [],\n };\n this.permissionSet = new Set(this.state.permissions);\n this.roleSet = new Set(this.state.roles);\n }\n\n getState(): PermissionState {\n return {\n permissions: [...this.state.permissions],\n roles: [...this.state.roles],\n isSuperAdmin: this.state.isSuperAdmin,\n };\n }\n\n setState(next: Partial<PermissionState>): void {\n this.state = {\n permissions: next.permissions ?? this.state.permissions,\n roles: next.roles ?? this.state.roles,\n isSuperAdmin: next.isSuperAdmin ?? this.state.isSuperAdmin,\n };\n this.permissionSet = new Set(this.state.permissions);\n this.roleSet = new Set(this.state.roles);\n this.emit();\n }\n\n setPermissions(permissions: PermissionCode[]): void {\n this.setState({ permissions });\n }\n\n setRoles(roles: RoleCode[]): void {\n this.setState({ roles });\n }\n\n setSuperAdmin(isSuperAdmin: boolean): void {\n this.setState({ isSuperAdmin });\n }\n\n /** Replace permissions, roles and super-admin flag in one shot (typical after login). */\n hydrate(payload: Partial<PermissionState>): void {\n this.setState({\n permissions: payload.permissions ?? [],\n roles: payload.roles ?? [],\n isSuperAdmin: payload.isSuperAdmin ?? false,\n });\n }\n\n /** Clear all authz data (typical after logout). */\n clear(): void {\n this.hydrate({});\n }\n\n hasPermission(\n codes: PermissionCode | PermissionCode[],\n options: CheckOptions = {},\n ): boolean {\n const mode = options.mode ?? 'any';\n return matchCodes(\n this.permissionSet,\n toArray(codes).filter(Boolean),\n mode,\n Boolean(this.state.isSuperAdmin),\n );\n }\n\n hasRole(codes: RoleCode | RoleCode[], options: CheckOptions = {}): boolean {\n const mode = options.mode ?? 'any';\n return matchCodes(\n this.roleSet,\n toArray(codes).filter(Boolean),\n mode,\n Boolean(this.state.isSuperAdmin),\n );\n }\n\n /** Alias of `hasPermission` for template-friendly APIs. */\n can(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean {\n return this.hasPermission(codes, options);\n }\n\n subscribe(listener: PermissionListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emit(): void {\n const snapshot = this.getState();\n this.listeners.forEach((listener) => listener(snapshot));\n }\n}\n\nexport function createPermissionStore(\n initial?: Partial<PermissionState>,\n): PermissionStoreAPI {\n return new PermissionStore(initial);\n}\n","import type { ReactNode } from 'react';\nimport type { CheckOptions, PermissionCode, RoleCode } from '../core';\nimport { usePermission } from './context';\n\nexport interface CanProps {\n /** Permission codes to check. */\n permission?: PermissionCode | PermissionCode[];\n /** Role codes to check. */\n role?: RoleCode | RoleCode[];\n /**\n * `any` — pass when at least one code matches (default)\n * `all` — pass only when every code matches\n */\n mode?: CheckOptions['mode'];\n /**\n * How permission and role conditions combine when both are provided.\n * Default: `and` (must satisfy both).\n */\n combine?: 'and' | 'or';\n children: ReactNode;\n /** Fallback when access is denied. */\n fallback?: ReactNode;\n}\n\nfunction evaluateAccess(\n hasPermission: (c: PermissionCode | PermissionCode[], o?: CheckOptions) => boolean,\n hasRole: (c: RoleCode | RoleCode[], o?: CheckOptions) => boolean,\n props: Pick<CanProps, 'permission' | 'role' | 'mode' | 'combine'>,\n): boolean {\n const { permission, role, mode, combine = 'and' } = props;\n const options: CheckOptions = { mode };\n\n const hasPermCheck = permission !== undefined;\n const hasRoleCheck = role !== undefined;\n\n if (!hasPermCheck && !hasRoleCheck) return true;\n\n const permOk = hasPermCheck ? hasPermission(permission!, options) : true;\n const roleOk = hasRoleCheck ? hasRole(role!, options) : true;\n\n if (hasPermCheck && hasRoleCheck) {\n return combine === 'or' ? permOk || roleOk : permOk && roleOk;\n }\n\n return hasPermCheck ? permOk : roleOk;\n}\n\n/**\n * Conditionally render children based on permission / role.\n *\n * @example\n * <Can permission=\"user:edit\">\n * <button>Edit</button>\n * </Can>\n *\n * <Can permission={['user:edit', 'user:delete']} mode=\"all\" fallback={null}>\n * <AdminPanel />\n * </Can>\n */\nexport function Can({\n permission,\n role,\n mode,\n combine,\n children,\n fallback = null,\n}: CanProps) {\n const { hasPermission, hasRole } = usePermission();\n const allowed = evaluateAccess(hasPermission, hasRole, {\n permission,\n role,\n mode,\n combine,\n });\n\n return <>{allowed ? children : fallback}</>;\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type FormEvent,\n type ReactNode,\n} from 'react';\nimport {\n RESOURCE_PRIVATE_OPTIONS,\n RESOURCE_STATUS_ENABLED,\n RESOURCE_STATUS_OPTIONS,\n type AuthorizationResource,\n type AuthorizationResourceApi,\n type AuthorizationResourceFormValues,\n type PageDirection,\n} from '../resources';\n\nconst PAGE_SIZE_OPTIONS = ['10', '20', '50', '100'];\n\nconst emptyForm = (): AuthorizationResourceFormValues => ({\n name: '',\n identification: '',\n status: RESOURCE_STATUS_ENABLED,\n private: false,\n description: '',\n});\n\nexport type ResourceManagerProps = {\n api: AuthorizationResourceApi;\n title?: string;\n pageSize?: string;\n /** 自定义顶部右侧操作区 */\n toolbarExtra?: ReactNode;\n};\n\nexport function ResourceManager({\n api,\n title = '权限点管理',\n pageSize: initialPageSize = '20',\n toolbarExtra,\n}: ResourceManagerProps) {\n const [records, setRecords] = useState<AuthorizationResource[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageToken, setPageToken] = useState('');\n const [hasPreviousPage, setHasPreviousPage] = useState(false);\n const [hasNextPage, setHasNextPage] = useState(false);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editing, setEditing] = useState<AuthorizationResource | null>(null);\n const [form, setForm] = useState<AuthorizationResourceFormValues>(emptyForm);\n const [saving, setSaving] = useState(false);\n const [deletingRow, setDeletingRow] = useState<AuthorizationResource | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const loadList = useCallback(\n async (direction: PageDirection = 'current', token = pageToken) => {\n setLoading(true);\n setError('');\n try {\n const result = await api.list({\n pagination: {\n pageToken: token,\n pageSize,\n pageDirection: direction,\n },\n });\n setRecords(result.records);\n setPageToken(result.pageToken);\n setHasPreviousPage(result.hasPreviousPage);\n setHasNextPage(result.hasNextPage);\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载失败');\n } finally {\n setLoading(false);\n }\n },\n [api, pageSize, pageToken],\n );\n\n useEffect(() => {\n void loadList('current', '');\n // 仅 pageSize / api 变化时重置首页\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, pageSize]);\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm());\n setDialogOpen(true);\n };\n\n const openEdit = (row: AuthorizationResource) => {\n setEditing(row);\n setForm({\n name: row.name,\n identification: row.identification,\n status: row.status,\n private: row.private,\n description: row.description,\n });\n setDialogOpen(true);\n };\n\n const closeDialog = () => {\n if (saving) return;\n setDialogOpen(false);\n };\n\n const handleSubmit = async (event: FormEvent) => {\n event.preventDefault();\n if (!form.name.trim()) {\n setError('请填写权限名称');\n return;\n }\n if (!form.identification.trim()) {\n setError('请填写接口标识');\n return;\n }\n\n setSaving(true);\n setError('');\n try {\n if (editing) {\n await api.update(editing.resourceId, form);\n } else {\n await api.create(form);\n }\n setDialogOpen(false);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '保存失败');\n } finally {\n setSaving(false);\n }\n };\n\n const askDelete = (row: AuthorizationResource) => {\n setDeletingRow(row);\n };\n\n const closeDeleteDialog = () => {\n if (deleting) return;\n setDeletingRow(null);\n };\n\n const confirmDelete = async () => {\n if (!deletingRow) return;\n setDeleting(true);\n setError('');\n try {\n await api.remove(deletingRow.resourceId);\n setDeletingRow(null);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '删除失败');\n } finally {\n setDeleting(false);\n }\n };\n\n const statusLabel = useMemo(\n () =>\n Object.fromEntries(RESOURCE_STATUS_OPTIONS.map((o) => [o.value, o.label])) as Record<\n number,\n string\n >,\n [],\n );\n\n return (\n <div style={styles.root}>\n <div style={styles.toolbar}>\n <h2 style={styles.title}>{title}</h2>\n <div style={styles.toolbarRight}>\n {toolbarExtra}\n <button type=\"button\" style={styles.primaryBtn} onClick={openCreate}>\n 新增\n </button>\n </div>\n </div>\n\n {error ? <div style={styles.error}>{error}</div> : null}\n\n <div style={styles.tableWrap}>\n <table style={styles.table}>\n <thead>\n <tr>\n <th style={styles.th}>权限名称</th>\n <th style={styles.th}>接口标识</th>\n <th style={styles.th}>描述</th>\n <th style={{ ...styles.th, width: 90 }}>状态</th>\n <th style={{ ...styles.th, width: 140 }}>操作</th>\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={5} style={styles.empty}>\n 加载中…\n </td>\n </tr>\n ) : records.length === 0 ? (\n <tr>\n <td colSpan={5} style={styles.empty}>\n 暂无数据\n </td>\n </tr>\n ) : (\n records.map((row) => (\n <tr key={row.resourceId}>\n <td style={styles.td}>{row.name}</td>\n <td style={styles.td}>\n <code style={styles.code}>{row.identification}</code>\n </td>\n <td style={styles.td}>{row.description || '—'}</td>\n <td style={styles.td}>\n <span\n style={{\n ...styles.badge,\n background:\n row.status === RESOURCE_STATUS_ENABLED ? '#e8f7ef' : '#f4f4f5',\n color: row.status === RESOURCE_STATUS_ENABLED ? '#067647' : '#667085',\n }}\n >\n {statusLabel[row.status] ?? row.status}\n </span>\n </td>\n <td style={styles.td}>\n <button type=\"button\" style={styles.linkBtn} onClick={() => openEdit(row)}>\n 编辑\n </button>\n <button\n type=\"button\"\n style={{ ...styles.linkBtn, color: '#d92d20' }}\n onClick={() => askDelete(row)}\n >\n 删除\n </button>\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div style={styles.pagination}>\n <label style={styles.pageSize}>\n 每页\n <select\n value={pageSize}\n onChange={(e) => {\n setPageToken('');\n setPageSize(e.target.value);\n }}\n style={styles.select}\n >\n {PAGE_SIZE_OPTIONS.map((size) => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </label>\n <div style={styles.pageBtns}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasPreviousPage || loading}\n onClick={() => void loadList('previous')}\n >\n 上一页\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasNextPage || loading}\n onClick={() => void loadList('next')}\n >\n 下一页\n </button>\n </div>\n </div>\n\n {dialogOpen ? (\n <div style={styles.mask} onClick={closeDialog}>\n <div\n style={styles.dialog}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>{editing ? '编辑权限点' : '新增权限点'}</h3>\n <button type=\"button\" style={styles.iconBtn} onClick={closeDialog} aria-label=\"关闭\">\n ×\n </button>\n </div>\n <form style={styles.form} onSubmit={(e) => void handleSubmit(e)}>\n <label style={styles.field}>\n <span style={styles.label}>权限名称</span>\n <input\n style={styles.input}\n value={form.name}\n onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}\n placeholder=\"请输入权限名称\"\n required\n />\n </label>\n <label style={styles.field}>\n <span style={styles.label}>接口标识</span>\n <input\n style={styles.input}\n value={form.identification}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, identification: e.target.value }))\n }\n placeholder=\"如 user:list\"\n required\n />\n </label>\n <label style={styles.field}>\n <span style={styles.label}>状态</span>\n <select\n style={styles.input}\n value={form.status}\n onChange={(e) =>\n setForm((prev) => ({\n ...prev,\n status: Number(e.target.value) as 0 | 1,\n }))\n }\n >\n {RESOURCE_STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n <label style={styles.field}>\n <span style={styles.label}>私有资源</span>\n <select\n style={styles.input}\n value={form.private ? '1' : '0'}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, private: e.target.value === '1' }))\n }\n >\n {RESOURCE_PRIVATE_OPTIONS.map((opt) => (\n <option key={String(opt.value)} value={opt.value ? '1' : '0'}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n <label style={styles.field}>\n <span style={styles.label}>描述</span>\n <textarea\n style={{ ...styles.input, minHeight: 88, resize: 'vertical' }}\n value={form.description}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, description: e.target.value }))\n }\n placeholder=\"请输入描述\"\n />\n </label>\n <div style={styles.dialogFooter}>\n <button type=\"button\" style={styles.secondaryBtn} onClick={closeDialog}>\n 取消\n </button>\n <button type=\"submit\" style={styles.primaryBtn} disabled={saving}>\n {saving ? '保存中…' : '保存'}\n </button>\n </div>\n </form>\n </div>\n </div>\n ) : null}\n\n {deletingRow ? (\n <div style={styles.mask} onClick={closeDeleteDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 420 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"angel-auth-delete-title\"\n >\n <div style={styles.dialogHeader}>\n <h3 id=\"angel-auth-delete-title\" style={styles.dialogTitle}>\n 确认删除\n </h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeDeleteDialog}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.confirmBody}>\n <p style={styles.confirmText}>\n 确认删除权限点「<strong>{deletingRow.name}</strong>」吗?删除后不可恢复。\n </p>\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeDeleteDialog}\n disabled={deleting}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.dangerBtn}\n onClick={() => void confirmDelete()}\n disabled={deleting}\n >\n {deleting ? '删除中…' : '确认删除'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n padding: 16,\n color: '#101828',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n title: { margin: 0, fontSize: 18, fontWeight: 600 },\n toolbarRight: { display: 'flex', alignItems: 'center', gap: 8 },\n error: {\n padding: '10px 12px',\n borderRadius: 8,\n background: '#fef3f2',\n color: '#b42318',\n fontSize: 13,\n },\n tableWrap: {\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 10,\n background: '#fff',\n },\n table: { width: '100%', borderCollapse: 'collapse', minWidth: 720 },\n th: {\n textAlign: 'left',\n padding: '12px 14px',\n fontSize: 13,\n fontWeight: 600,\n color: '#475467',\n background: '#f9fafb',\n borderBottom: '1px solid #eaecf0',\n },\n td: {\n padding: '12px 14px',\n fontSize: 14,\n borderBottom: '1px solid #f2f4f7',\n verticalAlign: 'middle',\n },\n empty: {\n padding: 28,\n textAlign: 'center',\n color: '#98a2b3',\n fontSize: 14,\n },\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 13,\n background: '#f2f4f7',\n padding: '2px 6px',\n borderRadius: 4,\n },\n badge: {\n display: 'inline-block',\n padding: '2px 8px',\n borderRadius: 999,\n fontSize: 12,\n fontWeight: 500,\n },\n linkBtn: {\n border: 'none',\n background: 'transparent',\n color: '#049BAD',\n cursor: 'pointer',\n padding: '0 8px 0 0',\n fontSize: 13,\n },\n pagination: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n pageSize: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#475467' },\n pageBtns: { display: 'flex', gap: 8 },\n primaryBtn: {\n border: 'none',\n background: '#049BAD',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n secondaryBtn: {\n border: '1px solid #d0d5dd',\n background: '#fff',\n color: '#344054',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n dangerBtn: {\n border: 'none',\n background: '#d92d20',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n select: {\n border: '1px solid #d0d5dd',\n borderRadius: 6,\n padding: '4px 8px',\n fontSize: 13,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n mask: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(16, 24, 40, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n padding: 16,\n },\n dialog: {\n width: '100%',\n maxWidth: 480,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 20px 40px rgba(16,24,40,0.18)',\n },\n dialogHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 16px',\n borderBottom: '1px solid #eaecf0',\n },\n dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },\n iconBtn: {\n border: 'none',\n background: 'transparent',\n fontSize: 22,\n lineHeight: 1,\n cursor: 'pointer',\n color: '#667085',\n },\n form: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n confirmBody: { display: 'flex', flexDirection: 'column', gap: 16, padding: 16 },\n confirmText: { margin: 0, fontSize: 14, color: '#344054', lineHeight: 1.6 },\n field: { display: 'flex', flexDirection: 'column', gap: 6 },\n label: { fontSize: 13, color: '#344054', fontWeight: 500 },\n input: {\n border: '1px solid #d0d5dd',\n borderRadius: 8,\n padding: '8px 10px',\n fontSize: 14,\n outline: 'none',\n backgroundColor: '#ffffff',\n color: '#101828',\n boxSizing: 'border-box',\n width: '100%',\n },\n dialogFooter: {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n paddingTop: 4,\n },\n};\n","export type PageDirection = 'previous' | 'current' | 'next';\n\nexport type ListPaginationParams = {\n pageToken?: string;\n pageSize?: string;\n pageDirection?: PageDirection;\n};\n\nexport type ListPaginationResult = {\n pageToken: string;\n hasPreviousPage: boolean;\n hasNextPage: boolean;\n};\n\n/** 通用状态:权限点 1 启用 / 0 禁用;菜单 1 显示 / 0 隐藏 */\nexport type ResourceStatus = 0 | 1;\n\n/** 权限点类型 */\nexport type ApiResourceType = 'api';\n\n/** 菜单资源类型 */\nexport type MenuResourceType = 'page' | 'menu' | 'button';\n\nexport type ResourceType = ApiResourceType | MenuResourceType;\n\nexport type AuthorizationResource = {\n resourceId: string;\n type: ApiResourceType;\n name: string;\n identification: string;\n status: ResourceStatus;\n private: boolean;\n description: string;\n};\n\nexport type AuthorizationResourceFormValues = {\n name: string;\n identification: string;\n status: ResourceStatus;\n private: boolean;\n description: string;\n};\n\nexport type CreateAuthorizationResourceBody = AuthorizationResourceFormValues & {\n resourceId: string;\n type: ApiResourceType;\n};\n\nexport type UpdateAuthorizationResourceBody = Partial<AuthorizationResourceFormValues> & {\n type?: ApiResourceType;\n};\n\nexport type FetchAuthorizationResourcesParams = {\n pagination?: ListPaginationParams;\n};\n\nexport type AuthorizationResourceListResult = {\n records: AuthorizationResource[];\n pageToken: string;\n hasPreviousPage: boolean;\n hasNextPage: boolean;\n};\n\nexport type MenuResource = {\n resourceId: string;\n /** 上级菜单 ID;无上级时为 null */\n parentId: string | null;\n /**\n * 菜单层级:无上级(根)为 1,其余为上级 depth + 1\n */\n depth: number;\n /**\n * 是否叶子节点:`1` 表示无下级菜单,不可再展开\n */\n leaf: number;\n type: MenuResourceType;\n name: string;\n identification: string;\n permissionPointIds: string[];\n /** 关联权限点名称(列表展示用,后端可能返回) */\n permissionPointNames?: string[];\n status: ResourceStatus;\n};\n\nexport type MenuResourceFormValues = {\n /** 上级菜单 ID;选择「无」时为 null */\n parentId: string | null;\n /** 由 parentId 自动计算:无为 1,否则上级 depth + 1 */\n depth: number;\n type: MenuResourceType;\n name: string;\n identification: string;\n permissionPointIds: string[];\n status: ResourceStatus;\n};\n\nexport type CreateMenuResourceBody = MenuResourceFormValues & {\n resourceId: string;\n};\n\nexport type UpdateMenuResourceBody = Partial<MenuResourceFormValues>;\n\nexport type FetchMenuResourcesParams = {\n /** 列表默认传 1,只拉根层 */\n depth?: number;\n pagination?: ListPaginationParams;\n};\n\nexport type MenuResourceListResult = {\n records: MenuResource[];\n pageToken: string;\n hasPreviousPage: boolean;\n hasNextPage: boolean;\n};\n\n/** leaf === 1 表示无下级 */\nexport const MENU_LEAF_YES = 1;\nexport const MENU_LEAF_NO = 0;\n\nexport const RESOURCE_TYPE_API: ApiResourceType = 'api';\nexport const MENU_TYPE_PAGE: MenuResourceType = 'page';\nexport const MENU_TYPE_MENU: MenuResourceType = 'menu';\nexport const MENU_TYPE_BUTTON: MenuResourceType = 'button';\n\n/** 菜单列表查询 type 参数 */\nexport const MENU_LIST_TYPE_PARAM = 'page,menu,button';\n\n/**\n * 上级菜单选择「无」时,表单 select 使用的空值。\n * 提交接口时会转换为 parentId: null。\n */\nexport const ROOT_PARENT_ID = '';\n\n/** 无上级时的菜单层级 */\nexport const ROOT_MENU_DEPTH = 1;\n\nexport const RESOURCE_STATUS_ENABLED: ResourceStatus = 1;\nexport const RESOURCE_STATUS_DISABLED: ResourceStatus = 0;\n\nexport const RESOURCE_STATUS_OPTIONS: { label: string; value: ResourceStatus }[] = [\n { label: '启用', value: RESOURCE_STATUS_ENABLED },\n { label: '禁用', value: RESOURCE_STATUS_DISABLED },\n];\n\n/** 菜单可见性 */\nexport const MENU_VISIBILITY_OPTIONS: { label: string; value: ResourceStatus }[] = [\n { label: '显示', value: RESOURCE_STATUS_ENABLED },\n { label: '隐藏', value: RESOURCE_STATUS_DISABLED },\n];\n\nexport const RESOURCE_PRIVATE_OPTIONS: { label: string; value: boolean }[] = [\n { label: '是', value: true },\n { label: '否', value: false },\n];\n\nexport const MENU_TYPE_OPTIONS: { label: string; value: MenuResourceType }[] = [\n { label: '目录', value: MENU_TYPE_PAGE },\n { label: '菜单', value: MENU_TYPE_MENU },\n { label: '按钮', value: MENU_TYPE_BUTTON },\n];\n\nexport const MENU_TYPE_LABEL: Record<MenuResourceType, string> = {\n page: '目录',\n menu: '菜单',\n button: '按钮',\n};\n","const DEVICE_WORKER_ID_KEY = 'hgams_device_worker_id';\n\nfunction generateDeviceWorkerId(): bigint {\n const cached = localStorage.getItem(DEVICE_WORKER_ID_KEY);\n if (cached !== null && cached !== '') {\n return BigInt(cached);\n }\n\n const components = [\n navigator.userAgent,\n screen.width + 'x' + screen.height,\n screen.colorDepth,\n navigator.language,\n new Date().getTimezoneOffset(),\n navigator.hardwareConcurrency,\n (navigator as Navigator & { deviceMemory?: number }).deviceMemory,\n ];\n\n const fingerprint = components.join('|');\n\n let hash = 0;\n for (let i = 0; i < fingerprint.length; i++) {\n hash = (hash << 5) - hash + fingerprint.charCodeAt(i);\n hash |= 0;\n }\n\n const maxWorkerId = Math.pow(2, 14) - 1;\n const workerId = Math.abs(hash % maxWorkerId);\n const workerIdBigInt = BigInt(workerId);\n localStorage.setItem(DEVICE_WORKER_ID_KEY, workerIdBigInt.toString());\n return workerIdBigInt;\n}\n\ninterface SnowyflakeOptions {\n epoch?: bigint;\n workerId?: bigint;\n processId?: bigint;\n workerIdBits?: number;\n processIdBits?: number;\n sequenceBits?: number;\n}\n\n/**\n * snowyflake 2.0.1 仅支持固定 5+5+12 位布局,此处按相同 nextId 算法实现可配置位数版本。\n */\nclass ConfigurableSnowflake {\n readonly epoch: bigint;\n readonly workerId: bigint;\n readonly processId: bigint;\n\n private readonly sequenceMask: bigint;\n private readonly timestampLeftShift: bigint;\n private readonly workerIdShift: bigint;\n private readonly processIdShift: bigint;\n private sequence = 0n;\n private latestTimestamp = BigInt(Date.now());\n\n constructor({\n epoch = 0n,\n workerId = 0n,\n processId = 0n,\n workerIdBits = 5,\n processIdBits = 5,\n sequenceBits = 12,\n }: SnowyflakeOptions = {}) {\n this.epoch = epoch;\n\n const workerIdBitsBig = BigInt(workerIdBits);\n const processIdBitsBig = BigInt(processIdBits);\n const sequenceBitsBig = BigInt(sequenceBits);\n const workerIdMask = -1n ^ (-1n << workerIdBitsBig);\n const processIdMask = -1n ^ (-1n << processIdBitsBig);\n\n this.sequenceMask = -1n ^ (-1n << sequenceBitsBig);\n this.timestampLeftShift =\n sequenceBitsBig + workerIdBitsBig + processIdBitsBig;\n this.workerIdShift = sequenceBitsBig + processIdBitsBig;\n this.processIdShift = sequenceBitsBig;\n\n this.workerId = workerId & workerIdMask;\n this.processId = processId & processIdMask;\n }\n\n nextId(): bigint {\n const timestamp = BigInt(Date.now());\n\n if (this.latestTimestamp === timestamp) {\n this.sequence = (this.sequence + 1n) & this.sequenceMask;\n } else {\n this.sequence = 0n;\n this.latestTimestamp = timestamp;\n }\n\n return (\n ((timestamp - this.epoch) << this.timestampLeftShift) |\n (this.workerId << this.workerIdShift) |\n (this.processId << this.processIdShift) |\n this.sequence\n );\n }\n}\n\n/** 应用级单例,模块加载时只初始化一次(不受 React StrictMode 重复 mount 影响) */\nexport const snowyflake = new ConfigurableSnowflake({\n workerId: generateDeviceWorkerId(),\n workerIdBits: 14,\n processIdBits: 0,\n sequenceBits: 8,\n epoch: BigInt(new Date('2026-06-08').getTime()),\n});\n\n/** 生成雪花 ID 字符串(reportId、detailId、resourceId 等) */\nexport function getAppClientId(): string {\n return snowyflake.nextId().toString();\n}\n\nexport function getDeviceWorkerId(): string {\n return snowyflake.workerId.toString();\n}\n","import type { ListPaginationResult } from './types';\n\nexport function appendQueryParam(parts: string[], key: string, value: string): void {\n if (value !== undefined && value !== null && String(value) !== '') {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n }\n}\n\nexport function extractPagination(payload: unknown): ListPaginationResult {\n if (!payload || typeof payload !== 'object') {\n return {\n pageToken: '',\n hasPreviousPage: false,\n hasNextPage: false,\n };\n }\n\n const envelope = payload as Record<string, unknown>;\n const pagination = (\n envelope.pagination && typeof envelope.pagination === 'object'\n ? envelope.pagination\n : envelope.page && typeof envelope.page === 'object'\n ? envelope.page\n : null\n ) as Record<string, unknown> | null;\n\n const rawPageToken =\n pagination?.['page-token'] ??\n pagination?.pageToken ??\n pagination?.nextPageToken ??\n envelope['page-token'] ??\n envelope.pageToken ??\n '';\n const pageToken =\n rawPageToken === undefined || rawPageToken === null ? '' : String(rawPageToken);\n\n const hasPreviousPage = Boolean(\n pagination?.hasPreviousPage ??\n pagination?.hasPrevious ??\n pagination?.hasPre ??\n pagination?.previous ??\n envelope.hasPreviousPage ??\n envelope.hasPrevious,\n );\n const hasNextPage = Boolean(\n pagination?.hasNextPage ??\n pagination?.hasNext ??\n pagination?.next ??\n envelope.hasNextPage ??\n envelope.hasNext,\n );\n\n return {\n pageToken,\n hasPreviousPage,\n hasNextPage,\n };\n}\n\nexport function extractRecords(payload: unknown): unknown[] {\n if (!payload) return [];\n if (Array.isArray(payload)) return payload;\n\n if (typeof payload === 'object') {\n const envelope = payload as Record<string, unknown>;\n const data = envelope.data;\n\n if (Array.isArray(data)) return data;\n\n if (data && typeof data === 'object') {\n const nested = data as Record<string, unknown>;\n if (Array.isArray(nested.records)) return nested.records;\n if (Array.isArray(nested.items)) return nested.items;\n if (Array.isArray(nested.list)) return nested.list;\n if (Array.isArray(nested.content)) return nested.content;\n }\n\n if (Array.isArray(envelope.records)) return envelope.records;\n if (Array.isArray(envelope.items)) return envelope.items;\n if (Array.isArray(envelope.list)) return envelope.list;\n if (Array.isArray(envelope.content)) return envelope.content;\n }\n\n return [];\n}\n","import { getAppClientId } from '../utils/snowflake';\nimport { appendQueryParam, extractPagination, extractRecords } from './pagination';\nimport {\n MENU_LIST_TYPE_PARAM,\n MENU_LEAF_YES,\n MENU_TYPE_BUTTON,\n MENU_TYPE_MENU,\n MENU_TYPE_PAGE,\n RESOURCE_STATUS_DISABLED,\n RESOURCE_STATUS_ENABLED,\n RESOURCE_TYPE_API,\n ROOT_MENU_DEPTH,\n type AuthorizationResource,\n type AuthorizationResourceFormValues,\n type AuthorizationResourceListResult,\n type CreateAuthorizationResourceBody,\n type CreateMenuResourceBody,\n type FetchAuthorizationResourcesParams,\n type FetchMenuResourcesParams,\n type MenuResource,\n type MenuResourceFormValues,\n type MenuResourceListResult,\n type MenuResourceType,\n type ResourceStatus,\n type UpdateAuthorizationResourceBody,\n type UpdateMenuResourceBody,\n} from './types';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE';\n\nexport type ResourceRequestOptions = {\n method: HttpMethod;\n url: string;\n body?: unknown;\n signal?: AbortSignal;\n};\n\n/**\n * 由宿主应用注入的请求函数(可对接 Angel_HGAMS 的 apiGetJson / apiPostJson 等)。\n */\nexport type ResourceHttpRequest = <T = unknown>(\n options: ResourceRequestOptions,\n) => Promise<T>;\n\nexport type AuthorizationResourceApi = {\n list: (\n params?: FetchAuthorizationResourcesParams,\n signal?: AbortSignal,\n ) => Promise<AuthorizationResourceListResult>;\n create: (\n values: AuthorizationResourceFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n update: (\n resourceId: string,\n values: AuthorizationResourceFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n remove: (resourceId: string, signal?: AbortSignal) => Promise<unknown>;\n};\n\nexport type MenuResourceApi = {\n list: (\n params?: FetchMenuResourcesParams,\n signal?: AbortSignal,\n ) => Promise<MenuResourceListResult>;\n /** 展开下级:GET /authorization-resources/{resource-id}/sub-resources */\n listSubResources: (\n resourceId: string,\n signal?: AbortSignal,\n ) => Promise<MenuResource[]>;\n /** 拉取权限点(type=api),供菜单表单多选 */\n listPermissionPoints: (\n params?: FetchAuthorizationResourcesParams,\n signal?: AbortSignal,\n ) => Promise<AuthorizationResourceListResult>;\n create: (values: MenuResourceFormValues, signal?: AbortSignal) => Promise<unknown>;\n update: (\n resourceId: string,\n values: MenuResourceFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n remove: (resourceId: string, signal?: AbortSignal) => Promise<unknown>;\n};\n\nfunction toResourceStatus(value: unknown): ResourceStatus {\n const n = Number(value);\n return n === RESOURCE_STATUS_ENABLED ? RESOURCE_STATUS_ENABLED : RESOURCE_STATUS_DISABLED;\n}\n\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'number') return value !== 0;\n if (typeof value === 'string') {\n const v = value.trim().toLowerCase();\n return v === 'true' || v === '1' || v === 'yes' || v === '是';\n }\n return false;\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value\n .map((item) => {\n if (item && typeof item === 'object') {\n const row = item as Record<string, unknown>;\n const id = row.resourceId ?? row.resource_id ?? row.id;\n return id === undefined || id === null ? '' : String(id);\n }\n return String(item ?? '');\n })\n .filter(Boolean);\n }\n if (typeof value === 'string' && value.trim()) {\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n }\n return [];\n}\n\nfunction toMenuType(value: unknown): MenuResourceType {\n const v = String(value ?? '').toLowerCase();\n if (v === MENU_TYPE_PAGE || v === MENU_TYPE_MENU || v === MENU_TYPE_BUTTON) {\n return v;\n }\n return MENU_TYPE_MENU;\n}\n\nexport function mapAuthorizationResource(item: unknown): AuthorizationResource | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const resourceId = row.resourceId ?? row.resource_id ?? row.id;\n if (resourceId === undefined || resourceId === null || resourceId === '') return null;\n\n return {\n resourceId: String(resourceId),\n type: RESOURCE_TYPE_API,\n name: String(row.name ?? ''),\n identification: String(row.identification ?? row.identity ?? ''),\n status: toResourceStatus(row.status),\n private: toBoolean(row.private ?? row.isPrivate ?? row.is_private),\n description: String(row.description ?? row.desc ?? ''),\n };\n}\n\nexport function mapMenuResource(item: unknown): MenuResource | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const resourceId = row.resourceId ?? row.resource_id ?? row.id;\n if (resourceId === undefined || resourceId === null || resourceId === '') return null;\n\n const permissionPointIds = toStringArray(\n row.permissionPointIds ??\n row.permission_point_ids ??\n row.permissionPoints ??\n row.permissions,\n );\n\n const permissionNamesRaw =\n row.permissionPointNames ?? row.permission_point_names ?? row.permissionNames;\n const permissionPointNames = Array.isArray(permissionNamesRaw)\n ? permissionNamesRaw.map((n) => String(n ?? '')).filter(Boolean)\n : undefined;\n\n const rawParentId = row.parentId ?? row.parent_id;\n const parentId =\n rawParentId === undefined ||\n rawParentId === null ||\n rawParentId === '' ||\n String(rawParentId) === '0'\n ? null\n : String(rawParentId);\n\n const rawDepth = row.depth;\n const parsedDepth = Number(rawDepth);\n const depth =\n Number.isFinite(parsedDepth) && parsedDepth > 0\n ? Math.floor(parsedDepth)\n : parentId\n ? ROOT_MENU_DEPTH + 1\n : ROOT_MENU_DEPTH;\n\n const rawLeaf = row.leaf;\n const leaf =\n rawLeaf === true ||\n rawLeaf === 1 ||\n rawLeaf === '1' ||\n String(rawLeaf).toLowerCase() === 'true'\n ? MENU_LEAF_YES\n : Number(rawLeaf) === MENU_LEAF_YES\n ? MENU_LEAF_YES\n : 0;\n\n return {\n resourceId: String(resourceId),\n parentId,\n depth,\n leaf,\n type: toMenuType(row.type),\n name: String(row.name ?? ''),\n identification: String(row.identification ?? row.identity ?? row.path ?? ''),\n permissionPointIds,\n permissionPointNames,\n status: toResourceStatus(row.status),\n };\n}\n\n/**\n * leaf === 1 表示无下级菜单。\n */\nexport function isMenuLeaf(row: Pick<MenuResource, 'leaf'>): boolean {\n return Number(row.leaf) === MENU_LEAF_YES;\n}\n\n/**\n * 根据上级菜单计算 depth:无上级为 1,否则为上级 depth + 1。\n */\nexport function resolveMenuDepth(\n parentId: string | null | undefined,\n menus: Array<Pick<MenuResource, 'resourceId' | 'depth'>>,\n): number {\n if (!parentId) return ROOT_MENU_DEPTH;\n const parent = menus.find((item) => item.resourceId === parentId);\n const parentDepth =\n parent && Number.isFinite(parent.depth) && parent.depth > 0\n ? Math.floor(parent.depth)\n : ROOT_MENU_DEPTH;\n return parentDepth + 1;\n}\n\nfunction buildListUrl(\n type: string,\n params?: {\n pagination?: FetchAuthorizationResourcesParams['pagination'];\n depth?: number | string;\n },\n): string {\n const parts: string[] = [];\n appendQueryParam(parts, 'type', type);\n if (params?.depth !== undefined && params?.depth !== null && String(params.depth) !== '') {\n appendQueryParam(parts, 'depth', String(params.depth));\n }\n appendQueryParam(parts, 'page-token', params?.pagination?.pageToken ?? '');\n appendQueryParam(parts, 'page-size', params?.pagination?.pageSize ?? '20');\n appendQueryParam(parts, 'page-direction', params?.pagination?.pageDirection ?? 'current');\n return `/authorization-resources?${parts.join('&')}`;\n}\n\nexport function buildCreateBody(\n values: AuthorizationResourceFormValues,\n resourceId = getAppClientId(),\n): CreateAuthorizationResourceBody {\n return {\n resourceId,\n type: RESOURCE_TYPE_API,\n name: values.name.trim(),\n identification: values.identification.trim(),\n status: values.status,\n private: values.private,\n description: values.description.trim(),\n };\n}\n\nexport function buildUpdateBody(\n values: AuthorizationResourceFormValues,\n): UpdateAuthorizationResourceBody {\n return {\n type: RESOURCE_TYPE_API,\n name: values.name.trim(),\n identification: values.identification.trim(),\n status: values.status,\n private: values.private,\n description: values.description.trim(),\n };\n}\n\nexport function buildCreateMenuBody(\n values: MenuResourceFormValues,\n resourceId = getAppClientId(),\n): CreateMenuResourceBody {\n const parentId = values.parentId ? values.parentId : null;\n return {\n resourceId,\n parentId,\n depth: values.depth > 0 ? Math.floor(values.depth) : parentId ? ROOT_MENU_DEPTH + 1 : ROOT_MENU_DEPTH,\n type: values.type,\n name: values.name.trim(),\n identification: values.identification.trim(),\n permissionPointIds: [...values.permissionPointIds],\n status: values.status,\n };\n}\n\nexport function buildUpdateMenuBody(values: MenuResourceFormValues): UpdateMenuResourceBody {\n const parentId = values.parentId ? values.parentId : null;\n return {\n parentId,\n depth: values.depth > 0 ? Math.floor(values.depth) : parentId ? ROOT_MENU_DEPTH + 1 : ROOT_MENU_DEPTH,\n type: values.type,\n name: values.name.trim(),\n identification: values.identification.trim(),\n permissionPointIds: [...values.permissionPointIds],\n status: values.status,\n };\n}\n\nexport function createAuthorizationResourceApi(\n request: ResourceHttpRequest,\n): AuthorizationResourceApi {\n return {\n async list(params, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: buildListUrl(RESOURCE_TYPE_API, params),\n signal,\n });\n const records = extractRecords(json)\n .map(mapAuthorizationResource)\n .filter((item): item is AuthorizationResource => item !== null);\n const pagination = extractPagination(json);\n return {\n records,\n ...pagination,\n };\n },\n\n async create(values, signal) {\n return request({\n method: 'POST',\n url: '/authorization-resources',\n body: buildCreateBody(values),\n signal,\n });\n },\n\n async update(resourceId, values, signal) {\n return request({\n method: 'PATCH',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n body: buildUpdateBody(values),\n signal,\n });\n },\n\n async remove(resourceId, signal) {\n return request({\n method: 'DELETE',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n signal,\n });\n },\n };\n}\n\nexport function createMenuResourceApi(request: ResourceHttpRequest): MenuResourceApi {\n const permissionApi = createAuthorizationResourceApi(request);\n\n return {\n async list(params, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: buildListUrl(MENU_LIST_TYPE_PARAM, {\n pagination: params?.pagination,\n depth: params?.depth ?? ROOT_MENU_DEPTH,\n }),\n signal,\n });\n const records = extractRecords(json)\n .map(mapMenuResource)\n .filter((item): item is MenuResource => item !== null);\n const pagination = extractPagination(json);\n return {\n records,\n ...pagination,\n };\n },\n\n async listSubResources(resourceId, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}/sub-resources`,\n signal,\n });\n return extractRecords(json)\n .map(mapMenuResource)\n .filter((item): item is MenuResource => item !== null);\n },\n\n listPermissionPoints(params, signal) {\n return permissionApi.list(params, signal);\n },\n\n async create(values, signal) {\n return request({\n method: 'POST',\n url: '/authorization-resources',\n body: buildCreateMenuBody(values),\n signal,\n });\n },\n\n async update(resourceId, values, signal) {\n return request({\n method: 'PATCH',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n body: buildUpdateMenuBody(values),\n signal,\n });\n },\n\n async remove(resourceId, signal) {\n return request({\n method: 'DELETE',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n signal,\n });\n },\n };\n}\n\nexport type CreateDefaultResourceRequestOptions = {\n /** API 前缀,如 `/api` 或完整域名 */\n baseUrl?: string;\n /** 追加请求头(如 Authorization) */\n getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n credentials?: RequestCredentials;\n};\n\n/**\n * 基于 fetch 的默认请求实现,便于快速接入。\n * 生产环境建议注入宿主应用已有的 request 封装。\n */\nexport function createDefaultResourceRequest(\n options: CreateDefaultResourceRequestOptions = {},\n): ResourceHttpRequest {\n const baseUrl = (options.baseUrl ?? '').replace(/\\/+$/, '');\n const credentials = options.credentials ?? 'include';\n\n return async function request<T = unknown>({\n method,\n url,\n body,\n signal,\n }: ResourceRequestOptions): Promise<T> {\n const path = url.startsWith('http') ? url : `${baseUrl}${url.startsWith('/') ? url : `/${url}`}`;\n const headers: Record<string, string> = {\n Accept: 'application/json',\n ...(await options.getHeaders?.()),\n };\n\n let payload: BodyInit | undefined;\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n payload = JSON.stringify(body);\n }\n\n const response = await fetch(path, {\n method,\n headers,\n body: payload,\n credentials,\n signal,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(text || `HTTP ${response.status}`);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) return undefined as T;\n return JSON.parse(text) as T;\n };\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type FormEvent,\n type ReactNode,\n} from 'react';\nimport {\n MENU_TYPE_LABEL,\n MENU_TYPE_MENU,\n MENU_TYPE_OPTIONS,\n MENU_VISIBILITY_OPTIONS,\n RESOURCE_STATUS_ENABLED,\n ROOT_MENU_DEPTH,\n ROOT_PARENT_ID,\n isMenuLeaf,\n resolveMenuDepth,\n type AuthorizationResource,\n type MenuResource,\n type MenuResourceApi,\n type MenuResourceFormValues,\n type MenuResourceType,\n type PageDirection,\n} from '../resources';\n\nconst PAGE_SIZE_OPTIONS = ['10', '20', '50', '100'];\n\nconst emptyForm = (): MenuResourceFormValues => ({\n parentId: null,\n depth: ROOT_MENU_DEPTH,\n type: MENU_TYPE_MENU,\n name: '',\n identification: '',\n permissionPointIds: [],\n status: RESOURCE_STATUS_ENABLED,\n});\n\nexport type MenuManagerProps = {\n api: MenuResourceApi;\n title?: string;\n pageSize?: string;\n toolbarExtra?: ReactNode;\n};\n\nexport function MenuManager({\n api,\n title = '菜单管理',\n pageSize: initialPageSize = '20',\n toolbarExtra,\n}: MenuManagerProps) {\n const [records, setRecords] = useState<MenuResource[]>([]);\n const [childrenMap, setChildrenMap] = useState<Record<string, MenuResource[]>>({});\n const [expandedIds, setExpandedIds] = useState<Record<string, boolean>>({});\n const [expandingIds, setExpandingIds] = useState<Record<string, boolean>>({});\n const [permissionPoints, setPermissionPoints] = useState<AuthorizationResource[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageToken, setPageToken] = useState('');\n const [hasPreviousPage, setHasPreviousPage] = useState(false);\n const [hasNextPage, setHasNextPage] = useState(false);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editing, setEditing] = useState<MenuResource | null>(null);\n const [form, setForm] = useState<MenuResourceFormValues>(emptyForm);\n const [saving, setSaving] = useState(false);\n const [deletingRow, setDeletingRow] = useState<MenuResource | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const permissionNameMap = useMemo(() => {\n const map = new Map<string, string>();\n permissionPoints.forEach((p) => map.set(p.resourceId, p.name || p.identification));\n return map;\n }, [permissionPoints]);\n\n const allKnownMenus = useMemo(() => {\n const map = new Map<string, MenuResource>();\n records.forEach((row) => map.set(row.resourceId, row));\n Object.values(childrenMap).forEach((list) => {\n list.forEach((row) => map.set(row.resourceId, row));\n });\n return Array.from(map.values());\n }, [records, childrenMap]);\n\n const parentOptions = useMemo(() => {\n return allKnownMenus\n .filter((row) => !editing || row.resourceId !== editing.resourceId)\n .map((row) => ({\n value: row.resourceId,\n label: `${row.name}(${MENU_TYPE_LABEL[row.type]})`,\n }));\n }, [allKnownMenus, editing]);\n\n const flatRows = useMemo(() => {\n const rows: MenuResource[] = [];\n const walk = (list: MenuResource[]) => {\n list.forEach((row) => {\n rows.push(row);\n if (expandedIds[row.resourceId] && childrenMap[row.resourceId]?.length) {\n walk(childrenMap[row.resourceId]);\n }\n });\n };\n walk(records);\n return rows;\n }, [records, childrenMap, expandedIds]);\n\n const loadList = useCallback(\n async (direction: PageDirection = 'current', token = pageToken) => {\n setLoading(true);\n setError('');\n try {\n const result = await api.list({\n depth: ROOT_MENU_DEPTH,\n pagination: {\n pageToken: token,\n pageSize,\n pageDirection: direction,\n },\n });\n setRecords(result.records);\n setChildrenMap({});\n setExpandedIds({});\n setExpandingIds({});\n setPageToken(result.pageToken);\n setHasPreviousPage(result.hasPreviousPage);\n setHasNextPage(result.hasNextPage);\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载失败');\n } finally {\n setLoading(false);\n }\n },\n [api, pageSize, pageToken],\n );\n\n const loadPermissionPoints = useCallback(async () => {\n try {\n const result = await api.listPermissionPoints({\n pagination: { pageSize: '200', pageDirection: 'current' },\n });\n setPermissionPoints(result.records);\n } catch {\n // 权限点加载失败不阻断菜单列表\n }\n }, [api]);\n\n const toggleExpand = async (row: MenuResource) => {\n if (isMenuLeaf(row)) return;\n const id = row.resourceId;\n if (expandedIds[id]) {\n setExpandedIds((prev) => ({ ...prev, [id]: false }));\n return;\n }\n\n if (!childrenMap[id]) {\n setExpandingIds((prev) => ({ ...prev, [id]: true }));\n setError('');\n try {\n const children = await api.listSubResources(id);\n setChildrenMap((prev) => ({ ...prev, [id]: children }));\n setExpandedIds((prev) => ({ ...prev, [id]: true }));\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载下级菜单失败');\n } finally {\n setExpandingIds((prev) => ({ ...prev, [id]: false }));\n }\n return;\n }\n\n setExpandedIds((prev) => ({ ...prev, [id]: true }));\n };\n\n useEffect(() => {\n void loadList('current', '');\n void loadPermissionPoints();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, pageSize]);\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm());\n setDialogOpen(true);\n void loadPermissionPoints();\n };\n\n const openEdit = (row: MenuResource) => {\n setEditing(row);\n setForm({\n parentId: row.parentId ?? null,\n depth: resolveMenuDepth(row.parentId ?? null, allKnownMenus),\n type: row.type,\n name: row.name,\n identification: row.identification,\n permissionPointIds: [...row.permissionPointIds],\n status: row.status,\n });\n setDialogOpen(true);\n void loadPermissionPoints();\n };\n\n const closeDialog = () => {\n if (saving) return;\n setDialogOpen(false);\n };\n\n const handleSubmit = async (event: FormEvent) => {\n event.preventDefault();\n if (!form.name.trim()) {\n setError('请填写菜单名称');\n return;\n }\n\n setSaving(true);\n setError('');\n try {\n if (editing) {\n await api.update(editing.resourceId, form);\n } else {\n await api.create(form);\n }\n setDialogOpen(false);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '保存失败');\n } finally {\n setSaving(false);\n }\n };\n\n const askDelete = (row: MenuResource) => setDeletingRow(row);\n\n const closeDeleteDialog = () => {\n if (!deleting) setDeletingRow(null);\n };\n\n const confirmDelete = async () => {\n if (!deletingRow) return;\n setDeleting(true);\n setError('');\n try {\n await api.remove(deletingRow.resourceId);\n setDeletingRow(null);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '删除失败');\n } finally {\n setDeleting(false);\n }\n };\n\n const togglePermission = (id: string) => {\n setForm((prev) => {\n const exists = prev.permissionPointIds.includes(id);\n return {\n ...prev,\n permissionPointIds: exists\n ? prev.permissionPointIds.filter((x) => x !== id)\n : [...prev.permissionPointIds, id],\n };\n });\n };\n\n const renderPermissionLabels = (row: MenuResource) => {\n if (row.permissionPointNames?.length) {\n return row.permissionPointNames.join('、');\n }\n if (!row.permissionPointIds.length) return '—';\n return row.permissionPointIds\n .map((id) => permissionNameMap.get(id) ?? id)\n .join('、');\n };\n\n return (\n <div style={styles.root}>\n <div style={styles.toolbar}>\n <h2 style={styles.title}>{title}</h2>\n <div style={styles.toolbarRight}>\n {toolbarExtra}\n <button type=\"button\" style={styles.primaryBtn} onClick={openCreate}>\n 新增\n </button>\n </div>\n </div>\n\n {error ? <div style={styles.error}>{error}</div> : null}\n\n <div style={styles.tableWrap}>\n <table style={styles.table}>\n <thead>\n <tr>\n <th style={styles.th}>菜单名称</th>\n <th style={styles.th}>请求地址</th>\n <th style={{ ...styles.th, width: 90 }}>类型</th>\n <th style={{ ...styles.th, width: 80 }}>可见</th>\n <th style={styles.th}>权限标识</th>\n <th style={{ ...styles.th, width: 140 }}>操作</th>\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={6} style={styles.empty}>\n 加载中…\n </td>\n </tr>\n ) : flatRows.length === 0 ? (\n <tr>\n <td colSpan={6} style={styles.empty}>\n 暂无数据\n </td>\n </tr>\n ) : (\n flatRows.map((row) => {\n const leaf = isMenuLeaf(row);\n const expanded = Boolean(expandedIds[row.resourceId]);\n const expanding = Boolean(expandingIds[row.resourceId]);\n const indent = Math.max(0, (row.depth || 1) - 1) * 18;\n return (\n <tr key={row.resourceId}>\n <td style={styles.td}>\n <div style={{ ...styles.treeCell, paddingLeft: indent }}>\n {leaf ? (\n <span style={styles.treeSpacer} />\n ) : (\n <button\n type=\"button\"\n style={styles.treeToggle}\n onClick={() => void toggleExpand(row)}\n disabled={expanding}\n aria-label={expanded ? '收起' : '展开'}\n >\n {expanding ? '…' : expanded ? '▼' : '▶'}\n </button>\n )}\n <span>{row.name}</span>\n </div>\n </td>\n <td style={styles.td}>\n <code style={styles.code}>{row.identification || '—'}</code>\n </td>\n <td style={styles.td}>{MENU_TYPE_LABEL[row.type]}</td>\n <td style={styles.td}>\n <span\n style={{\n ...styles.badge,\n background:\n row.status === RESOURCE_STATUS_ENABLED ? '#e8f7ef' : '#f4f4f5',\n color:\n row.status === RESOURCE_STATUS_ENABLED ? '#067647' : '#667085',\n }}\n >\n {row.status === RESOURCE_STATUS_ENABLED ? '显示' : '隐藏'}\n </span>\n </td>\n <td style={styles.td}>{renderPermissionLabels(row)}</td>\n <td style={styles.td}>\n <button type=\"button\" style={styles.linkBtn} onClick={() => openEdit(row)}>\n 编辑\n </button>\n <button\n type=\"button\"\n style={{ ...styles.linkBtn, color: '#d92d20' }}\n onClick={() => askDelete(row)}\n >\n 删除\n </button>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n <div style={styles.pagination}>\n <label style={styles.pageSize}>\n 每页\n <select\n value={pageSize}\n onChange={(e) => {\n setPageToken('');\n setPageSize(e.target.value);\n }}\n style={styles.select}\n >\n {PAGE_SIZE_OPTIONS.map((size) => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </label>\n <div style={styles.pageBtns}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasPreviousPage || loading}\n onClick={() => void loadList('previous')}\n >\n 上一页\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasNextPage || loading}\n onClick={() => void loadList('next')}\n >\n 下一页\n </button>\n </div>\n </div>\n\n {dialogOpen ? (\n <div style={styles.mask} onClick={closeDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 520 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>{editing ? '编辑菜单' : '新增菜单'}</h3>\n <button type=\"button\" style={styles.iconBtn} onClick={closeDialog} aria-label=\"关闭\">\n ×\n </button>\n </div>\n <form style={styles.form} onSubmit={(e) => void handleSubmit(e)}>\n <label style={styles.field}>\n <span style={styles.label}>上级菜单</span>\n <select\n style={styles.input}\n value={form.parentId ?? ROOT_PARENT_ID}\n onChange={(e) => {\n const parentId = e.target.value ? e.target.value : null;\n setForm((prev) => ({\n ...prev,\n parentId,\n depth: resolveMenuDepth(parentId, allKnownMenus),\n }));\n }}\n >\n <option value={ROOT_PARENT_ID}>无</option>\n {parentOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n\n <fieldset style={styles.fieldset}>\n <legend style={styles.label}>菜单类型</legend>\n <div style={styles.radioGroup}>\n {MENU_TYPE_OPTIONS.map((opt) => (\n <label key={opt.value} style={styles.radioItem}>\n <input\n type=\"radio\"\n name=\"menu-type\"\n style={styles.control}\n checked={form.type === opt.value}\n onChange={() =>\n setForm((prev) => ({\n ...prev,\n type: opt.value as MenuResourceType,\n }))\n }\n />\n {opt.label}\n </label>\n ))}\n </div>\n </fieldset>\n\n <label style={styles.field}>\n <span style={styles.label}>菜单名称</span>\n <input\n style={styles.input}\n value={form.name}\n onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}\n placeholder=\"请输入菜单名称\"\n required\n />\n </label>\n\n <label style={styles.field}>\n <span style={styles.label}>请求地址</span>\n <input\n style={styles.input}\n value={form.identification}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, identification: e.target.value }))\n }\n placeholder=\"如 /system/user\"\n />\n </label>\n\n <fieldset style={styles.fieldset}>\n <legend style={styles.label}>权限标识</legend>\n <div style={styles.multiSelect}>\n {permissionPoints.length === 0 ? (\n <div style={styles.hint}>暂无权限点,请先在权限点管理中新增</div>\n ) : (\n permissionPoints.map((p) => (\n <label key={p.resourceId} style={styles.checkItem}>\n <input\n type=\"checkbox\"\n style={styles.control}\n checked={form.permissionPointIds.includes(p.resourceId)}\n onChange={() => togglePermission(p.resourceId)}\n />\n <span>\n {p.name}\n <code style={{ ...styles.code, marginLeft: 6 }}>{p.identification}</code>\n </span>\n </label>\n ))\n )}\n </div>\n </fieldset>\n\n <fieldset style={styles.fieldset}>\n <legend style={styles.label}>状态</legend>\n <div style={styles.radioGroup}>\n {MENU_VISIBILITY_OPTIONS.map((opt) => (\n <label key={opt.value} style={styles.radioItem}>\n <input\n type=\"radio\"\n name=\"menu-status\"\n style={styles.control}\n checked={form.status === opt.value}\n onChange={() => setForm((prev) => ({ ...prev, status: opt.value }))}\n />\n {opt.label}\n </label>\n ))}\n </div>\n </fieldset>\n\n <div style={styles.dialogFooter}>\n <button type=\"button\" style={styles.secondaryBtn} onClick={closeDialog}>\n 取消\n </button>\n <button type=\"submit\" style={styles.primaryBtn} disabled={saving}>\n {saving ? '保存中…' : '保存'}\n </button>\n </div>\n </form>\n </div>\n </div>\n ) : null}\n\n {deletingRow ? (\n <div style={styles.mask} onClick={closeDeleteDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 420 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>确认删除</h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeDeleteDialog}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.confirmBody}>\n <p style={styles.confirmText}>\n 确认删除菜单「<strong>{deletingRow.name}</strong>」吗?删除后不可恢复。\n </p>\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeDeleteDialog}\n disabled={deleting}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.dangerBtn}\n onClick={() => void confirmDelete()}\n disabled={deleting}\n >\n {deleting ? '删除中…' : '确认删除'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n padding: 16,\n color: '#101828',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n title: { margin: 0, fontSize: 18, fontWeight: 600 },\n toolbarRight: { display: 'flex', alignItems: 'center', gap: 8 },\n error: {\n padding: '10px 12px',\n borderRadius: 8,\n background: '#fef3f2',\n color: '#b42318',\n fontSize: 13,\n },\n tableWrap: {\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 10,\n background: '#fff',\n },\n table: { width: '100%', borderCollapse: 'collapse', minWidth: 820 },\n th: {\n textAlign: 'left',\n padding: '12px 14px',\n fontSize: 13,\n fontWeight: 600,\n color: '#475467',\n background: '#f9fafb',\n borderBottom: '1px solid #eaecf0',\n },\n td: {\n padding: '12px 14px',\n fontSize: 14,\n borderBottom: '1px solid #f2f4f7',\n verticalAlign: 'middle',\n },\n treeCell: {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n },\n treeToggle: {\n width: 22,\n height: 22,\n border: '1px solid #d0d5dd',\n borderRadius: 4,\n background: '#fff',\n color: '#475467',\n cursor: 'pointer',\n fontSize: 10,\n lineHeight: '20px',\n padding: 0,\n flexShrink: 0,\n },\n treeSpacer: {\n width: 22,\n height: 22,\n flexShrink: 0,\n display: 'inline-block',\n },\n empty: { padding: 28, textAlign: 'center', color: '#98a2b3', fontSize: 14 },\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 13,\n background: '#f2f4f7',\n padding: '2px 6px',\n borderRadius: 4,\n },\n badge: {\n display: 'inline-block',\n padding: '2px 8px',\n borderRadius: 999,\n fontSize: 12,\n fontWeight: 500,\n },\n linkBtn: {\n border: 'none',\n background: 'transparent',\n color: '#049BAD',\n cursor: 'pointer',\n padding: '0 8px 0 0',\n fontSize: 13,\n },\n pagination: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n pageSize: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#475467' },\n pageBtns: { display: 'flex', gap: 8 },\n primaryBtn: {\n border: 'none',\n background: '#049BAD',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n secondaryBtn: {\n border: '1px solid #d0d5dd',\n background: '#fff',\n color: '#344054',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n dangerBtn: {\n border: 'none',\n background: '#d92d20',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n select: {\n border: '1px solid #d0d5dd',\n borderRadius: 6,\n padding: '4px 8px',\n fontSize: 13,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n mask: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(16, 24, 40, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n padding: 16,\n },\n dialog: {\n width: '100%',\n maxWidth: 480,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 20px 40px rgba(16,24,40,0.18)',\n maxHeight: '90vh',\n overflow: 'auto',\n },\n dialogHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 16px',\n borderBottom: '1px solid #eaecf0',\n position: 'sticky',\n top: 0,\n background: '#fff',\n zIndex: 1,\n },\n dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },\n iconBtn: {\n border: 'none',\n background: 'transparent',\n fontSize: 22,\n lineHeight: 1,\n cursor: 'pointer',\n color: '#667085',\n },\n form: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n confirmBody: { display: 'flex', flexDirection: 'column', gap: 16, padding: 16 },\n confirmText: { margin: 0, fontSize: 14, color: '#344054', lineHeight: 1.6 },\n field: { display: 'flex', flexDirection: 'column', gap: 6 },\n fieldset: {\n margin: 0,\n padding: 0,\n border: 'none',\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n backgroundColor: 'transparent',\n color: '#101828',\n },\n label: { fontSize: 13, color: '#344054', fontWeight: 500 },\n input: {\n border: '1px solid #d0d5dd',\n borderRadius: 8,\n padding: '8px 10px',\n fontSize: 14,\n outline: 'none',\n backgroundColor: '#ffffff',\n color: '#101828',\n boxSizing: 'border-box',\n width: '100%',\n },\n control: {\n width: 16,\n height: 16,\n margin: 0,\n flexShrink: 0,\n accentColor: '#049BAD',\n backgroundColor: '#ffffff',\n colorScheme: 'light' as const,\n },\n radioGroup: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 16,\n backgroundColor: 'transparent',\n },\n radioItem: {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontSize: 14,\n color: '#344054',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n },\n multiSelect: {\n maxHeight: 160,\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 8,\n padding: 8,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n checkItem: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 4px',\n fontSize: 13,\n color: '#344054',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n },\n hint: { fontSize: 13, color: '#98a2b3', padding: 8 },\n dialogFooter: {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n paddingTop: 4,\n },\n};\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type FormEvent,\n type ReactNode,\n} from 'react';\nimport type { PageDirection } from '../resources';\nimport {\n collectTreeResourceIds,\n type RolePermissionTreeNode,\n type SystemRole,\n type SystemRoleApi,\n type SystemRoleFormValues,\n} from '../roles';\n\nconst PAGE_SIZE_OPTIONS = ['10', '20', '50', '100'];\n\nconst emptyForm = (): SystemRoleFormValues => ({\n name: '',\n description: '',\n});\n\nfunction countCheckedDescendants(\n node: RolePermissionTreeNode,\n checked: Set<string>,\n): { total: number; checkedCount: number } {\n let total = 0;\n let checkedCount = 0;\n const walk = (n: RolePermissionTreeNode) => {\n for (const child of n.children) {\n total += 1;\n if (checked.has(child.resourceId)) checkedCount += 1;\n walk(child);\n }\n };\n walk(node);\n return { total, checkedCount };\n}\n\nexport type RoleManagerProps = {\n api: SystemRoleApi;\n title?: string;\n pageSize?: string;\n toolbarExtra?: ReactNode;\n};\n\nexport function RoleManager({\n api,\n title = '角色管理',\n pageSize: initialPageSize = '20',\n toolbarExtra,\n}: RoleManagerProps) {\n const [records, setRecords] = useState<SystemRole[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [keyword, setKeyword] = useState('');\n const [keywordInput, setKeywordInput] = useState('');\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageToken, setPageToken] = useState('');\n const [hasPreviousPage, setHasPreviousPage] = useState(false);\n const [hasNextPage, setHasNextPage] = useState(false);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editing, setEditing] = useState<SystemRole | null>(null);\n const [form, setForm] = useState<SystemRoleFormValues>(emptyForm);\n const [saving, setSaving] = useState(false);\n const [deletingRow, setDeletingRow] = useState<SystemRole | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const [authRole, setAuthRole] = useState<SystemRole | null>(null);\n const [authTree, setAuthTree] = useState<RolePermissionTreeNode[]>([]);\n const [authChecked, setAuthChecked] = useState<Set<string>>(() => new Set());\n const [authExpanded, setAuthExpanded] = useState<Record<string, boolean>>({});\n const [authLoading, setAuthLoading] = useState(false);\n const [authSaving, setAuthSaving] = useState(false);\n const [authError, setAuthError] = useState('');\n\n const loadList = useCallback(\n async (direction: PageDirection = 'current', token = pageToken) => {\n setLoading(true);\n setError('');\n try {\n const result = await api.list({\n keyword,\n pagination: {\n pageToken: token,\n pageSize,\n pageDirection: direction,\n },\n });\n setRecords(result.records);\n setPageToken(result.pageToken);\n setHasPreviousPage(result.hasPreviousPage);\n setHasNextPage(result.hasNextPage);\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载失败');\n } finally {\n setLoading(false);\n }\n },\n [api, keyword, pageSize, pageToken],\n );\n\n useEffect(() => {\n void loadList('current', '');\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, pageSize, keyword]);\n\n const handleSearch = () => {\n setPageToken('');\n setKeyword(keywordInput.trim());\n };\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm());\n setDialogOpen(true);\n };\n\n const openEdit = (row: SystemRole) => {\n setEditing(row);\n setForm({\n name: row.name,\n description: row.description,\n });\n setDialogOpen(true);\n };\n\n const closeDialog = () => {\n if (!saving) setDialogOpen(false);\n };\n\n const handleSubmit = async (event: FormEvent) => {\n event.preventDefault();\n if (!form.name.trim()) {\n setError('请填写角色名称');\n return;\n }\n\n setSaving(true);\n setError('');\n try {\n if (editing) {\n await api.update(editing.roleId, form);\n } else {\n await api.create(form);\n }\n setDialogOpen(false);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '保存失败');\n } finally {\n setSaving(false);\n }\n };\n\n const askDelete = (row: SystemRole) => setDeletingRow(row);\n\n const closeDeleteDialog = () => {\n if (!deleting) setDeletingRow(null);\n };\n\n const confirmDelete = async () => {\n if (!deletingRow) return;\n setDeleting(true);\n setError('');\n try {\n await api.remove(deletingRow.roleId);\n setDeletingRow(null);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '删除失败');\n } finally {\n setDeleting(false);\n }\n };\n\n const openAuthorize = async (row: SystemRole) => {\n setAuthRole(row);\n setAuthTree([]);\n setAuthChecked(new Set());\n setAuthExpanded({});\n setAuthError('');\n setAuthLoading(true);\n try {\n const result = await api.getPermissions(row.roleId);\n setAuthTree(result.resourceTree);\n setAuthChecked(new Set(result.resourceIds));\n const expanded: Record<string, boolean> = {};\n const walk = (nodes: RolePermissionTreeNode[]) => {\n for (const node of nodes) {\n if (node.children.length > 0) {\n expanded[node.resourceId] = true;\n walk(node.children);\n }\n }\n };\n walk(result.resourceTree);\n setAuthExpanded(expanded);\n } catch (err) {\n setAuthError(err instanceof Error ? err.message : '加载授权树失败');\n } finally {\n setAuthLoading(false);\n }\n };\n\n const closeAuthorize = () => {\n if (!authSaving) {\n setAuthRole(null);\n setAuthError('');\n }\n };\n\n const toggleExpand = (resourceId: string) => {\n setAuthExpanded((prev) => ({ ...prev, [resourceId]: !prev[resourceId] }));\n };\n\n const toggleCheck = (node: RolePermissionTreeNode) => {\n setAuthChecked((prev) => {\n const next = new Set(prev);\n const ids = collectTreeResourceIds(node);\n const shouldCheck = !prev.has(node.resourceId);\n if (shouldCheck) {\n ids.forEach((id) => next.add(id));\n } else {\n ids.forEach((id) => next.delete(id));\n }\n return next;\n });\n };\n\n const saveAuthorize = async () => {\n if (!authRole) return;\n setAuthSaving(true);\n setAuthError('');\n try {\n await api.savePermissions(authRole.roleId, Array.from(authChecked));\n setAuthRole(null);\n } catch (err) {\n setAuthError(err instanceof Error ? err.message : '保存授权失败');\n } finally {\n setAuthSaving(false);\n }\n };\n\n const renderTreeNodes = (nodes: RolePermissionTreeNode[], depth = 0): ReactNode =>\n nodes.map((node) => {\n const hasChildren = node.children.length > 0;\n const expanded = Boolean(authExpanded[node.resourceId]);\n const checked = authChecked.has(node.resourceId);\n const { total, checkedCount } = countCheckedDescendants(node, authChecked);\n const indeterminate = hasChildren && checkedCount > 0 && checkedCount < total && !checked;\n\n return (\n <div key={node.resourceId}>\n <div style={{ ...styles.treeRow, paddingLeft: 12 + depth * 20 }}>\n {hasChildren ? (\n <button\n type=\"button\"\n style={styles.treeToggle}\n onClick={() => toggleExpand(node.resourceId)}\n aria-label={expanded ? '收起' : '展开'}\n >\n {expanded ? '▼' : '▶'}\n </button>\n ) : (\n <span style={styles.treeSpacer} />\n )}\n <label style={styles.treeLabel}>\n <TreeCheckbox\n checked={checked}\n indeterminate={indeterminate}\n onChange={() => toggleCheck(node)}\n />\n <span>{node.name || node.resourceId}</span>\n </label>\n </div>\n {hasChildren && expanded ? renderTreeNodes(node.children, depth + 1) : null}\n </div>\n );\n });\n\n return (\n <div style={styles.root}>\n <div style={styles.toolbar}>\n <h2 style={styles.title}>{title}</h2>\n <div style={styles.toolbarRight}>\n {toolbarExtra}\n <button type=\"button\" style={styles.primaryBtn} onClick={openCreate}>\n 新增角色\n </button>\n </div>\n </div>\n\n <div style={styles.searchBar}>\n <input\n style={{ ...styles.input, maxWidth: 260 }}\n value={keywordInput}\n onChange={(e) => setKeywordInput(e.target.value)}\n placeholder=\"搜索角色名称 / 描述\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSearch();\n }}\n />\n <button type=\"button\" style={styles.secondaryBtn} onClick={handleSearch}>\n 查询\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={() => {\n setKeywordInput('');\n setKeyword('');\n setPageToken('');\n }}\n >\n 重置\n </button>\n </div>\n\n {error ? <div style={styles.error}>{error}</div> : null}\n\n <div style={styles.tableWrap}>\n <table style={styles.table}>\n <thead>\n <tr>\n <th style={styles.th}>角色名称</th>\n <th style={styles.th}>角色描述</th>\n <th style={{ ...styles.th, width: 200 }}>操作</th>\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={3} style={styles.empty}>\n 加载中…\n </td>\n </tr>\n ) : records.length === 0 ? (\n <tr>\n <td colSpan={3} style={styles.empty}>\n 暂无数据\n </td>\n </tr>\n ) : (\n records.map((row) => (\n <tr key={row.roleId}>\n <td style={styles.td}>{row.name}</td>\n <td style={styles.td}>{row.description || '—'}</td>\n <td style={styles.td}>\n <button type=\"button\" style={styles.linkBtn} onClick={() => openEdit(row)}>\n 编辑\n </button>\n <button\n type=\"button\"\n style={styles.linkBtn}\n onClick={() => void openAuthorize(row)}\n >\n 授权\n </button>\n <button\n type=\"button\"\n style={{ ...styles.linkBtn, color: '#d92d20' }}\n onClick={() => askDelete(row)}\n >\n 删除\n </button>\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div style={styles.pagination}>\n <label style={styles.pageSize}>\n 每页\n <select\n value={pageSize}\n onChange={(e) => {\n setPageToken('');\n setPageSize(e.target.value);\n }}\n style={styles.select}\n >\n {PAGE_SIZE_OPTIONS.map((size) => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </label>\n <div style={styles.pageBtns}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasPreviousPage || loading}\n onClick={() => void loadList('previous')}\n >\n 上一页\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasNextPage || loading}\n onClick={() => void loadList('next')}\n >\n 下一页\n </button>\n </div>\n </div>\n\n {dialogOpen ? (\n <div style={styles.mask} onClick={closeDialog}>\n <div\n style={styles.dialog}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>{editing ? '编辑角色' : '新增角色'}</h3>\n <button type=\"button\" style={styles.iconBtn} onClick={closeDialog} aria-label=\"关闭\">\n ×\n </button>\n </div>\n <form style={styles.form} onSubmit={(e) => void handleSubmit(e)}>\n <label style={styles.field}>\n <span style={styles.label}>角色名称</span>\n <input\n style={styles.input}\n value={form.name}\n onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}\n placeholder=\"请输入角色名称\"\n required\n />\n </label>\n <label style={styles.field}>\n <span style={styles.label}>角色描述</span>\n <textarea\n style={{ ...styles.input, minHeight: 88, resize: 'vertical' }}\n value={form.description}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, description: e.target.value }))\n }\n placeholder=\"请输入角色描述\"\n />\n </label>\n <div style={styles.dialogFooter}>\n <button type=\"button\" style={styles.secondaryBtn} onClick={closeDialog}>\n 取消\n </button>\n <button type=\"submit\" style={styles.primaryBtn} disabled={saving}>\n {saving ? '保存中…' : '保存'}\n </button>\n </div>\n </form>\n </div>\n </div>\n ) : null}\n\n {deletingRow ? (\n <div style={styles.mask} onClick={closeDeleteDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 420 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>确认删除</h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeDeleteDialog}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.confirmBody}>\n <p style={styles.confirmText}>\n 确认删除角色「<strong>{deletingRow.name}</strong>」吗?删除后不可恢复。\n </p>\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeDeleteDialog}\n disabled={deleting}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.dangerBtn}\n onClick={() => void confirmDelete()}\n disabled={deleting}\n >\n {deleting ? '删除中…' : '确认删除'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n\n {authRole ? (\n <div style={styles.mask} onClick={closeAuthorize}>\n <div\n style={{ ...styles.dialog, maxWidth: 560 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>角色授权 — {authRole.name}</h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeAuthorize}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.authBody}>\n {authError ? <div style={styles.error}>{authError}</div> : null}\n {authLoading ? (\n <div style={styles.empty}>加载中…</div>\n ) : authTree.length === 0 ? (\n <div style={styles.empty}>暂无可授权资源</div>\n ) : (\n <div style={styles.treePanel}>{renderTreeNodes(authTree)}</div>\n )}\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeAuthorize}\n disabled={authSaving}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.primaryBtn}\n onClick={() => void saveAuthorize()}\n disabled={authLoading || authSaving}\n >\n {authSaving ? '保存中…' : '保存'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction TreeCheckbox({\n checked,\n indeterminate,\n onChange,\n}: {\n checked: boolean;\n indeterminate: boolean;\n onChange: () => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n return (\n <input\n ref={ref}\n type=\"checkbox\"\n checked={checked}\n onChange={onChange}\n style={styles.checkbox}\n />\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n padding: 16,\n color: '#101828',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n title: { margin: 0, fontSize: 18, fontWeight: 600 },\n toolbarRight: { display: 'flex', alignItems: 'center', gap: 8 },\n searchBar: { display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' },\n error: {\n padding: '10px 12px',\n borderRadius: 8,\n background: '#fef3f2',\n color: '#b42318',\n fontSize: 13,\n },\n tableWrap: {\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 10,\n background: '#fff',\n },\n table: { width: '100%', borderCollapse: 'collapse', minWidth: 560 },\n th: {\n textAlign: 'left',\n padding: '12px 14px',\n fontSize: 13,\n fontWeight: 600,\n color: '#475467',\n background: '#f9fafb',\n borderBottom: '1px solid #eaecf0',\n },\n td: {\n padding: '12px 14px',\n fontSize: 14,\n borderBottom: '1px solid #f2f4f7',\n verticalAlign: 'middle',\n },\n empty: { padding: 28, textAlign: 'center', color: '#98a2b3', fontSize: 14 },\n linkBtn: {\n border: 'none',\n background: 'transparent',\n color: '#049BAD',\n cursor: 'pointer',\n padding: '0 8px 0 0',\n fontSize: 13,\n },\n pagination: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n pageSize: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#475467' },\n pageBtns: { display: 'flex', gap: 8 },\n primaryBtn: {\n border: 'none',\n background: '#049BAD',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n secondaryBtn: {\n border: '1px solid #d0d5dd',\n background: '#fff',\n color: '#344054',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n dangerBtn: {\n border: 'none',\n background: '#d92d20',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n select: {\n border: '1px solid #d0d5dd',\n borderRadius: 6,\n padding: '4px 8px',\n fontSize: 13,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n mask: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(16, 24, 40, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n padding: 16,\n },\n dialog: {\n width: '100%',\n maxWidth: 480,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 20px 40px rgba(16,24,40,0.18)',\n },\n dialogHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 16px',\n borderBottom: '1px solid #eaecf0',\n },\n dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },\n iconBtn: {\n border: 'none',\n background: 'transparent',\n fontSize: 22,\n lineHeight: 1,\n cursor: 'pointer',\n color: '#667085',\n },\n form: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n confirmBody: { display: 'flex', flexDirection: 'column', gap: 16, padding: 16 },\n confirmText: { margin: 0, fontSize: 14, color: '#344054', lineHeight: 1.6 },\n authBody: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n treePanel: {\n maxHeight: 420,\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 8,\n padding: '8px 0',\n background: '#fff',\n },\n treeRow: {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n minHeight: 32,\n paddingRight: 12,\n },\n treeToggle: {\n border: 'none',\n background: 'transparent',\n width: 20,\n height: 20,\n padding: 0,\n cursor: 'pointer',\n color: '#667085',\n fontSize: 10,\n flexShrink: 0,\n },\n treeSpacer: { width: 20, flexShrink: 0 },\n treeLabel: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 14,\n color: '#101828',\n cursor: 'pointer',\n userSelect: 'none' as const,\n },\n checkbox: {\n width: 16,\n height: 16,\n accentColor: '#049BAD',\n cursor: 'pointer',\n colorScheme: 'light' as const,\n backgroundColor: '#ffffff',\n },\n field: { display: 'flex', flexDirection: 'column', gap: 6 },\n label: { fontSize: 13, color: '#344054', fontWeight: 500 },\n input: {\n border: '1px solid #d0d5dd',\n borderRadius: 8,\n padding: '8px 10px',\n fontSize: 14,\n outline: 'none',\n backgroundColor: '#ffffff',\n color: '#101828',\n boxSizing: 'border-box',\n width: '100%',\n },\n dialogFooter: {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n paddingTop: 4,\n },\n};\n","import { appendQueryParam, extractPagination, extractRecords } from '../resources/pagination';\nimport type { ResourceHttpRequest } from '../resources';\nimport type {\n CreateSystemRoleBody,\n FetchSystemRolesParams,\n RolePermissionTreeNode,\n RolePermissionsResult,\n SaveRolePermissionsBody,\n SystemRole,\n SystemRoleFormValues,\n SystemRoleListResult,\n UpdateSystemRoleBody,\n} from './types';\n\nexport type {\n CreateSystemRoleBody,\n FetchSystemRolesParams,\n RolePermissionTreeNode,\n RolePermissionsResult,\n SaveRolePermissionsBody,\n SystemRole,\n SystemRoleFormValues,\n SystemRoleListResult,\n UpdateSystemRoleBody,\n} from './types';\n\nexport type SystemRoleApi = {\n list: (\n params?: FetchSystemRolesParams,\n signal?: AbortSignal,\n ) => Promise<SystemRoleListResult>;\n create: (values: SystemRoleFormValues, signal?: AbortSignal) => Promise<unknown>;\n update: (\n roleId: string,\n values: SystemRoleFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n remove: (roleId: string, signal?: AbortSignal) => Promise<unknown>;\n getPermissions: (\n roleId: string,\n signal?: AbortSignal,\n ) => Promise<RolePermissionsResult>;\n savePermissions: (\n roleId: string,\n resourceIds: string[],\n signal?: AbortSignal,\n ) => Promise<unknown>;\n};\n\nexport function mapSystemRole(item: unknown): SystemRole | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const roleId = row.roleId ?? row.role_id ?? row.id;\n if (roleId === undefined || roleId === null || roleId === '') return null;\n\n return {\n roleId: String(roleId),\n name: String(row.name ?? ''),\n description: String(row.description ?? row.desc ?? ''),\n };\n}\n\nexport function mapPermissionTreeNode(item: unknown): RolePermissionTreeNode | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const resourceId = row.resourceId ?? row.resource_id ?? row.id;\n if (resourceId === undefined || resourceId === null || resourceId === '') return null;\n\n const rawChildren = row.children ?? row.childList ?? row.child_list ?? [];\n const children = Array.isArray(rawChildren)\n ? rawChildren\n .map(mapPermissionTreeNode)\n .filter((node): node is RolePermissionTreeNode => node !== null)\n : [];\n\n return {\n resourceId: String(resourceId),\n name: String(row.name ?? ''),\n children,\n };\n}\n\nfunction asObject(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' ? (value as Record<string, unknown>) : null;\n}\n\nexport function mapRolePermissions(payload: unknown): RolePermissionsResult {\n const envelope = asObject(payload) ?? {};\n const data = asObject(envelope.data) ?? envelope;\n\n const rawIds = data.resourceIds ?? data.resource_ids ?? [];\n const resourceIds = Array.isArray(rawIds)\n ? rawIds\n .map((id) => (id === undefined || id === null ? '' : String(id)))\n .filter(Boolean)\n : [];\n\n const rawTree = data.resourceTree ?? data.resource_tree ?? [];\n const resourceTree = Array.isArray(rawTree)\n ? rawTree\n .map(mapPermissionTreeNode)\n .filter((node): node is RolePermissionTreeNode => node !== null)\n : [];\n\n return { resourceIds, resourceTree };\n}\n\n/** 收集节点及其全部子孙 resourceId */\nexport function collectTreeResourceIds(node: RolePermissionTreeNode): string[] {\n return [node.resourceId, ...node.children.flatMap(collectTreeResourceIds)];\n}\n\nfunction buildListUrl(params?: FetchSystemRolesParams): string {\n const parts: string[] = [];\n appendQueryParam(parts, 'keyword', params?.keyword ?? '');\n appendQueryParam(parts, 'page-token', params?.pagination?.pageToken ?? '');\n appendQueryParam(parts, 'page-size', params?.pagination?.pageSize ?? '20');\n appendQueryParam(parts, 'page-direction', params?.pagination?.pageDirection ?? 'current');\n return parts.length ? `/system/roles?${parts.join('&')}` : '/system/roles';\n}\n\nexport function buildCreateRoleBody(values: SystemRoleFormValues): CreateSystemRoleBody {\n return {\n name: values.name.trim(),\n description: values.description.trim(),\n };\n}\n\nexport function buildUpdateRoleBody(values: SystemRoleFormValues): UpdateSystemRoleBody {\n return {\n name: values.name.trim(),\n description: values.description.trim(),\n };\n}\n\nexport function buildSavePermissionsBody(resourceIds: string[]): SaveRolePermissionsBody {\n return {\n resourceIds: [...new Set(resourceIds.map(String).filter(Boolean))],\n };\n}\n\nexport function createSystemRoleApi(request: ResourceHttpRequest): SystemRoleApi {\n return {\n async list(params, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: buildListUrl(params),\n signal,\n });\n const records = extractRecords(json)\n .map(mapSystemRole)\n .filter((item): item is SystemRole => item !== null);\n return {\n records,\n ...extractPagination(json),\n };\n },\n\n async create(values, signal) {\n return request({\n method: 'POST',\n url: '/system/roles',\n body: buildCreateRoleBody(values),\n signal,\n });\n },\n\n async update(roleId, values, signal) {\n return request({\n method: 'PATCH',\n url: `/system/roles/${encodeURIComponent(roleId)}`,\n body: buildUpdateRoleBody(values),\n signal,\n });\n },\n\n async remove(roleId, signal) {\n return request({\n method: 'DELETE',\n url: `/system/roles/${encodeURIComponent(roleId)}`,\n signal,\n });\n },\n\n async getPermissions(roleId, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: `/system/roles/${encodeURIComponent(roleId)}/permissions`,\n signal,\n });\n return mapRolePermissions(json);\n },\n\n async savePermissions(roleId, resourceIds, signal) {\n return request({\n method: 'POST',\n url: `/system/roles/${encodeURIComponent(roleId)}/permissions`,\n body: buildSavePermissionsBody(resourceIds),\n signal,\n });\n },\n };\n}\n","import { useMemo, useState, type CSSProperties, type ReactNode } from 'react';\nimport {\n SYSTEM_ADMIN_DEFAULT_KEY,\n SYSTEM_ADMIN_MENU,\n type SystemAdminMenuKey,\n} from '../admin';\nimport type { AuthorizationResourceApi, MenuResourceApi } from '../resources';\nimport type { SystemRoleApi } from '../roles';\nimport { MenuManager } from './MenuManager';\nimport { ResourceManager } from './ResourceManager';\nimport { RoleManager } from './RoleManager';\n\nexport type SystemAdminProps = {\n menuApi: MenuResourceApi;\n resourceApi: AuthorizationResourceApi;\n roleApi: SystemRoleApi;\n /** 默认选中的子菜单,默认菜单管理 */\n defaultActiveKey?: SystemAdminMenuKey;\n /** 受控选中 key */\n activeKey?: SystemAdminMenuKey;\n onActiveKeyChange?: (key: SystemAdminMenuKey) => void;\n title?: string;\n toolbarExtra?: ReactNode;\n};\n\n/**\n * 系统管理:侧栏父菜单「系统管理」,子菜单为菜单 / 权限点 / 角色管理。\n */\nexport function SystemAdmin({\n menuApi,\n resourceApi,\n roleApi,\n defaultActiveKey = SYSTEM_ADMIN_DEFAULT_KEY,\n activeKey: controlledKey,\n onActiveKeyChange,\n title = SYSTEM_ADMIN_MENU.label,\n toolbarExtra,\n}: SystemAdminProps) {\n const [innerKey, setInnerKey] = useState<SystemAdminMenuKey>(defaultActiveKey);\n const activeKey = controlledKey ?? innerKey;\n\n const setActiveKey = (key: SystemAdminMenuKey) => {\n if (controlledKey === undefined) setInnerKey(key);\n onActiveKeyChange?.(key);\n };\n\n const activeLabel = useMemo(\n () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey)?.label ?? '',\n [activeKey],\n );\n\n return (\n <div style={styles.root}>\n <aside style={styles.sidebar}>\n <div style={styles.sidebarTitle}>{title}</div>\n <nav style={styles.nav}>\n {SYSTEM_ADMIN_MENU.children.map((item) => {\n const active = item.key === activeKey;\n return (\n <button\n key={item.key}\n type=\"button\"\n style={{\n ...styles.navItem,\n ...(active ? styles.navItemActive : null),\n }}\n onClick={() => setActiveKey(item.key)}\n >\n {item.label}\n </button>\n );\n })}\n </nav>\n </aside>\n\n <main style={styles.content}>\n <div style={styles.contentHeader}>\n <div style={styles.breadcrumb}>\n <span style={styles.breadcrumbParent}>{title}</span>\n <span style={styles.breadcrumbSep}>/</span>\n <span style={styles.breadcrumbCurrent}>{activeLabel}</span>\n </div>\n {toolbarExtra}\n </div>\n\n <div style={styles.panel}>\n {activeKey === 'menu' ? (\n <MenuManager api={menuApi} title=\"菜单管理\" />\n ) : activeKey === 'resource' ? (\n <ResourceManager api={resourceApi} title=\"权限点管理\" />\n ) : (\n <RoleManager api={roleApi} title=\"角色管理\" />\n )}\n </div>\n </main>\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n minHeight: 560,\n border: '1px solid #eaecf0',\n borderRadius: 12,\n overflow: 'hidden',\n background: '#fff',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n color: '#101828',\n },\n sidebar: {\n width: 200,\n flexShrink: 0,\n borderRight: '1px solid #eaecf0',\n background: '#f9fafb',\n padding: '16px 12px',\n },\n sidebarTitle: {\n fontSize: 14,\n fontWeight: 600,\n color: '#344054',\n padding: '4px 10px 12px',\n },\n nav: {\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n },\n navItem: {\n border: 'none',\n background: 'transparent',\n textAlign: 'left',\n padding: '10px 12px',\n borderRadius: 8,\n fontSize: 14,\n color: '#475467',\n cursor: 'pointer',\n },\n navItemActive: {\n background: '#e6f7f9',\n color: '#049BAD',\n fontWeight: 600,\n },\n content: {\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n background: '#fff',\n },\n contentHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 16px',\n borderBottom: '1px solid #f2f4f7',\n },\n breadcrumb: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 13,\n },\n breadcrumbParent: { color: '#98a2b3' },\n breadcrumbSep: { color: '#d0d5dd' },\n breadcrumbCurrent: { color: '#344054', fontWeight: 600 },\n panel: {\n flex: 1,\n minHeight: 0,\n overflow: 'auto',\n },\n};\n","export type SystemAdminMenuKey = 'menu' | 'resource' | 'role';\n\nexport type SystemAdminSubMenu = {\n key: SystemAdminMenuKey;\n label: string;\n};\n\nexport type SystemAdminMenuGroup = {\n key: 'system';\n label: string;\n children: SystemAdminSubMenu[];\n};\n\n/** 系统管理菜单结构 */\nexport const SYSTEM_ADMIN_MENU: SystemAdminMenuGroup = {\n key: 'system',\n label: '系统管理',\n children: [\n { key: 'menu', label: '菜单管理' },\n { key: 'resource', label: '权限点管理' },\n { key: 'role', label: '角色管理' },\n ],\n};\n\nexport const SYSTEM_ADMIN_DEFAULT_KEY: SystemAdminMenuKey = 'menu';\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useState","text","jsx","useState","useCallback","useEffect","useMemo","useCallback","useEffect","useMemo","useState","jsx","jsxs","PAGE_SIZE_OPTIONS","emptyForm","useState","useMemo","useCallback","useEffect","styles","useCallback","useEffect","useState","buildListUrl","jsx","jsxs","PAGE_SIZE_OPTIONS","emptyForm","useState","useCallback","useEffect","styles","useMemo","useState","jsx","jsxs","useState","useMemo","styles"]}
1
+ {"version":3,"sources":["../../src/react/context.tsx","../../src/core/store.ts","../../src/react/Can.tsx","../../src/react/ResourceManager.tsx","../../src/resources/types.ts","../../src/utils/snowflake.ts","../../src/resources/pagination.ts","../../src/resources/api.ts","../../src/react/MenuManager.tsx","../../src/react/RoleManager.tsx","../../src/roles/index.ts","../../src/react/SystemAdmin.tsx","../../src/admin/menu.ts"],"sourcesContent":["import {\n createContext,\n createElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n createPermissionStore,\n type CheckOptions,\n type PermissionCode,\n type PermissionState,\n type PermissionStoreAPI,\n type RoleCode,\n} from '../core';\n\nconst PermissionContext = createContext<PermissionStoreAPI | null>(null);\n\nexport interface PermissionProviderProps {\n children: ReactNode;\n /** Pass an existing store to share across trees, or omit to create one. */\n store?: PermissionStoreAPI;\n /** Initial state when the provider creates its own store. */\n initialState?: Partial<PermissionState>;\n}\n\nexport function PermissionProvider({\n children,\n store: externalStore,\n initialState,\n}: PermissionProviderProps) {\n const store = useMemo(\n () => externalStore ?? createPermissionStore(initialState),\n // store identity is intentional; initialState only applies on first create\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [externalStore],\n );\n\n return createElement(PermissionContext.Provider, { value: store }, children);\n}\n\nfunction useStore(): PermissionStoreAPI {\n const store = useContext(PermissionContext);\n if (!store) {\n throw new Error(\n '[com-angel-authorization/react] usePermission* hooks must be used within <PermissionProvider>.',\n );\n }\n return store;\n}\n\nfunction usePermissionSnapshot(store: PermissionStoreAPI): PermissionState {\n const [state, setState] = useState(() => store.getState());\n\n useEffect(() => {\n setState(store.getState());\n return store.subscribe(setState);\n }, [store]);\n\n return state;\n}\n\nexport interface UsePermissionResult {\n permissions: PermissionCode[];\n roles: RoleCode[];\n isSuperAdmin: boolean;\n hasPermission: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;\n can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n setPermissions: (permissions: PermissionCode[]) => void;\n setRoles: (roles: RoleCode[]) => void;\n setSuperAdmin: (isSuperAdmin: boolean) => void;\n hydrate: (payload: Partial<PermissionState>) => void;\n clear: () => void;\n store: PermissionStoreAPI;\n}\n\nexport function usePermission(): UsePermissionResult {\n const store = useStore();\n const state = usePermissionSnapshot(store);\n\n const hasPermission = useCallback(\n (codes: PermissionCode | PermissionCode[], options?: CheckOptions) =>\n store.hasPermission(codes, options),\n [store],\n );\n\n const hasRole = useCallback(\n (codes: RoleCode | RoleCode[], options?: CheckOptions) => store.hasRole(codes, options),\n [store],\n );\n\n const can = useCallback(\n (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => store.can(codes, options),\n [store],\n );\n\n return {\n permissions: state.permissions,\n roles: state.roles,\n isSuperAdmin: Boolean(state.isSuperAdmin),\n hasPermission,\n hasRole,\n can,\n setPermissions: store.setPermissions.bind(store),\n setRoles: store.setRoles.bind(store),\n setSuperAdmin: store.setSuperAdmin.bind(store),\n hydrate: store.hydrate.bind(store),\n clear: store.clear.bind(store),\n store,\n };\n}\n\n/** Returns whether the current user has the given permission(s). */\nexport function useHasPermission(\n codes: PermissionCode | PermissionCode[],\n options?: CheckOptions,\n): boolean {\n const { hasPermission, permissions, isSuperAdmin } = usePermission();\n // re-compute when permission list / super-admin changes\n void permissions;\n void isSuperAdmin;\n return hasPermission(codes, options);\n}\n\n/** Returns whether the current user has the given role(s). */\nexport function useHasRole(\n codes: RoleCode | RoleCode[],\n options?: CheckOptions,\n): boolean {\n const { hasRole, roles, isSuperAdmin } = usePermission();\n void roles;\n void isSuperAdmin;\n return hasRole(codes, options);\n}\n","import type {\n CheckOptions,\n MatchMode,\n PermissionCode,\n PermissionListener,\n PermissionState,\n PermissionStoreAPI,\n RoleCode,\n} from './types';\n\nconst DEFAULT_STATE: PermissionState = {\n permissions: [],\n roles: [],\n isSuperAdmin: false,\n};\n\nfunction toArray<T>(value: T | T[]): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nfunction matchCodes(\n owned: Set<string>,\n required: string[],\n mode: MatchMode,\n isSuperAdmin: boolean,\n): boolean {\n if (isSuperAdmin) return true;\n if (required.length === 0) return true;\n\n if (mode === 'all') {\n return required.every((code) => owned.has(code));\n }\n\n return required.some((code) => owned.has(code));\n}\n\n/**\n * Mutable permission store shared by React / Vue adapters.\n * Framework-agnostic — safe to use in Node, browser, or any UI lib.\n */\nexport class PermissionStore implements PermissionStoreAPI {\n private state: PermissionState;\n private permissionSet: Set<string>;\n private roleSet: Set<string>;\n private listeners = new Set<PermissionListener>();\n\n constructor(initial?: Partial<PermissionState>) {\n this.state = {\n ...DEFAULT_STATE,\n ...initial,\n permissions: initial?.permissions ?? [],\n roles: initial?.roles ?? [],\n };\n this.permissionSet = new Set(this.state.permissions);\n this.roleSet = new Set(this.state.roles);\n }\n\n getState(): PermissionState {\n return {\n permissions: [...this.state.permissions],\n roles: [...this.state.roles],\n isSuperAdmin: this.state.isSuperAdmin,\n };\n }\n\n setState(next: Partial<PermissionState>): void {\n this.state = {\n permissions: next.permissions ?? this.state.permissions,\n roles: next.roles ?? this.state.roles,\n isSuperAdmin: next.isSuperAdmin ?? this.state.isSuperAdmin,\n };\n this.permissionSet = new Set(this.state.permissions);\n this.roleSet = new Set(this.state.roles);\n this.emit();\n }\n\n setPermissions(permissions: PermissionCode[]): void {\n this.setState({ permissions });\n }\n\n setRoles(roles: RoleCode[]): void {\n this.setState({ roles });\n }\n\n setSuperAdmin(isSuperAdmin: boolean): void {\n this.setState({ isSuperAdmin });\n }\n\n /** Replace permissions, roles and super-admin flag in one shot (typical after login). */\n hydrate(payload: Partial<PermissionState>): void {\n this.setState({\n permissions: payload.permissions ?? [],\n roles: payload.roles ?? [],\n isSuperAdmin: payload.isSuperAdmin ?? false,\n });\n }\n\n /** Clear all authz data (typical after logout). */\n clear(): void {\n this.hydrate({});\n }\n\n hasPermission(\n codes: PermissionCode | PermissionCode[],\n options: CheckOptions = {},\n ): boolean {\n const mode = options.mode ?? 'any';\n return matchCodes(\n this.permissionSet,\n toArray(codes).filter(Boolean),\n mode,\n Boolean(this.state.isSuperAdmin),\n );\n }\n\n hasRole(codes: RoleCode | RoleCode[], options: CheckOptions = {}): boolean {\n const mode = options.mode ?? 'any';\n return matchCodes(\n this.roleSet,\n toArray(codes).filter(Boolean),\n mode,\n Boolean(this.state.isSuperAdmin),\n );\n }\n\n /** Alias of `hasPermission` for template-friendly APIs. */\n can(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean {\n return this.hasPermission(codes, options);\n }\n\n subscribe(listener: PermissionListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emit(): void {\n const snapshot = this.getState();\n this.listeners.forEach((listener) => listener(snapshot));\n }\n}\n\nexport function createPermissionStore(\n initial?: Partial<PermissionState>,\n): PermissionStoreAPI {\n return new PermissionStore(initial);\n}\n","import type { ReactNode } from 'react';\nimport type { CheckOptions, PermissionCode, RoleCode } from '../core';\nimport { usePermission } from './context';\n\nexport interface CanProps {\n /** Permission codes to check. */\n permission?: PermissionCode | PermissionCode[];\n /** Role codes to check. */\n role?: RoleCode | RoleCode[];\n /**\n * `any` — pass when at least one code matches (default)\n * `all` — pass only when every code matches\n */\n mode?: CheckOptions['mode'];\n /**\n * How permission and role conditions combine when both are provided.\n * Default: `and` (must satisfy both).\n */\n combine?: 'and' | 'or';\n children: ReactNode;\n /** Fallback when access is denied. */\n fallback?: ReactNode;\n}\n\nfunction evaluateAccess(\n hasPermission: (c: PermissionCode | PermissionCode[], o?: CheckOptions) => boolean,\n hasRole: (c: RoleCode | RoleCode[], o?: CheckOptions) => boolean,\n props: Pick<CanProps, 'permission' | 'role' | 'mode' | 'combine'>,\n): boolean {\n const { permission, role, mode, combine = 'and' } = props;\n const options: CheckOptions = { mode };\n\n const hasPermCheck = permission !== undefined;\n const hasRoleCheck = role !== undefined;\n\n if (!hasPermCheck && !hasRoleCheck) return true;\n\n const permOk = hasPermCheck ? hasPermission(permission!, options) : true;\n const roleOk = hasRoleCheck ? hasRole(role!, options) : true;\n\n if (hasPermCheck && hasRoleCheck) {\n return combine === 'or' ? permOk || roleOk : permOk && roleOk;\n }\n\n return hasPermCheck ? permOk : roleOk;\n}\n\n/**\n * Conditionally render children based on permission / role.\n *\n * @example\n * <Can permission=\"user:edit\">\n * <button>Edit</button>\n * </Can>\n *\n * <Can permission={['user:edit', 'user:delete']} mode=\"all\" fallback={null}>\n * <AdminPanel />\n * </Can>\n */\nexport function Can({\n permission,\n role,\n mode,\n combine,\n children,\n fallback = null,\n}: CanProps) {\n const { hasPermission, hasRole } = usePermission();\n const allowed = evaluateAccess(hasPermission, hasRole, {\n permission,\n role,\n mode,\n combine,\n });\n\n return <>{allowed ? children : fallback}</>;\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type FormEvent,\n type ReactNode,\n} from 'react';\nimport {\n RESOURCE_PRIVATE_OPTIONS,\n RESOURCE_STATUS_ENABLED,\n RESOURCE_STATUS_OPTIONS,\n type AuthorizationResource,\n type AuthorizationResourceApi,\n type AuthorizationResourceFormValues,\n type PageDirection,\n} from '../resources';\n\nconst PAGE_SIZE_OPTIONS = ['10', '20', '50', '100'];\n\nconst emptyForm = (): AuthorizationResourceFormValues => ({\n name: '',\n identification: '',\n status: RESOURCE_STATUS_ENABLED,\n private: false,\n description: '',\n});\n\nexport type ResourceManagerProps = {\n api: AuthorizationResourceApi;\n title?: string;\n pageSize?: string;\n /** 自定义顶部右侧操作区 */\n toolbarExtra?: ReactNode;\n};\n\nexport function ResourceManager({\n api,\n title = '权限点管理',\n pageSize: initialPageSize = '20',\n toolbarExtra,\n}: ResourceManagerProps) {\n const [records, setRecords] = useState<AuthorizationResource[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageToken, setPageToken] = useState('');\n const [hasPreviousPage, setHasPreviousPage] = useState(false);\n const [hasNextPage, setHasNextPage] = useState(false);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editing, setEditing] = useState<AuthorizationResource | null>(null);\n const [form, setForm] = useState<AuthorizationResourceFormValues>(emptyForm);\n const [saving, setSaving] = useState(false);\n const [deletingRow, setDeletingRow] = useState<AuthorizationResource | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const loadList = useCallback(\n async (direction: PageDirection = 'current', token = pageToken) => {\n setLoading(true);\n setError('');\n try {\n const result = await api.list({\n pagination: {\n pageToken: token,\n pageSize,\n pageDirection: direction,\n },\n });\n setRecords(result.records);\n setPageToken(result.pageToken);\n setHasPreviousPage(result.hasPreviousPage);\n setHasNextPage(result.hasNextPage);\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载失败');\n } finally {\n setLoading(false);\n }\n },\n [api, pageSize, pageToken],\n );\n\n useEffect(() => {\n void loadList('current', '');\n // 仅 pageSize / api 变化时重置首页\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, pageSize]);\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm());\n setDialogOpen(true);\n };\n\n const openEdit = (row: AuthorizationResource) => {\n setEditing(row);\n setForm({\n name: row.name,\n identification: row.identification,\n status: row.status,\n private: row.private,\n description: row.description,\n });\n setDialogOpen(true);\n };\n\n const closeDialog = () => {\n if (saving) return;\n setDialogOpen(false);\n };\n\n const handleSubmit = async (event: FormEvent) => {\n event.preventDefault();\n if (!form.name.trim()) {\n setError('请填写权限名称');\n return;\n }\n if (!form.identification.trim()) {\n setError('请填写接口标识');\n return;\n }\n\n setSaving(true);\n setError('');\n try {\n if (editing) {\n await api.update(editing.resourceId, form);\n } else {\n await api.create(form);\n }\n setDialogOpen(false);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '保存失败');\n } finally {\n setSaving(false);\n }\n };\n\n const askDelete = (row: AuthorizationResource) => {\n setDeletingRow(row);\n };\n\n const closeDeleteDialog = () => {\n if (deleting) return;\n setDeletingRow(null);\n };\n\n const confirmDelete = async () => {\n if (!deletingRow) return;\n setDeleting(true);\n setError('');\n try {\n await api.remove(deletingRow.resourceId);\n setDeletingRow(null);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '删除失败');\n } finally {\n setDeleting(false);\n }\n };\n\n const statusLabel = useMemo(\n () =>\n Object.fromEntries(RESOURCE_STATUS_OPTIONS.map((o) => [o.value, o.label])) as Record<\n number,\n string\n >,\n [],\n );\n\n return (\n <div style={styles.root}>\n <div style={styles.toolbar}>\n <h2 style={styles.title}>{title}</h2>\n <div style={styles.toolbarRight}>\n {toolbarExtra}\n <button type=\"button\" style={styles.primaryBtn} onClick={openCreate}>\n 新增\n </button>\n </div>\n </div>\n\n {error ? <div style={styles.error}>{error}</div> : null}\n\n <div style={styles.tableWrap}>\n <table style={styles.table}>\n <thead>\n <tr>\n <th style={styles.th}>权限名称</th>\n <th style={styles.th}>接口标识</th>\n <th style={styles.th}>描述</th>\n <th style={{ ...styles.th, width: 90 }}>状态</th>\n <th style={{ ...styles.th, width: 140 }}>操作</th>\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={5} style={styles.empty}>\n 加载中…\n </td>\n </tr>\n ) : records.length === 0 ? (\n <tr>\n <td colSpan={5} style={styles.empty}>\n 暂无数据\n </td>\n </tr>\n ) : (\n records.map((row) => (\n <tr key={row.resourceId}>\n <td style={styles.td}>{row.name}</td>\n <td style={styles.td}>\n <code style={styles.code}>{row.identification}</code>\n </td>\n <td style={styles.td}>{row.description || '—'}</td>\n <td style={styles.td}>\n <span\n style={{\n ...styles.badge,\n background:\n row.status === RESOURCE_STATUS_ENABLED ? '#e8f7ef' : '#f4f4f5',\n color: row.status === RESOURCE_STATUS_ENABLED ? '#067647' : '#667085',\n }}\n >\n {statusLabel[row.status] ?? row.status}\n </span>\n </td>\n <td style={styles.td}>\n <button type=\"button\" style={styles.linkBtn} onClick={() => openEdit(row)}>\n 编辑\n </button>\n <button\n type=\"button\"\n style={{ ...styles.linkBtn, color: '#d92d20' }}\n onClick={() => askDelete(row)}\n >\n 删除\n </button>\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div style={styles.pagination}>\n <label style={styles.pageSize}>\n 每页\n <select\n value={pageSize}\n onChange={(e) => {\n setPageToken('');\n setPageSize(e.target.value);\n }}\n style={styles.select}\n >\n {PAGE_SIZE_OPTIONS.map((size) => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </label>\n <div style={styles.pageBtns}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasPreviousPage || loading}\n onClick={() => void loadList('previous')}\n >\n 上一页\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasNextPage || loading}\n onClick={() => void loadList('next')}\n >\n 下一页\n </button>\n </div>\n </div>\n\n {dialogOpen ? (\n <div style={styles.mask} onClick={closeDialog}>\n <div\n style={styles.dialog}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>{editing ? '编辑权限点' : '新增权限点'}</h3>\n <button type=\"button\" style={styles.iconBtn} onClick={closeDialog} aria-label=\"关闭\">\n ×\n </button>\n </div>\n <form style={styles.form} onSubmit={(e) => void handleSubmit(e)}>\n <label style={styles.field}>\n <span style={styles.label}>权限名称</span>\n <input\n style={styles.input}\n value={form.name}\n onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}\n placeholder=\"请输入权限名称\"\n required\n />\n </label>\n <label style={styles.field}>\n <span style={styles.label}>接口标识</span>\n <input\n style={styles.input}\n value={form.identification}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, identification: e.target.value }))\n }\n placeholder=\"如 user:list\"\n required\n />\n </label>\n <label style={styles.field}>\n <span style={styles.label}>状态</span>\n <select\n style={styles.input}\n value={form.status}\n onChange={(e) =>\n setForm((prev) => ({\n ...prev,\n status: Number(e.target.value) as 0 | 1,\n }))\n }\n >\n {RESOURCE_STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n <label style={styles.field}>\n <span style={styles.label}>私有资源</span>\n <select\n style={styles.input}\n value={form.private ? '1' : '0'}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, private: e.target.value === '1' }))\n }\n >\n {RESOURCE_PRIVATE_OPTIONS.map((opt) => (\n <option key={String(opt.value)} value={opt.value ? '1' : '0'}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n <label style={styles.field}>\n <span style={styles.label}>描述</span>\n <textarea\n style={{ ...styles.input, minHeight: 88, resize: 'vertical' }}\n value={form.description}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, description: e.target.value }))\n }\n placeholder=\"请输入描述\"\n />\n </label>\n <div style={styles.dialogFooter}>\n <button type=\"button\" style={styles.secondaryBtn} onClick={closeDialog}>\n 取消\n </button>\n <button type=\"submit\" style={styles.primaryBtn} disabled={saving}>\n {saving ? '保存中…' : '保存'}\n </button>\n </div>\n </form>\n </div>\n </div>\n ) : null}\n\n {deletingRow ? (\n <div style={styles.mask} onClick={closeDeleteDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 420 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"angel-auth-delete-title\"\n >\n <div style={styles.dialogHeader}>\n <h3 id=\"angel-auth-delete-title\" style={styles.dialogTitle}>\n 确认删除\n </h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeDeleteDialog}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.confirmBody}>\n <p style={styles.confirmText}>\n 确认删除权限点「<strong>{deletingRow.name}</strong>」吗?删除后不可恢复。\n </p>\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeDeleteDialog}\n disabled={deleting}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.dangerBtn}\n onClick={() => void confirmDelete()}\n disabled={deleting}\n >\n {deleting ? '删除中…' : '确认删除'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n padding: 16,\n color: '#101828',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n title: { margin: 0, fontSize: 18, fontWeight: 600 },\n toolbarRight: { display: 'flex', alignItems: 'center', gap: 8 },\n error: {\n padding: '10px 12px',\n borderRadius: 8,\n background: '#fef3f2',\n color: '#b42318',\n fontSize: 13,\n },\n tableWrap: {\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 10,\n background: '#fff',\n },\n table: { width: '100%', borderCollapse: 'collapse', minWidth: 720 },\n th: {\n textAlign: 'left',\n padding: '12px 14px',\n fontSize: 13,\n fontWeight: 600,\n color: '#475467',\n background: '#f9fafb',\n borderBottom: '1px solid #eaecf0',\n },\n td: {\n padding: '12px 14px',\n fontSize: 14,\n borderBottom: '1px solid #f2f4f7',\n verticalAlign: 'middle',\n },\n empty: {\n padding: 28,\n textAlign: 'center',\n color: '#98a2b3',\n fontSize: 14,\n },\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 13,\n background: '#f2f4f7',\n padding: '2px 6px',\n borderRadius: 4,\n },\n badge: {\n display: 'inline-block',\n padding: '2px 8px',\n borderRadius: 999,\n fontSize: 12,\n fontWeight: 500,\n },\n linkBtn: {\n border: 'none',\n background: 'transparent',\n color: '#049BAD',\n cursor: 'pointer',\n padding: '0 8px 0 0',\n fontSize: 13,\n },\n pagination: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n pageSize: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#475467' },\n pageBtns: { display: 'flex', gap: 8 },\n primaryBtn: {\n border: 'none',\n background: '#049BAD',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n secondaryBtn: {\n border: '1px solid #d0d5dd',\n background: '#fff',\n color: '#344054',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n dangerBtn: {\n border: 'none',\n background: '#d92d20',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n select: {\n border: '1px solid #d0d5dd',\n borderRadius: 6,\n padding: '4px 8px',\n fontSize: 13,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n mask: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(16, 24, 40, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n padding: 16,\n },\n dialog: {\n width: '100%',\n maxWidth: 480,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 20px 40px rgba(16,24,40,0.18)',\n },\n dialogHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 16px',\n borderBottom: '1px solid #eaecf0',\n },\n dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },\n iconBtn: {\n border: 'none',\n background: 'transparent',\n fontSize: 22,\n lineHeight: 1,\n cursor: 'pointer',\n color: '#667085',\n },\n form: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n confirmBody: { display: 'flex', flexDirection: 'column', gap: 16, padding: 16 },\n confirmText: { margin: 0, fontSize: 14, color: '#344054', lineHeight: 1.6 },\n field: { display: 'flex', flexDirection: 'column', gap: 6 },\n label: { fontSize: 13, color: '#344054', fontWeight: 500 },\n input: {\n border: '1px solid #d0d5dd',\n borderRadius: 8,\n padding: '8px 10px',\n fontSize: 14,\n outline: 'none',\n backgroundColor: '#ffffff',\n color: '#101828',\n boxSizing: 'border-box',\n width: '100%',\n },\n dialogFooter: {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n paddingTop: 4,\n },\n};\n","export type PageDirection = 'previous' | 'current' | 'next';\n\nexport type ListPaginationParams = {\n pageToken?: string;\n pageSize?: string;\n pageDirection?: PageDirection;\n};\n\nexport type ListPaginationResult = {\n pageToken: string;\n hasPreviousPage: boolean;\n hasNextPage: boolean;\n};\n\n/** 通用状态:权限点 1 启用 / 0 禁用;菜单 1 显示 / 0 隐藏 */\nexport type ResourceStatus = 0 | 1;\n\n/** 权限点类型 */\nexport type ApiResourceType = 'api';\n\n/** 菜单资源类型 */\nexport type MenuResourceType = 'page' | 'menu' | 'button';\n\nexport type ResourceType = ApiResourceType | MenuResourceType;\n\nexport type AuthorizationResource = {\n resourceId: string;\n type: ApiResourceType;\n name: string;\n identification: string;\n status: ResourceStatus;\n private: boolean;\n description: string;\n};\n\nexport type AuthorizationResourceFormValues = {\n name: string;\n identification: string;\n status: ResourceStatus;\n private: boolean;\n description: string;\n};\n\nexport type CreateAuthorizationResourceBody = AuthorizationResourceFormValues & {\n resourceId: string;\n type: ApiResourceType;\n};\n\nexport type UpdateAuthorizationResourceBody = Partial<AuthorizationResourceFormValues> & {\n type?: ApiResourceType;\n};\n\nexport type FetchAuthorizationResourcesParams = {\n pagination?: ListPaginationParams;\n};\n\nexport type AuthorizationResourceListResult = {\n records: AuthorizationResource[];\n pageToken: string;\n hasPreviousPage: boolean;\n hasNextPage: boolean;\n};\n\nexport type MenuResource = {\n resourceId: string;\n /** 上级菜单 ID;无上级时为 null */\n parentId: string | null;\n /**\n * 菜单层级:无上级(根)为 1,其余为上级 depth + 1\n */\n depth: number;\n /**\n * 是否叶子节点:`1` 表示无下级菜单,不可再展开\n */\n leaf: number;\n type: MenuResourceType;\n name: string;\n identification: string;\n permissionPointIds: string[];\n /** 关联权限点名称(列表展示用,后端可能返回) */\n permissionPointNames?: string[];\n status: ResourceStatus;\n};\n\nexport type MenuResourceFormValues = {\n /** 上级菜单 ID;选择「无」时为 null */\n parentId: string | null;\n /** 由 parentId 自动计算:无为 1,否则上级 depth + 1 */\n depth: number;\n type: MenuResourceType;\n name: string;\n identification: string;\n permissionPointIds: string[];\n status: ResourceStatus;\n};\n\nexport type CreateMenuResourceBody = MenuResourceFormValues & {\n resourceId: string;\n};\n\nexport type UpdateMenuResourceBody = Partial<MenuResourceFormValues>;\n\nexport type FetchMenuResourcesParams = {\n /** 列表默认传 1,只拉根层 */\n depth?: number;\n pagination?: ListPaginationParams;\n};\n\nexport type MenuResourceListResult = {\n records: MenuResource[];\n pageToken: string;\n hasPreviousPage: boolean;\n hasNextPage: boolean;\n};\n\n/** leaf === 1 表示无下级 */\nexport const MENU_LEAF_YES = 1;\nexport const MENU_LEAF_NO = 0;\n\nexport const RESOURCE_TYPE_API: ApiResourceType = 'api';\nexport const MENU_TYPE_PAGE: MenuResourceType = 'page';\nexport const MENU_TYPE_MENU: MenuResourceType = 'menu';\nexport const MENU_TYPE_BUTTON: MenuResourceType = 'button';\n\n/** 菜单列表查询 type 参数 */\nexport const MENU_LIST_TYPE_PARAM = 'page,menu,button';\n\n/**\n * 上级菜单选择「无」时,表单 select 使用的空值。\n * 提交接口时会转换为 parentId: null。\n */\nexport const ROOT_PARENT_ID = '';\n\n/** 无上级时的菜单层级 */\nexport const ROOT_MENU_DEPTH = 1;\n\nexport const RESOURCE_STATUS_ENABLED: ResourceStatus = 1;\nexport const RESOURCE_STATUS_DISABLED: ResourceStatus = 0;\n\nexport const RESOURCE_STATUS_OPTIONS: { label: string; value: ResourceStatus }[] = [\n { label: '启用', value: RESOURCE_STATUS_ENABLED },\n { label: '禁用', value: RESOURCE_STATUS_DISABLED },\n];\n\n/** 菜单可见性 */\nexport const MENU_VISIBILITY_OPTIONS: { label: string; value: ResourceStatus }[] = [\n { label: '显示', value: RESOURCE_STATUS_ENABLED },\n { label: '隐藏', value: RESOURCE_STATUS_DISABLED },\n];\n\nexport const RESOURCE_PRIVATE_OPTIONS: { label: string; value: boolean }[] = [\n { label: '是', value: true },\n { label: '否', value: false },\n];\n\nexport const MENU_TYPE_OPTIONS: { label: string; value: MenuResourceType }[] = [\n { label: '目录', value: MENU_TYPE_PAGE },\n { label: '菜单', value: MENU_TYPE_MENU },\n { label: '按钮', value: MENU_TYPE_BUTTON },\n];\n\nexport const MENU_TYPE_LABEL: Record<MenuResourceType, string> = {\n page: '目录',\n menu: '菜单',\n button: '按钮',\n};\n","const DEVICE_WORKER_ID_KEY = 'hgams_device_worker_id';\n\nfunction generateDeviceWorkerId(): bigint {\n const cached = localStorage.getItem(DEVICE_WORKER_ID_KEY);\n if (cached !== null && cached !== '') {\n return BigInt(cached);\n }\n\n const components = [\n navigator.userAgent,\n screen.width + 'x' + screen.height,\n screen.colorDepth,\n navigator.language,\n new Date().getTimezoneOffset(),\n navigator.hardwareConcurrency,\n (navigator as Navigator & { deviceMemory?: number }).deviceMemory,\n ];\n\n const fingerprint = components.join('|');\n\n let hash = 0;\n for (let i = 0; i < fingerprint.length; i++) {\n hash = (hash << 5) - hash + fingerprint.charCodeAt(i);\n hash |= 0;\n }\n\n const maxWorkerId = Math.pow(2, 14) - 1;\n const workerId = Math.abs(hash % maxWorkerId);\n const workerIdBigInt = BigInt(workerId);\n localStorage.setItem(DEVICE_WORKER_ID_KEY, workerIdBigInt.toString());\n return workerIdBigInt;\n}\n\ninterface SnowyflakeOptions {\n epoch?: bigint;\n workerId?: bigint;\n processId?: bigint;\n workerIdBits?: number;\n processIdBits?: number;\n sequenceBits?: number;\n}\n\n/**\n * snowyflake 2.0.1 仅支持固定 5+5+12 位布局,此处按相同 nextId 算法实现可配置位数版本。\n */\nclass ConfigurableSnowflake {\n readonly epoch: bigint;\n readonly workerId: bigint;\n readonly processId: bigint;\n\n private readonly sequenceMask: bigint;\n private readonly timestampLeftShift: bigint;\n private readonly workerIdShift: bigint;\n private readonly processIdShift: bigint;\n private sequence = 0n;\n private latestTimestamp = BigInt(Date.now());\n\n constructor({\n epoch = 0n,\n workerId = 0n,\n processId = 0n,\n workerIdBits = 5,\n processIdBits = 5,\n sequenceBits = 12,\n }: SnowyflakeOptions = {}) {\n this.epoch = epoch;\n\n const workerIdBitsBig = BigInt(workerIdBits);\n const processIdBitsBig = BigInt(processIdBits);\n const sequenceBitsBig = BigInt(sequenceBits);\n const workerIdMask = -1n ^ (-1n << workerIdBitsBig);\n const processIdMask = -1n ^ (-1n << processIdBitsBig);\n\n this.sequenceMask = -1n ^ (-1n << sequenceBitsBig);\n this.timestampLeftShift =\n sequenceBitsBig + workerIdBitsBig + processIdBitsBig;\n this.workerIdShift = sequenceBitsBig + processIdBitsBig;\n this.processIdShift = sequenceBitsBig;\n\n this.workerId = workerId & workerIdMask;\n this.processId = processId & processIdMask;\n }\n\n nextId(): bigint {\n const timestamp = BigInt(Date.now());\n\n if (this.latestTimestamp === timestamp) {\n this.sequence = (this.sequence + 1n) & this.sequenceMask;\n } else {\n this.sequence = 0n;\n this.latestTimestamp = timestamp;\n }\n\n return (\n ((timestamp - this.epoch) << this.timestampLeftShift) |\n (this.workerId << this.workerIdShift) |\n (this.processId << this.processIdShift) |\n this.sequence\n );\n }\n}\n\n/** 应用级单例,模块加载时只初始化一次(不受 React StrictMode 重复 mount 影响) */\nexport const snowyflake = new ConfigurableSnowflake({\n workerId: generateDeviceWorkerId(),\n workerIdBits: 14,\n processIdBits: 0,\n sequenceBits: 8,\n epoch: BigInt(new Date('2026-06-08').getTime()),\n});\n\n/** 生成雪花 ID 字符串(reportId、detailId、resourceId 等) */\nexport function getAppClientId(): string {\n return snowyflake.nextId().toString();\n}\n\nexport function getDeviceWorkerId(): string {\n return snowyflake.workerId.toString();\n}\n","import type { ListPaginationResult } from './types';\n\nexport function appendQueryParam(parts: string[], key: string, value: string): void {\n if (value !== undefined && value !== null && String(value) !== '') {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n }\n}\n\nexport function extractPagination(payload: unknown): ListPaginationResult {\n if (!payload || typeof payload !== 'object') {\n return {\n pageToken: '',\n hasPreviousPage: false,\n hasNextPage: false,\n };\n }\n\n const envelope = payload as Record<string, unknown>;\n const pagination = (\n envelope.pagination && typeof envelope.pagination === 'object'\n ? envelope.pagination\n : envelope.page && typeof envelope.page === 'object'\n ? envelope.page\n : null\n ) as Record<string, unknown> | null;\n\n const rawPageToken =\n pagination?.['page-token'] ??\n pagination?.pageToken ??\n pagination?.nextPageToken ??\n envelope['page-token'] ??\n envelope.pageToken ??\n '';\n const pageToken =\n rawPageToken === undefined || rawPageToken === null ? '' : String(rawPageToken);\n\n const hasPreviousPage = Boolean(\n pagination?.hasPreviousPage ??\n pagination?.hasPrevious ??\n pagination?.hasPre ??\n pagination?.previous ??\n envelope.hasPreviousPage ??\n envelope.hasPrevious,\n );\n const hasNextPage = Boolean(\n pagination?.hasNextPage ??\n pagination?.hasNext ??\n pagination?.next ??\n envelope.hasNextPage ??\n envelope.hasNext,\n );\n\n return {\n pageToken,\n hasPreviousPage,\n hasNextPage,\n };\n}\n\nexport function extractRecords(payload: unknown): unknown[] {\n if (!payload) return [];\n if (Array.isArray(payload)) return payload;\n\n if (typeof payload === 'object') {\n const envelope = payload as Record<string, unknown>;\n const data = envelope.data;\n\n if (Array.isArray(data)) return data;\n\n if (data && typeof data === 'object') {\n const nested = data as Record<string, unknown>;\n if (Array.isArray(nested.records)) return nested.records;\n if (Array.isArray(nested.items)) return nested.items;\n if (Array.isArray(nested.list)) return nested.list;\n if (Array.isArray(nested.content)) return nested.content;\n }\n\n if (Array.isArray(envelope.records)) return envelope.records;\n if (Array.isArray(envelope.items)) return envelope.items;\n if (Array.isArray(envelope.list)) return envelope.list;\n if (Array.isArray(envelope.content)) return envelope.content;\n }\n\n return [];\n}\n","import { getAppClientId } from '../utils/snowflake';\nimport { appendQueryParam, extractPagination, extractRecords } from './pagination';\nimport {\n MENU_LIST_TYPE_PARAM,\n MENU_LEAF_YES,\n MENU_TYPE_BUTTON,\n MENU_TYPE_MENU,\n MENU_TYPE_PAGE,\n RESOURCE_STATUS_DISABLED,\n RESOURCE_STATUS_ENABLED,\n RESOURCE_TYPE_API,\n ROOT_MENU_DEPTH,\n type AuthorizationResource,\n type AuthorizationResourceFormValues,\n type AuthorizationResourceListResult,\n type CreateAuthorizationResourceBody,\n type CreateMenuResourceBody,\n type FetchAuthorizationResourcesParams,\n type FetchMenuResourcesParams,\n type MenuResource,\n type MenuResourceFormValues,\n type MenuResourceListResult,\n type MenuResourceType,\n type ResourceStatus,\n type UpdateAuthorizationResourceBody,\n type UpdateMenuResourceBody,\n} from './types';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE';\n\nexport type ResourceRequestOptions = {\n method: HttpMethod;\n url: string;\n body?: unknown;\n signal?: AbortSignal;\n};\n\n/**\n * 由宿主应用注入的请求函数(可对接 Angel_HGAMS 的 apiGetJson / apiPostJson 等)。\n */\nexport type ResourceHttpRequest = <T = unknown>(\n options: ResourceRequestOptions,\n) => Promise<T>;\n\nexport type AuthorizationResourceApi = {\n list: (\n params?: FetchAuthorizationResourcesParams,\n signal?: AbortSignal,\n ) => Promise<AuthorizationResourceListResult>;\n create: (\n values: AuthorizationResourceFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n update: (\n resourceId: string,\n values: AuthorizationResourceFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n remove: (resourceId: string, signal?: AbortSignal) => Promise<unknown>;\n};\n\nexport type MenuResourceApi = {\n list: (\n params?: FetchMenuResourcesParams,\n signal?: AbortSignal,\n ) => Promise<MenuResourceListResult>;\n /** 展开下级:GET /authorization-resources/{resource-id}/sub-resources */\n listSubResources: (\n resourceId: string,\n signal?: AbortSignal,\n ) => Promise<MenuResource[]>;\n /** 拉取权限点(type=api),供菜单表单多选 */\n listPermissionPoints: (\n params?: FetchAuthorizationResourcesParams,\n signal?: AbortSignal,\n ) => Promise<AuthorizationResourceListResult>;\n create: (values: MenuResourceFormValues, signal?: AbortSignal) => Promise<unknown>;\n update: (\n resourceId: string,\n values: MenuResourceFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n remove: (resourceId: string, signal?: AbortSignal) => Promise<unknown>;\n};\n\nfunction toResourceStatus(value: unknown): ResourceStatus {\n const n = Number(value);\n return n === RESOURCE_STATUS_ENABLED ? RESOURCE_STATUS_ENABLED : RESOURCE_STATUS_DISABLED;\n}\n\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'number') return value !== 0;\n if (typeof value === 'string') {\n const v = value.trim().toLowerCase();\n return v === 'true' || v === '1' || v === 'yes' || v === '是';\n }\n return false;\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value\n .map((item) => {\n if (item && typeof item === 'object') {\n const row = item as Record<string, unknown>;\n const id = row.resourceId ?? row.resource_id ?? row.id;\n return id === undefined || id === null ? '' : String(id);\n }\n return String(item ?? '');\n })\n .filter(Boolean);\n }\n if (typeof value === 'string' && value.trim()) {\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n }\n return [];\n}\n\nfunction toMenuType(value: unknown): MenuResourceType {\n const v = String(value ?? '').toLowerCase();\n if (v === MENU_TYPE_PAGE || v === MENU_TYPE_MENU || v === MENU_TYPE_BUTTON) {\n return v;\n }\n return MENU_TYPE_MENU;\n}\n\nexport function mapAuthorizationResource(item: unknown): AuthorizationResource | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const resourceId = row.resourceId ?? row.resource_id ?? row.id;\n if (resourceId === undefined || resourceId === null || resourceId === '') return null;\n\n return {\n resourceId: String(resourceId),\n type: RESOURCE_TYPE_API,\n name: String(row.name ?? ''),\n identification: String(row.identification ?? row.identity ?? ''),\n status: toResourceStatus(row.status),\n private: toBoolean(row.private ?? row.isPrivate ?? row.is_private),\n description: String(row.description ?? row.desc ?? ''),\n };\n}\n\nexport function mapMenuResource(item: unknown): MenuResource | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const resourceId = row.resourceId ?? row.resource_id ?? row.id;\n if (resourceId === undefined || resourceId === null || resourceId === '') return null;\n\n const permissionPointIds = toStringArray(\n row.permissionPointIds ??\n row.permission_point_ids ??\n row.permissionPoints ??\n row.permissions,\n );\n\n const permissionNamesRaw =\n row.permissionPointNames ?? row.permission_point_names ?? row.permissionNames;\n const permissionPointNames = Array.isArray(permissionNamesRaw)\n ? permissionNamesRaw.map((n) => String(n ?? '')).filter(Boolean)\n : undefined;\n\n const rawParentId = row.parentId ?? row.parent_id;\n const parentId =\n rawParentId === undefined ||\n rawParentId === null ||\n rawParentId === '' ||\n String(rawParentId) === '0'\n ? null\n : String(rawParentId);\n\n const rawDepth = row.depth;\n const parsedDepth = Number(rawDepth);\n const depth =\n Number.isFinite(parsedDepth) && parsedDepth > 0\n ? Math.floor(parsedDepth)\n : parentId\n ? ROOT_MENU_DEPTH + 1\n : ROOT_MENU_DEPTH;\n\n const rawLeaf = row.leaf;\n const leaf =\n rawLeaf === true ||\n rawLeaf === 1 ||\n rawLeaf === '1' ||\n String(rawLeaf).toLowerCase() === 'true'\n ? MENU_LEAF_YES\n : Number(rawLeaf) === MENU_LEAF_YES\n ? MENU_LEAF_YES\n : 0;\n\n return {\n resourceId: String(resourceId),\n parentId,\n depth,\n leaf,\n type: toMenuType(row.type),\n name: String(row.name ?? ''),\n identification: String(row.identification ?? row.identity ?? row.path ?? ''),\n permissionPointIds,\n permissionPointNames,\n status: toResourceStatus(row.status),\n };\n}\n\n/**\n * leaf === 1 表示无下级菜单。\n */\nexport function isMenuLeaf(row: Pick<MenuResource, 'leaf'>): boolean {\n return Number(row.leaf) === MENU_LEAF_YES;\n}\n\n/**\n * 根据上级菜单计算 depth:无上级为 1,否则为上级 depth + 1。\n */\nexport function resolveMenuDepth(\n parentId: string | null | undefined,\n menus: Array<Pick<MenuResource, 'resourceId' | 'depth'>>,\n): number {\n if (!parentId) return ROOT_MENU_DEPTH;\n const parent = menus.find((item) => item.resourceId === parentId);\n const parentDepth =\n parent && Number.isFinite(parent.depth) && parent.depth > 0\n ? Math.floor(parent.depth)\n : ROOT_MENU_DEPTH;\n return parentDepth + 1;\n}\n\nfunction buildListUrl(\n type: string,\n params?: {\n pagination?: FetchAuthorizationResourcesParams['pagination'];\n depth?: number | string;\n },\n): string {\n const parts: string[] = [];\n appendQueryParam(parts, 'type', type);\n if (params?.depth !== undefined && params?.depth !== null && String(params.depth) !== '') {\n appendQueryParam(parts, 'depth', String(params.depth));\n }\n appendQueryParam(parts, 'page-token', params?.pagination?.pageToken ?? '');\n appendQueryParam(parts, 'page-size', params?.pagination?.pageSize ?? '20');\n appendQueryParam(parts, 'page-direction', params?.pagination?.pageDirection ?? 'current');\n return `/authorization-resources?${parts.join('&')}`;\n}\n\nexport function buildCreateBody(\n values: AuthorizationResourceFormValues,\n resourceId = getAppClientId(),\n): CreateAuthorizationResourceBody {\n return {\n resourceId,\n type: RESOURCE_TYPE_API,\n name: values.name.trim(),\n identification: values.identification.trim(),\n status: values.status,\n private: values.private,\n description: values.description.trim(),\n };\n}\n\nexport function buildUpdateBody(\n values: AuthorizationResourceFormValues,\n): UpdateAuthorizationResourceBody {\n return {\n type: RESOURCE_TYPE_API,\n name: values.name.trim(),\n identification: values.identification.trim(),\n status: values.status,\n private: values.private,\n description: values.description.trim(),\n };\n}\n\nexport function buildCreateMenuBody(\n values: MenuResourceFormValues,\n resourceId = getAppClientId(),\n): CreateMenuResourceBody {\n const parentId = values.parentId ? values.parentId : null;\n return {\n resourceId,\n parentId,\n depth: values.depth > 0 ? Math.floor(values.depth) : parentId ? ROOT_MENU_DEPTH + 1 : ROOT_MENU_DEPTH,\n type: values.type,\n name: values.name.trim(),\n identification: values.identification.trim(),\n permissionPointIds: [...values.permissionPointIds],\n status: values.status,\n };\n}\n\nexport function buildUpdateMenuBody(values: MenuResourceFormValues): UpdateMenuResourceBody {\n const parentId = values.parentId ? values.parentId : null;\n return {\n parentId,\n depth: values.depth > 0 ? Math.floor(values.depth) : parentId ? ROOT_MENU_DEPTH + 1 : ROOT_MENU_DEPTH,\n type: values.type,\n name: values.name.trim(),\n identification: values.identification.trim(),\n permissionPointIds: [...values.permissionPointIds],\n status: values.status,\n };\n}\n\nexport function createAuthorizationResourceApi(\n request: ResourceHttpRequest,\n): AuthorizationResourceApi {\n return {\n async list(params, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: buildListUrl(RESOURCE_TYPE_API, params),\n signal,\n });\n const records = extractRecords(json)\n .map(mapAuthorizationResource)\n .filter((item): item is AuthorizationResource => item !== null);\n const pagination = extractPagination(json);\n return {\n records,\n ...pagination,\n };\n },\n\n async create(values, signal) {\n return request({\n method: 'POST',\n url: '/authorization-resources',\n body: buildCreateBody(values),\n signal,\n });\n },\n\n async update(resourceId, values, signal) {\n return request({\n method: 'PATCH',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n body: buildUpdateBody(values),\n signal,\n });\n },\n\n async remove(resourceId, signal) {\n return request({\n method: 'DELETE',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n signal,\n });\n },\n };\n}\n\nexport function createMenuResourceApi(request: ResourceHttpRequest): MenuResourceApi {\n const permissionApi = createAuthorizationResourceApi(request);\n\n return {\n async list(params, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: buildListUrl(MENU_LIST_TYPE_PARAM, {\n pagination: params?.pagination,\n depth: params?.depth ?? ROOT_MENU_DEPTH,\n }),\n signal,\n });\n const records = extractRecords(json)\n .map(mapMenuResource)\n .filter((item): item is MenuResource => item !== null);\n const pagination = extractPagination(json);\n return {\n records,\n ...pagination,\n };\n },\n\n async listSubResources(resourceId, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}/sub-resources`,\n signal,\n });\n return extractRecords(json)\n .map(mapMenuResource)\n .filter((item): item is MenuResource => item !== null);\n },\n\n listPermissionPoints(params, signal) {\n return permissionApi.list(params, signal);\n },\n\n async create(values, signal) {\n return request({\n method: 'POST',\n url: '/authorization-resources',\n body: buildCreateMenuBody(values),\n signal,\n });\n },\n\n async update(resourceId, values, signal) {\n return request({\n method: 'PATCH',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n body: buildUpdateMenuBody(values),\n signal,\n });\n },\n\n async remove(resourceId, signal) {\n return request({\n method: 'DELETE',\n url: `/authorization-resources/${encodeURIComponent(resourceId)}`,\n signal,\n });\n },\n };\n}\n\nexport type CreateDefaultResourceRequestOptions = {\n /** API 前缀,如 `/api` 或完整域名 */\n baseUrl?: string;\n /** 追加请求头(如 Authorization) */\n getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n credentials?: RequestCredentials;\n};\n\n/**\n * 基于 fetch 的默认请求实现,便于快速接入。\n * 生产环境建议注入宿主应用已有的 request 封装。\n */\nexport function createDefaultResourceRequest(\n options: CreateDefaultResourceRequestOptions = {},\n): ResourceHttpRequest {\n const baseUrl = (options.baseUrl ?? '').replace(/\\/+$/, '');\n const credentials = options.credentials ?? 'include';\n\n return async function request<T = unknown>({\n method,\n url,\n body,\n signal,\n }: ResourceRequestOptions): Promise<T> {\n const path = url.startsWith('http') ? url : `${baseUrl}${url.startsWith('/') ? url : `/${url}`}`;\n const headers: Record<string, string> = {\n Accept: 'application/json',\n ...(await options.getHeaders?.()),\n };\n\n let payload: BodyInit | undefined;\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n payload = JSON.stringify(body);\n }\n\n const response = await fetch(path, {\n method,\n headers,\n body: payload,\n credentials,\n signal,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(text || `HTTP ${response.status}`);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) return undefined as T;\n return JSON.parse(text) as T;\n };\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type FormEvent,\n type ReactNode,\n} from 'react';\nimport {\n MENU_TYPE_LABEL,\n MENU_TYPE_MENU,\n MENU_TYPE_OPTIONS,\n MENU_VISIBILITY_OPTIONS,\n RESOURCE_STATUS_ENABLED,\n ROOT_MENU_DEPTH,\n ROOT_PARENT_ID,\n isMenuLeaf,\n resolveMenuDepth,\n type AuthorizationResource,\n type MenuResource,\n type MenuResourceApi,\n type MenuResourceFormValues,\n type MenuResourceType,\n type PageDirection,\n} from '../resources';\n\nconst PAGE_SIZE_OPTIONS = ['10', '20', '50', '100'];\n\nconst emptyForm = (): MenuResourceFormValues => ({\n parentId: null,\n depth: ROOT_MENU_DEPTH,\n type: MENU_TYPE_MENU,\n name: '',\n identification: '',\n permissionPointIds: [],\n status: RESOURCE_STATUS_ENABLED,\n});\n\nexport type MenuManagerProps = {\n api: MenuResourceApi;\n title?: string;\n pageSize?: string;\n toolbarExtra?: ReactNode;\n};\n\nexport function MenuManager({\n api,\n title = '菜单管理',\n pageSize: initialPageSize = '20',\n toolbarExtra,\n}: MenuManagerProps) {\n const [records, setRecords] = useState<MenuResource[]>([]);\n const [childrenMap, setChildrenMap] = useState<Record<string, MenuResource[]>>({});\n const [expandedIds, setExpandedIds] = useState<Record<string, boolean>>({});\n const [expandingIds, setExpandingIds] = useState<Record<string, boolean>>({});\n const [permissionPoints, setPermissionPoints] = useState<AuthorizationResource[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageToken, setPageToken] = useState('');\n const [hasPreviousPage, setHasPreviousPage] = useState(false);\n const [hasNextPage, setHasNextPage] = useState(false);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editing, setEditing] = useState<MenuResource | null>(null);\n const [form, setForm] = useState<MenuResourceFormValues>(emptyForm);\n const [saving, setSaving] = useState(false);\n const [deletingRow, setDeletingRow] = useState<MenuResource | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const permissionNameMap = useMemo(() => {\n const map = new Map<string, string>();\n permissionPoints.forEach((p) => map.set(p.resourceId, p.name || p.identification));\n return map;\n }, [permissionPoints]);\n\n const allKnownMenus = useMemo(() => {\n const map = new Map<string, MenuResource>();\n records.forEach((row) => map.set(row.resourceId, row));\n Object.values(childrenMap).forEach((list) => {\n list.forEach((row) => map.set(row.resourceId, row));\n });\n return Array.from(map.values());\n }, [records, childrenMap]);\n\n const parentOptions = useMemo(() => {\n return allKnownMenus\n .filter((row) => !editing || row.resourceId !== editing.resourceId)\n .map((row) => ({\n value: row.resourceId,\n label: `${row.name}(${MENU_TYPE_LABEL[row.type]})`,\n }));\n }, [allKnownMenus, editing]);\n\n const flatRows = useMemo(() => {\n const rows: MenuResource[] = [];\n const walk = (list: MenuResource[]) => {\n list.forEach((row) => {\n rows.push(row);\n if (expandedIds[row.resourceId] && childrenMap[row.resourceId]?.length) {\n walk(childrenMap[row.resourceId]);\n }\n });\n };\n walk(records);\n return rows;\n }, [records, childrenMap, expandedIds]);\n\n const loadList = useCallback(\n async (direction: PageDirection = 'current', token = pageToken) => {\n setLoading(true);\n setError('');\n try {\n const result = await api.list({\n depth: ROOT_MENU_DEPTH,\n pagination: {\n pageToken: token,\n pageSize,\n pageDirection: direction,\n },\n });\n setRecords(result.records);\n setChildrenMap({});\n setExpandedIds({});\n setExpandingIds({});\n setPageToken(result.pageToken);\n setHasPreviousPage(result.hasPreviousPage);\n setHasNextPage(result.hasNextPage);\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载失败');\n } finally {\n setLoading(false);\n }\n },\n [api, pageSize, pageToken],\n );\n\n const loadPermissionPoints = useCallback(async () => {\n try {\n const result = await api.listPermissionPoints({\n pagination: { pageSize: '200', pageDirection: 'current' },\n });\n setPermissionPoints(result.records);\n } catch {\n // 权限点加载失败不阻断菜单列表\n }\n }, [api]);\n\n const toggleExpand = async (row: MenuResource) => {\n if (isMenuLeaf(row)) return;\n const id = row.resourceId;\n if (expandedIds[id]) {\n setExpandedIds((prev) => ({ ...prev, [id]: false }));\n return;\n }\n\n if (!childrenMap[id]) {\n setExpandingIds((prev) => ({ ...prev, [id]: true }));\n setError('');\n try {\n const children = await api.listSubResources(id);\n setChildrenMap((prev) => ({ ...prev, [id]: children }));\n setExpandedIds((prev) => ({ ...prev, [id]: true }));\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载下级菜单失败');\n } finally {\n setExpandingIds((prev) => ({ ...prev, [id]: false }));\n }\n return;\n }\n\n setExpandedIds((prev) => ({ ...prev, [id]: true }));\n };\n\n useEffect(() => {\n void loadList('current', '');\n void loadPermissionPoints();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, pageSize]);\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm());\n setDialogOpen(true);\n void loadPermissionPoints();\n };\n\n const openEdit = (row: MenuResource) => {\n setEditing(row);\n setForm({\n parentId: row.parentId ?? null,\n depth: resolveMenuDepth(row.parentId ?? null, allKnownMenus),\n type: row.type,\n name: row.name,\n identification: row.identification,\n permissionPointIds: [...row.permissionPointIds],\n status: row.status,\n });\n setDialogOpen(true);\n void loadPermissionPoints();\n };\n\n const closeDialog = () => {\n if (saving) return;\n setDialogOpen(false);\n };\n\n const handleSubmit = async (event: FormEvent) => {\n event.preventDefault();\n if (!form.name.trim()) {\n setError('请填写菜单名称');\n return;\n }\n\n setSaving(true);\n setError('');\n try {\n if (editing) {\n await api.update(editing.resourceId, form);\n } else {\n await api.create(form);\n }\n setDialogOpen(false);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '保存失败');\n } finally {\n setSaving(false);\n }\n };\n\n const askDelete = (row: MenuResource) => setDeletingRow(row);\n\n const closeDeleteDialog = () => {\n if (!deleting) setDeletingRow(null);\n };\n\n const confirmDelete = async () => {\n if (!deletingRow) return;\n setDeleting(true);\n setError('');\n try {\n await api.remove(deletingRow.resourceId);\n setDeletingRow(null);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '删除失败');\n } finally {\n setDeleting(false);\n }\n };\n\n const togglePermission = (id: string) => {\n setForm((prev) => {\n const exists = prev.permissionPointIds.includes(id);\n return {\n ...prev,\n permissionPointIds: exists\n ? prev.permissionPointIds.filter((x) => x !== id)\n : [...prev.permissionPointIds, id],\n };\n });\n };\n\n const renderPermissionLabels = (row: MenuResource) => {\n if (row.permissionPointNames?.length) {\n return row.permissionPointNames.join('、');\n }\n if (!row.permissionPointIds.length) return '—';\n return row.permissionPointIds\n .map((id) => permissionNameMap.get(id) ?? id)\n .join('、');\n };\n\n return (\n <div style={styles.root}>\n <div style={styles.toolbar}>\n <h2 style={styles.title}>{title}</h2>\n <div style={styles.toolbarRight}>\n {toolbarExtra}\n <button type=\"button\" style={styles.primaryBtn} onClick={openCreate}>\n 新增\n </button>\n </div>\n </div>\n\n {error ? <div style={styles.error}>{error}</div> : null}\n\n <div style={styles.tableWrap}>\n <table style={styles.table}>\n <thead>\n <tr>\n <th style={styles.th}>菜单名称</th>\n <th style={styles.th}>请求地址</th>\n <th style={{ ...styles.th, width: 90 }}>类型</th>\n <th style={{ ...styles.th, width: 80 }}>可见</th>\n <th style={styles.th}>权限标识</th>\n <th style={{ ...styles.th, width: 140 }}>操作</th>\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={6} style={styles.empty}>\n 加载中…\n </td>\n </tr>\n ) : flatRows.length === 0 ? (\n <tr>\n <td colSpan={6} style={styles.empty}>\n 暂无数据\n </td>\n </tr>\n ) : (\n flatRows.map((row) => {\n const leaf = isMenuLeaf(row);\n const expanded = Boolean(expandedIds[row.resourceId]);\n const expanding = Boolean(expandingIds[row.resourceId]);\n const indent = Math.max(0, (row.depth || 1) - 1) * 18;\n return (\n <tr key={row.resourceId}>\n <td style={styles.td}>\n <div style={{ ...styles.treeCell, paddingLeft: indent }}>\n {leaf ? (\n <span style={styles.treeSpacer} />\n ) : (\n <button\n type=\"button\"\n style={styles.treeToggle}\n onClick={() => void toggleExpand(row)}\n disabled={expanding}\n aria-label={expanded ? '收起' : '展开'}\n >\n {expanding ? '…' : expanded ? '▼' : '▶'}\n </button>\n )}\n <span>{row.name}</span>\n </div>\n </td>\n <td style={styles.td}>\n <code style={styles.code}>{row.identification || '—'}</code>\n </td>\n <td style={styles.td}>{MENU_TYPE_LABEL[row.type]}</td>\n <td style={styles.td}>\n <span\n style={{\n ...styles.badge,\n background:\n row.status === RESOURCE_STATUS_ENABLED ? '#e8f7ef' : '#f4f4f5',\n color:\n row.status === RESOURCE_STATUS_ENABLED ? '#067647' : '#667085',\n }}\n >\n {row.status === RESOURCE_STATUS_ENABLED ? '显示' : '隐藏'}\n </span>\n </td>\n <td style={styles.td}>{renderPermissionLabels(row)}</td>\n <td style={styles.td}>\n <button type=\"button\" style={styles.linkBtn} onClick={() => openEdit(row)}>\n 编辑\n </button>\n <button\n type=\"button\"\n style={{ ...styles.linkBtn, color: '#d92d20' }}\n onClick={() => askDelete(row)}\n >\n 删除\n </button>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n <div style={styles.pagination}>\n <label style={styles.pageSize}>\n 每页\n <select\n value={pageSize}\n onChange={(e) => {\n setPageToken('');\n setPageSize(e.target.value);\n }}\n style={styles.select}\n >\n {PAGE_SIZE_OPTIONS.map((size) => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </label>\n <div style={styles.pageBtns}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasPreviousPage || loading}\n onClick={() => void loadList('previous')}\n >\n 上一页\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasNextPage || loading}\n onClick={() => void loadList('next')}\n >\n 下一页\n </button>\n </div>\n </div>\n\n {dialogOpen ? (\n <div style={styles.mask} onClick={closeDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 520 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>{editing ? '编辑菜单' : '新增菜单'}</h3>\n <button type=\"button\" style={styles.iconBtn} onClick={closeDialog} aria-label=\"关闭\">\n ×\n </button>\n </div>\n <form style={styles.form} onSubmit={(e) => void handleSubmit(e)}>\n <label style={styles.field}>\n <span style={styles.label}>上级菜单</span>\n <select\n style={styles.input}\n value={form.parentId ?? ROOT_PARENT_ID}\n onChange={(e) => {\n const parentId = e.target.value ? e.target.value : null;\n setForm((prev) => ({\n ...prev,\n parentId,\n depth: resolveMenuDepth(parentId, allKnownMenus),\n }));\n }}\n >\n <option value={ROOT_PARENT_ID}>无</option>\n {parentOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n\n <fieldset style={styles.fieldset}>\n <legend style={styles.label}>菜单类型</legend>\n <div style={styles.radioGroup}>\n {MENU_TYPE_OPTIONS.map((opt) => (\n <label key={opt.value} style={styles.radioItem}>\n <input\n type=\"radio\"\n name=\"menu-type\"\n style={styles.control}\n checked={form.type === opt.value}\n onChange={() =>\n setForm((prev) => ({\n ...prev,\n type: opt.value as MenuResourceType,\n }))\n }\n />\n {opt.label}\n </label>\n ))}\n </div>\n </fieldset>\n\n <label style={styles.field}>\n <span style={styles.label}>菜单名称</span>\n <input\n style={styles.input}\n value={form.name}\n onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}\n placeholder=\"请输入菜单名称\"\n required\n />\n </label>\n\n <label style={styles.field}>\n <span style={styles.label}>请求地址</span>\n <input\n style={styles.input}\n value={form.identification}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, identification: e.target.value }))\n }\n placeholder=\"如 /system/user\"\n />\n </label>\n\n <fieldset style={styles.fieldset}>\n <legend style={styles.label}>权限标识</legend>\n <div style={styles.multiSelect}>\n {permissionPoints.length === 0 ? (\n <div style={styles.hint}>暂无权限点,请先在权限点管理中新增</div>\n ) : (\n permissionPoints.map((p) => (\n <label key={p.resourceId} style={styles.checkItem}>\n <input\n type=\"checkbox\"\n style={styles.control}\n checked={form.permissionPointIds.includes(p.resourceId)}\n onChange={() => togglePermission(p.resourceId)}\n />\n <span>\n {p.name}\n <code style={{ ...styles.code, marginLeft: 6 }}>{p.identification}</code>\n </span>\n </label>\n ))\n )}\n </div>\n </fieldset>\n\n <fieldset style={styles.fieldset}>\n <legend style={styles.label}>状态</legend>\n <div style={styles.radioGroup}>\n {MENU_VISIBILITY_OPTIONS.map((opt) => (\n <label key={opt.value} style={styles.radioItem}>\n <input\n type=\"radio\"\n name=\"menu-status\"\n style={styles.control}\n checked={form.status === opt.value}\n onChange={() => setForm((prev) => ({ ...prev, status: opt.value }))}\n />\n {opt.label}\n </label>\n ))}\n </div>\n </fieldset>\n\n <div style={styles.dialogFooter}>\n <button type=\"button\" style={styles.secondaryBtn} onClick={closeDialog}>\n 取消\n </button>\n <button type=\"submit\" style={styles.primaryBtn} disabled={saving}>\n {saving ? '保存中…' : '保存'}\n </button>\n </div>\n </form>\n </div>\n </div>\n ) : null}\n\n {deletingRow ? (\n <div style={styles.mask} onClick={closeDeleteDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 420 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>确认删除</h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeDeleteDialog}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.confirmBody}>\n <p style={styles.confirmText}>\n 确认删除菜单「<strong>{deletingRow.name}</strong>」吗?删除后不可恢复。\n </p>\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeDeleteDialog}\n disabled={deleting}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.dangerBtn}\n onClick={() => void confirmDelete()}\n disabled={deleting}\n >\n {deleting ? '删除中…' : '确认删除'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n padding: 16,\n color: '#101828',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n title: { margin: 0, fontSize: 18, fontWeight: 600 },\n toolbarRight: { display: 'flex', alignItems: 'center', gap: 8 },\n error: {\n padding: '10px 12px',\n borderRadius: 8,\n background: '#fef3f2',\n color: '#b42318',\n fontSize: 13,\n },\n tableWrap: {\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 10,\n background: '#fff',\n },\n table: { width: '100%', borderCollapse: 'collapse', minWidth: 820 },\n th: {\n textAlign: 'left',\n padding: '12px 14px',\n fontSize: 13,\n fontWeight: 600,\n color: '#475467',\n background: '#f9fafb',\n borderBottom: '1px solid #eaecf0',\n },\n td: {\n padding: '12px 14px',\n fontSize: 14,\n borderBottom: '1px solid #f2f4f7',\n verticalAlign: 'middle',\n },\n treeCell: {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n },\n treeToggle: {\n width: 22,\n height: 22,\n border: '1px solid #d0d5dd',\n borderRadius: 4,\n background: '#fff',\n color: '#475467',\n cursor: 'pointer',\n fontSize: 10,\n lineHeight: '20px',\n padding: 0,\n flexShrink: 0,\n },\n treeSpacer: {\n width: 22,\n height: 22,\n flexShrink: 0,\n display: 'inline-block',\n },\n empty: { padding: 28, textAlign: 'center', color: '#98a2b3', fontSize: 14 },\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 13,\n background: '#f2f4f7',\n padding: '2px 6px',\n borderRadius: 4,\n },\n badge: {\n display: 'inline-block',\n padding: '2px 8px',\n borderRadius: 999,\n fontSize: 12,\n fontWeight: 500,\n },\n linkBtn: {\n border: 'none',\n background: 'transparent',\n color: '#049BAD',\n cursor: 'pointer',\n padding: '0 8px 0 0',\n fontSize: 13,\n },\n pagination: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n pageSize: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#475467' },\n pageBtns: { display: 'flex', gap: 8 },\n primaryBtn: {\n border: 'none',\n background: '#049BAD',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n secondaryBtn: {\n border: '1px solid #d0d5dd',\n background: '#fff',\n color: '#344054',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n dangerBtn: {\n border: 'none',\n background: '#d92d20',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n select: {\n border: '1px solid #d0d5dd',\n borderRadius: 6,\n padding: '4px 8px',\n fontSize: 13,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n mask: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(16, 24, 40, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n padding: 16,\n },\n dialog: {\n width: '100%',\n maxWidth: 480,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 20px 40px rgba(16,24,40,0.18)',\n maxHeight: '90vh',\n overflow: 'auto',\n },\n dialogHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 16px',\n borderBottom: '1px solid #eaecf0',\n position: 'sticky',\n top: 0,\n background: '#fff',\n zIndex: 1,\n },\n dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },\n iconBtn: {\n border: 'none',\n background: 'transparent',\n fontSize: 22,\n lineHeight: 1,\n cursor: 'pointer',\n color: '#667085',\n },\n form: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n confirmBody: { display: 'flex', flexDirection: 'column', gap: 16, padding: 16 },\n confirmText: { margin: 0, fontSize: 14, color: '#344054', lineHeight: 1.6 },\n field: { display: 'flex', flexDirection: 'column', gap: 6 },\n fieldset: {\n margin: 0,\n padding: 0,\n border: 'none',\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n backgroundColor: 'transparent',\n color: '#101828',\n },\n label: { fontSize: 13, color: '#344054', fontWeight: 500 },\n input: {\n border: '1px solid #d0d5dd',\n borderRadius: 8,\n padding: '8px 10px',\n fontSize: 14,\n outline: 'none',\n backgroundColor: '#ffffff',\n color: '#101828',\n boxSizing: 'border-box',\n width: '100%',\n },\n control: {\n width: 16,\n height: 16,\n margin: 0,\n flexShrink: 0,\n accentColor: '#049BAD',\n backgroundColor: '#ffffff',\n colorScheme: 'light' as const,\n },\n radioGroup: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 16,\n backgroundColor: 'transparent',\n },\n radioItem: {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontSize: 14,\n color: '#344054',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n },\n multiSelect: {\n maxHeight: 160,\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 8,\n padding: 8,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n checkItem: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 4px',\n fontSize: 13,\n color: '#344054',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n },\n hint: { fontSize: 13, color: '#98a2b3', padding: 8 },\n dialogFooter: {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n paddingTop: 4,\n },\n};\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type FormEvent,\n type ReactNode,\n} from 'react';\nimport type { PageDirection } from '../resources';\nimport {\n isPermissionNodeIndeterminate,\n togglePermissionCheck,\n type RolePermissionTreeNode,\n type SystemRole,\n type SystemRoleApi,\n type SystemRoleFormValues,\n} from '../roles';\n\nconst PAGE_SIZE_OPTIONS = ['10', '20', '50', '100'];\n\nconst emptyForm = (): SystemRoleFormValues => ({\n name: '',\n description: '',\n});\n\nexport type RoleManagerProps = {\n api: SystemRoleApi;\n title?: string;\n pageSize?: string;\n toolbarExtra?: ReactNode;\n};\n\nexport function RoleManager({\n api,\n title = '角色管理',\n pageSize: initialPageSize = '20',\n toolbarExtra,\n}: RoleManagerProps) {\n const [records, setRecords] = useState<SystemRole[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [keyword, setKeyword] = useState('');\n const [keywordInput, setKeywordInput] = useState('');\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageToken, setPageToken] = useState('');\n const [hasPreviousPage, setHasPreviousPage] = useState(false);\n const [hasNextPage, setHasNextPage] = useState(false);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editing, setEditing] = useState<SystemRole | null>(null);\n const [form, setForm] = useState<SystemRoleFormValues>(emptyForm);\n const [saving, setSaving] = useState(false);\n const [deletingRow, setDeletingRow] = useState<SystemRole | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const [authRole, setAuthRole] = useState<SystemRole | null>(null);\n const [authTree, setAuthTree] = useState<RolePermissionTreeNode[]>([]);\n const [authChecked, setAuthChecked] = useState<Set<string>>(() => new Set());\n const [authExpanded, setAuthExpanded] = useState<Record<string, boolean>>({});\n const [authLoading, setAuthLoading] = useState(false);\n const [authSaving, setAuthSaving] = useState(false);\n const [authError, setAuthError] = useState('');\n\n const loadList = useCallback(\n async (direction: PageDirection = 'current', token = pageToken) => {\n setLoading(true);\n setError('');\n try {\n const result = await api.list({\n keyword,\n pagination: {\n pageToken: token,\n pageSize,\n pageDirection: direction,\n },\n });\n setRecords(result.records);\n setPageToken(result.pageToken);\n setHasPreviousPage(result.hasPreviousPage);\n setHasNextPage(result.hasNextPage);\n } catch (err) {\n setError(err instanceof Error ? err.message : '加载失败');\n } finally {\n setLoading(false);\n }\n },\n [api, keyword, pageSize, pageToken],\n );\n\n useEffect(() => {\n void loadList('current', '');\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, pageSize, keyword]);\n\n const handleSearch = () => {\n setPageToken('');\n setKeyword(keywordInput.trim());\n };\n\n const openCreate = () => {\n setEditing(null);\n setForm(emptyForm());\n setDialogOpen(true);\n };\n\n const openEdit = (row: SystemRole) => {\n setEditing(row);\n setForm({\n name: row.name,\n description: row.description,\n });\n setDialogOpen(true);\n };\n\n const closeDialog = () => {\n if (!saving) setDialogOpen(false);\n };\n\n const handleSubmit = async (event: FormEvent) => {\n event.preventDefault();\n if (!form.name.trim()) {\n setError('请填写角色名称');\n return;\n }\n\n setSaving(true);\n setError('');\n try {\n if (editing) {\n await api.update(editing.roleId, form);\n } else {\n await api.create(form);\n }\n setDialogOpen(false);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '保存失败');\n } finally {\n setSaving(false);\n }\n };\n\n const askDelete = (row: SystemRole) => setDeletingRow(row);\n\n const closeDeleteDialog = () => {\n if (!deleting) setDeletingRow(null);\n };\n\n const confirmDelete = async () => {\n if (!deletingRow) return;\n setDeleting(true);\n setError('');\n try {\n await api.remove(deletingRow.roleId);\n setDeletingRow(null);\n await loadList('current', '');\n } catch (err) {\n setError(err instanceof Error ? err.message : '删除失败');\n } finally {\n setDeleting(false);\n }\n };\n\n const openAuthorize = async (row: SystemRole) => {\n setAuthRole(row);\n setAuthTree([]);\n setAuthChecked(new Set());\n setAuthExpanded({});\n setAuthError('');\n setAuthLoading(true);\n try {\n const result = await api.getPermissions(row.roleId);\n setAuthTree(result.resourceTree);\n setAuthChecked(new Set(result.resourceIds));\n const expanded: Record<string, boolean> = {};\n const walk = (nodes: RolePermissionTreeNode[]) => {\n for (const node of nodes) {\n if (node.children.length > 0) {\n expanded[node.resourceId] = true;\n walk(node.children);\n }\n }\n };\n walk(result.resourceTree);\n setAuthExpanded(expanded);\n } catch (err) {\n setAuthError(err instanceof Error ? err.message : '加载授权树失败');\n } finally {\n setAuthLoading(false);\n }\n };\n\n const closeAuthorize = () => {\n if (!authSaving) {\n setAuthRole(null);\n setAuthError('');\n }\n };\n\n const toggleExpand = (resourceId: string) => {\n setAuthExpanded((prev) => ({ ...prev, [resourceId]: !prev[resourceId] }));\n };\n\n const toggleCheck = (node: RolePermissionTreeNode) => {\n setAuthChecked((prev) => togglePermissionCheck(authTree, prev, node));\n };\n\n const saveAuthorize = async () => {\n if (!authRole) return;\n setAuthSaving(true);\n setAuthError('');\n try {\n await api.savePermissions(authRole.roleId, Array.from(authChecked));\n setAuthRole(null);\n } catch (err) {\n setAuthError(err instanceof Error ? err.message : '保存授权失败');\n } finally {\n setAuthSaving(false);\n }\n };\n\n const renderTreeNodes = (nodes: RolePermissionTreeNode[], depth = 0): ReactNode =>\n nodes.map((node) => {\n const hasChildren = node.children.length > 0;\n const expanded = Boolean(authExpanded[node.resourceId]);\n const checked = authChecked.has(node.resourceId);\n const indeterminate = isPermissionNodeIndeterminate(node, authChecked);\n\n return (\n <div key={node.resourceId}>\n <div style={{ ...styles.treeRow, paddingLeft: 12 + depth * 20 }}>\n {hasChildren ? (\n <button\n type=\"button\"\n style={styles.treeToggle}\n onClick={() => toggleExpand(node.resourceId)}\n aria-label={expanded ? '收起' : '展开'}\n >\n {expanded ? '▼' : '▶'}\n </button>\n ) : (\n <span style={styles.treeSpacer} />\n )}\n <label style={styles.treeLabel}>\n <TreeCheckbox\n checked={checked}\n indeterminate={indeterminate}\n onChange={() => toggleCheck(node)}\n />\n <span>{node.name || node.resourceId}</span>\n </label>\n </div>\n {hasChildren && expanded ? renderTreeNodes(node.children, depth + 1) : null}\n </div>\n );\n });\n\n return (\n <div style={styles.root}>\n <div style={styles.toolbar}>\n <h2 style={styles.title}>{title}</h2>\n <div style={styles.toolbarRight}>\n {toolbarExtra}\n <button type=\"button\" style={styles.primaryBtn} onClick={openCreate}>\n 新增角色\n </button>\n </div>\n </div>\n\n <div style={styles.searchBar}>\n <input\n style={{ ...styles.input, maxWidth: 260 }}\n value={keywordInput}\n onChange={(e) => setKeywordInput(e.target.value)}\n placeholder=\"搜索角色名称 / 描述\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSearch();\n }}\n />\n <button type=\"button\" style={styles.secondaryBtn} onClick={handleSearch}>\n 查询\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={() => {\n setKeywordInput('');\n setKeyword('');\n setPageToken('');\n }}\n >\n 重置\n </button>\n </div>\n\n {error ? <div style={styles.error}>{error}</div> : null}\n\n <div style={styles.tableWrap}>\n <table style={styles.table}>\n <thead>\n <tr>\n <th style={styles.th}>角色名称</th>\n <th style={styles.th}>角色描述</th>\n <th style={{ ...styles.th, width: 200 }}>操作</th>\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={3} style={styles.empty}>\n 加载中…\n </td>\n </tr>\n ) : records.length === 0 ? (\n <tr>\n <td colSpan={3} style={styles.empty}>\n 暂无数据\n </td>\n </tr>\n ) : (\n records.map((row) => (\n <tr key={row.roleId}>\n <td style={styles.td}>{row.name}</td>\n <td style={styles.td}>{row.description || '—'}</td>\n <td style={styles.td}>\n <button type=\"button\" style={styles.linkBtn} onClick={() => openEdit(row)}>\n 编辑\n </button>\n <button\n type=\"button\"\n style={styles.linkBtn}\n onClick={() => void openAuthorize(row)}\n >\n 授权\n </button>\n <button\n type=\"button\"\n style={{ ...styles.linkBtn, color: '#d92d20' }}\n onClick={() => askDelete(row)}\n >\n 删除\n </button>\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div style={styles.pagination}>\n <label style={styles.pageSize}>\n 每页\n <select\n value={pageSize}\n onChange={(e) => {\n setPageToken('');\n setPageSize(e.target.value);\n }}\n style={styles.select}\n >\n {PAGE_SIZE_OPTIONS.map((size) => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </label>\n <div style={styles.pageBtns}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasPreviousPage || loading}\n onClick={() => void loadList('previous')}\n >\n 上一页\n </button>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n disabled={!hasNextPage || loading}\n onClick={() => void loadList('next')}\n >\n 下一页\n </button>\n </div>\n </div>\n\n {dialogOpen ? (\n <div style={styles.mask} onClick={closeDialog}>\n <div\n style={styles.dialog}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>{editing ? '编辑角色' : '新增角色'}</h3>\n <button type=\"button\" style={styles.iconBtn} onClick={closeDialog} aria-label=\"关闭\">\n ×\n </button>\n </div>\n <form style={styles.form} onSubmit={(e) => void handleSubmit(e)}>\n <label style={styles.field}>\n <span style={styles.label}>角色名称</span>\n <input\n style={styles.input}\n value={form.name}\n onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}\n placeholder=\"请输入角色名称\"\n required\n />\n </label>\n <label style={styles.field}>\n <span style={styles.label}>角色描述</span>\n <textarea\n style={{ ...styles.input, minHeight: 88, resize: 'vertical' }}\n value={form.description}\n onChange={(e) =>\n setForm((prev) => ({ ...prev, description: e.target.value }))\n }\n placeholder=\"请输入角色描述\"\n />\n </label>\n <div style={styles.dialogFooter}>\n <button type=\"button\" style={styles.secondaryBtn} onClick={closeDialog}>\n 取消\n </button>\n <button type=\"submit\" style={styles.primaryBtn} disabled={saving}>\n {saving ? '保存中…' : '保存'}\n </button>\n </div>\n </form>\n </div>\n </div>\n ) : null}\n\n {deletingRow ? (\n <div style={styles.mask} onClick={closeDeleteDialog}>\n <div\n style={{ ...styles.dialog, maxWidth: 420 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>确认删除</h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeDeleteDialog}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.confirmBody}>\n <p style={styles.confirmText}>\n 确认删除角色「<strong>{deletingRow.name}</strong>」吗?删除后不可恢复。\n </p>\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeDeleteDialog}\n disabled={deleting}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.dangerBtn}\n onClick={() => void confirmDelete()}\n disabled={deleting}\n >\n {deleting ? '删除中…' : '确认删除'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n\n {authRole ? (\n <div style={styles.mask} onClick={closeAuthorize}>\n <div\n style={{ ...styles.dialog, maxWidth: 560 }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <div style={styles.dialogHeader}>\n <h3 style={styles.dialogTitle}>角色授权 — {authRole.name}</h3>\n <button\n type=\"button\"\n style={styles.iconBtn}\n onClick={closeAuthorize}\n aria-label=\"关闭\"\n >\n ×\n </button>\n </div>\n <div style={styles.authBody}>\n {authError ? <div style={styles.error}>{authError}</div> : null}\n {authLoading ? (\n <div style={styles.empty}>加载中…</div>\n ) : authTree.length === 0 ? (\n <div style={styles.empty}>暂无可授权资源</div>\n ) : (\n <div style={styles.treePanel}>{renderTreeNodes(authTree)}</div>\n )}\n <div style={styles.dialogFooter}>\n <button\n type=\"button\"\n style={styles.secondaryBtn}\n onClick={closeAuthorize}\n disabled={authSaving}\n >\n 取消\n </button>\n <button\n type=\"button\"\n style={styles.primaryBtn}\n onClick={() => void saveAuthorize()}\n disabled={authLoading || authSaving}\n >\n {authSaving ? '保存中…' : '保存'}\n </button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction TreeCheckbox({\n checked,\n indeterminate,\n onChange,\n}: {\n checked: boolean;\n indeterminate: boolean;\n onChange: () => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n return (\n <input\n ref={ref}\n type=\"checkbox\"\n checked={checked}\n onChange={onChange}\n style={styles.checkbox}\n />\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n padding: 16,\n color: '#101828',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n title: { margin: 0, fontSize: 18, fontWeight: 600 },\n toolbarRight: { display: 'flex', alignItems: 'center', gap: 8 },\n searchBar: { display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' },\n error: {\n padding: '10px 12px',\n borderRadius: 8,\n background: '#fef3f2',\n color: '#b42318',\n fontSize: 13,\n },\n tableWrap: {\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 10,\n background: '#fff',\n },\n table: { width: '100%', borderCollapse: 'collapse', minWidth: 560 },\n th: {\n textAlign: 'left',\n padding: '12px 14px',\n fontSize: 13,\n fontWeight: 600,\n color: '#475467',\n background: '#f9fafb',\n borderBottom: '1px solid #eaecf0',\n },\n td: {\n padding: '12px 14px',\n fontSize: 14,\n borderBottom: '1px solid #f2f4f7',\n verticalAlign: 'middle',\n },\n empty: { padding: 28, textAlign: 'center', color: '#98a2b3', fontSize: 14 },\n linkBtn: {\n border: 'none',\n background: 'transparent',\n color: '#049BAD',\n cursor: 'pointer',\n padding: '0 8px 0 0',\n fontSize: 13,\n },\n pagination: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n },\n pageSize: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#475467' },\n pageBtns: { display: 'flex', gap: 8 },\n primaryBtn: {\n border: 'none',\n background: '#049BAD',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n secondaryBtn: {\n border: '1px solid #d0d5dd',\n background: '#fff',\n color: '#344054',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n dangerBtn: {\n border: 'none',\n background: '#d92d20',\n color: '#fff',\n borderRadius: 8,\n padding: '8px 14px',\n cursor: 'pointer',\n fontSize: 14,\n },\n select: {\n border: '1px solid #d0d5dd',\n borderRadius: 6,\n padding: '4px 8px',\n fontSize: 13,\n backgroundColor: '#ffffff',\n color: '#101828',\n },\n mask: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(16, 24, 40, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n padding: 16,\n },\n dialog: {\n width: '100%',\n maxWidth: 480,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 20px 40px rgba(16,24,40,0.18)',\n },\n dialogHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 16px',\n borderBottom: '1px solid #eaecf0',\n },\n dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },\n iconBtn: {\n border: 'none',\n background: 'transparent',\n fontSize: 22,\n lineHeight: 1,\n cursor: 'pointer',\n color: '#667085',\n },\n form: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n confirmBody: { display: 'flex', flexDirection: 'column', gap: 16, padding: 16 },\n confirmText: { margin: 0, fontSize: 14, color: '#344054', lineHeight: 1.6 },\n authBody: { display: 'flex', flexDirection: 'column', gap: 12, padding: 16 },\n treePanel: {\n maxHeight: 420,\n overflow: 'auto',\n border: '1px solid #eaecf0',\n borderRadius: 8,\n padding: '8px 0',\n background: '#fff',\n },\n treeRow: {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n minHeight: 32,\n paddingRight: 12,\n },\n treeToggle: {\n border: 'none',\n background: 'transparent',\n width: 20,\n height: 20,\n padding: 0,\n cursor: 'pointer',\n color: '#667085',\n fontSize: 10,\n flexShrink: 0,\n },\n treeSpacer: { width: 20, flexShrink: 0 },\n treeLabel: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 14,\n color: '#101828',\n cursor: 'pointer',\n userSelect: 'none' as const,\n },\n checkbox: {\n width: 16,\n height: 16,\n accentColor: '#049BAD',\n cursor: 'pointer',\n colorScheme: 'light' as const,\n backgroundColor: '#ffffff',\n },\n field: { display: 'flex', flexDirection: 'column', gap: 6 },\n label: { fontSize: 13, color: '#344054', fontWeight: 500 },\n input: {\n border: '1px solid #d0d5dd',\n borderRadius: 8,\n padding: '8px 10px',\n fontSize: 14,\n outline: 'none',\n backgroundColor: '#ffffff',\n color: '#101828',\n boxSizing: 'border-box',\n width: '100%',\n },\n dialogFooter: {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n paddingTop: 4,\n },\n};\n","import { appendQueryParam, extractPagination, extractRecords } from '../resources/pagination';\nimport type { ResourceHttpRequest } from '../resources';\nimport type {\n CreateSystemRoleBody,\n FetchSystemRolesParams,\n RolePermissionTreeNode,\n RolePermissionsResult,\n SaveRolePermissionsBody,\n SystemRole,\n SystemRoleFormValues,\n SystemRoleListResult,\n UpdateSystemRoleBody,\n} from './types';\n\nexport type {\n CreateSystemRoleBody,\n FetchSystemRolesParams,\n RolePermissionTreeNode,\n RolePermissionsResult,\n SaveRolePermissionsBody,\n SystemRole,\n SystemRoleFormValues,\n SystemRoleListResult,\n UpdateSystemRoleBody,\n} from './types';\n\nexport type SystemRoleApi = {\n list: (\n params?: FetchSystemRolesParams,\n signal?: AbortSignal,\n ) => Promise<SystemRoleListResult>;\n create: (values: SystemRoleFormValues, signal?: AbortSignal) => Promise<unknown>;\n update: (\n roleId: string,\n values: SystemRoleFormValues,\n signal?: AbortSignal,\n ) => Promise<unknown>;\n remove: (roleId: string, signal?: AbortSignal) => Promise<unknown>;\n getPermissions: (\n roleId: string,\n signal?: AbortSignal,\n ) => Promise<RolePermissionsResult>;\n savePermissions: (\n roleId: string,\n resourceIds: string[],\n signal?: AbortSignal,\n ) => Promise<unknown>;\n};\n\nexport function mapSystemRole(item: unknown): SystemRole | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const roleId = row.roleId ?? row.role_id ?? row.id;\n if (roleId === undefined || roleId === null || roleId === '') return null;\n\n return {\n roleId: String(roleId),\n name: String(row.name ?? ''),\n description: String(row.description ?? row.desc ?? ''),\n };\n}\n\nexport function mapPermissionTreeNode(item: unknown): RolePermissionTreeNode | null {\n if (!item || typeof item !== 'object') return null;\n const row = item as Record<string, unknown>;\n const resourceId = row.resourceId ?? row.resource_id ?? row.id;\n if (resourceId === undefined || resourceId === null || resourceId === '') return null;\n\n const rawChildren = row.children ?? row.childList ?? row.child_list ?? [];\n const children = Array.isArray(rawChildren)\n ? rawChildren\n .map(mapPermissionTreeNode)\n .filter((node): node is RolePermissionTreeNode => node !== null)\n : [];\n\n return {\n resourceId: String(resourceId),\n name: String(row.name ?? ''),\n children,\n };\n}\n\nfunction asObject(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' ? (value as Record<string, unknown>) : null;\n}\n\nexport function mapRolePermissions(payload: unknown): RolePermissionsResult {\n const envelope = asObject(payload) ?? {};\n const data = asObject(envelope.data) ?? envelope;\n\n const rawIds = data.resourceIds ?? data.resource_ids ?? [];\n const resourceIds = Array.isArray(rawIds)\n ? rawIds\n .map((id) => (id === undefined || id === null ? '' : String(id)))\n .filter(Boolean)\n : [];\n\n const rawTree = data.resourceTree ?? data.resource_tree ?? [];\n const resourceTree = Array.isArray(rawTree)\n ? rawTree\n .map(mapPermissionTreeNode)\n .filter((node): node is RolePermissionTreeNode => node !== null)\n : [];\n\n return { resourceIds, resourceTree };\n}\n\n/** 收集节点及其全部子孙 resourceId */\nexport function collectTreeResourceIds(node: RolePermissionTreeNode): string[] {\n return [node.resourceId, ...node.children.flatMap(collectTreeResourceIds)];\n}\n\nexport type PermissionTreeIndex = {\n parentMap: Map<string, string | null>;\n nodeMap: Map<string, RolePermissionTreeNode>;\n};\n\n/** 建立父节点索引,供父子联动向上回写 */\nexport function buildPermissionTreeIndex(\n tree: RolePermissionTreeNode[],\n): PermissionTreeIndex {\n const parentMap = new Map<string, string | null>();\n const nodeMap = new Map<string, RolePermissionTreeNode>();\n\n const walk = (nodes: RolePermissionTreeNode[], parentId: string | null) => {\n for (const node of nodes) {\n parentMap.set(node.resourceId, parentId);\n nodeMap.set(node.resourceId, node);\n if (node.children.length > 0) {\n walk(node.children, node.resourceId);\n }\n }\n };\n walk(tree, null);\n\n return { parentMap, nodeMap };\n}\n\n/**\n * 父子联动勾选:\n * - 勾选:当前节点 + 全部子孙选中,并向上:子节点全选则父节点选中\n * - 取消:当前节点 + 全部子孙取消,并向上:任一子未选则父节点取消(半选由 UI 展示)\n */\nexport function togglePermissionCheck(\n tree: RolePermissionTreeNode[],\n checked: ReadonlySet<string>,\n node: RolePermissionTreeNode,\n): Set<string> {\n const next = new Set(checked);\n const ids = collectTreeResourceIds(node);\n const shouldCheck = !checked.has(node.resourceId);\n\n if (shouldCheck) {\n ids.forEach((id) => next.add(id));\n } else {\n ids.forEach((id) => next.delete(id));\n }\n\n const { parentMap, nodeMap } = buildPermissionTreeIndex(tree);\n let parentId = parentMap.get(node.resourceId) ?? null;\n while (parentId) {\n const parent = nodeMap.get(parentId);\n if (!parent) break;\n const allChildrenChecked = parent.children.every((child) =>\n next.has(child.resourceId),\n );\n if (allChildrenChecked && parent.children.length > 0) {\n next.add(parentId);\n } else {\n next.delete(parentId);\n }\n parentId = parentMap.get(parentId) ?? null;\n }\n\n return next;\n}\n\n/** 子孙勾选统计(不含自身),用于半选态 */\nexport function countCheckedDescendants(\n node: RolePermissionTreeNode,\n checked: ReadonlySet<string>,\n): { total: number; checkedCount: number } {\n let total = 0;\n let checkedCount = 0;\n const walk = (n: RolePermissionTreeNode) => {\n for (const child of n.children) {\n total += 1;\n if (checked.has(child.resourceId)) checkedCount += 1;\n walk(child);\n }\n };\n walk(node);\n return { total, checkedCount };\n}\n\n/** 是否存在已勾选的子孙节点 */\nexport function hasCheckedDescendant(\n node: RolePermissionTreeNode,\n checked: ReadonlySet<string>,\n): boolean {\n for (const child of node.children) {\n if (checked.has(child.resourceId) || hasCheckedDescendant(child, checked)) {\n return true;\n }\n }\n return false;\n}\n\n/** 半选:自身未勾选,但存在已勾选的子孙 */\nexport function isPermissionNodeIndeterminate(\n node: RolePermissionTreeNode,\n checked: ReadonlySet<string>,\n): boolean {\n if (checked.has(node.resourceId) || node.children.length === 0) return false;\n return hasCheckedDescendant(node, checked);\n}\n\nfunction buildListUrl(params?: FetchSystemRolesParams): string {\n const parts: string[] = [];\n appendQueryParam(parts, 'keyword', params?.keyword ?? '');\n appendQueryParam(parts, 'page-token', params?.pagination?.pageToken ?? '');\n appendQueryParam(parts, 'page-size', params?.pagination?.pageSize ?? '20');\n appendQueryParam(parts, 'page-direction', params?.pagination?.pageDirection ?? 'current');\n return parts.length ? `/system/roles?${parts.join('&')}` : '/system/roles';\n}\n\nexport function buildCreateRoleBody(values: SystemRoleFormValues): CreateSystemRoleBody {\n return {\n name: values.name.trim(),\n description: values.description.trim(),\n };\n}\n\nexport function buildUpdateRoleBody(values: SystemRoleFormValues): UpdateSystemRoleBody {\n return {\n name: values.name.trim(),\n description: values.description.trim(),\n };\n}\n\nexport function buildSavePermissionsBody(resourceIds: string[]): SaveRolePermissionsBody {\n return {\n resourceIds: [...new Set(resourceIds.map(String).filter(Boolean))],\n };\n}\n\nexport function createSystemRoleApi(request: ResourceHttpRequest): SystemRoleApi {\n return {\n async list(params, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: buildListUrl(params),\n signal,\n });\n const records = extractRecords(json)\n .map(mapSystemRole)\n .filter((item): item is SystemRole => item !== null);\n return {\n records,\n ...extractPagination(json),\n };\n },\n\n async create(values, signal) {\n return request({\n method: 'POST',\n url: '/system/roles',\n body: buildCreateRoleBody(values),\n signal,\n });\n },\n\n async update(roleId, values, signal) {\n return request({\n method: 'PATCH',\n url: `/system/roles/${encodeURIComponent(roleId)}`,\n body: buildUpdateRoleBody(values),\n signal,\n });\n },\n\n async remove(roleId, signal) {\n return request({\n method: 'DELETE',\n url: `/system/roles/${encodeURIComponent(roleId)}`,\n signal,\n });\n },\n\n async getPermissions(roleId, signal) {\n const json = await request<unknown>({\n method: 'GET',\n url: `/system/roles/${encodeURIComponent(roleId)}/permissions`,\n signal,\n });\n return mapRolePermissions(json);\n },\n\n async savePermissions(roleId, resourceIds, signal) {\n return request({\n method: 'POST',\n url: `/system/roles/${encodeURIComponent(roleId)}/permissions`,\n body: buildSavePermissionsBody(resourceIds),\n signal,\n });\n },\n };\n}\n","import { useMemo, useState, type CSSProperties, type ReactNode } from 'react';\nimport {\n SYSTEM_ADMIN_DEFAULT_KEY,\n SYSTEM_ADMIN_MENU,\n type SystemAdminMenuKey,\n} from '../admin';\nimport type { AuthorizationResourceApi, MenuResourceApi } from '../resources';\nimport type { SystemRoleApi } from '../roles';\nimport { MenuManager } from './MenuManager';\nimport { ResourceManager } from './ResourceManager';\nimport { RoleManager } from './RoleManager';\n\nexport type SystemAdminProps = {\n menuApi: MenuResourceApi;\n resourceApi: AuthorizationResourceApi;\n roleApi: SystemRoleApi;\n /** 默认选中的子菜单,默认菜单管理 */\n defaultActiveKey?: SystemAdminMenuKey;\n /** 受控选中 key */\n activeKey?: SystemAdminMenuKey;\n onActiveKeyChange?: (key: SystemAdminMenuKey) => void;\n title?: string;\n toolbarExtra?: ReactNode;\n};\n\n/**\n * 系统管理:侧栏父菜单「系统管理」,子菜单为菜单 / 权限点 / 角色管理。\n */\nexport function SystemAdmin({\n menuApi,\n resourceApi,\n roleApi,\n defaultActiveKey = SYSTEM_ADMIN_DEFAULT_KEY,\n activeKey: controlledKey,\n onActiveKeyChange,\n title = SYSTEM_ADMIN_MENU.label,\n toolbarExtra,\n}: SystemAdminProps) {\n const [innerKey, setInnerKey] = useState<SystemAdminMenuKey>(defaultActiveKey);\n const activeKey = controlledKey ?? innerKey;\n\n const setActiveKey = (key: SystemAdminMenuKey) => {\n if (controlledKey === undefined) setInnerKey(key);\n onActiveKeyChange?.(key);\n };\n\n const activeLabel = useMemo(\n () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey)?.label ?? '',\n [activeKey],\n );\n\n return (\n <div style={styles.root}>\n <aside style={styles.sidebar}>\n <div style={styles.sidebarTitle}>{title}</div>\n <nav style={styles.nav}>\n {SYSTEM_ADMIN_MENU.children.map((item) => {\n const active = item.key === activeKey;\n return (\n <button\n key={item.key}\n type=\"button\"\n style={{\n ...styles.navItem,\n ...(active ? styles.navItemActive : null),\n }}\n onClick={() => setActiveKey(item.key)}\n >\n {item.label}\n </button>\n );\n })}\n </nav>\n </aside>\n\n <main style={styles.content}>\n <div style={styles.contentHeader}>\n <div style={styles.breadcrumb}>\n <span style={styles.breadcrumbParent}>{title}</span>\n <span style={styles.breadcrumbSep}>/</span>\n <span style={styles.breadcrumbCurrent}>{activeLabel}</span>\n </div>\n {toolbarExtra}\n </div>\n\n <div style={styles.panel}>\n {activeKey === 'menu' ? (\n <MenuManager api={menuApi} title=\"菜单管理\" />\n ) : activeKey === 'resource' ? (\n <ResourceManager api={resourceApi} title=\"权限点管理\" />\n ) : (\n <RoleManager api={roleApi} title=\"角色管理\" />\n )}\n </div>\n </main>\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'flex',\n minHeight: 560,\n border: '1px solid #eaecf0',\n borderRadius: 12,\n overflow: 'hidden',\n background: '#fff',\n fontFamily:\n '\"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, sans-serif',\n color: '#101828',\n },\n sidebar: {\n width: 200,\n flexShrink: 0,\n borderRight: '1px solid #eaecf0',\n background: '#f9fafb',\n padding: '16px 12px',\n },\n sidebarTitle: {\n fontSize: 14,\n fontWeight: 600,\n color: '#344054',\n padding: '4px 10px 12px',\n },\n nav: {\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n },\n navItem: {\n border: 'none',\n background: 'transparent',\n textAlign: 'left',\n padding: '10px 12px',\n borderRadius: 8,\n fontSize: 14,\n color: '#475467',\n cursor: 'pointer',\n },\n navItemActive: {\n background: '#e6f7f9',\n color: '#049BAD',\n fontWeight: 600,\n },\n content: {\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n background: '#fff',\n },\n contentHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 16px',\n borderBottom: '1px solid #f2f4f7',\n },\n breadcrumb: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 13,\n },\n breadcrumbParent: { color: '#98a2b3' },\n breadcrumbSep: { color: '#d0d5dd' },\n breadcrumbCurrent: { color: '#344054', fontWeight: 600 },\n panel: {\n flex: 1,\n minHeight: 0,\n overflow: 'auto',\n },\n};\n","export type SystemAdminMenuKey = 'menu' | 'resource' | 'role';\n\nexport type SystemAdminSubMenu = {\n key: SystemAdminMenuKey;\n label: string;\n};\n\nexport type SystemAdminMenuGroup = {\n key: 'system';\n label: string;\n children: SystemAdminSubMenu[];\n};\n\n/** 系统管理菜单结构 */\nexport const SYSTEM_ADMIN_MENU: SystemAdminMenuGroup = {\n key: 'system',\n label: '系统管理',\n children: [\n { key: 'menu', label: '菜单管理' },\n { key: 'resource', label: '权限点管理' },\n { key: 'role', label: '角色管理' },\n ],\n};\n\nexport const SYSTEM_ADMIN_DEFAULT_KEY: SystemAdminMenuKey = 'menu';\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useState","text","jsx","useState","useCallback","useEffect","useMemo","useCallback","useEffect","useMemo","useState","jsx","jsxs","PAGE_SIZE_OPTIONS","emptyForm","useState","useMemo","useCallback","useEffect","styles","useCallback","useEffect","useState","buildListUrl","jsx","jsxs","PAGE_SIZE_OPTIONS","emptyForm","useState","useCallback","useEffect","styles","useMemo","useState","jsx","jsxs","useState","useMemo","styles"]}