com-angel-authorization 1.0.17 → 1.0.20

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.
@@ -46,15 +46,18 @@ __export(react_exports, {
46
46
  SYSTEM_ADMIN_DEFAULT_KEY: () => SYSTEM_ADMIN_DEFAULT_KEY,
47
47
  SYSTEM_ADMIN_MENU: () => SYSTEM_ADMIN_MENU,
48
48
  SystemAdmin: () => SystemAdmin,
49
+ UserManager: () => UserManager,
49
50
  appendQueryParam: () => appendQueryParam,
50
51
  buildCreateBody: () => buildCreateBody,
51
52
  buildCreateMenuBody: () => buildCreateMenuBody,
52
53
  buildCreateRoleBody: () => buildCreateRoleBody,
54
+ buildCreateUserBody: () => buildCreateUserBody,
53
55
  buildPermissionTreeIndex: () => buildPermissionTreeIndex,
54
56
  buildSavePermissionsBody: () => buildSavePermissionsBody,
55
57
  buildUpdateBody: () => buildUpdateBody,
56
58
  buildUpdateMenuBody: () => buildUpdateMenuBody,
57
59
  buildUpdateRoleBody: () => buildUpdateRoleBody,
60
+ buildUpdateUserBody: () => buildUpdateUserBody,
58
61
  collectTreeResourceIds: () => collectTreeResourceIds,
59
62
  countCheckedDescendants: () => countCheckedDescendants,
60
63
  createAuthorizationResourceApi: () => createAuthorizationResourceApi,
@@ -62,6 +65,7 @@ __export(react_exports, {
62
65
  createMenuResourceApi: () => createMenuResourceApi,
63
66
  createPermissionStore: () => createPermissionStore,
64
67
  createSystemRoleApi: () => createSystemRoleApi,
68
+ createSystemUserApi: () => createSystemUserApi,
65
69
  extractPagination: () => extractPagination,
66
70
  extractRecords: () => extractRecords,
67
71
  getAppClientId: () => getAppClientId,
@@ -73,13 +77,17 @@ __export(react_exports, {
73
77
  mapMenuResource: () => mapMenuResource,
74
78
  mapPermissionTreeNode: () => mapPermissionTreeNode,
75
79
  mapRolePermissions: () => mapRolePermissions,
80
+ mapSystemGroupOption: () => mapSystemGroupOption,
76
81
  mapSystemRole: () => mapSystemRole,
82
+ mapSystemRoleOption: () => mapSystemRoleOption,
83
+ mapSystemUser: () => mapSystemUser,
77
84
  resolveMenuDepth: () => resolveMenuDepth,
78
85
  snowyflake: () => snowyflake,
79
86
  togglePermissionCheck: () => togglePermissionCheck,
80
87
  useHasPermission: () => useHasPermission,
81
88
  useHasRole: () => useHasRole,
82
- usePermission: () => usePermission
89
+ usePermission: () => usePermission,
90
+ validateUsername: () => validateUsername
83
91
  });
84
92
  module.exports = __toCommonJS(react_exports);
85
93
 
@@ -2903,55 +2911,1038 @@ var styles3 = {
2903
2911
  }
2904
2912
  };
2905
2913
 
2914
+ // src/react/UserManager.tsx
2915
+ var import_react5 = require("react");
2916
+
2917
+ // src/users/index.ts
2918
+ function asIdList(value) {
2919
+ if (!Array.isArray(value)) return [];
2920
+ return value.map((item) => {
2921
+ if (item === void 0 || item === null || item === "") return "";
2922
+ if (typeof item === "object") {
2923
+ const row = item;
2924
+ const id = row.groupId ?? row.roleId ?? row.id;
2925
+ return id === void 0 || id === null ? "" : String(id);
2926
+ }
2927
+ return String(item);
2928
+ }).filter(Boolean);
2929
+ }
2930
+ function asNameList(value) {
2931
+ if (!Array.isArray(value)) return void 0;
2932
+ const names = value.map((item) => {
2933
+ if (item === void 0 || item === null) return "";
2934
+ if (typeof item === "object") {
2935
+ return String(item.name ?? "");
2936
+ }
2937
+ return String(item);
2938
+ }).filter(Boolean);
2939
+ return names.length ? names : void 0;
2940
+ }
2941
+ function mapSystemUser(item) {
2942
+ if (!item || typeof item !== "object") return null;
2943
+ const row = item;
2944
+ const userId = row.userId ?? row.user_id ?? row.id;
2945
+ if (userId === void 0 || userId === null || userId === "") return null;
2946
+ return {
2947
+ userId: String(userId),
2948
+ username: String(row.username ?? row.account ?? ""),
2949
+ name: String(row.name ?? ""),
2950
+ groupIds: asIdList(row.groupIds ?? row.group_ids ?? row.groups),
2951
+ roleIds: asIdList(row.roleIds ?? row.role_ids ?? row.roles),
2952
+ groupNames: asNameList(row.groupNames ?? row.group_names ?? row.groups),
2953
+ roleNames: asNameList(row.roleNames ?? row.role_names ?? row.roles),
2954
+ enabled: Boolean(row.enabled ?? row.enable ?? true)
2955
+ };
2956
+ }
2957
+ function mapSystemGroupOption(item) {
2958
+ if (!item || typeof item !== "object") return null;
2959
+ const row = item;
2960
+ const groupId = row.groupId ?? row.group_id ?? row.id;
2961
+ if (groupId === void 0 || groupId === null || groupId === "") return null;
2962
+ return {
2963
+ groupId: String(groupId),
2964
+ name: String(row.name ?? "")
2965
+ };
2966
+ }
2967
+ function mapSystemRoleOption(item) {
2968
+ if (!item || typeof item !== "object") return null;
2969
+ const row = item;
2970
+ const roleId = row.roleId ?? row.role_id ?? row.id;
2971
+ if (roleId === void 0 || roleId === null || roleId === "") return null;
2972
+ return {
2973
+ roleId: String(roleId),
2974
+ name: String(row.name ?? "")
2975
+ };
2976
+ }
2977
+ function validateUsername(username) {
2978
+ const value = username.trim();
2979
+ if (value.length < 6) return "\u8D26\u53F7\u957F\u5EA6\u4E0D\u5C11\u4E8E 6 \u4E2A\u5B57\u7B26";
2980
+ if (!/[A-Za-z]/.test(value) || !/[0-9]/.test(value)) {
2981
+ return "\u8D26\u53F7\u9700\u540C\u65F6\u5305\u542B\u5B57\u6BCD\u548C\u6570\u5B57";
2982
+ }
2983
+ return null;
2984
+ }
2985
+ function buildListUrl3(params) {
2986
+ const parts = [];
2987
+ appendQueryParam(parts, "keyword", params?.keyword ?? "");
2988
+ if (params?.enabled !== void 0) {
2989
+ appendQueryParam(parts, "enabled", String(params.enabled));
2990
+ }
2991
+ appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
2992
+ appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
2993
+ appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
2994
+ return parts.length ? `/system/users?${parts.join("&")}` : "/system/users";
2995
+ }
2996
+ function buildKeywordUrl(base, keyword) {
2997
+ const parts = [];
2998
+ appendQueryParam(parts, "keyword", keyword ?? "");
2999
+ return parts.length ? `${base}?${parts.join("&")}` : base;
3000
+ }
3001
+ function buildCreateUserBody(values) {
3002
+ return {
3003
+ username: values.username.trim(),
3004
+ name: values.name.trim(),
3005
+ password: values.password,
3006
+ groupIds: [...new Set(values.groupIds.map(String))],
3007
+ roleIds: [...new Set(values.roleIds.map(String))],
3008
+ enabled: Boolean(values.enabled)
3009
+ };
3010
+ }
3011
+ function buildUpdateUserBody(values) {
3012
+ const body = {
3013
+ username: values.username.trim(),
3014
+ name: values.name.trim(),
3015
+ groupIds: [...new Set(values.groupIds.map(String))],
3016
+ roleIds: [...new Set(values.roleIds.map(String))],
3017
+ enabled: Boolean(values.enabled)
3018
+ };
3019
+ if (values.password.trim()) {
3020
+ body.password = values.password;
3021
+ }
3022
+ return body;
3023
+ }
3024
+ function createSystemUserApi(request) {
3025
+ return {
3026
+ async list(params, signal) {
3027
+ const json = await request({
3028
+ method: "GET",
3029
+ url: buildListUrl3(params),
3030
+ signal
3031
+ });
3032
+ const records = extractRecords(json).map(mapSystemUser).filter((item) => item !== null);
3033
+ return {
3034
+ records,
3035
+ ...extractPagination(json)
3036
+ };
3037
+ },
3038
+ async create(values, signal) {
3039
+ return request({
3040
+ method: "POST",
3041
+ url: "/system/users",
3042
+ body: buildCreateUserBody(values),
3043
+ signal
3044
+ });
3045
+ },
3046
+ async update(userId, values, signal) {
3047
+ return request({
3048
+ method: "PATCH",
3049
+ url: `/system/users/${encodeURIComponent(userId)}`,
3050
+ body: buildUpdateUserBody(values),
3051
+ signal
3052
+ });
3053
+ },
3054
+ async remove(userId, signal) {
3055
+ return request({
3056
+ method: "DELETE",
3057
+ url: `/system/users/${encodeURIComponent(userId)}`,
3058
+ signal
3059
+ });
3060
+ },
3061
+ async listGroups(params, signal) {
3062
+ const json = await request({
3063
+ method: "GET",
3064
+ url: buildKeywordUrl("/system/groups", params?.keyword),
3065
+ signal
3066
+ });
3067
+ return extractRecords(json).map(mapSystemGroupOption).filter((item) => item !== null);
3068
+ },
3069
+ async listRoleOptions(params, signal) {
3070
+ const json = await request({
3071
+ method: "GET",
3072
+ url: buildKeywordUrl("/system/roles", params?.keyword),
3073
+ signal
3074
+ });
3075
+ return extractRecords(json).map(mapSystemRoleOption).filter((item) => item !== null);
3076
+ }
3077
+ };
3078
+ }
3079
+
3080
+ // src/react/UserManager.tsx
3081
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3082
+ var PAGE_SIZE_OPTIONS4 = ["10", "20", "50", "100"];
3083
+ var emptyForm4 = () => ({
3084
+ username: "",
3085
+ name: "",
3086
+ password: "",
3087
+ groupIds: [],
3088
+ roleIds: [],
3089
+ enabled: true
3090
+ });
3091
+ function UserManager({
3092
+ api,
3093
+ title = "\u7528\u6237\u7BA1\u7406",
3094
+ pageSize: initialPageSize = "20",
3095
+ toolbarExtra
3096
+ }) {
3097
+ const [records, setRecords] = (0, import_react5.useState)([]);
3098
+ const [loading, setLoading] = (0, import_react5.useState)(false);
3099
+ const [error, setError] = (0, import_react5.useState)("");
3100
+ const [keyword, setKeyword] = (0, import_react5.useState)("");
3101
+ const [keywordInput, setKeywordInput] = (0, import_react5.useState)("");
3102
+ const [enabledFilter, setEnabledFilter] = (0, import_react5.useState)("all");
3103
+ const [pageSize, setPageSize] = (0, import_react5.useState)(initialPageSize);
3104
+ const [pageToken, setPageToken] = (0, import_react5.useState)("");
3105
+ const [hasPreviousPage, setHasPreviousPage] = (0, import_react5.useState)(false);
3106
+ const [hasNextPage, setHasNextPage] = (0, import_react5.useState)(false);
3107
+ const [dialogOpen, setDialogOpen] = (0, import_react5.useState)(false);
3108
+ const [editing, setEditing] = (0, import_react5.useState)(null);
3109
+ const [form, setForm] = (0, import_react5.useState)(emptyForm4);
3110
+ const [formError, setFormError] = (0, import_react5.useState)("");
3111
+ const [saving, setSaving] = (0, import_react5.useState)(false);
3112
+ const [deletingRow, setDeletingRow] = (0, import_react5.useState)(null);
3113
+ const [deleting, setDeleting] = (0, import_react5.useState)(false);
3114
+ const [groups, setGroups] = (0, import_react5.useState)([]);
3115
+ const [roles, setRoles] = (0, import_react5.useState)([]);
3116
+ const [rolesLoading, setRolesLoading] = (0, import_react5.useState)(false);
3117
+ const [groupsOpen, setGroupsOpen] = (0, import_react5.useState)(false);
3118
+ const [groupsLoading, setGroupsLoading] = (0, import_react5.useState)(false);
3119
+ const [groupsLoaded, setGroupsLoaded] = (0, import_react5.useState)(false);
3120
+ const enabledParam = enabledFilter === "all" ? void 0 : enabledFilter === "true";
3121
+ const loadList = (0, import_react5.useCallback)(
3122
+ async (direction = "current", token = pageToken) => {
3123
+ setLoading(true);
3124
+ setError("");
3125
+ try {
3126
+ const result = await api.list({
3127
+ keyword,
3128
+ enabled: enabledParam,
3129
+ pagination: {
3130
+ pageToken: token,
3131
+ pageSize,
3132
+ pageDirection: direction
3133
+ }
3134
+ });
3135
+ setRecords(result.records);
3136
+ setPageToken(result.pageToken);
3137
+ setHasPreviousPage(result.hasPreviousPage);
3138
+ setHasNextPage(result.hasNextPage);
3139
+ } catch (err) {
3140
+ setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u5931\u8D25");
3141
+ } finally {
3142
+ setLoading(false);
3143
+ }
3144
+ },
3145
+ [api, keyword, enabledParam, pageSize, pageToken]
3146
+ );
3147
+ (0, import_react5.useEffect)(() => {
3148
+ void loadList("current", "");
3149
+ }, [api, pageSize, keyword, enabledFilter]);
3150
+ const loadRoles = (0, import_react5.useCallback)(async () => {
3151
+ setRolesLoading(true);
3152
+ try {
3153
+ setRoles(await api.listRoleOptions());
3154
+ } catch (err) {
3155
+ setFormError(err instanceof Error ? err.message : "\u52A0\u8F7D\u89D2\u8272\u5931\u8D25");
3156
+ } finally {
3157
+ setRolesLoading(false);
3158
+ }
3159
+ }, [api]);
3160
+ const loadGroups = (0, import_react5.useCallback)(async () => {
3161
+ if (groupsLoaded || groupsLoading) return;
3162
+ setGroupsLoading(true);
3163
+ try {
3164
+ setGroups(await api.listGroups());
3165
+ setGroupsLoaded(true);
3166
+ } catch (err) {
3167
+ setFormError(err instanceof Error ? err.message : "\u52A0\u8F7D\u90E8\u95E8\u5931\u8D25");
3168
+ } finally {
3169
+ setGroupsLoading(false);
3170
+ }
3171
+ }, [api, groupsLoaded, groupsLoading]);
3172
+ const handleSearch = () => {
3173
+ setPageToken("");
3174
+ setKeyword(keywordInput.trim());
3175
+ };
3176
+ const resetGroupPanel = () => {
3177
+ setGroupsOpen(false);
3178
+ setGroups([]);
3179
+ setGroupsLoaded(false);
3180
+ };
3181
+ const openCreate = () => {
3182
+ setEditing(null);
3183
+ setForm(emptyForm4());
3184
+ setFormError("");
3185
+ resetGroupPanel();
3186
+ setDialogOpen(true);
3187
+ void loadRoles();
3188
+ };
3189
+ const openEdit = (row) => {
3190
+ setEditing(row);
3191
+ setForm({
3192
+ username: row.username,
3193
+ name: row.name,
3194
+ password: "",
3195
+ groupIds: [...row.groupIds],
3196
+ roleIds: [...row.roleIds],
3197
+ enabled: row.enabled
3198
+ });
3199
+ setFormError("");
3200
+ resetGroupPanel();
3201
+ setDialogOpen(true);
3202
+ void loadRoles();
3203
+ };
3204
+ const closeDialog = () => {
3205
+ if (!saving) setDialogOpen(false);
3206
+ };
3207
+ const toggleGroupsPanel = () => {
3208
+ setGroupsOpen((prev) => {
3209
+ const next = !prev;
3210
+ if (next) void loadGroups();
3211
+ return next;
3212
+ });
3213
+ };
3214
+ const toggleId = (field, id) => {
3215
+ setForm((prev) => {
3216
+ const exists = prev[field].includes(id);
3217
+ return {
3218
+ ...prev,
3219
+ [field]: exists ? prev[field].filter((x) => x !== id) : [...prev[field], id]
3220
+ };
3221
+ });
3222
+ };
3223
+ const handleSubmit = async (event) => {
3224
+ event.preventDefault();
3225
+ const usernameError = validateUsername(form.username);
3226
+ if (usernameError) {
3227
+ setFormError(usernameError);
3228
+ return;
3229
+ }
3230
+ if (!form.name.trim()) {
3231
+ setFormError("\u8BF7\u586B\u5199\u7528\u6237\u540D");
3232
+ return;
3233
+ }
3234
+ if (!editing && !form.password.trim()) {
3235
+ setFormError("\u8BF7\u586B\u5199\u521D\u59CB\u5BC6\u7801");
3236
+ return;
3237
+ }
3238
+ if (!form.groupIds.length) {
3239
+ setFormError("\u8BF7\u9009\u62E9\u5F52\u5C5E\u90E8\u95E8");
3240
+ return;
3241
+ }
3242
+ setSaving(true);
3243
+ setFormError("");
3244
+ setError("");
3245
+ try {
3246
+ if (editing) {
3247
+ await api.update(editing.userId, form);
3248
+ } else {
3249
+ await api.create(form);
3250
+ }
3251
+ setDialogOpen(false);
3252
+ await loadList("current", "");
3253
+ } catch (err) {
3254
+ setFormError(err instanceof Error ? err.message : "\u4FDD\u5B58\u5931\u8D25");
3255
+ } finally {
3256
+ setSaving(false);
3257
+ }
3258
+ };
3259
+ const askDelete = (row) => setDeletingRow(row);
3260
+ const closeDeleteDialog = () => {
3261
+ if (!deleting) setDeletingRow(null);
3262
+ };
3263
+ const confirmDelete = async () => {
3264
+ if (!deletingRow) return;
3265
+ setDeleting(true);
3266
+ setError("");
3267
+ try {
3268
+ await api.remove(deletingRow.userId);
3269
+ setDeletingRow(null);
3270
+ await loadList("current", "");
3271
+ } catch (err) {
3272
+ setError(err instanceof Error ? err.message : "\u5220\u9664\u5931\u8D25");
3273
+ } finally {
3274
+ setDeleting(false);
3275
+ }
3276
+ };
3277
+ const groupLabel = (row) => {
3278
+ if (row.groupNames?.length) return row.groupNames.join("\u3001");
3279
+ if (!row.groupIds.length) return "\u2014";
3280
+ return row.groupIds.join("\u3001");
3281
+ };
3282
+ const roleLabel = (row) => {
3283
+ if (row.roleNames?.length) return row.roleNames.join("\u3001");
3284
+ if (!row.roleIds.length) return "\u2014";
3285
+ const map = new Map(roles.map((r) => [r.roleId, r.name]));
3286
+ return row.roleIds.map((id) => map.get(id) || id).join("\u3001");
3287
+ };
3288
+ const selectedGroupSummary = () => {
3289
+ if (!form.groupIds.length) return "\u8BF7\u9009\u62E9\u5F52\u5C5E\u90E8\u95E8";
3290
+ if (groupsLoaded) {
3291
+ const map = new Map(groups.map((g) => [g.groupId, g.name]));
3292
+ return form.groupIds.map((id) => map.get(id) || id).join("\u3001");
3293
+ }
3294
+ if (editing?.groupNames?.length && editing.groupIds.every((id) => form.groupIds.includes(id))) {
3295
+ const map = new Map(editing.groupIds.map((id, i) => [id, editing.groupNames?.[i] || id]));
3296
+ return form.groupIds.map((id) => map.get(id) || id).join("\u3001");
3297
+ }
3298
+ return `\u5DF2\u9009 ${form.groupIds.length} \u4E2A\u90E8\u95E8`;
3299
+ };
3300
+ (0, import_react5.useEffect)(() => {
3301
+ void (async () => {
3302
+ try {
3303
+ setRoles(await api.listRoleOptions());
3304
+ } catch {
3305
+ }
3306
+ })();
3307
+ }, [api]);
3308
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.root, children: [
3309
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.toolbar, children: [
3310
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { style: styles4.title, children: title }),
3311
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.toolbarRight, children: [
3312
+ toolbarExtra,
3313
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", style: styles4.primaryBtn, onClick: openCreate, children: "\u65B0\u589E\u7528\u6237" })
3314
+ ] })
3315
+ ] }),
3316
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.searchBar, children: [
3317
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3318
+ "input",
3319
+ {
3320
+ style: { ...styles4.input, maxWidth: 240 },
3321
+ value: keywordInput,
3322
+ onChange: (e) => setKeywordInput(e.target.value),
3323
+ placeholder: "\u641C\u7D22\u8D26\u53F7 / \u7528\u6237\u540D",
3324
+ onKeyDown: (e) => {
3325
+ if (e.key === "Enter") handleSearch();
3326
+ }
3327
+ }
3328
+ ),
3329
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3330
+ "select",
3331
+ {
3332
+ style: styles4.select,
3333
+ value: enabledFilter,
3334
+ onChange: (e) => {
3335
+ setPageToken("");
3336
+ setEnabledFilter(e.target.value);
3337
+ },
3338
+ children: [
3339
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "all", children: "\u5168\u90E8\u72B6\u6001" }),
3340
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "true", children: "\u5DF2\u542F\u7528" }),
3341
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "false", children: "\u5DF2\u7981\u7528" })
3342
+ ]
3343
+ }
3344
+ ),
3345
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", style: styles4.secondaryBtn, onClick: handleSearch, children: "\u67E5\u8BE2" }),
3346
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3347
+ "button",
3348
+ {
3349
+ type: "button",
3350
+ style: styles4.secondaryBtn,
3351
+ onClick: () => {
3352
+ setKeywordInput("");
3353
+ setKeyword("");
3354
+ setEnabledFilter("all");
3355
+ setPageToken("");
3356
+ },
3357
+ children: "\u91CD\u7F6E"
3358
+ }
3359
+ )
3360
+ ] }),
3361
+ error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.error, children: error }) : null,
3362
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.tableWrap, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("table", { style: styles4.table, children: [
3363
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { children: [
3364
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { style: styles4.th, children: "\u8D26\u53F7" }),
3365
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { style: styles4.th, children: "\u7528\u6237\u540D" }),
3366
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { style: styles4.th, children: "\u5F52\u5C5E\u90E8\u95E8" }),
3367
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { style: styles4.th, children: "\u7528\u6237\u89D2\u8272" }),
3368
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { style: { ...styles4.th, width: 90 }, children: "\u72B6\u6001" }),
3369
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { style: { ...styles4.th, width: 140 }, children: "\u64CD\u4F5C" })
3370
+ ] }) }),
3371
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tbody", { children: loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { colSpan: 6, style: styles4.empty, children: "\u52A0\u8F7D\u4E2D\u2026" }) }) : records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { colSpan: 6, style: styles4.empty, children: "\u6682\u65E0\u6570\u636E" }) }) : records.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { children: [
3372
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { style: styles4.td, children: row.username }),
3373
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { style: styles4.td, children: row.name }),
3374
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { style: styles4.td, children: groupLabel(row) }),
3375
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { style: styles4.td, children: roleLabel(row) }),
3376
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { style: styles4.td, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3377
+ "span",
3378
+ {
3379
+ style: {
3380
+ ...styles4.badge,
3381
+ ...row.enabled ? styles4.badgeOn : styles4.badgeOff
3382
+ },
3383
+ children: row.enabled ? "\u542F\u7528" : "\u7981\u7528"
3384
+ }
3385
+ ) }),
3386
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("td", { style: styles4.td, children: [
3387
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", style: styles4.linkBtn, onClick: () => openEdit(row), children: "\u7F16\u8F91" }),
3388
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3389
+ "button",
3390
+ {
3391
+ type: "button",
3392
+ style: { ...styles4.linkBtn, color: "#d92d20" },
3393
+ onClick: () => askDelete(row),
3394
+ children: "\u5220\u9664"
3395
+ }
3396
+ )
3397
+ ] })
3398
+ ] }, row.userId)) })
3399
+ ] }) }),
3400
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.pagination, children: [
3401
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: styles4.pageSize, children: [
3402
+ "\u6BCF\u9875",
3403
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3404
+ "select",
3405
+ {
3406
+ value: pageSize,
3407
+ onChange: (e) => {
3408
+ setPageToken("");
3409
+ setPageSize(e.target.value);
3410
+ },
3411
+ style: styles4.select,
3412
+ children: PAGE_SIZE_OPTIONS4.map((size) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: size, children: size }, size))
3413
+ }
3414
+ )
3415
+ ] }),
3416
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.pageBtns, children: [
3417
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3418
+ "button",
3419
+ {
3420
+ type: "button",
3421
+ style: styles4.secondaryBtn,
3422
+ disabled: !hasPreviousPage || loading,
3423
+ onClick: () => void loadList("previous"),
3424
+ children: "\u4E0A\u4E00\u9875"
3425
+ }
3426
+ ),
3427
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3428
+ "button",
3429
+ {
3430
+ type: "button",
3431
+ style: styles4.secondaryBtn,
3432
+ disabled: !hasNextPage || loading,
3433
+ onClick: () => void loadList("next"),
3434
+ children: "\u4E0B\u4E00\u9875"
3435
+ }
3436
+ )
3437
+ ] })
3438
+ ] }),
3439
+ dialogOpen ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.mask, onClick: closeDialog, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3440
+ "div",
3441
+ {
3442
+ style: { ...styles4.dialog, maxWidth: 560 },
3443
+ onClick: (e) => e.stopPropagation(),
3444
+ role: "dialog",
3445
+ "aria-modal": "true",
3446
+ children: [
3447
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.dialogHeader, children: [
3448
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { style: styles4.dialogTitle, children: editing ? "\u7F16\u8F91\u7528\u6237" : "\u65B0\u589E\u7528\u6237" }),
3449
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", style: styles4.iconBtn, onClick: closeDialog, "aria-label": "\u5173\u95ED", children: "\xD7" })
3450
+ ] }),
3451
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { style: styles4.form, onSubmit: (e) => void handleSubmit(e), children: [
3452
+ formError ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.error, children: formError }) : null,
3453
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: styles4.field, children: [
3454
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.label, children: "\u8D26\u53F7" }),
3455
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3456
+ "input",
3457
+ {
3458
+ style: styles4.input,
3459
+ value: form.username,
3460
+ onChange: (e) => setForm((prev) => ({ ...prev, username: e.target.value })),
3461
+ placeholder: "\u81F3\u5C116\u4F4D\uFF0C\u9700\u542B\u5B57\u6BCD\u548C\u6570\u5B57",
3462
+ required: true
3463
+ }
3464
+ )
3465
+ ] }),
3466
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: styles4.field, children: [
3467
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.label, children: "\u7528\u6237\u540D" }),
3468
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3469
+ "input",
3470
+ {
3471
+ style: styles4.input,
3472
+ value: form.name,
3473
+ onChange: (e) => setForm((prev) => ({ ...prev, name: e.target.value })),
3474
+ placeholder: "\u8BF7\u8F93\u5165\u7528\u6237\u540D",
3475
+ required: true
3476
+ }
3477
+ )
3478
+ ] }),
3479
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: styles4.field, children: [
3480
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.label, children: editing ? "\u5BC6\u7801\uFF08\u7559\u7A7A\u5219\u4E0D\u4FEE\u6539\uFF09" : "\u521D\u59CB\u5BC6\u7801" }),
3481
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3482
+ "input",
3483
+ {
3484
+ style: styles4.input,
3485
+ type: "password",
3486
+ value: form.password,
3487
+ onChange: (e) => setForm((prev) => ({ ...prev, password: e.target.value })),
3488
+ placeholder: editing ? "\u7559\u7A7A\u8868\u793A\u4E0D\u4FEE\u6539\u5BC6\u7801" : "\u8BF7\u8F93\u5165\u521D\u59CB\u5BC6\u7801",
3489
+ required: !editing,
3490
+ autoComplete: "new-password"
3491
+ }
3492
+ )
3493
+ ] }),
3494
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("fieldset", { style: styles4.fieldset, children: [
3495
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("legend", { style: styles4.label, children: [
3496
+ "\u5F52\u5C5E\u90E8\u95E8 ",
3497
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.required, children: "*" })
3498
+ ] }),
3499
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3500
+ "button",
3501
+ {
3502
+ type: "button",
3503
+ style: styles4.selectTrigger,
3504
+ onClick: toggleGroupsPanel,
3505
+ "aria-expanded": groupsOpen,
3506
+ children: [
3507
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3508
+ "span",
3509
+ {
3510
+ style: {
3511
+ ...styles4.selectTriggerText,
3512
+ ...form.groupIds.length ? null : styles4.selectPlaceholder
3513
+ },
3514
+ children: selectedGroupSummary()
3515
+ }
3516
+ ),
3517
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.selectChevron, children: groupsOpen ? "\u25B2" : "\u25BC" })
3518
+ ]
3519
+ }
3520
+ ),
3521
+ groupsOpen ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.multiSelect, children: groupsLoading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.hint, children: "\u52A0\u8F7D\u4E2D\u2026" }) : groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.hint, children: "\u6682\u65E0\u90E8\u95E8\u6570\u636E" }) : groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: styles4.checkItem, children: [
3522
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3523
+ "input",
3524
+ {
3525
+ type: "checkbox",
3526
+ style: styles4.control,
3527
+ checked: form.groupIds.includes(g.groupId),
3528
+ onChange: () => toggleId("groupIds", g.groupId)
3529
+ }
3530
+ ),
3531
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: g.name || g.groupId })
3532
+ ] }, g.groupId)) }) : null
3533
+ ] }),
3534
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("fieldset", { style: styles4.fieldset, children: [
3535
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("legend", { style: styles4.label, children: "\u7528\u6237\u89D2\u8272" }),
3536
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.multiSelect, children: rolesLoading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.hint, children: "\u52A0\u8F7D\u4E2D\u2026" }) : roles.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.hint, children: "\u6682\u65E0\u89D2\u8272\u6570\u636E" }) : roles.map((r) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: styles4.checkItem, children: [
3537
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3538
+ "input",
3539
+ {
3540
+ type: "checkbox",
3541
+ style: styles4.control,
3542
+ checked: form.roleIds.includes(r.roleId),
3543
+ onChange: () => toggleId("roleIds", r.roleId)
3544
+ }
3545
+ ),
3546
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: r.name || r.roleId })
3547
+ ] }, r.roleId)) })
3548
+ ] }),
3549
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.switchRow, children: [
3550
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.label, children: "\u662F\u5426\u542F\u7528" }),
3551
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3552
+ "button",
3553
+ {
3554
+ type: "button",
3555
+ role: "switch",
3556
+ "aria-checked": form.enabled,
3557
+ style: {
3558
+ ...styles4.switchTrack,
3559
+ ...form.enabled ? styles4.switchTrackOn : null
3560
+ },
3561
+ onClick: () => setForm((prev) => ({ ...prev, enabled: !prev.enabled })),
3562
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3563
+ "span",
3564
+ {
3565
+ style: {
3566
+ ...styles4.switchThumb,
3567
+ ...form.enabled ? styles4.switchThumbOn : null
3568
+ }
3569
+ }
3570
+ )
3571
+ }
3572
+ )
3573
+ ] }),
3574
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.dialogFooter, children: [
3575
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", style: styles4.secondaryBtn, onClick: closeDialog, children: "\u53D6\u6D88" }),
3576
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "submit", style: styles4.primaryBtn, disabled: saving, children: saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
3577
+ ] })
3578
+ ] })
3579
+ ]
3580
+ }
3581
+ ) }) : null,
3582
+ deletingRow ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.mask, onClick: closeDeleteDialog, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3583
+ "div",
3584
+ {
3585
+ style: { ...styles4.dialog, maxWidth: 420 },
3586
+ onClick: (e) => e.stopPropagation(),
3587
+ role: "dialog",
3588
+ "aria-modal": "true",
3589
+ children: [
3590
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.dialogHeader, children: [
3591
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { style: styles4.dialogTitle, children: "\u786E\u8BA4\u5220\u9664" }),
3592
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3593
+ "button",
3594
+ {
3595
+ type: "button",
3596
+ style: styles4.iconBtn,
3597
+ onClick: closeDeleteDialog,
3598
+ "aria-label": "\u5173\u95ED",
3599
+ children: "\xD7"
3600
+ }
3601
+ )
3602
+ ] }),
3603
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.confirmBody, children: [
3604
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: styles4.confirmText, children: [
3605
+ "\u786E\u8BA4\u5220\u9664\u7528\u6237\u300C",
3606
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: deletingRow.name }),
3607
+ "\u300D\uFF08",
3608
+ deletingRow.username,
3609
+ "\uFF09\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002"
3610
+ ] }),
3611
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.dialogFooter, children: [
3612
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3613
+ "button",
3614
+ {
3615
+ type: "button",
3616
+ style: styles4.secondaryBtn,
3617
+ onClick: closeDeleteDialog,
3618
+ disabled: deleting,
3619
+ children: "\u53D6\u6D88"
3620
+ }
3621
+ ),
3622
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3623
+ "button",
3624
+ {
3625
+ type: "button",
3626
+ style: styles4.dangerBtn,
3627
+ onClick: () => void confirmDelete(),
3628
+ disabled: deleting,
3629
+ children: deleting ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u5220\u9664"
3630
+ }
3631
+ )
3632
+ ] })
3633
+ ] })
3634
+ ]
3635
+ }
3636
+ ) }) : null
3637
+ ] });
3638
+ }
3639
+ var styles4 = {
3640
+ root: {
3641
+ display: "flex",
3642
+ flexDirection: "column",
3643
+ gap: 16,
3644
+ padding: 16,
3645
+ color: "#101828",
3646
+ fontFamily: '"PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, sans-serif'
3647
+ },
3648
+ toolbar: {
3649
+ display: "flex",
3650
+ alignItems: "center",
3651
+ justifyContent: "space-between",
3652
+ gap: 12
3653
+ },
3654
+ title: { margin: 0, fontSize: 18, fontWeight: 600 },
3655
+ toolbarRight: { display: "flex", alignItems: "center", gap: 8 },
3656
+ searchBar: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" },
3657
+ error: {
3658
+ padding: "10px 12px",
3659
+ borderRadius: 8,
3660
+ background: "#fef3f2",
3661
+ color: "#b42318",
3662
+ fontSize: 13
3663
+ },
3664
+ tableWrap: {
3665
+ overflow: "auto",
3666
+ border: "1px solid #eaecf0",
3667
+ borderRadius: 10,
3668
+ background: "#fff"
3669
+ },
3670
+ table: { width: "100%", borderCollapse: "collapse", minWidth: 720 },
3671
+ th: {
3672
+ textAlign: "left",
3673
+ padding: "12px 14px",
3674
+ fontSize: 13,
3675
+ fontWeight: 600,
3676
+ color: "#475467",
3677
+ background: "#f9fafb",
3678
+ borderBottom: "1px solid #eaecf0"
3679
+ },
3680
+ td: {
3681
+ padding: "12px 14px",
3682
+ fontSize: 14,
3683
+ borderBottom: "1px solid #f2f4f7",
3684
+ verticalAlign: "middle"
3685
+ },
3686
+ empty: { padding: 28, textAlign: "center", color: "#98a2b3", fontSize: 14 },
3687
+ linkBtn: {
3688
+ border: "none",
3689
+ background: "transparent",
3690
+ color: "#049BAD",
3691
+ cursor: "pointer",
3692
+ padding: "0 8px 0 0",
3693
+ fontSize: 13
3694
+ },
3695
+ badge: {
3696
+ display: "inline-block",
3697
+ padding: "2px 8px",
3698
+ borderRadius: 999,
3699
+ fontSize: 12,
3700
+ fontWeight: 500
3701
+ },
3702
+ badgeOn: { background: "#ecfdf3", color: "#027a48" },
3703
+ badgeOff: { background: "#f2f4f7", color: "#667085" },
3704
+ pagination: {
3705
+ display: "flex",
3706
+ alignItems: "center",
3707
+ justifyContent: "space-between",
3708
+ gap: 12
3709
+ },
3710
+ pageSize: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "#475467" },
3711
+ pageBtns: { display: "flex", gap: 8 },
3712
+ primaryBtn: {
3713
+ border: "none",
3714
+ background: "#049BAD",
3715
+ color: "#fff",
3716
+ borderRadius: 8,
3717
+ padding: "8px 14px",
3718
+ cursor: "pointer",
3719
+ fontSize: 14
3720
+ },
3721
+ secondaryBtn: {
3722
+ border: "1px solid #d0d5dd",
3723
+ background: "#fff",
3724
+ color: "#344054",
3725
+ borderRadius: 8,
3726
+ padding: "8px 14px",
3727
+ cursor: "pointer",
3728
+ fontSize: 14
3729
+ },
3730
+ dangerBtn: {
3731
+ border: "none",
3732
+ background: "#d92d20",
3733
+ color: "#fff",
3734
+ borderRadius: 8,
3735
+ padding: "8px 14px",
3736
+ cursor: "pointer",
3737
+ fontSize: 14
3738
+ },
3739
+ select: {
3740
+ border: "1px solid #d0d5dd",
3741
+ borderRadius: 6,
3742
+ padding: "4px 8px",
3743
+ fontSize: 13,
3744
+ backgroundColor: "#ffffff",
3745
+ color: "#101828"
3746
+ },
3747
+ mask: {
3748
+ position: "fixed",
3749
+ inset: 0,
3750
+ background: "rgba(16, 24, 40, 0.45)",
3751
+ display: "flex",
3752
+ alignItems: "center",
3753
+ justifyContent: "center",
3754
+ zIndex: 1e3,
3755
+ padding: 16
3756
+ },
3757
+ dialog: {
3758
+ width: "100%",
3759
+ maxWidth: 480,
3760
+ background: "#fff",
3761
+ borderRadius: 12,
3762
+ boxShadow: "0 20px 40px rgba(16,24,40,0.18)",
3763
+ maxHeight: "90vh",
3764
+ overflow: "auto"
3765
+ },
3766
+ dialogHeader: {
3767
+ display: "flex",
3768
+ alignItems: "center",
3769
+ justifyContent: "space-between",
3770
+ padding: "14px 16px",
3771
+ borderBottom: "1px solid #eaecf0",
3772
+ position: "sticky",
3773
+ top: 0,
3774
+ background: "#fff",
3775
+ zIndex: 1
3776
+ },
3777
+ dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },
3778
+ iconBtn: {
3779
+ border: "none",
3780
+ background: "transparent",
3781
+ fontSize: 22,
3782
+ lineHeight: 1,
3783
+ cursor: "pointer",
3784
+ color: "#667085"
3785
+ },
3786
+ form: { display: "flex", flexDirection: "column", gap: 12, padding: 16 },
3787
+ confirmBody: { display: "flex", flexDirection: "column", gap: 16, padding: 16 },
3788
+ confirmText: { margin: 0, fontSize: 14, color: "#344054", lineHeight: 1.6 },
3789
+ field: { display: "flex", flexDirection: "column", gap: 6 },
3790
+ fieldset: {
3791
+ border: "1px solid #eaecf0",
3792
+ borderRadius: 8,
3793
+ margin: 0,
3794
+ padding: "10px 12px 12px"
3795
+ },
3796
+ label: { fontSize: 13, color: "#344054", fontWeight: 500 },
3797
+ input: {
3798
+ border: "1px solid #d0d5dd",
3799
+ borderRadius: 8,
3800
+ padding: "8px 10px",
3801
+ fontSize: 14,
3802
+ outline: "none",
3803
+ backgroundColor: "#ffffff",
3804
+ color: "#101828",
3805
+ boxSizing: "border-box",
3806
+ width: "100%"
3807
+ },
3808
+ multiSelect: {
3809
+ display: "flex",
3810
+ flexDirection: "column",
3811
+ gap: 6,
3812
+ maxHeight: 160,
3813
+ overflow: "auto",
3814
+ marginTop: 8
3815
+ },
3816
+ selectTrigger: {
3817
+ display: "flex",
3818
+ alignItems: "center",
3819
+ justifyContent: "space-between",
3820
+ gap: 8,
3821
+ width: "100%",
3822
+ border: "1px solid #d0d5dd",
3823
+ borderRadius: 8,
3824
+ padding: "8px 10px",
3825
+ background: "#fff",
3826
+ cursor: "pointer",
3827
+ fontSize: 14,
3828
+ color: "#101828",
3829
+ boxSizing: "border-box",
3830
+ textAlign: "left"
3831
+ },
3832
+ selectTriggerText: {
3833
+ flex: 1,
3834
+ overflow: "hidden",
3835
+ textOverflow: "ellipsis",
3836
+ whiteSpace: "nowrap"
3837
+ },
3838
+ selectPlaceholder: { color: "#98a2b3" },
3839
+ selectChevron: { color: "#667085", fontSize: 10, flexShrink: 0 },
3840
+ required: { color: "#d92d20", marginLeft: 2 },
3841
+ checkItem: {
3842
+ display: "flex",
3843
+ alignItems: "center",
3844
+ gap: 8,
3845
+ fontSize: 14,
3846
+ color: "#101828",
3847
+ cursor: "pointer"
3848
+ },
3849
+ control: {
3850
+ width: 16,
3851
+ height: 16,
3852
+ accentColor: "#049BAD",
3853
+ cursor: "pointer",
3854
+ colorScheme: "light",
3855
+ backgroundColor: "#ffffff"
3856
+ },
3857
+ hint: { fontSize: 13, color: "#98a2b3", padding: "4px 0" },
3858
+ switchRow: {
3859
+ display: "flex",
3860
+ alignItems: "center",
3861
+ justifyContent: "flex-start",
3862
+ gap: 12
3863
+ },
3864
+ switchTrack: {
3865
+ width: 44,
3866
+ height: 24,
3867
+ borderRadius: 999,
3868
+ border: "none",
3869
+ padding: 2,
3870
+ background: "#d0d5dd",
3871
+ cursor: "pointer",
3872
+ position: "relative",
3873
+ transition: "background 0.15s ease"
3874
+ },
3875
+ switchTrackOn: { background: "#049BAD" },
3876
+ switchThumb: {
3877
+ display: "block",
3878
+ width: 20,
3879
+ height: 20,
3880
+ borderRadius: "50%",
3881
+ background: "#fff",
3882
+ boxShadow: "0 1px 2px rgba(16,24,40,0.2)",
3883
+ transform: "translateX(0)",
3884
+ transition: "transform 0.15s ease"
3885
+ },
3886
+ switchThumbOn: { transform: "translateX(20px)" },
3887
+ dialogFooter: {
3888
+ display: "flex",
3889
+ justifyContent: "flex-end",
3890
+ gap: 8,
3891
+ paddingTop: 4
3892
+ }
3893
+ };
3894
+
2906
3895
  // src/react/SystemAdmin.tsx
