com-angel-authorization 1.0.16 → 1.0.18

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.
@@ -2005,6 +2005,72 @@ function mapRolePermissions(payload) {
2005
2005
  function collectTreeResourceIds(node) {
2006
2006
  return [node.resourceId, ...node.children.flatMap(collectTreeResourceIds)];
2007
2007
  }
2008
+ function buildPermissionTreeIndex(tree) {
2009
+ const parentMap = /* @__PURE__ */ new Map();
2010
+ const nodeMap = /* @__PURE__ */ new Map();
2011
+ const walk = (nodes, parentId) => {
2012
+ for (const node of nodes) {
2013
+ parentMap.set(node.resourceId, parentId);
2014
+ nodeMap.set(node.resourceId, node);
2015
+ if (node.children.length > 0) {
2016
+ walk(node.children, node.resourceId);
2017
+ }
2018
+ }
2019
+ };
2020
+ walk(tree, null);
2021
+ return { parentMap, nodeMap };
2022
+ }
2023
+ function togglePermissionCheck(tree, checked, node) {
2024
+ const next = new Set(checked);
2025
+ const ids = collectTreeResourceIds(node);
2026
+ const shouldCheck = !checked.has(node.resourceId);
2027
+ if (shouldCheck) {
2028
+ ids.forEach((id) => next.add(id));
2029
+ } else {
2030
+ ids.forEach((id) => next.delete(id));
2031
+ }
2032
+ const { parentMap, nodeMap } = buildPermissionTreeIndex(tree);
2033
+ let parentId = parentMap.get(node.resourceId) ?? null;
2034
+ while (parentId) {
2035
+ const parent = nodeMap.get(parentId);
2036
+ if (!parent) break;
2037
+ const allChildrenChecked = parent.children.every(
2038
+ (child) => next.has(child.resourceId)
2039
+ );
2040
+ if (allChildrenChecked && parent.children.length > 0) {
2041
+ next.add(parentId);
2042
+ } else {
2043
+ next.delete(parentId);
2044
+ }
2045
+ parentId = parentMap.get(parentId) ?? null;
2046
+ }
2047
+ return next;
2048
+ }
2049
+ function countCheckedDescendants(node, checked) {
2050
+ let total = 0;
2051
+ let checkedCount = 0;
2052
+ const walk = (n) => {
2053
+ for (const child of n.children) {
2054
+ total += 1;
2055
+ if (checked.has(child.resourceId)) checkedCount += 1;
2056
+ walk(child);
2057
+ }
2058
+ };
2059
+ walk(node);
2060
+ return { total, checkedCount };
2061
+ }
2062
+ function hasCheckedDescendant(node, checked) {
2063
+ for (const child of node.children) {
2064
+ if (checked.has(child.resourceId) || hasCheckedDescendant(child, checked)) {
2065
+ return true;
2066
+ }
2067
+ }
2068
+ return false;
2069
+ }
2070
+ function isPermissionNodeIndeterminate(node, checked) {
2071
+ if (checked.has(node.resourceId) || node.children.length === 0) return false;
2072
+ return hasCheckedDescendant(node, checked);
2073
+ }
2008
2074
  function buildListUrl2(params) {
2009
2075
  const parts = [];
2010
2076
  appendQueryParam(parts, "keyword", params?.keyword ?? "");
@@ -2093,19 +2159,6 @@ var emptyForm3 = () => ({
2093
2159
  name: "",
2094
2160
  description: ""
2095
2161
  });
2096
- function countCheckedDescendants(node, checked) {
2097
- let total = 0;
2098
- let checkedCount = 0;
2099
- const walk = (n) => {
2100
- for (const child of n.children) {
2101
- total += 1;
2102
- if (checked.has(child.resourceId)) checkedCount += 1;
2103
- walk(child);
2104
- }
2105
- };
2106
- walk(node);
2107
- return { total, checkedCount };
2108
- }
2109
2162
  function RoleManager({
2110
2163
  api,
2111
2164
  title = "\u89D2\u8272\u7BA1\u7406",
@@ -2260,17 +2313,7 @@ function RoleManager({
2260
2313
  setAuthExpanded((prev) => ({ ...prev, [resourceId]: !prev[resourceId] }));
2261
2314
  };
2262
2315
  const toggleCheck = (node) => {
2263
- setAuthChecked((prev) => {
2264
- const next = new Set(prev);
2265
- const ids = collectTreeResourceIds(node);
2266
- const shouldCheck = !prev.has(node.resourceId);
2267
- if (shouldCheck) {
2268
- ids.forEach((id) => next.add(id));
2269
- } else {
2270
- ids.forEach((id) => next.delete(id));
2271
- }
2272
- return next;
2273
- });
2316
+ setAuthChecked((prev) => togglePermissionCheck(authTree, prev, node));
2274
2317
  };
2275
2318
  const saveAuthorize = async () => {
2276
2319
  if (!authRole) return;
@@ -2289,8 +2332,7 @@ function RoleManager({
2289
2332
  const hasChildren = node.children.length > 0;
2290
2333
  const expanded = Boolean(authExpanded[node.resourceId]);
2291
2334
  const checked = authChecked.has(node.resourceId);
2292
- const { total, checkedCount } = countCheckedDescendants(node, authChecked);
2293
- const indeterminate = hasChildren && checkedCount > 0 && checkedCount < total && !checked;
2335
+ const indeterminate = isPermissionNodeIndeterminate(node, authChecked);
2294
2336
  return /* @__PURE__ */ jsxs3("div", { children: [
2295
2337
  /* @__PURE__ */ jsxs3("div", { style: { ...styles3.treeRow, paddingLeft: 12 + depth * 20 }, children: [
2296
2338
  hasChildren ? /* @__PURE__ */ jsx4(
@@ -2801,55 +2843,957 @@ var styles3 = {
2801
2843
  }
2802
2844
  };
2803
2845
 
2804
- // src/react/SystemAdmin.tsx
2805
- import { useMemo as useMemo4, useState as useState5 } from "react";
2846
+ // src/react/UserManager.tsx
2847
+ import {
2848
+ useCallback as useCallback5,
2849
+ useEffect as useEffect5,
2850
+ useState as useState5
2851
+ } from "react";
2806
2852
 
2807
- // src/admin/menu.ts
2808
- var SYSTEM_ADMIN_MENU = {
2809
- key: "system",
2810
- label: "\u7CFB\u7EDF\u7BA1\u7406",
2811
- children: [
2812
- { key: "menu", label: "\u83DC\u5355\u7BA1\u7406" },
2813
- { key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" },
2814
- { key: "role", label: "\u89D2\u8272\u7BA1\u7406" }
2815
- ]
2816
- };
2817
- var SYSTEM_ADMIN_DEFAULT_KEY = "menu";
2853
+ // src/users/index.ts
2854
+ function asIdList(value) {
2855
+ if (!Array.isArray(value)) return [];
2856
+ return value.map((item) => {
2857
+ if (item === void 0 || item === null || item === "") return "";
2858
+ if (typeof item === "object") {
2859
+ const row = item;
2860
+ const id = row.groupId ?? row.roleId ?? row.id;
2861
+ return id === void 0 || id === null ? "" : String(id);
2862
+ }
2863
+ return String(item);
2864
+ }).filter(Boolean);
2865
+ }
2866
+ function asNameList(value) {
2867
+ if (!Array.isArray(value)) return void 0;
2868
+ const names = value.map((item) => {
2869
+ if (item === void 0 || item === null) return "";
2870
+ if (typeof item === "object") {
2871
+ return String(item.name ?? "");
2872
+ }
2873
+ return String(item);
2874
+ }).filter(Boolean);
2875
+ return names.length ? names : void 0;
2876
+ }
2877
+ function mapSystemUser(item) {
2878
+ if (!item || typeof item !== "object") return null;
2879
+ const row = item;
2880
+ const userId = row.userId ?? row.user_id ?? row.id;
2881
+ if (userId === void 0 || userId === null || userId === "") return null;
2882
+ return {
2883
+ userId: String(userId),
2884
+ username: String(row.username ?? row.account ?? ""),
2885
+ name: String(row.name ?? ""),
2886
+ groupIds: asIdList(row.groupIds ?? row.group_ids ?? row.groups),
2887
+ roleIds: asIdList(row.roleIds ?? row.role_ids ?? row.roles),
2888
+ groupNames: asNameList(row.groupNames ?? row.group_names ?? row.groups),
2889
+ roleNames: asNameList(row.roleNames ?? row.role_names ?? row.roles),
2890
+ enabled: Boolean(row.enabled ?? row.enable ?? true)
2891
+ };
2892
+ }
2893
+ function mapSystemGroupOption(item) {
2894
+ if (!item || typeof item !== "object") return null;
2895
+ const row = item;
2896
+ const groupId = row.groupId ?? row.group_id ?? row.id;
2897
+ if (groupId === void 0 || groupId === null || groupId === "") return null;
2898
+ return {
2899
+ groupId: String(groupId),
2900
+ name: String(row.name ?? "")
2901
+ };
2902
+ }
2903
+ function mapSystemRoleOption(item) {
2904
+ if (!item || typeof item !== "object") return null;
2905
+ const row = item;
2906
+ const roleId = row.roleId ?? row.role_id ?? row.id;
2907
+ if (roleId === void 0 || roleId === null || roleId === "") return null;
2908
+ return {
2909
+ roleId: String(roleId),
2910
+ name: String(row.name ?? "")
2911
+ };
2912
+ }
2913
+ function validateUsername(username) {
2914
+ const value = username.trim();
2915
+ if (value.length < 6) return "\u8D26\u53F7\u957F\u5EA6\u4E0D\u5C11\u4E8E 6 \u4E2A\u5B57\u7B26";
2916
+ if (!/[A-Za-z]/.test(value) || !/[0-9]/.test(value)) {
2917
+ return "\u8D26\u53F7\u9700\u540C\u65F6\u5305\u542B\u5B57\u6BCD\u548C\u6570\u5B57";
2918
+ }
2919
+ return null;
2920
+ }
2921
+ function buildListUrl3(params) {
2922
+ const parts = [];
2923
+ appendQueryParam(parts, "keyword", params?.keyword ?? "");
2924
+ if (params?.enabled !== void 0) {
2925
+ appendQueryParam(parts, "enabled", String(params.enabled));
2926
+ }
2927
+ appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
2928
+ appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
2929
+ appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
2930
+ return parts.length ? `/system/users?${parts.join("&")}` : "/system/users";
2931
+ }
2932
+ function buildKeywordUrl(base, keyword) {
2933
+ const parts = [];
2934
+ appendQueryParam(parts, "keyword", keyword ?? "");
2935
+ return parts.length ? `${base}?${parts.join("&")}` : base;
2936
+ }
2937
+ function buildCreateUserBody(values) {
2938
+ return {
2939
+ username: values.username.trim(),
2940
+ name: values.name.trim(),
2941
+ password: values.password,
2942
+ groupIds: [...new Set(values.groupIds.map(String))],
2943
+ roleIds: [...new Set(values.roleIds.map(String))],
2944
+ enabled: Boolean(values.enabled)
2945
+ };
2946
+ }
2947
+ function buildUpdateUserBody(values) {
2948
+ const body = {
2949
+ username: values.username.trim(),
2950
+ name: values.name.trim(),
2951
+ groupIds: [...new Set(values.groupIds.map(String))],
2952
+ roleIds: [...new Set(values.roleIds.map(String))],
2953
+ enabled: Boolean(values.enabled)
2954
+ };
2955
+ if (values.password.trim()) {
2956
+ body.password = values.password;
2957
+ }
2958
+ return body;
2959
+ }
2960
+ function createSystemUserApi(request) {
2961
+ return {
2962
+ async list(params, signal) {
2963
+ const json = await request({
2964
+ method: "GET",
2965
+ url: buildListUrl3(params),
2966
+ signal
2967
+ });
2968
+ const records = extractRecords(json).map(mapSystemUser).filter((item) => item !== null);
2969
+ return {
2970
+ records,
2971
+ ...extractPagination(json)
2972
+ };
2973
+ },
2974
+ async create(values, signal) {
2975
+ return request({
2976
+ method: "POST",
2977
+ url: "/system/users",
2978
+ body: buildCreateUserBody(values),
2979
+ signal
2980
+ });
2981
+ },
2982
+ async update(userId, values, signal) {
2983
+ return request({
2984
+ method: "PATCH",
2985
+ url: `/system/users/${encodeURIComponent(userId)}`,
2986
+ body: buildUpdateUserBody(values),
2987
+ signal
2988
+ });
2989
+ },
2990
+ async remove(userId, signal) {
2991
+ return request({
2992
+ method: "DELETE",
2993
+ url: `/system/users/${encodeURIComponent(userId)}`,
2994
+ signal
2995
+ });
2996
+ },
2997
+ async listGroups(params, signal) {
2998
+ const json = await request({
2999
+ method: "GET",
3000
+ url: buildKeywordUrl("/system/groups", params?.keyword),
3001
+ signal
3002
+ });
3003
+ return extractRecords(json).map(mapSystemGroupOption).filter((item) => item !== null);
3004
+ },
3005
+ async listRoleOptions(params, signal) {
3006
+ const json = await request({
3007
+ method: "GET",
3008
+ url: buildKeywordUrl("/system/roles", params?.keyword),
3009
+ signal
3010
+ });
3011
+ return extractRecords(json).map(mapSystemRoleOption).filter((item) => item !== null);
3012
+ }
3013
+ };
3014
+ }
2818
3015
 
2819
- // src/react/SystemAdmin.tsx
3016
+ // src/react/UserManager.tsx
2820
3017
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2821
- function SystemAdmin({
2822
- menuApi,
2823
- resourceApi,
2824
- roleApi,
2825
- defaultActiveKey = SYSTEM_ADMIN_DEFAULT_KEY,
2826
- activeKey: controlledKey,
2827
- onActiveKeyChange,
2828
- title = SYSTEM_ADMIN_MENU.label,
3018
+ var PAGE_SIZE_OPTIONS4 = ["10", "20", "50", "100"];
3019
+ var emptyForm4 = () => ({
3020
+ username: "",
3021
+ name: "",
3022
+ password: "",
3023
+ groupIds: [],
3024
+ roleIds: [],
3025
+ enabled: true
3026
+ });
3027
+ function UserManager({
3028
+ api,
3029
+ title = "\u7528\u6237\u7BA1\u7406",
3030
+ pageSize: initialPageSize = "20",
2829
3031
  toolbarExtra
2830
3032
  }) {
2831
- const [innerKey, setInnerKey] = useState5(defaultActiveKey);
2832
- const activeKey = controlledKey ?? innerKey;
2833
- const setActiveKey = (key) => {
2834
- if (controlledKey === void 0) setInnerKey(key);
2835
- onActiveKeyChange?.(key);
2836
- };
2837
- const activeLabel = useMemo4(
2838
- () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey)?.label ?? "",
2839
- [activeKey]
3033
+ const [records, setRecords] = useState5([]);
3034
+ const [loading, setLoading] = useState5(false);
3035
+ const [error, setError] = useState5("");
3036
+ const [keyword, setKeyword] = useState5("");
3037
+ const [keywordInput, setKeywordInput] = useState5("");
3038
+ const [enabledFilter, setEnabledFilter] = useState5("all");
3039
+ const [pageSize, setPageSize] = useState5(initialPageSize);
3040
+ const [pageToken, setPageToken] = useState5("");
3041
+ const [hasPreviousPage, setHasPreviousPage] = useState5(false);
3042
+ const [hasNextPage, setHasNextPage] = useState5(false);
3043
+ const [dialogOpen, setDialogOpen] = useState5(false);
3044
+ const [editing, setEditing] = useState5(null);
3045
+ const [form, setForm] = useState5(emptyForm4);
3046
+ const [formError, setFormError] = useState5("");
3047
+ const [saving, setSaving] = useState5(false);
3048
+ const [deletingRow, setDeletingRow] = useState5(null);
3049
+ const [deleting, setDeleting] = useState5(false);
3050
+ const [groups, setGroups] = useState5([]);
3051
+ const [roles, setRoles] = useState5([]);
3052
+ const [optionsLoading, setOptionsLoading] = useState5(false);
3053
+ const enabledParam = enabledFilter === "all" ? void 0 : enabledFilter === "true";
3054
+ const loadList = useCallback5(
3055
+ async (direction = "current", token = pageToken) => {
3056
+ setLoading(true);
3057
+ setError("");
3058
+ try {
3059
+ const result = await api.list({
3060
+ keyword,
3061
+ enabled: enabledParam,
3062
+ pagination: {
3063
+ pageToken: token,
3064
+ pageSize,
3065
+ pageDirection: direction
3066
+ }
3067
+ });
3068
+ setRecords(result.records);
3069
+ setPageToken(result.pageToken);
3070
+ setHasPreviousPage(result.hasPreviousPage);
3071
+ setHasNextPage(result.hasNextPage);
3072
+ } catch (err) {
3073
+ setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u5931\u8D25");
3074
+ } finally {
3075
+ setLoading(false);
3076
+ }
3077
+ },
3078
+ [api, keyword, enabledParam, pageSize, pageToken]
2840
3079
  );
3080
+ useEffect5(() => {
3081
+ void loadList("current", "");
3082
+ }, [api, pageSize, keyword, enabledFilter]);
3083
+ const loadOptions = useCallback5(async () => {
3084
+ setOptionsLoading(true);
3085
+ try {
3086
+ const [groupList, roleList] = await Promise.all([
3087
+ api.listGroups(),
3088
+ api.listRoleOptions()
3089
+ ]);
3090
+ setGroups(groupList);
3091
+ setRoles(roleList);
3092
+ } catch (err) {
3093
+ setFormError(err instanceof Error ? err.message : "\u52A0\u8F7D\u90E8\u95E8/\u89D2\u8272\u5931\u8D25");
3094
+ } finally {
3095
+ setOptionsLoading(false);
3096
+ }
3097
+ }, [api]);
3098
+ const handleSearch = () => {
3099
+ setPageToken("");
3100
+ setKeyword(keywordInput.trim());
3101
+ };
3102
+ const openCreate = () => {
3103
+ setEditing(null);
3104
+ setForm(emptyForm4());
3105
+ setFormError("");
3106
+ setDialogOpen(true);
3107
+ void loadOptions();
3108
+ };
3109
+ const openEdit = (row) => {
3110
+ setEditing(row);
3111
+ setForm({
3112
+ username: row.username,
3113
+ name: row.name,
3114
+ password: "",
3115
+ groupIds: [...row.groupIds],
3116
+ roleIds: [...row.roleIds],
3117
+ enabled: row.enabled
3118
+ });
3119
+ setFormError("");
3120
+ setDialogOpen(true);
3121
+ void loadOptions();
3122
+ };
3123
+ const closeDialog = () => {
3124
+ if (!saving) setDialogOpen(false);
3125
+ };
3126
+ const toggleId = (field, id) => {
3127
+ setForm((prev) => {
3128
+ const exists = prev[field].includes(id);
3129
+ return {
3130
+ ...prev,
3131
+ [field]: exists ? prev[field].filter((x) => x !== id) : [...prev[field], id]
3132
+ };
3133
+ });
3134
+ };
3135
+ const handleSubmit = async (event) => {
3136
+ event.preventDefault();
3137
+ const usernameError = validateUsername(form.username);
3138
+ if (usernameError) {
3139
+ setFormError(usernameError);
3140
+ return;
3141
+ }
3142
+ if (!form.name.trim()) {
3143
+ setFormError("\u8BF7\u586B\u5199\u7528\u6237\u540D");
3144
+ return;
3145
+ }
3146
+ if (!editing && !form.password.trim()) {
3147
+ setFormError("\u8BF7\u586B\u5199\u521D\u59CB\u5BC6\u7801");
3148
+ return;
3149
+ }
3150
+ setSaving(true);
3151
+ setFormError("");
3152
+ setError("");
3153
+ try {
3154
+ if (editing) {
3155
+ await api.update(editing.userId, form);
3156
+ } else {
3157
+ await api.create(form);
3158
+ }
3159
+ setDialogOpen(false);
3160
+ await loadList("current", "");
3161
+ } catch (err) {
3162
+ setFormError(err instanceof Error ? err.message : "\u4FDD\u5B58\u5931\u8D25");
3163
+ } finally {
3164
+ setSaving(false);
3165
+ }
3166
+ };
3167
+ const askDelete = (row) => setDeletingRow(row);
3168
+ const closeDeleteDialog = () => {
3169
+ if (!deleting) setDeletingRow(null);
3170
+ };
3171
+ const confirmDelete = async () => {
3172
+ if (!deletingRow) return;
3173
+ setDeleting(true);
3174
+ setError("");
3175
+ try {
3176
+ await api.remove(deletingRow.userId);
3177
+ setDeletingRow(null);
3178
+ await loadList("current", "");
3179
+ } catch (err) {
3180
+ setError(err instanceof Error ? err.message : "\u5220\u9664\u5931\u8D25");
3181
+ } finally {
3182
+ setDeleting(false);
3183
+ }
3184
+ };
3185
+ const groupLabel = (row) => {
3186
+ if (row.groupNames?.length) return row.groupNames.join("\u3001");
3187
+ if (!row.groupIds.length) return "\u2014";
3188
+ const map = new Map(groups.map((g) => [g.groupId, g.name]));
3189
+ return row.groupIds.map((id) => map.get(id) || id).join("\u3001");
3190
+ };
3191
+ const roleLabel = (row) => {
3192
+ if (row.roleNames?.length) return row.roleNames.join("\u3001");
3193
+ if (!row.roleIds.length) return "\u2014";
3194
+ const map = new Map(roles.map((r) => [r.roleId, r.name]));
3195
+ return row.roleIds.map((id) => map.get(id) || id).join("\u3001");
3196
+ };
3197
+ useEffect5(() => {
3198
+ void (async () => {
3199
+ try {
3200
+ const [groupList, roleList] = await Promise.all([
3201
+ api.listGroups(),
3202
+ api.listRoleOptions()
3203
+ ]);
3204
+ setGroups(groupList);
3205
+ setRoles(roleList);
3206
+ } catch {
3207
+ }
3208
+ })();
3209
+ }, [api]);
2841
3210
  return /* @__PURE__ */ jsxs4("div", { style: styles4.root, children: [
2842
- /* @__PURE__ */ jsxs4("aside", { style: styles4.sidebar, children: [
2843
- /* @__PURE__ */ jsx5("div", { style: styles4.sidebarTitle, children: title }),
2844
- /* @__PURE__ */ jsx5("nav", { style: styles4.nav, children: SYSTEM_ADMIN_MENU.children.map((item) => {
3211
+ /* @__PURE__ */ jsxs4("div", { style: styles4.toolbar, children: [
3212
+ /* @__PURE__ */ jsx5("h2", { style: styles4.title, children: title }),
3213
+ /* @__PURE__ */ jsxs4("div", { style: styles4.toolbarRight, children: [
3214
+ toolbarExtra,
3215
+ /* @__PURE__ */ jsx5("button", { type: "button", style: styles4.primaryBtn, onClick: openCreate, children: "\u65B0\u589E\u7528\u6237" })
3216
+ ] })
3217
+ ] }),
3218
+ /* @__PURE__ */ jsxs4("div", { style: styles4.searchBar, children: [
3219
+ /* @__PURE__ */ jsx5(
3220
+ "input",
3221
+ {
3222
+ style: { ...styles4.input, maxWidth: 240 },
3223
+ value: keywordInput,
3224
+ onChange: (e) => setKeywordInput(e.target.value),
3225
+ placeholder: "\u641C\u7D22\u8D26\u53F7 / \u7528\u6237\u540D",
3226
+ onKeyDown: (e) => {
3227
+ if (e.key === "Enter") handleSearch();
3228
+ }
3229
+ }
3230
+ ),
3231
+ /* @__PURE__ */ jsxs4(
3232
+ "select",
3233
+ {
3234
+ style: styles4.select,
3235
+ value: enabledFilter,
3236
+ onChange: (e) => {
3237
+ setPageToken("");
3238
+ setEnabledFilter(e.target.value);
3239
+ },
3240
+ children: [
3241
+ /* @__PURE__ */ jsx5("option", { value: "all", children: "\u5168\u90E8\u72B6\u6001" }),
3242
+ /* @__PURE__ */ jsx5("option", { value: "true", children: "\u5DF2\u542F\u7528" }),
3243
+ /* @__PURE__ */ jsx5("option", { value: "false", children: "\u5DF2\u7981\u7528" })
3244
+ ]
3245
+ }
3246
+ ),
3247
+ /* @__PURE__ */ jsx5("button", { type: "button", style: styles4.secondaryBtn, onClick: handleSearch, children: "\u67E5\u8BE2" }),
3248
+ /* @__PURE__ */ jsx5(
3249
+ "button",
3250
+ {
3251
+ type: "button",
3252
+ style: styles4.secondaryBtn,
3253
+ onClick: () => {
3254
+ setKeywordInput("");
3255
+ setKeyword("");
3256
+ setEnabledFilter("all");
3257
+ setPageToken("");
3258
+ },
3259
+ children: "\u91CD\u7F6E"
3260
+ }
3261
+ )
3262
+ ] }),
3263
+ error ? /* @__PURE__ */ jsx5("div", { style: styles4.error, children: error }) : null,
3264
+ /* @__PURE__ */ jsx5("div", { style: styles4.tableWrap, children: /* @__PURE__ */ jsxs4("table", { style: styles4.table, children: [
3265
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs4("tr", { children: [
3266
+ /* @__PURE__ */ jsx5("th", { style: styles4.th, children: "\u8D26\u53F7" }),
3267
+ /* @__PURE__ */ jsx5("th", { style: styles4.th, children: "\u7528\u6237\u540D" }),
3268
+ /* @__PURE__ */ jsx5("th", { style: styles4.th, children: "\u5F52\u5C5E\u90E8\u95E8" }),
3269
+ /* @__PURE__ */ jsx5("th", { style: styles4.th, children: "\u7528\u6237\u89D2\u8272" }),
3270
+ /* @__PURE__ */ jsx5("th", { style: { ...styles4.th, width: 90 }, children: "\u72B6\u6001" }),
3271
+ /* @__PURE__ */ jsx5("th", { style: { ...styles4.th, width: 140 }, children: "\u64CD\u4F5C" })
3272
+ ] }) }),
3273
+ /* @__PURE__ */ jsx5("tbody", { children: loading ? /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: 6, style: styles4.empty, children: "\u52A0\u8F7D\u4E2D\u2026" }) }) : records.length === 0 ? /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: 6, style: styles4.empty, children: "\u6682\u65E0\u6570\u636E" }) }) : records.map((row) => /* @__PURE__ */ jsxs4("tr", { children: [
3274
+ /* @__PURE__ */ jsx5("td", { style: styles4.td, children: row.username }),
3275
+ /* @__PURE__ */ jsx5("td", { style: styles4.td, children: row.name }),
3276
+ /* @__PURE__ */ jsx5("td", { style: styles4.td, children: groupLabel(row) }),
3277
+ /* @__PURE__ */ jsx5("td", { style: styles4.td, children: roleLabel(row) }),
3278
+ /* @__PURE__ */ jsx5("td", { style: styles4.td, children: /* @__PURE__ */ jsx5(
3279
+ "span",
3280
+ {
3281
+ style: {
3282
+ ...styles4.badge,
3283
+ ...row.enabled ? styles4.badgeOn : styles4.badgeOff
3284
+ },
3285
+ children: row.enabled ? "\u542F\u7528" : "\u7981\u7528"
3286
+ }
3287
+ ) }),
3288
+ /* @__PURE__ */ jsxs4("td", { style: styles4.td, children: [
3289
+ /* @__PURE__ */ jsx5("button", { type: "button", style: styles4.linkBtn, onClick: () => openEdit(row), children: "\u7F16\u8F91" }),
3290
+ /* @__PURE__ */ jsx5(
3291
+ "button",
3292
+ {
3293
+ type: "button",
3294
+ style: { ...styles4.linkBtn, color: "#d92d20" },
3295
+ onClick: () => askDelete(row),
3296
+ children: "\u5220\u9664"
3297
+ }
3298
+ )
3299
+ ] })
3300
+ ] }, row.userId)) })
3301
+ ] }) }),
3302
+ /* @__PURE__ */ jsxs4("div", { style: styles4.pagination, children: [
3303
+ /* @__PURE__ */ jsxs4("label", { style: styles4.pageSize, children: [
3304
+ "\u6BCF\u9875",
3305
+ /* @__PURE__ */ jsx5(
3306
+ "select",
3307
+ {
3308
+ value: pageSize,
3309
+ onChange: (e) => {
3310
+ setPageToken("");
3311
+ setPageSize(e.target.value);
3312
+ },
3313
+ style: styles4.select,
3314
+ children: PAGE_SIZE_OPTIONS4.map((size) => /* @__PURE__ */ jsx5("option", { value: size, children: size }, size))
3315
+ }
3316
+ )
3317
+ ] }),
3318
+ /* @__PURE__ */ jsxs4("div", { style: styles4.pageBtns, children: [
3319
+ /* @__PURE__ */ jsx5(
3320
+ "button",
3321
+ {
3322
+ type: "button",
3323
+ style: styles4.secondaryBtn,
3324
+ disabled: !hasPreviousPage || loading,
3325
+ onClick: () => void loadList("previous"),
3326
+ children: "\u4E0A\u4E00\u9875"
3327
+ }
3328
+ ),
3329
+ /* @__PURE__ */ jsx5(
3330
+ "button",
3331
+ {
3332
+ type: "button",
3333
+ style: styles4.secondaryBtn,
3334
+ disabled: !hasNextPage || loading,
3335
+ onClick: () => void loadList("next"),
3336
+ children: "\u4E0B\u4E00\u9875"
3337
+ }
3338
+ )
3339
+ ] })
3340
+ ] }),
3341
+ dialogOpen ? /* @__PURE__ */ jsx5("div", { style: styles4.mask, onClick: closeDialog, children: /* @__PURE__ */ jsxs4(
3342
+ "div",
3343
+ {
3344
+ style: { ...styles4.dialog, maxWidth: 560 },
3345
+ onClick: (e) => e.stopPropagation(),
3346
+ role: "dialog",
3347
+ "aria-modal": "true",
3348
+ children: [
3349
+ /* @__PURE__ */ jsxs4("div", { style: styles4.dialogHeader, children: [
3350
+ /* @__PURE__ */ jsx5("h3", { style: styles4.dialogTitle, children: editing ? "\u7F16\u8F91\u7528\u6237" : "\u65B0\u589E\u7528\u6237" }),
3351
+ /* @__PURE__ */ jsx5("button", { type: "button", style: styles4.iconBtn, onClick: closeDialog, "aria-label": "\u5173\u95ED", children: "\xD7" })
3352
+ ] }),
3353
+ /* @__PURE__ */ jsxs4("form", { style: styles4.form, onSubmit: (e) => void handleSubmit(e), children: [
3354
+ formError ? /* @__PURE__ */ jsx5("div", { style: styles4.error, children: formError }) : null,
3355
+ /* @__PURE__ */ jsxs4("label", { style: styles4.field, children: [
3356
+ /* @__PURE__ */ jsx5("span", { style: styles4.label, children: "\u8D26\u53F7" }),
3357
+ /* @__PURE__ */ jsx5(
3358
+ "input",
3359
+ {
3360
+ style: styles4.input,
3361
+ value: form.username,
3362
+ onChange: (e) => setForm((prev) => ({ ...prev, username: e.target.value })),
3363
+ placeholder: "\u81F3\u5C116\u4F4D\uFF0C\u9700\u542B\u5B57\u6BCD\u548C\u6570\u5B57",
3364
+ required: true
3365
+ }
3366
+ )
3367
+ ] }),
3368
+ /* @__PURE__ */ jsxs4("label", { style: styles4.field, children: [
3369
+ /* @__PURE__ */ jsx5("span", { style: styles4.label, children: "\u7528\u6237\u540D" }),
3370
+ /* @__PURE__ */ jsx5(
3371
+ "input",
3372
+ {
3373
+ style: styles4.input,
3374
+ value: form.name,
3375
+ onChange: (e) => setForm((prev) => ({ ...prev, name: e.target.value })),
3376
+ placeholder: "\u8BF7\u8F93\u5165\u7528\u6237\u540D",
3377
+ required: true
3378
+ }
3379
+ )
3380
+ ] }),
3381
+ /* @__PURE__ */ jsxs4("label", { style: styles4.field, children: [
3382
+ /* @__PURE__ */ jsx5("span", { style: styles4.label, children: editing ? "\u5BC6\u7801\uFF08\u7559\u7A7A\u5219\u4E0D\u4FEE\u6539\uFF09" : "\u521D\u59CB\u5BC6\u7801" }),
3383
+ /* @__PURE__ */ jsx5(
3384
+ "input",
3385
+ {
3386
+ style: styles4.input,
3387
+ type: "password",
3388
+ value: form.password,
3389
+ onChange: (e) => setForm((prev) => ({ ...prev, password: e.target.value })),
3390
+ placeholder: editing ? "\u7559\u7A7A\u8868\u793A\u4E0D\u4FEE\u6539\u5BC6\u7801" : "\u8BF7\u8F93\u5165\u521D\u59CB\u5BC6\u7801",
3391
+ required: !editing,
3392
+ autoComplete: "new-password"
3393
+ }
3394
+ )
3395
+ ] }),
3396
+ /* @__PURE__ */ jsxs4("fieldset", { style: styles4.fieldset, children: [
3397
+ /* @__PURE__ */ jsx5("legend", { style: styles4.label, children: "\u5F52\u5C5E\u90E8\u95E8" }),
3398
+ /* @__PURE__ */ jsx5("div", { style: styles4.multiSelect, children: optionsLoading ? /* @__PURE__ */ jsx5("div", { style: styles4.hint, children: "\u52A0\u8F7D\u4E2D\u2026" }) : groups.length === 0 ? /* @__PURE__ */ jsx5("div", { style: styles4.hint, children: "\u6682\u65E0\u90E8\u95E8\u6570\u636E" }) : groups.map((g) => /* @__PURE__ */ jsxs4("label", { style: styles4.checkItem, children: [
3399
+ /* @__PURE__ */ jsx5(
3400
+ "input",
3401
+ {
3402
+ type: "checkbox",
3403
+ style: styles4.control,
3404
+ checked: form.groupIds.includes(g.groupId),
3405
+ onChange: () => toggleId("groupIds", g.groupId)
3406
+ }
3407
+ ),
3408
+ /* @__PURE__ */ jsx5("span", { children: g.name || g.groupId })
3409
+ ] }, g.groupId)) })
3410
+ ] }),
3411
+ /* @__PURE__ */ jsxs4("fieldset", { style: styles4.fieldset, children: [
3412
+ /* @__PURE__ */ jsx5("legend", { style: styles4.label, children: "\u7528\u6237\u89D2\u8272" }),
3413
+ /* @__PURE__ */ jsx5("div", { style: styles4.multiSelect, children: optionsLoading ? /* @__PURE__ */ jsx5("div", { style: styles4.hint, children: "\u52A0\u8F7D\u4E2D\u2026" }) : roles.length === 0 ? /* @__PURE__ */ jsx5("div", { style: styles4.hint, children: "\u6682\u65E0\u89D2\u8272\u6570\u636E" }) : roles.map((r) => /* @__PURE__ */ jsxs4("label", { style: styles4.checkItem, children: [
3414
+ /* @__PURE__ */ jsx5(
3415
+ "input",
3416
+ {
3417
+ type: "checkbox",
3418
+ style: styles4.control,
3419
+ checked: form.roleIds.includes(r.roleId),
3420
+ onChange: () => toggleId("roleIds", r.roleId)
3421
+ }
3422
+ ),
3423
+ /* @__PURE__ */ jsx5("span", { children: r.name || r.roleId })
3424
+ ] }, r.roleId)) })
3425
+ ] }),
3426
+ /* @__PURE__ */ jsxs4("div", { style: styles4.switchRow, children: [
3427
+ /* @__PURE__ */ jsx5("span", { style: styles4.label, children: "\u662F\u5426\u542F\u7528" }),
3428
+ /* @__PURE__ */ jsx5(
3429
+ "button",
3430
+ {
3431
+ type: "button",
3432
+ role: "switch",
3433
+ "aria-checked": form.enabled,
3434
+ style: {
3435
+ ...styles4.switchTrack,
3436
+ ...form.enabled ? styles4.switchTrackOn : null
3437
+ },
3438
+ onClick: () => setForm((prev) => ({ ...prev, enabled: !prev.enabled })),
3439
+ children: /* @__PURE__ */ jsx5(
3440
+ "span",
3441
+ {
3442
+ style: {
3443
+ ...styles4.switchThumb,
3444
+ ...form.enabled ? styles4.switchThumbOn : null
3445
+ }
3446
+ }
3447
+ )
3448
+ }
3449
+ )
3450
+ ] }),
3451
+ /* @__PURE__ */ jsxs4("div", { style: styles4.dialogFooter, children: [
3452
+ /* @__PURE__ */ jsx5("button", { type: "button", style: styles4.secondaryBtn, onClick: closeDialog, children: "\u53D6\u6D88" }),
3453
+ /* @__PURE__ */ jsx5("button", { type: "submit", style: styles4.primaryBtn, disabled: saving, children: saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
3454
+ ] })
3455
+ ] })
3456
+ ]
3457
+ }
3458
+ ) }) : null,
3459
+ deletingRow ? /* @__PURE__ */ jsx5("div", { style: styles4.mask, onClick: closeDeleteDialog, children: /* @__PURE__ */ jsxs4(
3460
+ "div",
3461
+ {
3462
+ style: { ...styles4.dialog, maxWidth: 420 },
3463
+ onClick: (e) => e.stopPropagation(),
3464
+ role: "dialog",
3465
+ "aria-modal": "true",
3466
+ children: [
3467
+ /* @__PURE__ */ jsxs4("div", { style: styles4.dialogHeader, children: [
3468
+ /* @__PURE__ */ jsx5("h3", { style: styles4.dialogTitle, children: "\u786E\u8BA4\u5220\u9664" }),
3469
+ /* @__PURE__ */ jsx5(
3470
+ "button",
3471
+ {
3472
+ type: "button",
3473
+ style: styles4.iconBtn,
3474
+ onClick: closeDeleteDialog,
3475
+ "aria-label": "\u5173\u95ED",
3476
+ children: "\xD7"
3477
+ }
3478
+ )
3479
+ ] }),
3480
+ /* @__PURE__ */ jsxs4("div", { style: styles4.confirmBody, children: [
3481
+ /* @__PURE__ */ jsxs4("p", { style: styles4.confirmText, children: [
3482
+ "\u786E\u8BA4\u5220\u9664\u7528\u6237\u300C",
3483
+ /* @__PURE__ */ jsx5("strong", { children: deletingRow.name }),
3484
+ "\u300D\uFF08",
3485
+ deletingRow.username,
3486
+ "\uFF09\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002"
3487
+ ] }),
3488
+ /* @__PURE__ */ jsxs4("div", { style: styles4.dialogFooter, children: [
3489
+ /* @__PURE__ */ jsx5(
3490
+ "button",
3491
+ {
3492
+ type: "button",
3493
+ style: styles4.secondaryBtn,
3494
+ onClick: closeDeleteDialog,
3495
+ disabled: deleting,
3496
+ children: "\u53D6\u6D88"
3497
+ }
3498
+ ),
3499
+ /* @__PURE__ */ jsx5(
3500
+ "button",
3501
+ {
3502
+ type: "button",
3503
+ style: styles4.dangerBtn,
3504
+ onClick: () => void confirmDelete(),
3505
+ disabled: deleting,
3506
+ children: deleting ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u5220\u9664"
3507
+ }
3508
+ )
3509
+ ] })
3510
+ ] })
3511
+ ]
3512
+ }
3513
+ ) }) : null
3514
+ ] });
3515
+ }
3516
+ var styles4 = {
3517
+ root: {
3518
+ display: "flex",
3519
+ flexDirection: "column",
3520
+ gap: 16,
3521
+ padding: 16,
3522
+ color: "#101828",
3523
+ fontFamily: '"PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, sans-serif'
3524
+ },
3525
+ toolbar: {
3526
+ display: "flex",
3527
+ alignItems: "center",
3528
+ justifyContent: "space-between",
3529
+ gap: 12
3530
+ },
3531
+ title: { margin: 0, fontSize: 18, fontWeight: 600 },
3532
+ toolbarRight: { display: "flex", alignItems: "center", gap: 8 },
3533
+ searchBar: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" },
3534
+ error: {
3535
+ padding: "10px 12px",
3536
+ borderRadius: 8,
3537
+ background: "#fef3f2",
3538
+ color: "#b42318",
3539
+ fontSize: 13
3540
+ },
3541
+ tableWrap: {
3542
+ overflow: "auto",
3543
+ border: "1px solid #eaecf0",
3544
+ borderRadius: 10,
3545
+ background: "#fff"
3546
+ },
3547
+ table: { width: "100%", borderCollapse: "collapse", minWidth: 720 },
3548
+ th: {
3549
+ textAlign: "left",
3550
+ padding: "12px 14px",
3551
+ fontSize: 13,
3552
+ fontWeight: 600,
3553
+ color: "#475467",
3554
+ background: "#f9fafb",
3555
+ borderBottom: "1px solid #eaecf0"
3556
+ },
3557
+ td: {
3558
+ padding: "12px 14px",
3559
+ fontSize: 14,
3560
+ borderBottom: "1px solid #f2f4f7",
3561
+ verticalAlign: "middle"
3562
+ },
3563
+ empty: { padding: 28, textAlign: "center", color: "#98a2b3", fontSize: 14 },
3564
+ linkBtn: {
3565
+ border: "none",
3566
+ background: "transparent",
3567
+ color: "#049BAD",
3568
+ cursor: "pointer",
3569
+ padding: "0 8px 0 0",
3570
+ fontSize: 13
3571
+ },
3572
+ badge: {
3573
+ display: "inline-block",
3574
+ padding: "2px 8px",
3575
+ borderRadius: 999,
3576
+ fontSize: 12,
3577
+ fontWeight: 500
3578
+ },
3579
+ badgeOn: { background: "#ecfdf3", color: "#027a48" },
3580
+ badgeOff: { background: "#f2f4f7", color: "#667085" },
3581
+ pagination: {
3582
+ display: "flex",
3583
+ alignItems: "center",
3584
+ justifyContent: "space-between",
3585
+ gap: 12
3586
+ },
3587
+ pageSize: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "#475467" },
3588
+ pageBtns: { display: "flex", gap: 8 },
3589
+ primaryBtn: {
3590
+ border: "none",
3591
+ background: "#049BAD",
3592
+ color: "#fff",
3593
+ borderRadius: 8,
3594
+ padding: "8px 14px",
3595
+ cursor: "pointer",
3596
+ fontSize: 14
3597
+ },
3598
+ secondaryBtn: {
3599
+ border: "1px solid #d0d5dd",
3600
+ background: "#fff",
3601
+ color: "#344054",
3602
+ borderRadius: 8,
3603
+ padding: "8px 14px",
3604
+ cursor: "pointer",
3605
+ fontSize: 14
3606
+ },
3607
+ dangerBtn: {
3608
+ border: "none",
3609
+ background: "#d92d20",
3610
+ color: "#fff",
3611
+ borderRadius: 8,
3612
+ padding: "8px 14px",
3613
+ cursor: "pointer",
3614
+ fontSize: 14
3615
+ },
3616
+ select: {
3617
+ border: "1px solid #d0d5dd",
3618
+ borderRadius: 6,
3619
+ padding: "4px 8px",
3620
+ fontSize: 13,
3621
+ backgroundColor: "#ffffff",
3622
+ color: "#101828"
3623
+ },
3624
+ mask: {
3625
+ position: "fixed",
3626
+ inset: 0,
3627
+ background: "rgba(16, 24, 40, 0.45)",
3628
+ display: "flex",
3629
+ alignItems: "center",
3630
+ justifyContent: "center",
3631
+ zIndex: 1e3,
3632
+ padding: 16
3633
+ },
3634
+ dialog: {
3635
+ width: "100%",
3636
+ maxWidth: 480,
3637
+ background: "#fff",
3638
+ borderRadius: 12,
3639
+ boxShadow: "0 20px 40px rgba(16,24,40,0.18)",
3640
+ maxHeight: "90vh",
3641
+ overflow: "auto"
3642
+ },
3643
+ dialogHeader: {
3644
+ display: "flex",
3645
+ alignItems: "center",
3646
+ justifyContent: "space-between",
3647
+ padding: "14px 16px",
3648
+ borderBottom: "1px solid #eaecf0",
3649
+ position: "sticky",
3650
+ top: 0,
3651
+ background: "#fff",
3652
+ zIndex: 1
3653
+ },
3654
+ dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },
3655
+ iconBtn: {
3656
+ border: "none",
3657
+ background: "transparent",
3658
+ fontSize: 22,
3659
+ lineHeight: 1,
3660
+ cursor: "pointer",
3661
+ color: "#667085"
3662
+ },
3663
+ form: { display: "flex", flexDirection: "column", gap: 12, padding: 16 },
3664
+ confirmBody: { display: "flex", flexDirection: "column", gap: 16, padding: 16 },
3665
+ confirmText: { margin: 0, fontSize: 14, color: "#344054", lineHeight: 1.6 },
3666
+ field: { display: "flex", flexDirection: "column", gap: 6 },
3667
+ fieldset: {
3668
+ border: "1px solid #eaecf0",
3669
+ borderRadius: 8,
3670
+ margin: 0,
3671
+ padding: "10px 12px 12px"
3672
+ },
3673
+ label: { fontSize: 13, color: "#344054", fontWeight: 500 },
3674
+ input: {
3675
+ border: "1px solid #d0d5dd",
3676
+ borderRadius: 8,
3677
+ padding: "8px 10px",
3678
+ fontSize: 14,
3679
+ outline: "none",
3680
+ backgroundColor: "#ffffff",
3681
+ color: "#101828",
3682
+ boxSizing: "border-box",
3683
+ width: "100%"
3684
+ },
3685
+ multiSelect: {
3686
+ display: "flex",
3687
+ flexDirection: "column",
3688
+ gap: 6,
3689
+ maxHeight: 160,
3690
+ overflow: "auto"
3691
+ },
3692
+ checkItem: {
3693
+ display: "flex",
3694
+ alignItems: "center",
3695
+ gap: 8,
3696
+ fontSize: 14,
3697
+ color: "#101828",
3698
+ cursor: "pointer"
3699
+ },
3700
+ control: {
3701
+ width: 16,
3702
+ height: 16,
3703
+ accentColor: "#049BAD",
3704
+ cursor: "pointer",
3705
+ colorScheme: "light",
3706
+ backgroundColor: "#ffffff"
3707
+ },
3708
+ hint: { fontSize: 13, color: "#98a2b3", padding: "4px 0" },
3709
+ switchRow: {
3710
+ display: "flex",
3711
+ alignItems: "center",
3712
+ justifyContent: "space-between",
3713
+ gap: 12
3714
+ },
3715
+ switchTrack: {
3716
+ width: 44,
3717
+ height: 24,
3718
+ borderRadius: 999,
3719
+ border: "none",
3720
+ padding: 2,
3721
+ background: "#d0d5dd",
3722
+ cursor: "pointer",
3723
+ position: "relative",
3724
+ transition: "background 0.15s ease"
3725
+ },
3726
+ switchTrackOn: { background: "#049BAD" },
3727
+ switchThumb: {
3728
+ display: "block",
3729
+ width: 20,
3730
+ height: 20,
3731
+ borderRadius: "50%",
3732
+ background: "#fff",
3733
+ boxShadow: "0 1px 2px rgba(16,24,40,0.2)",
3734
+ transform: "translateX(0)",
3735
+ transition: "transform 0.15s ease"
3736
+ },
3737
+ switchThumbOn: { transform: "translateX(20px)" },
3738
+ dialogFooter: {
3739
+ display: "flex",
3740
+ justifyContent: "flex-end",
3741
+ gap: 8,
3742
+ paddingTop: 4
3743
+ }
3744
+ };
3745
+
3746
+ // src/react/SystemAdmin.tsx
3747
+ import { useMemo as useMemo4, useState as useState6 } from "react";
3748
+
3749
+ // src/admin/menu.ts
3750
+ var SYSTEM_ADMIN_MENU = {
3751
+ key: "system",
3752
+ label: "\u7CFB\u7EDF\u7BA1\u7406",
3753
+ children: [
3754
+ { key: "menu", label: "\u83DC\u5355\u7BA1\u7406" },
3755
+ { key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" },
3756
+ { key: "role", label: "\u89D2\u8272\u7BA1\u7406" },
3757
+ { key: "user", label: "\u7528\u6237\u7BA1\u7406" }
3758
+ ]
3759
+ };
3760
+ var SYSTEM_ADMIN_DEFAULT_KEY = "menu";
3761
+
3762
+ // src/react/SystemAdmin.tsx
3763
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
3764
+ function SystemAdmin({
3765
+ menuApi,
3766
+ resourceApi,
3767
+ roleApi,
3768
+ userApi,
3769
+ defaultActiveKey = SYSTEM_ADMIN_DEFAULT_KEY,
3770
+ activeKey: controlledKey,
3771
+ onActiveKeyChange,
3772
+ title = SYSTEM_ADMIN_MENU.label,
3773
+ toolbarExtra
3774
+ }) {
3775
+ const [innerKey, setInnerKey] = useState6(defaultActiveKey);
3776
+ const activeKey = controlledKey ?? innerKey;
3777
+ const setActiveKey = (key) => {
3778
+ if (controlledKey === void 0) setInnerKey(key);
3779
+ onActiveKeyChange?.(key);
3780
+ };
3781
+ const activeLabel = useMemo4(
3782
+ () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey)?.label ?? "",
3783
+ [activeKey]
3784
+ );
3785
+ return /* @__PURE__ */ jsxs5("div", { style: styles5.root, children: [
3786
+ /* @__PURE__ */ jsxs5("aside", { style: styles5.sidebar, children: [
3787
+ /* @__PURE__ */ jsx6("div", { style: styles5.sidebarTitle, children: title }),
3788
+ /* @__PURE__ */ jsx6("nav", { style: styles5.nav, children: SYSTEM_ADMIN_MENU.children.map((item) => {
2845
3789
  const active = item.key === activeKey;
2846
- return /* @__PURE__ */ jsx5(
3790
+ return /* @__PURE__ */ jsx6(
2847
3791
  "button",
2848
3792
  {
2849
3793
  type: "button",
2850
3794
  style: {
2851
- ...styles4.navItem,
2852
- ...active ? styles4.navItemActive : null
3795
+ ...styles5.navItem,
3796
+ ...active ? styles5.navItemActive : null
2853
3797
  },
2854
3798
  onClick: () => setActiveKey(item.key),
2855
3799
  children: item.label
@@ -2858,20 +3802,20 @@ function SystemAdmin({
2858
3802
  );
2859
3803
  }) })
2860
3804
  ] }),
2861
- /* @__PURE__ */ jsxs4("main", { style: styles4.content, children: [
2862
- /* @__PURE__ */ jsxs4("div", { style: styles4.contentHeader, children: [
2863
- /* @__PURE__ */ jsxs4("div", { style: styles4.breadcrumb, children: [
2864
- /* @__PURE__ */ jsx5("span", { style: styles4.breadcrumbParent, children: title }),
2865
- /* @__PURE__ */ jsx5("span", { style: styles4.breadcrumbSep, children: "/" }),
2866
- /* @__PURE__ */ jsx5("span", { style: styles4.breadcrumbCurrent, children: activeLabel })
3805
+ /* @__PURE__ */ jsxs5("main", { style: styles5.content, children: [
3806
+ /* @__PURE__ */ jsxs5("div", { style: styles5.contentHeader, children: [
3807
+ /* @__PURE__ */ jsxs5("div", { style: styles5.breadcrumb, children: [
3808
+ /* @__PURE__ */ jsx6("span", { style: styles5.breadcrumbParent, children: title }),
3809
+ /* @__PURE__ */ jsx6("span", { style: styles5.breadcrumbSep, children: "/" }),
3810
+ /* @__PURE__ */ jsx6("span", { style: styles5.breadcrumbCurrent, children: activeLabel })
2867
3811
  ] }),
2868
3812
  toolbarExtra
2869
3813
  ] }),
2870
- /* @__PURE__ */ jsx5("div", { style: styles4.panel, children: activeKey === "menu" ? /* @__PURE__ */ jsx5(MenuManager, { api: menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : activeKey === "resource" ? /* @__PURE__ */ jsx5(ResourceManager, { api: resourceApi, title: "\u6743\u9650\u70B9\u7BA1\u7406" }) : /* @__PURE__ */ jsx5(RoleManager, { api: roleApi, title: "\u89D2\u8272\u7BA1\u7406" }) })
3814
+ /* @__PURE__ */ jsx6("div", { style: styles5.panel, children: activeKey === "menu" ? /* @__PURE__ */ jsx6(MenuManager, { api: menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : activeKey === "resource" ? /* @__PURE__ */ jsx6(ResourceManager, { api: resourceApi, title: "\u6743\u9650\u70B9\u7BA1\u7406" }) : activeKey === "role" ? /* @__PURE__ */ jsx6(RoleManager, { api: roleApi, title: "\u89D2\u8272\u7BA1\u7406" }) : /* @__PURE__ */ jsx6(UserManager, { api: userApi, title: "\u7528\u6237\u7BA1\u7406" }) })
2871
3815
  ] })
2872
3816
  ] });
2873
3817
  }
2874
- var styles4 = {
3818
+ var styles5 = {
2875
3819
  root: {
2876
3820
  display: "flex",
2877
3821
  minHeight: 560,
@@ -2971,34 +3915,47 @@ export {
2971
3915
  SYSTEM_ADMIN_DEFAULT_KEY,
2972
3916
  SYSTEM_ADMIN_MENU,
2973
3917
  SystemAdmin,
3918
+ UserManager,
2974
3919
  appendQueryParam,
2975
3920
  buildCreateBody,
2976
3921
  buildCreateMenuBody,
2977
3922
  buildCreateRoleBody,
3923
+ buildCreateUserBody,
3924
+ buildPermissionTreeIndex,
2978
3925
  buildSavePermissionsBody,
2979
3926
  buildUpdateBody,
2980
3927
  buildUpdateMenuBody,
2981
3928
  buildUpdateRoleBody,
3929
+ buildUpdateUserBody,
2982
3930
  collectTreeResourceIds,
3931
+ countCheckedDescendants,
2983
3932
  createAuthorizationResourceApi,
2984
3933
  createDefaultResourceRequest,
2985
3934
  createMenuResourceApi,
2986
3935
  createPermissionStore,
2987
3936
  createSystemRoleApi,
3937
+ createSystemUserApi,
2988
3938
  extractPagination,
2989
3939
  extractRecords,
2990
3940
  getAppClientId,
2991
3941
  getDeviceWorkerId,
3942
+ hasCheckedDescendant,
2992
3943
  isMenuLeaf,
3944
+ isPermissionNodeIndeterminate,
2993
3945
  mapAuthorizationResource,
2994
3946
  mapMenuResource,
2995
3947
  mapPermissionTreeNode,
2996
3948
  mapRolePermissions,
3949
+ mapSystemGroupOption,
2997
3950
  mapSystemRole,
3951
+ mapSystemRoleOption,
3952
+ mapSystemUser,
2998
3953
  resolveMenuDepth,
2999
3954
  snowyflake,
3955
+ togglePermissionCheck,
3000
3956
  useHasPermission,
3001
3957
  useHasRole,
3002
- usePermission
3958
+ usePermission,
3959
+ validateUsername
3003
3960
  };
3004
3961
  //# sourceMappingURL=index.js.map