com-angel-authorization 1.0.17 → 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.
@@ -45,15 +45,18 @@ __export(vue_exports, {
45
45
  SYSTEM_ADMIN_DEFAULT_KEY: () => SYSTEM_ADMIN_DEFAULT_KEY,
46
46
  SYSTEM_ADMIN_MENU: () => SYSTEM_ADMIN_MENU,
47
47
  SystemAdmin: () => SystemAdmin,
48
+ UserManager: () => UserManager,
48
49
  appendQueryParam: () => appendQueryParam,
49
50
  buildCreateBody: () => buildCreateBody,
50
51
  buildCreateMenuBody: () => buildCreateMenuBody,
51
52
  buildCreateRoleBody: () => buildCreateRoleBody,
53
+ buildCreateUserBody: () => buildCreateUserBody,
52
54
  buildPermissionTreeIndex: () => buildPermissionTreeIndex,
53
55
  buildSavePermissionsBody: () => buildSavePermissionsBody,
54
56
  buildUpdateBody: () => buildUpdateBody,
55
57
  buildUpdateMenuBody: () => buildUpdateMenuBody,
56
58
  buildUpdateRoleBody: () => buildUpdateRoleBody,
59
+ buildUpdateUserBody: () => buildUpdateUserBody,
57
60
  collectTreeResourceIds: () => collectTreeResourceIds,
58
61
  countCheckedDescendants: () => countCheckedDescendants,
59
62
  createAuthorizationResourceApi: () => createAuthorizationResourceApi,
@@ -62,6 +65,7 @@ __export(vue_exports, {
62
65
  createPermissionPlugin: () => createPermissionPlugin,
63
66
  createPermissionStore: () => createPermissionStore,
64
67
  createSystemRoleApi: () => createSystemRoleApi,
68
+ createSystemUserApi: () => createSystemUserApi,
65
69
  createVPermission: () => createVPermission,
66
70
  extractPagination: () => extractPagination,
67
71
  extractRecords: () => extractRecords,
@@ -74,13 +78,17 @@ __export(vue_exports, {
74
78
  mapMenuResource: () => mapMenuResource,
75
79
  mapPermissionTreeNode: () => mapPermissionTreeNode,
76
80
  mapRolePermissions: () => mapRolePermissions,
81
+ mapSystemGroupOption: () => mapSystemGroupOption,
77
82
  mapSystemRole: () => mapSystemRole,
83
+ mapSystemRoleOption: () => mapSystemRoleOption,
84
+ mapSystemUser: () => mapSystemUser,
78
85
  resolveMenuDepth: () => resolveMenuDepth,
79
86
  snowyflake: () => snowyflake,
80
87
  togglePermissionCheck: () => togglePermissionCheck,
81
88
  useHasPermission: () => useHasPermission,
82
89
  useHasRole: () => useHasRole,
83
- usePermission: () => usePermission
90
+ usePermission: () => usePermission,
91
+ validateUsername: () => validateUsername
84
92
  });
85
93
  module.exports = __toCommonJS(vue_exports);
86
94
 
@@ -572,7 +580,7 @@ function toStringArray(value) {
572
580
  }).filter(Boolean);
573
581
  }
574
582
  if (typeof value === "string" && value.trim()) {
575
- return value.split(",").map((s5) => s5.trim()).filter(Boolean);
583
+ return value.split(",").map((s6) => s6.trim()).filter(Boolean);
576
584
  }
577
585
  return [];
578
586
  }
@@ -3434,8 +3442,1049 @@ var RoleManager = (0, import_vue5.defineComponent)({
3434
3442
  }
3435
3443
  });
3436
3444
 