2907
- var import_react5 = require("react");
3896
+ var import_react6 = require("react");
2908
3897
 
2909
3898
  // src/admin/menu.ts
2910
3899
  var SYSTEM_ADMIN_MENU = {
2911
3900
  key: "system",
2912
3901
  label: "\u7CFB\u7EDF\u7BA1\u7406",
2913
3902
  children: [
3903
+ { key: "user", label: "\u7528\u6237\u7BA1\u7406" },
3904
+ { key: "role", label: "\u89D2\u8272\u7BA1\u7406" },
2914
3905
  { key: "menu", label: "\u83DC\u5355\u7BA1\u7406" },
2915
- { key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" },
2916
- { key: "role", label: "\u89D2\u8272\u7BA1\u7406" }
3906
+ { key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" }
2917
3907
  ]
2918
3908
  };
2919
3909
  var SYSTEM_ADMIN_DEFAULT_KEY = "menu";
2920
3910
 
2921
3911
  // src/react/SystemAdmin.tsx
2922
- var import_jsx_runtime5 = require("react/jsx-runtime");
3912
+ var import_jsx_runtime6 = require("react/jsx-runtime");
2923
3913
  function SystemAdmin({
2924
3914
  menuApi,
2925
3915
  resourceApi,
2926
3916
  roleApi,
3917
+ userApi,
2927
3918
  defaultActiveKey = SYSTEM_ADMIN_DEFAULT_KEY,
2928
3919
  activeKey: controlledKey,
2929
3920
  onActiveKeyChange,
2930
3921
  title = SYSTEM_ADMIN_MENU.label,
2931
3922
  toolbarExtra
2932
3923
  }) {
2933
- const [innerKey, setInnerKey] = (0, import_react5.useState)(defaultActiveKey);
3924
+ const [innerKey, setInnerKey] = (0, import_react6.useState)(defaultActiveKey);
2934
3925
  const activeKey = controlledKey ?? innerKey;
2935
3926
  const setActiveKey = (key) => {
2936
3927
  if (controlledKey === void 0) setInnerKey(key);
2937
3928
  onActiveKeyChange?.(key);
2938
3929
  };
2939
- const activeLabel = (0, import_react5.useMemo)(
3930
+ const activeLabel = (0, import_react6.useMemo)(
2940
3931
  () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey)?.label ?? "",
2941
3932
  [activeKey]
2942
3933
  );
2943
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.root, children: [
2944
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("aside", { style: styles4.sidebar, children: [
2945
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.sidebarTitle, children: title }),
2946
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { style: styles4.nav, children: SYSTEM_ADMIN_MENU.children.map((item) => {
3934
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: styles5.root, children: [
3935
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("aside", { style: styles5.sidebar, children: [
3936
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: styles5.sidebarTitle, children: title }),
3937
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("nav", { style: styles5.nav, children: SYSTEM_ADMIN_MENU.children.map((item) => {
2947
3938
  const active = item.key === activeKey;
2948
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3939
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2949
3940
  "button",
2950
3941
  {
2951
3942
  type: "button",
2952
3943
  style: {
2953
- ...styles4.navItem,
2954
- ...active ? styles4.navItemActive : null
3944
+ ...styles5.navItem,
3945
+ ...active ? styles5.navItemActive : null
2955
3946
  },
2956
3947
  onClick: () => setActiveKey(item.key),
2957
3948
  children: item.label
@@ -2960,20 +3951,20 @@ function SystemAdmin({
2960
3951
  );
2961
3952
  }) })
2962
3953
  ] }),
2963
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("main", { style: styles4.content, children: [
2964
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.contentHeader, children: [
2965
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles4.breadcrumb, children: [
2966
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.breadcrumbParent, children: title }),
2967
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.breadcrumbSep, children: "/" }),
2968
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: styles4.breadcrumbCurrent, children: activeLabel })
3954
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("main", { style: styles5.content, children: [
3955
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: styles5.contentHeader, children: [
3956
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: styles5.breadcrumb, children: [
3957
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: styles5.breadcrumbParent, children: title }),
3958
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: styles5.breadcrumbSep, children: "/" }),
3959
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: styles5.breadcrumbCurrent, children: activeLabel })
2969
3960
  ] }),
2970
3961
  toolbarExtra
2971
3962
  ] }),
2972
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles4.panel, children: activeKey === "menu" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MenuManager, { api: menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : activeKey === "resource" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ResourceManager, { api: resourceApi, title: "\u6743\u9650\u70B9\u7BA1\u7406" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RoleManager, { api: roleApi, title: "\u89D2\u8272\u7BA1\u7406" }) })
3963
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: styles5.panel, children: activeKey === "menu" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MenuManager, { api: menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : activeKey === "resource" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ResourceManager, { api: resourceApi, title: "\u6743\u9650\u70B9\u7BA1\u7406" }) : activeKey === "role" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RoleManager, { api: roleApi, title: "\u89D2\u8272\u7BA1\u7406" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(UserManager, { api: userApi, title: "\u7528\u6237\u7BA1\u7406" }) })
2973
3964
  ] })