3445
+ // src/vue/UserManager.ts
3446
+ var import_vue6 = require("vue");
3447
+
3448
+ // src/users/index.ts
3449
+ function asIdList(value) {
3450
+ if (!Array.isArray(value)) return [];
3451
+ return value.map((item) => {
3452
+ if (item === void 0 || item === null || item === "") return "";
3453
+ if (typeof item === "object") {
3454
+ const row = item;
3455
+ const id = row.groupId ?? row.roleId ?? row.id;
3456
+ return id === void 0 || id === null ? "" : String(id);
3457
+ }
3458
+ return String(item);
3459
+ }).filter(Boolean);
3460
+ }
3461
+ function asNameList(value) {
3462
+ if (!Array.isArray(value)) return void 0;
3463
+ const names = value.map((item) => {
3464
+ if (item === void 0 || item === null) return "";
3465
+ if (typeof item === "object") {
3466
+ return String(item.name ?? "");
3467
+ }
3468
+ return String(item);
3469
+ }).filter(Boolean);
3470
+ return names.length ? names : void 0;
3471
+ }
3472
+ function mapSystemUser(item) {
3473
+ if (!item || typeof item !== "object") return null;
3474
+ const row = item;
3475
+ const userId = row.userId ?? row.user_id ?? row.id;
3476
+ if (userId === void 0 || userId === null || userId === "") return null;
3477
+ return {
3478
+ userId: String(userId),
3479
+ username: String(row.username ?? row.account ?? ""),
3480
+ name: String(row.name ?? ""),
3481
+ groupIds: asIdList(row.groupIds ?? row.group_ids ?? row.groups),
3482
+ roleIds: asIdList(row.roleIds ?? row.role_ids ?? row.roles),
3483
+ groupNames: asNameList(row.groupNames ?? row.group_names ?? row.groups),
3484
+ roleNames: asNameList(row.roleNames ?? row.role_names ?? row.roles),
3485
+ enabled: Boolean(row.enabled ?? row.enable ?? true)
3486
+ };
3487
+ }
3488
+ function mapSystemGroupOption(item) {
3489
+ if (!item || typeof item !== "object") return null;
3490
+ const row = item;
3491
+ const groupId = row.groupId ?? row.group_id ?? row.id;
3492
+ if (groupId === void 0 || groupId === null || groupId === "") return null;
3493
+ return {
3494
+ groupId: String(groupId),
3495
+ name: String(row.name ?? "")
3496
+ };
3497
+ }
3498
+ function mapSystemRoleOption(item) {
3499
+ if (!item || typeof item !== "object") return null;
3500
+ const row = item;
3501
+ const roleId = row.roleId ?? row.role_id ?? row.id;
3502
+ if (roleId === void 0 || roleId === null || roleId === "") return null;
3503
+ return {
3504
+ roleId: String(roleId),
3505
+ name: String(row.name ?? "")
3506
+ };
3507
+ }
3508
+ function validateUsername(username) {
3509
+ const value = username.trim();
3510
+ if (value.length < 6) return "\u8D26\u53F7\u957F\u5EA6\u4E0D\u5C11\u4E8E 6 \u4E2A\u5B57\u7B26";
3511
+ if (!/[A-Za-z]/.test(value) || !/[0-9]/.test(value)) {
3512
+ return "\u8D26\u53F7\u9700\u540C\u65F6\u5305\u542B\u5B57\u6BCD\u548C\u6570\u5B57";
3513
+ }
3514
+ return null;
3515
+ }
3516
+ function buildListUrl3(params) {
3517
+ const parts = [];
3518
+ appendQueryParam(parts, "keyword", params?.keyword ?? "");
3519
+ if (params?.enabled !== void 0) {
3520
+ appendQueryParam(parts, "enabled", String(params.enabled));
3521
+ }
3522
+ appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
3523
+ appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
3524
+ appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
3525
+ return parts.length ? `/system/users?${parts.join("&")}` : "/system/users";
3526
+ }
3527
+ function buildKeywordUrl(base, keyword) {
3528
+ const parts = [];
3529
+ appendQueryParam(parts, "keyword", keyword ?? "");
3530
+ return parts.length ? `${base}?${parts.join("&")}` : base;
3531
+ }
3532
+ function buildCreateUserBody(values) {
3533
+ return {
3534
+ username: values.username.trim(),
3535
+ name: values.name.trim(),
3536
+ password: values.password,
3537
+ groupIds: [...new Set(values.groupIds.map(String))],
3538
+ roleIds: [...new Set(values.roleIds.map(String))],
3539
+ enabled: Boolean(values.enabled)
3540
+ };
3541
+ }
3542
+ function buildUpdateUserBody(values) {
3543
+ const body = {
3544
+ username: values.username.trim(),
3545
+ name: values.name.trim(),
3546
+ groupIds: [...new Set(values.groupIds.map(String))],
3547
+ roleIds: [...new Set(values.roleIds.map(String))],
3548
+ enabled: Boolean(values.enabled)
3549
+ };
3550
+ if (values.password.trim()) {
3551
+ body.password = values.password;
3552
+ }
3553
+ return body;
3554
+ }
3555
+ function createSystemUserApi(request) {
3556
+ return {
3557
+ async list(params, signal) {
3558
+ const json = await request({
3559
+ method: "GET",
3560
+ url: buildListUrl3(params),
3561
+ signal
3562
+ });
3563
+ const records = extractRecords(json).map(mapSystemUser).filter((item) => item !== null);
3564
+ return {
3565
+ records,
3566
+ ...extractPagination(json)
3567
+ };
3568
+ },
3569
+ async create(values, signal) {
3570
+ return request({
3571
+ method: "POST",
3572
+ url: "/system/users",
3573
+ body: buildCreateUserBody(values),
3574
+ signal
3575
+ });
3576
+ },
3577
+ async update(userId, values, signal) {
3578
+ return request({
3579
+ method: "PATCH",
3580
+ url: `/system/users/${encodeURIComponent(userId)}`,
3581
+ body: buildUpdateUserBody(values),
3582
+ signal
3583
+ });
3584
+ },
3585
+ async remove(userId, signal) {
3586
+ return request({
3587
+ method: "DELETE",
3588
+ url: `/system/users/${encodeURIComponent(userId)}`,
3589
+ signal
3590
+ });
3591
+ },
3592
+ async listGroups(params, signal) {
3593
+ const json = await request({
3594
+ method: "GET",
3595
+ url: buildKeywordUrl("/system/groups", params?.keyword),
3596
+ signal
3597
+ });
3598
+ return extractRecords(json).map(mapSystemGroupOption).filter((item) => item !== null);
3599
+ },
3600
+ async listRoleOptions(params, signal) {
3601
+ const json = await request({
3602
+ method: "GET",
3603
+ url: buildKeywordUrl("/system/roles", params?.keyword),
3604
+ signal
3605
+ });
3606
+ return extractRecords(json).map(mapSystemRoleOption).filter((item) => item !== null);
3607
+ }
3608
+ };
3609
+ }
3610
+
3611
+ // src/vue/UserManager.ts
3612
+ var PAGE_SIZE_OPTIONS4 = ["10", "20", "50", "100"];
3613
+ function emptyForm4() {
3614
+ return {
3615
+ username: "",
3616
+ name: "",
3617
+ password: "",
3618
+ groupIds: [],
3619
+ roleIds: [],
3620
+ enabled: true
3621
+ };
3622
+ }
3623
+ var s4 = {
3624
+ root: {
3625
+ display: "flex",
3626
+ flexDirection: "column",
3627
+ gap: "16px",
3628
+ padding: "16px",
3629
+ color: "#101828",
3630
+ fontFamily: '"PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, sans-serif'
3631
+ },
3632
+ toolbar: {
3633
+ display: "flex",
3634
+ alignItems: "center",
3635
+ justifyContent: "space-between",
3636
+ gap: "12px"
3637
+ },
3638
+ title: { margin: "0", fontSize: "18px", fontWeight: "600" },
3639
+ toolbarRight: { display: "flex", alignItems: "center", gap: "8px" },
3640
+ searchBar: {
3641
+ display: "flex",
3642
+ alignItems: "center",
3643
+ gap: "8px",
3644
+ flexWrap: "wrap"
3645
+ },
3646
+ error: {
3647
+ padding: "10px 12px",
3648
+ borderRadius: "8px",
3649
+ background: "#fef3f2",
3650
+ color: "#b42318",
3651
+ fontSize: "13px"
3652
+ },
3653
+ tableWrap: {
3654
+ overflow: "auto",
3655
+ border: "1px solid #eaecf0",
3656
+ borderRadius: "10px",
3657
+ background: "#fff"
3658
+ },
3659
+ table: { width: "100%", borderCollapse: "collapse", minWidth: "720px" },
3660
+ th: {
3661
+ textAlign: "left",
3662
+ padding: "12px 14px",
3663
+ fontSize: "13px",
3664
+ fontWeight: "600",
3665
+ color: "#475467",
3666
+ background: "#f9fafb",
3667
+ borderBottom: "1px solid #eaecf0"
3668
+ },
3669
+ td: {
3670
+ padding: "12px 14px",
3671
+ fontSize: "14px",
3672
+ borderBottom: "1px solid #f2f4f7",
3673
+ verticalAlign: "middle"
3674
+ },
3675
+ empty: {
3676
+ padding: "28px",
3677
+ textAlign: "center",
3678
+ color: "#98a2b3",
3679
+ fontSize: "14px"
3680
+ },
3681
+ linkBtn: {
3682
+ border: "none",
3683
+ background: "transparent",
3684
+ color: "#049BAD",
3685
+ cursor: "pointer",
3686
+ padding: "0 8px 0 0",
3687
+ fontSize: "13px"
3688
+ },
3689
+ badge: {
3690
+ display: "inline-block",
3691
+ padding: "2px 8px",
3692
+ borderRadius: "999px",
3693
+ fontSize: "12px",
3694
+ fontWeight: "500"
3695
+ },
3696
+ badgeOn: { background: "#ecfdf3", color: "#027a48" },
3697
+ badgeOff: { background: "#f2f4f7", color: "#667085" },
3698
+ pagination: {
3699
+ display: "flex",
3700
+ alignItems: "center",
3701
+ justifyContent: "space-between",
3702
+ gap: "12px"
3703
+ },
3704
+ pageSize: {
3705
+ display: "flex",
3706
+ alignItems: "center",
3707
+ gap: "8px",
3708
+ fontSize: "13px",
3709
+ color: "#475467"
3710
+ },
3711
+ pageBtns: { display: "flex", gap: "8px" },
3712
+ primaryBtn: {
3713
+ border: "none",
3714
+ background: "#049BAD",
3715
+ color: "#fff",
3716
+ borderRadius: "8px",
3717
+ padding: "8px 14px",
3718
+ cursor: "pointer",
3719
+ fontSize: "14px"
3720
+ },
3721
+ secondaryBtn: {
3722
+ border: "1px solid #d0d5dd",
3723
+ background: "#fff",
3724
+ color: "#344054",
3725
+ borderRadius: "8px",
3726
+ padding: "8px 14px",
3727
+ cursor: "pointer",
3728
+ fontSize: "14px"
3729
+ },
3730
+ dangerBtn: {
3731
+ border: "none",
3732
+ background: "#d92d20",
3733
+ color: "#fff",
3734
+ borderRadius: "8px",
3735
+ padding: "8px 14px",
3736
+ cursor: "pointer",
3737
+ fontSize: "14px"
3738
+ },
3739
+ select: {
3740
+ border: "1px solid #d0d5dd",
3741
+ borderRadius: "6px",
3742
+ padding: "4px 8px",
3743
+ fontSize: "13px",
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: "1000",
3755
+ padding: "16px"
3756
+ },
3757
+ dialog: {
3758
+ width: "100%",
3759
+ maxWidth: "480px",
3760
+ background: "#fff",
3761
+ borderRadius: "12px",
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: "16px", fontWeight: "600" },
3778
+ iconBtn: {
3779
+ border: "none",
3780
+ background: "transparent",
3781
+ fontSize: "22px",
3782
+ lineHeight: "1",
3783
+ cursor: "pointer",
3784
+ color: "#667085"
3785
+ },
3786
+ form: {
3787
+ display: "flex",
3788
+ flexDirection: "column",
3789
+ gap: "12px",
3790
+ padding: "16px"
3791
+ },
3792
+ confirmBody: {
3793
+ display: "flex",
3794
+ flexDirection: "column",
3795
+ gap: "16px",
3796
+ padding: "16px"
3797
+ },
3798
+ confirmText: {
3799
+ margin: "0",
3800
+ fontSize: "14px",
3801
+ color: "#344054",
3802
+ lineHeight: "1.6"
3803
+ },
3804
+ field: { display: "flex", flexDirection: "column", gap: "6px" },
3805
+ fieldset: {
3806
+ border: "1px solid #eaecf0",
3807
+ borderRadius: "8px",
3808
+ margin: "0",
3809
+ padding: "10px 12px 12px"
3810
+ },
3811
+ label: { fontSize: "13px", color: "#344054", fontWeight: "500" },
3812
+ input: {
3813
+ border: "1px solid #d0d5dd",
3814
+ borderRadius: "8px",
3815
+ padding: "8px 10px",
3816
+ fontSize: "14px",
3817
+ outline: "none",
3818
+ backgroundColor: "#ffffff",
3819
+ color: "#101828",
3820
+ boxSizing: "border-box",
3821
+ width: "100%"
3822
+ },
3823
+ multiSelect: {
3824
+ display: "flex",
3825
+ flexDirection: "column",
3826
+ gap: "6px",
3827
+ maxHeight: "160px",
3828
+ overflow: "auto"
3829
+ },
3830
+ checkItem: {
3831
+ display: "flex",
3832
+ alignItems: "center",
3833
+ gap: "8px",
3834
+ fontSize: "14px",
3835
+ color: "#101828",
3836
+ cursor: "pointer"
3837
+ },
3838
+ control: {
3839
+ width: "16px",
3840
+ height: "16px",
3841
+ accentColor: "#049BAD",
3842
+ cursor: "pointer",
3843
+ colorScheme: "light",
3844
+ backgroundColor: "#ffffff"
3845
+ },
3846
+ hint: { fontSize: "13px", color: "#98a2b3", padding: "4px 0" },
3847
+ switchRow: {
3848
+ display: "flex",
3849
+ alignItems: "center",
3850
+ justifyContent: "space-between",
3851
+ gap: "12px"
3852
+ },
3853
+ switchTrack: {
3854
+ width: "44px",
3855
+ height: "24px",
3856
+ borderRadius: "999px",
3857
+ border: "none",
3858
+ padding: "2px",
3859
+ background: "#d0d5dd",
3860
+ cursor: "pointer",
3861
+ position: "relative",
3862
+ transition: "background 0.15s ease"
3863
+ },
3864
+ switchTrackOn: { background: "#049BAD" },
3865
+ switchThumb: {
3866
+ display: "block",
3867
+ width: "20px",
3868
+ height: "20px",
3869
+ borderRadius: "50%",
3870
+ background: "#fff",
3871
+ boxShadow: "0 1px 2px rgba(16,24,40,0.2)",
3872
+ transform: "translateX(0)",
3873
+ transition: "transform 0.15s ease"
3874
+ },
3875
+ switchThumbOn: { transform: "translateX(20px)" },
3876
+ dialogFooter: {
3877
+ display: "flex",
3878
+ justifyContent: "flex-end",
3879
+ gap: "8px",
3880
+ paddingTop: "4px"
3881
+ }
3882
+ };
3883
+ var UserManager = (0, import_vue6.defineComponent)({
3884
+ name: "UserManager",
3885
+ props: {
3886
+ api: {
3887
+ type: Object,
3888
+ required: true
3889
+ },
3890
+ title: {
3891
+ type: String,
3892
+ default: "\u7528\u6237\u7BA1\u7406"
3893
+ },
3894
+ pageSize: {
3895
+ type: String,
3896
+ default: "20"
3897
+ }
3898
+ },
3899
+ setup(props, { slots }) {
3900
+ const records = (0, import_vue6.ref)([]);
3901
+ const loading = (0, import_vue6.ref)(false);
3902
+ const error = (0, import_vue6.ref)("");
3903
+ const keyword = (0, import_vue6.ref)("");
3904
+ const keywordInput = (0, import_vue6.ref)("");
3905
+ const enabledFilter = (0, import_vue6.ref)("all");
3906
+ const pageSize = (0, import_vue6.ref)(props.pageSize);
3907
+ const pageToken = (0, import_vue6.ref)("");
3908
+ const hasPreviousPage = (0, import_vue6.ref)(false);
3909
+ const hasNextPage = (0, import_vue6.ref)(false);
3910
+ const dialogOpen = (0, import_vue6.ref)(false);
3911
+ const editing = (0, import_vue6.ref)(null);
3912
+ const form = (0, import_vue6.reactive)(emptyForm4());
3913
+ const formError = (0, import_vue6.ref)("");
3914
+ const saving = (0, import_vue6.ref)(false);
3915
+ const deletingRow = (0, import_vue6.ref)(null);
3916
+ const deleting = (0, import_vue6.ref)(false);
3917
+ const groups = (0, import_vue6.ref)([]);
3918
+ const roles = (0, import_vue6.ref)([]);
3919
+ const optionsLoading = (0, import_vue6.ref)(false);
3920
+ function enabledParam() {
3921
+ if (enabledFilter.value === "all") return void 0;
3922
+ return enabledFilter.value === "true";
3923
+ }
3924
+ async function loadList(direction = "current", token = pageToken.value) {
3925
+ loading.value = true;
3926
+ error.value = "";
3927
+ try {
3928
+ const result = await props.api.list({
3929
+ keyword: keyword.value,
3930
+ enabled: enabledParam(),
3931
+ pagination: {
3932
+ pageToken: token,
3933
+ pageSize: pageSize.value,
3934
+ pageDirection: direction
3935
+ }
3936
+ });
3937
+ records.value = result.records;
3938
+ pageToken.value = result.pageToken;
3939
+ hasPreviousPage.value = result.hasPreviousPage;
3940
+ hasNextPage.value = result.hasNextPage;
3941
+ } catch (err) {
3942
+ error.value = err instanceof Error ? err.message : "\u52A0\u8F7D\u5931\u8D25";
3943
+ } finally {
3944
+ loading.value = false;
3945
+ }
3946
+ }
3947
+ async function loadOptions() {
3948
+ optionsLoading.value = true;
3949
+ try {
3950
+ const [groupList, roleList] = await Promise.all([
3951
+ props.api.listGroups(),
3952
+ props.api.listRoleOptions()
3953
+ ]);
3954
+ groups.value = groupList;
3955
+ roles.value = roleList;
3956
+ } catch (err) {
3957
+ formError.value = err instanceof Error ? err.message : "\u52A0\u8F7D\u90E8\u95E8/\u89D2\u8272\u5931\u8D25";
3958
+ } finally {
3959
+ optionsLoading.value = false;
3960
+ }
3961
+ }
3962
+ function handleSearch() {
3963
+ pageToken.value = "";
3964
+ keyword.value = keywordInput.value.trim();
3965
+ }
3966
+ function handleReset() {
3967
+ keywordInput.value = "";
3968
+ keyword.value = "";
3969
+ enabledFilter.value = "all";
3970
+ pageToken.value = "";
3971
+ }
3972
+ function openCreate() {
3973
+ editing.value = null;
3974
+ Object.assign(form, emptyForm4());
3975
+ formError.value = "";
3976
+ dialogOpen.value = true;
3977
+ void loadOptions();
3978
+ }
3979
+ function openEdit(row) {
3980
+ editing.value = row;
3981
+ Object.assign(form, {
3982
+ username: row.username,
3983
+ name: row.name,
3984
+ password: "",
3985
+ groupIds: [...row.groupIds],
3986
+ roleIds: [...row.roleIds],
3987
+ enabled: row.enabled
3988
+ });
3989
+ formError.value = "";
3990
+ dialogOpen.value = true;
3991
+ void loadOptions();
3992
+ }
3993
+ function closeDialog() {
3994
+ if (!saving.value) dialogOpen.value = false;
3995
+ }
3996
+ function toggleId(field, id) {
3997
+ const exists = form[field].includes(id);
3998
+ form[field] = exists ? form[field].filter((x) => x !== id) : [...form[field], id];
3999
+ }
4000
+ async function handleSubmit(event) {
4001
+ event.preventDefault();
4002
+ const usernameError = validateUsername(form.username);
4003
+ if (usernameError) {
4004
+ formError.value = usernameError;
4005
+ return;
4006
+ }
4007
+ if (!form.name.trim()) {
4008
+ formError.value = "\u8BF7\u586B\u5199\u7528\u6237\u540D";
4009
+ return;
4010
+ }
4011
+ if (!editing.value && !form.password.trim()) {
4012
+ formError.value = "\u8BF7\u586B\u5199\u521D\u59CB\u5BC6\u7801";
4013
+ return;
4014
+ }
4015
+ saving.value = true;
4016
+ formError.value = "";
4017
+ error.value = "";
4018
+ try {
4019
+ if (editing.value) {
4020
+ await props.api.update(editing.value.userId, { ...form });
4021
+ } else {
4022
+ await props.api.create({ ...form });
4023
+ }
4024
+ dialogOpen.value = false;
4025
+ await loadList("current", "");
4026
+ } catch (err) {
4027
+ formError.value = err instanceof Error ? err.message : "\u4FDD\u5B58\u5931\u8D25";
4028
+ } finally {
4029
+ saving.value = false;
4030
+ }
4031
+ }
4032
+ function askDelete(row) {
4033
+ deletingRow.value = row;
4034
+ }
4035
+ function closeDeleteDialog() {
4036
+ if (!deleting.value) deletingRow.value = null;
4037
+ }
4038
+ async function confirmDelete() {
4039
+ if (!deletingRow.value) return;
4040
+ deleting.value = true;
4041
+ error.value = "";
4042
+ try {
4043
+ await props.api.remove(deletingRow.value.userId);
4044
+ deletingRow.value = null;
4045
+ await loadList("current", "");
4046
+ } catch (err) {
4047
+ error.value = err instanceof Error ? err.message : "\u5220\u9664\u5931\u8D25";
4048
+ } finally {
4049
+ deleting.value = false;
4050
+ }
4051
+ }
4052
+ function groupLabel(row) {
4053
+ if (row.groupNames?.length) return row.groupNames.join("\u3001");
4054
+ if (!row.groupIds.length) return "\u2014";
4055
+ const map = new Map(groups.value.map((g) => [g.groupId, g.name]));
4056
+ return row.groupIds.map((id) => map.get(id) || id).join("\u3001");
4057
+ }
4058
+ function roleLabel(row) {
4059
+ if (row.roleNames?.length) return row.roleNames.join("\u3001");
4060
+ if (!row.roleIds.length) return "\u2014";
4061
+ const map = new Map(roles.value.map((r) => [r.roleId, r.name]));
4062
+ return row.roleIds.map((id) => map.get(id) || id).join("\u3001");
4063
+ }
4064
+ (0, import_vue6.onMounted)(() => {
4065
+ void loadList("current", "");
4066
+ void (async () => {
4067
+ try {
4068
+ const [groupList, roleList] = await Promise.all([
4069
+ props.api.listGroups(),
4070
+ props.api.listRoleOptions()
4071
+ ]);
4072
+ groups.value = groupList;
4073
+ roles.value = roleList;
4074
+ } catch {
4075
+ }
4076
+ })();
4077
+ });
4078
+ (0, import_vue6.watch)(
4079
+ () => [
4080
+ props.api,
4081
+ pageSize.value,
4082
+ keyword.value,
4083
+ enabledFilter.value
4084
+ ],
4085
+ () => {
4086
+ pageToken.value = "";
4087
+ void loadList("current", "");
4088
+ }
4089
+ );
4090
+ return () => (0, import_vue6.h)("div", { style: s4.root }, [
4091
+ (0, import_vue6.h)("div", { style: s4.toolbar }, [
4092
+ (0, import_vue6.h)("h2", { style: s4.title }, props.title),
4093
+ (0, import_vue6.h)("div", { style: s4.toolbarRight }, [
4094
+ slots.toolbarExtra?.(),
4095
+ (0, import_vue6.h)(
4096
+ "button",
4097
+ { type: "button", style: s4.primaryBtn, onClick: openCreate },
4098
+ "\u65B0\u589E\u7528\u6237"
4099
+ )
4100
+ ])
4101
+ ]),
4102
+ (0, import_vue6.h)("div", { style: s4.searchBar }, [
4103
+ (0, import_vue6.h)("input", {
4104
+ style: { ...s4.input, maxWidth: "240px" },
4105
+ value: keywordInput.value,
4106
+ placeholder: "\u641C\u7D22\u8D26\u53F7 / \u7528\u6237\u540D",
4107
+ onInput: (e) => {
4108
+ keywordInput.value = e.target.value;
4109
+ },
4110
+ onKeydown: (e) => {
4111
+ if (e.key === "Enter") handleSearch();
4112
+ }
4113
+ }),
4114
+ (0, import_vue6.h)(
4115
+ "select",
4116
+ {
4117
+ style: s4.select,
4118
+ value: enabledFilter.value,
4119
+ onChange: (e) => {
4120
+ pageToken.value = "";
4121
+ enabledFilter.value = e.target.value;
4122
+ }
4123
+ },
4124
+ [
4125
+ (0, import_vue6.h)("option", { value: "all" }, "\u5168\u90E8\u72B6\u6001"),
4126
+ (0, import_vue6.h)("option", { value: "true" }, "\u5DF2\u542F\u7528"),
4127
+ (0, import_vue6.h)("option", { value: "false" }, "\u5DF2\u7981\u7528")
4128
+ ]
4129
+ ),
4130
+ (0, import_vue6.h)(
4131
+ "button",
4132
+ { type: "button", style: s4.secondaryBtn, onClick: handleSearch },
4133
+ "\u67E5\u8BE2"
4134
+ ),
4135
+ (0, import_vue6.h)(
4136
+ "button",
4137
+ { type: "button", style: s4.secondaryBtn, onClick: handleReset },
4138
+ "\u91CD\u7F6E"
4139
+ )
4140
+ ]),
4141
+ error.value ? (0, import_vue6.h)("div", { style: s4.error }, error.value) : null,
4142
+ (0, import_vue6.h)("div", { style: s4.tableWrap }, [
4143
+ (0, import_vue6.h)("table", { style: s4.table }, [
4144
+ (0, import_vue6.h)("thead", [
4145
+ (0, import_vue6.h)("tr", [
4146
+ (0, import_vue6.h)("th", { style: s4.th }, "\u8D26\u53F7"),
4147
+ (0, import_vue6.h)("th", { style: s4.th }, "\u7528\u6237\u540D"),
4148
+ (0, import_vue6.h)("th", { style: s4.th }, "\u5F52\u5C5E\u90E8\u95E8"),
4149
+ (0, import_vue6.h)("th", { style: s4.th }, "\u7528\u6237\u89D2\u8272"),
4150
+ (0, import_vue6.h)("th", { style: { ...s4.th, width: "90px" } }, "\u72B6\u6001"),
4151
+ (0, import_vue6.h)("th", { style: { ...s4.th, width: "140px" } }, "\u64CD\u4F5C")
4152
+ ])
4153
+ ]),
4154
+ (0, import_vue6.h)(
4155
+ "tbody",
4156
+ loading.value ? [
4157
+ (0, import_vue6.h)("tr", [
4158
+ (0, import_vue6.h)("td", { colspan: 6, style: s4.empty }, "\u52A0\u8F7D\u4E2D\u2026")
4159
+ ])
4160
+ ] : records.value.length === 0 ? [
4161
+ (0, import_vue6.h)("tr", [
4162
+ (0, import_vue6.h)("td", { colspan: 6, style: s4.empty }, "\u6682\u65E0\u6570\u636E")
4163
+ ])
4164
+ ] : records.value.map(
4165
+ (row) => (0, import_vue6.h)("tr", { key: row.userId }, [
4166
+ (0, import_vue6.h)("td", { style: s4.td }, row.username),
4167
+ (0, import_vue6.h)("td", { style: s4.td }, row.name),
4168
+ (0, import_vue6.h)("td", { style: s4.td }, groupLabel(row)),
4169
+ (0, import_vue6.h)("td", { style: s4.td }, roleLabel(row)),
4170
+ (0, import_vue6.h)("td", { style: s4.td }, [
4171
+ (0, import_vue6.h)(
4172
+ "span",
4173
+ {
4174
+ style: {
4175
+ ...s4.badge,
4176
+ ...row.enabled ? s4.badgeOn : s4.badgeOff
4177
+ }
4178
+ },
4179
+ row.enabled ? "\u542F\u7528" : "\u7981\u7528"
4180
+ )
4181
+ ]),
4182
+ (0, import_vue6.h)("td", { style: s4.td }, [
4183
+ (0, import_vue6.h)(
4184
+ "button",
4185
+ {
4186
+ type: "button",
4187
+ style: s4.linkBtn,
4188
+ onClick: () => openEdit(row)
4189
+ },
4190
+ "\u7F16\u8F91"
4191
+ ),
4192
+ (0, import_vue6.h)(
4193
+ "button",
4194
+ {
4195
+ type: "button",
4196
+ style: { ...s4.linkBtn, color: "#d92d20" },
4197
+ onClick: () => askDelete(row)
4198
+ },
4199
+ "\u5220\u9664"
4200
+ )
4201
+ ])
4202
+ ])
4203
+ )
4204
+ )
4205
+ ])
4206
+ ]),
4207
+ (0, import_vue6.h)("div", { style: s4.pagination }, [
4208
+ (0, import_vue6.h)("label", { style: s4.pageSize }, [
4209
+ "\u6BCF\u9875",
4210
+ (0, import_vue6.h)(
4211
+ "select",
4212
+ {
4213
+ style: s4.select,
4214
+ value: pageSize.value,
4215
+ onChange: (e) => {
4216
+ pageSize.value = e.target.value;
4217
+ }
4218
+ },
4219
+ PAGE_SIZE_OPTIONS4.map(
4220
+ (size) => (0, import_vue6.h)("option", { key: size, value: size }, size)
4221
+ )
4222
+ )
4223
+ ]),
4224
+ (0, import_vue6.h)("div", { style: s4.pageBtns }, [
4225
+ (0, import_vue6.h)(
4226
+ "button",
4227
+ {
4228
+ type: "button",
4229
+ style: s4.secondaryBtn,
4230
+ disabled: !hasPreviousPage.value || loading.value,
4231
+ onClick: () => void loadList("previous")
4232
+ },
4233
+ "\u4E0A\u4E00\u9875"
4234
+ ),
4235
+ (0, import_vue6.h)(
4236
+ "button",
4237
+ {
4238
+ type: "button",
4239
+ style: s4.secondaryBtn,
4240
+ disabled: !hasNextPage.value || loading.value,
4241
+ onClick: () => void loadList("next")
4242
+ },
4243
+ "\u4E0B\u4E00\u9875"
4244
+ )
4245
+ ])
4246
+ ]),
4247
+ dialogOpen.value ? (0, import_vue6.h)("div", { style: s4.mask, onClick: closeDialog }, [
4248
+ (0, import_vue6.h)(
4249
+ "div",
4250
+ {
4251
+ style: { ...s4.dialog, maxWidth: "560px" },
4252
+ role: "dialog",
4253
+ "aria-modal": "true",
4254
+ onClick: (e) => e.stopPropagation()
4255
+ },
4256
+ [
4257
+ (0, import_vue6.h)("div", { style: s4.dialogHeader }, [
4258
+ (0, import_vue6.h)(
4259
+ "h3",
4260
+ { style: s4.dialogTitle },
4261
+ editing.value ? "\u7F16\u8F91\u7528\u6237" : "\u65B0\u589E\u7528\u6237"
4262
+ ),
4263
+ (0, import_vue6.h)(
4264
+ "button",
4265
+ {
4266
+ type: "button",
4267
+ style: s4.iconBtn,
4268
+ "aria-label": "\u5173\u95ED",
4269
+ onClick: closeDialog
4270
+ },
4271
+ "\xD7"
4272
+ )
4273
+ ]),
4274
+ (0, import_vue6.h)(
4275
+ "form",
4276
+ {
4277
+ style: s4.form,
4278
+ onSubmit: (e) => void handleSubmit(e)
4279
+ },
4280
+ [
4281
+ formError.value ? (0, import_vue6.h)("div", { style: s4.error }, formError.value) : null,
4282
+ (0, import_vue6.h)("label", { style: s4.field }, [
4283
+ (0, import_vue6.h)("span", { style: s4.label }, "\u8D26\u53F7"),
4284
+ (0, import_vue6.h)("input", {
4285
+ style: s4.input,
4286
+ value: form.username,
4287
+ placeholder: "\u81F3\u5C116\u4F4D\uFF0C\u9700\u542B\u5B57\u6BCD\u548C\u6570\u5B57",
4288
+ required: true,
4289
+ onInput: (e) => {
4290
+ form.username = e.target.value;
4291
+ }
4292
+ })
4293
+ ]),
4294
+ (0, import_vue6.h)("label", { style: s4.field }, [
4295
+ (0, import_vue6.h)("span", { style: s4.label }, "\u7528\u6237\u540D"),
4296
+ (0, import_vue6.h)("input", {
4297
+ style: s4.input,
4298
+ value: form.name,
4299
+ placeholder: "\u8BF7\u8F93\u5165\u7528\u6237\u540D",
4300
+ required: true,
4301
+ onInput: (e) => {
4302
+ form.name = e.target.value;
4303
+ }
4304
+ })
4305
+ ]),
4306
+ (0, import_vue6.h)("label", { style: s4.field }, [
4307
+ (0, import_vue6.h)(
4308
+ "span",
4309
+ { style: s4.label },
4310
+ editing.value ? "\u5BC6\u7801\uFF08\u7559\u7A7A\u5219\u4E0D\u4FEE\u6539\uFF09" : "\u521D\u59CB\u5BC6\u7801"
4311
+ ),
4312
+ (0, import_vue6.h)("input", {
4313
+ style: s4.input,
4314
+ type: "password",
4315
+ value: form.password,
4316
+ placeholder: editing.value ? "\u7559\u7A7A\u8868\u793A\u4E0D\u4FEE\u6539\u5BC6\u7801" : "\u8BF7\u8F93\u5165\u521D\u59CB\u5BC6\u7801",
4317
+ required: !editing.value,
4318
+ autocomplete: "new-password",
4319
+ onInput: (e) => {
4320
+ form.password = e.target.value;
4321
+ }
4322
+ })
4323
+ ]),
4324
+ (0, import_vue6.h)("fieldset", { style: s4.fieldset }, [
4325
+ (0, import_vue6.h)("legend", { style: s4.label }, "\u5F52\u5C5E\u90E8\u95E8"),
4326
+ (0, import_vue6.h)("div", { style: s4.multiSelect }, [
4327
+ optionsLoading.value ? (0, import_vue6.h)("div", { style: s4.hint }, "\u52A0\u8F7D\u4E2D\u2026") : groups.value.length === 0 ? (0, import_vue6.h)("div", { style: s4.hint }, "\u6682\u65E0\u90E8\u95E8\u6570\u636E") : groups.value.map(
4328
+ (g) => (0, import_vue6.h)(
4329
+ "label",
4330
+ {
4331
+ key: g.groupId,
4332
+ style: s4.checkItem
4333
+ },
4334
+ [
4335
+ (0, import_vue6.h)("input", {
4336
+ type: "checkbox",
4337
+ style: s4.control,
4338
+ checked: form.groupIds.includes(
4339
+ g.groupId
4340
+ ),
4341
+ onChange: () => toggleId("groupIds", g.groupId)
4342
+ }),
4343
+ (0, import_vue6.h)("span", g.name || g.groupId)
4344
+ ]
4345
+ )
4346
+ )
4347
+ ])
4348
+ ]),
4349
+ (0, import_vue6.h)("fieldset", { style: s4.fieldset }, [
4350
+ (0, import_vue6.h)("legend", { style: s4.label }, "\u7528\u6237\u89D2\u8272"),
4351
+ (0, import_vue6.h)("div", { style: s4.multiSelect }, [
4352
+ optionsLoading.value ? (0, import_vue6.h)("div", { style: s4.hint }, "\u52A0\u8F7D\u4E2D\u2026") : roles.value.length === 0 ? (0, import_vue6.h)("div", { style: s4.hint }, "\u6682\u65E0\u89D2\u8272\u6570\u636E") : roles.value.map(
4353
+ (r) => (0, import_vue6.h)(
4354
+ "label",
4355
+ {
4356
+ key: r.roleId,
4357
+ style: s4.checkItem
4358
+ },
4359
+ [
4360
+ (0, import_vue6.h)("input", {
4361
+ type: "checkbox",
4362
+ style: s4.control,
4363
+ checked: form.roleIds.includes(
4364
+ r.roleId
4365
+ ),
4366
+ onChange: () => toggleId("roleIds", r.roleId)
4367
+ }),
4368
+ (0, import_vue6.h)("span", r.name || r.roleId)
4369
+ ]
4370
+ )
4371
+ )
4372
+ ])
4373
+ ]),
4374
+ (0, import_vue6.h)("div", { style: s4.switchRow }, [
4375
+ (0, import_vue6.h)("span", { style: s4.label }, "\u662F\u5426\u542F\u7528"),
4376
+ (0, import_vue6.h)(
4377
+ "button",
4378
+ {
4379
+ type: "button",
4380
+ role: "switch",
4381
+ "aria-checked": form.enabled,
4382
+ style: {
4383
+ ...s4.switchTrack,
4384
+ ...form.enabled ? s4.switchTrackOn : {}
4385
+ },
4386
+ onClick: () => {
4387
+ form.enabled = !form.enabled;
4388
+ }
4389
+ },
4390
+ [
4391
+ (0, import_vue6.h)("span", {
4392
+ style: {
4393
+ ...s4.switchThumb,
4394
+ ...form.enabled ? s4.switchThumbOn : {}
4395
+ }
4396
+ })
4397
+ ]
4398
+ )
4399
+ ]),
4400
+ (0, import_vue6.h)("div", { style: s4.dialogFooter }, [
4401
+ (0, import_vue6.h)(
4402
+ "button",
4403
+ {
4404
+ type: "button",
4405
+ style: s4.secondaryBtn,
4406
+ onClick: closeDialog
4407
+ },
4408
+ "\u53D6\u6D88"
4409
+ ),
4410
+ (0, import_vue6.h)(
4411
+ "button",
4412
+ {
4413
+ type: "submit",
4414
+ style: s4.primaryBtn,
4415
+ disabled: saving.value
4416
+ },
4417
+ saving.value ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"
4418
+ )
4419
+ ])
4420
+ ]
4421
+ )
4422
+ ]
4423
+ )
4424
+ ]) : null,
4425
+ deletingRow.value ? (0, import_vue6.h)("div", { style: s4.mask, onClick: closeDeleteDialog }, [
4426
+ (0, import_vue6.h)(
4427
+ "div",
4428
+ {
4429
+ style: { ...s4.dialog, maxWidth: "420px" },
4430
+ role: "dialog",
4431
+ "aria-modal": "true",
4432
+ onClick: (e) => e.stopPropagation()
4433
+ },
4434
+ [
4435
+ (0, import_vue6.h)("div", { style: s4.dialogHeader }, [
4436
+ (0, import_vue6.h)("h3", { style: s4.dialogTitle }, "\u786E\u8BA4\u5220\u9664"),
4437
+ (0, import_vue6.h)(
4438
+ "button",
4439
+ {
4440
+ type: "button",
4441
+ style: s4.iconBtn,
4442
+ "aria-label": "\u5173\u95ED",
4443
+ onClick: closeDeleteDialog
4444
+ },
4445
+ "\xD7"
4446
+ )
4447
+ ]),
4448
+ (0, import_vue6.h)("div", { style: s4.confirmBody }, [
4449
+ (0, import_vue6.h)("p", { style: s4.confirmText }, [
4450
+ "\u786E\u8BA4\u5220\u9664\u7528\u6237\u300C",
4451
+ (0, import_vue6.h)("strong", deletingRow.value.name),
4452
+ "\u300D\uFF08",
4453
+ deletingRow.value.username,
4454
+ "\uFF09\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002"
4455
+ ]),
4456
+ (0, import_vue6.h)("div", { style: s4.dialogFooter }, [
4457
+ (0, import_vue6.h)(
4458
+ "button",
4459
+ {
4460
+ type: "button",
4461
+ style: s4.secondaryBtn,
4462
+ disabled: deleting.value,
4463
+ onClick: closeDeleteDialog
4464
+ },
4465
+ "\u53D6\u6D88"
4466
+ ),
4467
+ (0, import_vue6.h)(
4468
+ "button",
4469
+ {
4470
+ type: "button",
4471
+ style: s4.dangerBtn,
4472
+ disabled: deleting.value,
4473
+ onClick: () => void confirmDelete()
4474
+ },
4475
+ deleting.value ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u5220\u9664"
4476
+ )
4477
+ ])
4478
+ ])
4479
+ ]
4480
+ )
4481
+ ]) : null
4482
+ ]);
4483
+ }
4484
+ });
4485
+
3437
4486
  // src/vue/SystemAdmin.ts
3438
- var import_vue6 = require("vue");
4487
+ var import_vue7 = require("vue");
3439
4488
 
3440
4489
  // src/admin/menu.ts
3441
4490
  var SYSTEM_ADMIN_MENU = {
@@ -3444,13 +4493,14 @@ var SYSTEM_ADMIN_MENU = {
3444
4493
  children: [
3445
4494
  { key: "menu", label: "\u83DC\u5355\u7BA1\u7406" },
3446
4495
  { key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" },
3447
- { key: "role", label: "\u89D2\u8272\u7BA1\u7406" }
4496
+ { key: "role", label: "\u89D2\u8272\u7BA1\u7406" },
4497
+ { key: "user", label: "\u7528\u6237\u7BA1\u7406" }
3448
4498
  ]
3449
4499
  };
3450
4500
  var SYSTEM_ADMIN_DEFAULT_KEY = "menu";
3451
4501
 
3452
4502
  // src/vue/SystemAdmin.ts
3453
- var s4 = {
4503
+ var s5 = {
3454
4504
  root: {
3455
4505
  display: "flex",
3456
4506
  minHeight: "560px",
@@ -3524,7 +4574,7 @@ var s4 = {
3524
4574
  overflow: "auto"
3525
4575
  }
3526
4576
  };
3527
- var SystemAdmin = (0, import_vue6.defineComponent)({
4577
+ var SystemAdmin = (0, import_vue7.defineComponent)({
3528
4578
  name: "SystemAdmin",
3529
4579
  props: {
3530
4580
  menuApi: {
@@ -3539,6 +4589,10 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3539
4589
  type: Object,
3540
4590
  required: true
3541
4591
  },
4592
+ userApi: {
4593
+ type: Object,
4594
+ required: true
4595
+ },
3542
4596
  defaultActiveKey: {
3543
4597
  type: String,
3544
4598
  default: SYSTEM_ADMIN_DEFAULT_KEY
@@ -3557,17 +4611,17 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3557
4611
  activeKeyChange: (_key) => true
3558
4612
  },
3559
4613
  setup(props, { emit, slots }) {
3560
- const innerKey = (0, import_vue6.ref)(props.defaultActiveKey);
3561
- (0, import_vue6.watch)(
4614
+ const innerKey = (0, import_vue7.ref)(props.defaultActiveKey);
4615
+ (0, import_vue7.watch)(
3562
4616
  () => props.defaultActiveKey,
3563
4617
  (value) => {
3564
4618
  if (props.activeKey === void 0) innerKey.value = value;
3565
4619
  }
3566
4620
  );
3567
- const activeKey = (0, import_vue6.computed)(
4621
+ const activeKey = (0, import_vue7.computed)(
3568
4622
  () => props.activeKey ?? innerKey.value
3569
4623
  );
3570
- const activeLabel = (0, import_vue6.computed)(
4624
+ const activeLabel = (0, import_vue7.computed)(
3571
4625
  () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey.value)?.label ?? ""
3572
4626
  );
3573
4627
  function setActiveKey(key) {
@@ -3575,22 +4629,22 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3575
4629
  emit("update:activeKey", key);
3576
4630
  emit("activeKeyChange", key);
3577
4631
  }
3578
- return () => (0, import_vue6.h)("div", { style: s4.root }, [
3579
- (0, import_vue6.h)("aside", { style: s4.sidebar }, [
3580
- (0, import_vue6.h)("div", { style: s4.sidebarTitle }, props.title),
3581
- (0, import_vue6.h)(
4632
+ return () => (0, import_vue7.h)("div", { style: s5.root }, [
4633
+ (0, import_vue7.h)("aside", { style: s5.sidebar }, [
4634
+ (0, import_vue7.h)("div", { style: s5.sidebarTitle }, props.title),
4635
+ (0, import_vue7.h)(
3582
4636
  "nav",
3583
- { style: s4.nav },
4637
+ { style: s5.nav },
3584
4638
  SYSTEM_ADMIN_MENU.children.map((item) => {
3585
4639
  const active = item.key === activeKey.value;
3586
- return (0, import_vue6.h)(
4640
+ return (0, import_vue7.h)(
3587
4641
  "button",
3588
4642
  {
3589
4643
  key: item.key,
3590
4644
  type: "button",
3591
4645
  style: {
3592
- ...s4.navItem,
3593
- ...active ? s4.navItemActive : {}
4646
+ ...s5.navItem,
4647
+ ...active ? s5.navItemActive : {}
3594
4648
  },
3595
4649
  onClick: () => setActiveKey(item.key)
3596
4650
  },
@@ -3599,20 +4653,20 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3599
4653
  })
3600
4654
  )
3601
4655
  ]),
3602
- (0, import_vue6.h)("main", { style: s4.content }, [
3603
- (0, import_vue6.h)("div", { style: s4.contentHeader }, [
3604
- (0, import_vue6.h)("div", { style: s4.breadcrumb }, [
3605
- (0, import_vue6.h)("span", { style: s4.breadcrumbParent }, props.title),
3606
- (0, import_vue6.h)("span", { style: s4.breadcrumbSep }, "/"),
3607
- (0, import_vue6.h)("span", { style: s4.breadcrumbCurrent }, activeLabel.value)
4656
+ (0, import_vue7.h)("main", { style: s5.content }, [
4657
+ (0, import_vue7.h)("div", { style: s5.contentHeader }, [
4658
+ (0, import_vue7.h)("div", { style: s5.breadcrumb }, [
4659
+ (0, import_vue7.h)("span", { style: s5.breadcrumbParent }, props.title),
4660
+ (0, import_vue7.h)("span", { style: s5.breadcrumbSep }, "/"),
4661
+ (0, import_vue7.h)("span", { style: s5.breadcrumbCurrent }, activeLabel.value)
3608
4662
  ]),
3609
4663
  slots.toolbarExtra?.()
3610
4664
  ]),
3611
- (0, import_vue6.h)("div", { style: s4.panel }, [
3612
- activeKey.value === "menu" ? (0, import_vue6.h)(MenuManager, { api: props.menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : activeKey.value === "resource" ? (0, import_vue6.h)(ResourceManager, {
4665
+ (0, import_vue7.h)("div", { style: s5.panel }, [
4666
+ activeKey.value === "menu" ? (0, import_vue7.h)(MenuManager, { api: props.menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : activeKey.value === "resource" ? (0, import_vue7.h)(ResourceManager, {
3613
4667
  api: props.resourceApi,
3614
4668
  title: "\u6743\u9650\u70B9\u7BA1\u7406"
3615
- }) : (0, import_vue6.h)(RoleManager, { api: props.roleApi, title: "\u89D2\u8272\u7BA1\u7406" })
4669
+ }) : activeKey.value === "role" ? (0, import_vue7.h)(RoleManager, { api: props.roleApi, title: "\u89D2\u8272\u7BA1\u7406" }) : (0, import_vue7.h)(UserManager, { api: props.userApi, title: "\u7528\u6237\u7BA1\u7406" })
3616
4670
  ])
3617
4671
  ])
3618
4672
  ]);
@@ -3645,15 +4699,18 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3645
4699
  SYSTEM_ADMIN_DEFAULT_KEY,
3646
4700
  SYSTEM_ADMIN_MENU,
3647
4701
  SystemAdmin,
4702
+ UserManager,
3648
4703
  appendQueryParam,
3649
4704
  buildCreateBody,
3650
4705
  buildCreateMenuBody,
3651
4706
  buildCreateRoleBody,
4707
+ buildCreateUserBody,
3652
4708
  buildPermissionTreeIndex,
3653
4709
  buildSavePermissionsBody,
3654
4710
  buildUpdateBody,
3655
4711
  buildUpdateMenuBody,
3656
4712
  buildUpdateRoleBody,
4713
+ buildUpdateUserBody,
3657
4714
  collectTreeResourceIds,
3658
4715
  countCheckedDescendants,
3659
4716
  createAuthorizationResourceApi,
@@ -3662,6 +4719,7 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3662
4719
  createPermissionPlugin,
3663
4720
  createPermissionStore,
3664
4721
  createSystemRoleApi,
4722
+ createSystemUserApi,
3665
4723
  createVPermission,
3666
4724
  extractPagination,
3667
4725
  extractRecords,
@@ -3674,12 +4732,16 @@ var SystemAdmin = (0, import_vue6.defineComponent)({
3674
4732
  mapMenuResource,
3675
4733
  mapPermissionTreeNode,
3676
4734
  mapRolePermissions,
4735
+ mapSystemGroupOption,
3677
4736
  mapSystemRole,
4737
+ mapSystemRoleOption,
4738
+ mapSystemUser,
3678
4739
  resolveMenuDepth,
3679
4740
  snowyflake,
3680
4741
  togglePermissionCheck,
3681
4742
  useHasPermission,
3682
4743
  useHasRole,
3683
- usePermission
4744
+ usePermission,
4745
+ validateUsername
3684
4746
  });
3685
4747
  //# sourceMappingURL=index.cjs.map