2974
3965
  ] });
2975
3966
  }
2976
- var styles4 = {
3967
+ var styles5 = {
2977
3968
  root: {
2978
3969
  display: "flex",
2979
3970
  minHeight: 560,
@@ -3074,15 +4065,18 @@ var styles4 = {
3074
4065
  SYSTEM_ADMIN_DEFAULT_KEY,
3075
4066
  SYSTEM_ADMIN_MENU,
3076
4067
  SystemAdmin,
4068
+ UserManager,
3077
4069
  appendQueryParam,
3078
4070
  buildCreateBody,
3079
4071
  buildCreateMenuBody,
3080
4072
  buildCreateRoleBody,
4073
+ buildCreateUserBody,
3081
4074
  buildPermissionTreeIndex,
3082
4075
  buildSavePermissionsBody,
3083
4076
  buildUpdateBody,
3084
4077
  buildUpdateMenuBody,
3085
4078
  buildUpdateRoleBody,
4079
+ buildUpdateUserBody,
3086
4080
  collectTreeResourceIds,
3087
4081
  countCheckedDescendants,
3088
4082
  createAuthorizationResourceApi,
@@ -3090,6 +4084,7 @@ var styles4 = {
3090
4084
  createMenuResourceApi,
3091
4085
  createPermissionStore,
3092
4086
  createSystemRoleApi,
4087
+ createSystemUserApi,
3093
4088
  extractPagination,
3094
4089
  extractRecords,
3095
4090
  getAppClientId,
@@ -3101,12 +4096,16 @@ var styles4 = {
3101
4096
  mapMenuResource,
3102
4097
  mapPermissionTreeNode,
3103
4098
  mapRolePermissions,
4099
+ mapSystemGroupOption,
3104
4100
  mapSystemRole,
4101
+ mapSystemRoleOption,
4102
+ mapSystemUser,
3105
4103
  resolveMenuDepth,
3106
4104
  snowyflake,
3107
4105
  togglePermissionCheck,
3108
4106
  useHasPermission,
3109
4107
  useHasRole,
3110
- usePermission
4108
+ usePermission,
4109
+ validateUsername
3111
4110
  });
3112
4111
  //# sourceMappingURL=index.cjs.map