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.
- package/README.md +58 -4
- package/dist/index.cjs +243 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -2
- package/dist/index.d.ts +106 -2
- package/dist/index.js +232 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +1041 -75
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +117 -4
- package/dist/react/index.d.ts +117 -4
- package/dist/react/index.js +1029 -72
- package/dist/react/index.js.map +1 -1
- package/dist/vue/index.cjs +1234 -114
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.d.cts +151 -3
- package/dist/vue/index.d.ts +151 -3
- package/dist/vue/index.js +1224 -110
- package/dist/vue/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -427,13 +427,59 @@ export function Page() {
|
|
|
427
427
|
|
|
428
428
|
列表支持 `keyword` 搜索与 page-token 分页。表头:角色名称、描述、操作(编辑 / 授权 / 删除)。
|
|
429
429
|
|
|
430
|
-
|
|
430
|
+
点击「授权」打开树形勾选弹窗(父子联动:勾选父节点级联子节点;子节点全选/取消会回写父节点;部分勾选为半选态)。保存调用 `POST /system/roles/{role-id}/permissions`。
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## 用户管理(CRUD)
|
|
435
|
+
|
|
436
|
+
对接后端 `/system/users`。
|
|
437
|
+
|
|
438
|
+
| 操作 | 方法 | 地址 |
|
|
439
|
+
|------|------|------|
|
|
440
|
+
| 列表 | GET | `/system/users?keyword=&enabled=&page-token=&page-size=&page-direction=` |
|
|
441
|
+
| 新增 | POST | `/system/users` |
|
|
442
|
+
| 修改 | PATCH | `/system/users/{user-id}` |
|
|
443
|
+
| 删除 | DELETE | `/system/users/{user-id}` |
|
|
444
|
+
| 部门下拉 | GET | `/system/groups?keyword=` |
|
|
445
|
+
| 角色下拉 | GET | `/system/roles?keyword=` |
|
|
446
|
+
|
|
447
|
+
### React
|
|
448
|
+
|
|
449
|
+
```tsx
|
|
450
|
+
import {
|
|
451
|
+
UserManager,
|
|
452
|
+
createSystemUserApi,
|
|
453
|
+
createDefaultResourceRequest,
|
|
454
|
+
} from 'com-angel-authorization/react';
|
|
455
|
+
|
|
456
|
+
const api = createSystemUserApi(
|
|
457
|
+
createDefaultResourceRequest({ baseUrl: '/api' }),
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
export function Page() {
|
|
461
|
+
return <UserManager api={api} />;
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 表单字段
|
|
466
|
+
|
|
467
|
+
| 字段 | 说明 |
|
|
468
|
+
|------|------|
|
|
469
|
+
| username | 账号:不少于 6 位,且同时包含字母与数字 |
|
|
470
|
+
| name | 用户名 |
|
|
471
|
+
| password | 初始密码(编辑时可留空表示不修改) |
|
|
472
|
+
| groupIds | 归属部门,多选(`/system/groups`) |
|
|
473
|
+
| roleIds | 用户角色,多选(`/system/roles`) |
|
|
474
|
+
| enabled | 是否启用(boolean,Switch) |
|
|
475
|
+
|
|
476
|
+
列表支持 `keyword`、`enabled` 过滤与 page-token 分页。
|
|
431
477
|
|
|
432
478
|
---
|
|
433
479
|
|
|
434
480
|
## 系统管理(含子菜单)
|
|
435
481
|
|
|
436
|
-
|
|
482
|
+
将「菜单管理」「权限点管理」「角色管理」「用户管理」作为「系统管理」的子菜单展示:
|
|
437
483
|
|
|
438
484
|
```tsx
|
|
439
485
|
import {
|
|
@@ -441,6 +487,7 @@ import {
|
|
|
441
487
|
createMenuResourceApi,
|
|
442
488
|
createAuthorizationResourceApi,
|
|
443
489
|
createSystemRoleApi,
|
|
490
|
+
createSystemUserApi,
|
|
444
491
|
createDefaultResourceRequest,
|
|
445
492
|
SYSTEM_ADMIN_MENU,
|
|
446
493
|
} from 'com-angel-authorization/react';
|
|
@@ -449,9 +496,15 @@ const request = createDefaultResourceRequest({ baseUrl: '/api' });
|
|
|
449
496
|
const menuApi = createMenuResourceApi(request);
|
|
450
497
|
const resourceApi = createAuthorizationResourceApi(request);
|
|
451
498
|
const roleApi = createSystemRoleApi(request);
|
|
499
|
+
const userApi = createSystemUserApi(request);
|
|
452
500
|
|
|
453
|
-
// 侧栏:系统管理 →
|
|
454
|
-
<SystemAdmin
|
|
501
|
+
// 侧栏:系统管理 → 菜单 / 权限点 / 角色 / 用户管理
|
|
502
|
+
<SystemAdmin
|
|
503
|
+
menuApi={menuApi}
|
|
504
|
+
resourceApi={resourceApi}
|
|
505
|
+
roleApi={roleApi}
|
|
506
|
+
userApi={userApi}
|
|
507
|
+
/>
|
|
455
508
|
|
|
456
509
|
// 也可把菜单结构接到自有路由
|
|
457
510
|
console.log(SYSTEM_ADMIN_MENU);
|
|
@@ -459,6 +512,7 @@ console.log(SYSTEM_ADMIN_MENU);
|
|
|
459
512
|
// { key: 'menu', label: '菜单管理' },
|
|
460
513
|
// { key: 'resource', label: '权限点管理' },
|
|
461
514
|
// { key: 'role', label: '角色管理' },
|
|
515
|
+
// { key: 'user', label: '用户管理' },
|
|
462
516
|
// ]}
|
|
463
517
|
```
|
|
464
518
|
|
package/dist/index.cjs
CHANGED
|
@@ -188,7 +188,8 @@ var SYSTEM_ADMIN_MENU = {
|
|
|
188
188
|
children: [
|
|
189
189
|
{ key: "menu", label: "\u83DC\u5355\u7BA1\u7406" },
|
|
190
190
|
{ key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" },
|
|
191
|
-
{ key: "role", label: "\u89D2\u8272\u7BA1\u7406" }
|
|
191
|
+
{ key: "role", label: "\u89D2\u8272\u7BA1\u7406" },
|
|
192
|
+
{ key: "user", label: "\u7528\u6237\u7BA1\u7406" }
|
|
192
193
|
]
|
|
193
194
|
};
|
|
194
195
|
var SYSTEM_ADMIN_DEFAULT_KEY = "menu";
|
|
@@ -602,6 +603,72 @@ function mapRolePermissions(payload) {
|
|
|
602
603
|
function collectTreeResourceIds(node) {
|
|
603
604
|
return [node.resourceId, ...node.children.flatMap(collectTreeResourceIds)];
|
|
604
605
|
}
|
|
606
|
+
function buildPermissionTreeIndex(tree) {
|
|
607
|
+
const parentMap = /* @__PURE__ */ new Map();
|
|
608
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
609
|
+
const walk = (nodes, parentId) => {
|
|
610
|
+
for (const node of nodes) {
|
|
611
|
+
parentMap.set(node.resourceId, parentId);
|
|
612
|
+
nodeMap.set(node.resourceId, node);
|
|
613
|
+
if (node.children.length > 0) {
|
|
614
|
+
walk(node.children, node.resourceId);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
walk(tree, null);
|
|
619
|
+
return { parentMap, nodeMap };
|
|
620
|
+
}
|
|
621
|
+
function togglePermissionCheck(tree, checked, node) {
|
|
622
|
+
const next = new Set(checked);
|
|
623
|
+
const ids = collectTreeResourceIds(node);
|
|
624
|
+
const shouldCheck = !checked.has(node.resourceId);
|
|
625
|
+
if (shouldCheck) {
|
|
626
|
+
ids.forEach((id) => next.add(id));
|
|
627
|
+
} else {
|
|
628
|
+
ids.forEach((id) => next.delete(id));
|
|
629
|
+
}
|
|
630
|
+
const { parentMap, nodeMap } = buildPermissionTreeIndex(tree);
|
|
631
|
+
let parentId = parentMap.get(node.resourceId) ?? null;
|
|
632
|
+
while (parentId) {
|
|
633
|
+
const parent = nodeMap.get(parentId);
|
|
634
|
+
if (!parent) break;
|
|
635
|
+
const allChildrenChecked = parent.children.every(
|
|
636
|
+
(child) => next.has(child.resourceId)
|
|
637
|
+
);
|
|
638
|
+
if (allChildrenChecked && parent.children.length > 0) {
|
|
639
|
+
next.add(parentId);
|
|
640
|
+
} else {
|
|
641
|
+
next.delete(parentId);
|
|
642
|
+
}
|
|
643
|
+
parentId = parentMap.get(parentId) ?? null;
|
|
644
|
+
}
|
|
645
|
+
return next;
|
|
646
|
+
}
|
|
647
|
+
function countCheckedDescendants(node, checked) {
|
|
648
|
+
let total = 0;
|
|
649
|
+
let checkedCount = 0;
|
|
650
|
+
const walk = (n) => {
|
|
651
|
+
for (const child of n.children) {
|
|
652
|
+
total += 1;
|
|
653
|
+
if (checked.has(child.resourceId)) checkedCount += 1;
|
|
654
|
+
walk(child);
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
walk(node);
|
|
658
|
+
return { total, checkedCount };
|
|
659
|
+
}
|
|
660
|
+
function hasCheckedDescendant(node, checked) {
|
|
661
|
+
for (const child of node.children) {
|
|
662
|
+
if (checked.has(child.resourceId) || hasCheckedDescendant(child, checked)) {
|
|
663
|
+
return true;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
function isPermissionNodeIndeterminate(node, checked) {
|
|
669
|
+
if (checked.has(node.resourceId) || node.children.length === 0) return false;
|
|
670
|
+
return hasCheckedDescendant(node, checked);
|
|
671
|
+
}
|
|
605
672
|
function buildListUrl2(params) {
|
|
606
673
|
const parts = [];
|
|
607
674
|
appendQueryParam(parts, "keyword", params?.keyword ?? "");
|
|
@@ -683,6 +750,169 @@ function createSystemRoleApi(request) {
|
|
|
683
750
|
};
|
|
684
751
|
}
|
|
685
752
|
|
|
753
|
+
// src/users/index.ts
|
|
754
|
+
function asIdList(value) {
|
|
755
|
+
if (!Array.isArray(value)) return [];
|
|
756
|
+
return value.map((item) => {
|
|
757
|
+
if (item === void 0 || item === null || item === "") return "";
|
|
758
|
+
if (typeof item === "object") {
|
|
759
|
+
const row = item;
|
|
760
|
+
const id = row.groupId ?? row.roleId ?? row.id;
|
|
761
|
+
return id === void 0 || id === null ? "" : String(id);
|
|
762
|
+
}
|
|
763
|
+
return String(item);
|
|
764
|
+
}).filter(Boolean);
|
|
765
|
+
}
|
|
766
|
+
function asNameList(value) {
|
|
767
|
+
if (!Array.isArray(value)) return void 0;
|
|
768
|
+
const names = value.map((item) => {
|
|
769
|
+
if (item === void 0 || item === null) return "";
|
|
770
|
+
if (typeof item === "object") {
|
|
771
|
+
return String(item.name ?? "");
|
|
772
|
+
}
|
|
773
|
+
return String(item);
|
|
774
|
+
}).filter(Boolean);
|
|
775
|
+
return names.length ? names : void 0;
|
|
776
|
+
}
|
|
777
|
+
function mapSystemUser(item) {
|
|
778
|
+
if (!item || typeof item !== "object") return null;
|
|
779
|
+
const row = item;
|
|
780
|
+
const userId = row.userId ?? row.user_id ?? row.id;
|
|
781
|
+
if (userId === void 0 || userId === null || userId === "") return null;
|
|
782
|
+
return {
|
|
783
|
+
userId: String(userId),
|
|
784
|
+
username: String(row.username ?? row.account ?? ""),
|
|
785
|
+
name: String(row.name ?? ""),
|
|
786
|
+
groupIds: asIdList(row.groupIds ?? row.group_ids ?? row.groups),
|
|
787
|
+
roleIds: asIdList(row.roleIds ?? row.role_ids ?? row.roles),
|
|
788
|
+
groupNames: asNameList(row.groupNames ?? row.group_names ?? row.groups),
|
|
789
|
+
roleNames: asNameList(row.roleNames ?? row.role_names ?? row.roles),
|
|
790
|
+
enabled: Boolean(row.enabled ?? row.enable ?? true)
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
function mapSystemGroupOption(item) {
|
|
794
|
+
if (!item || typeof item !== "object") return null;
|
|
795
|
+
const row = item;
|
|
796
|
+
const groupId = row.groupId ?? row.group_id ?? row.id;
|
|
797
|
+
if (groupId === void 0 || groupId === null || groupId === "") return null;
|
|
798
|
+
return {
|
|
799
|
+
groupId: String(groupId),
|
|
800
|
+
name: String(row.name ?? "")
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
function mapSystemRoleOption(item) {
|
|
804
|
+
if (!item || typeof item !== "object") return null;
|
|
805
|
+
const row = item;
|
|
806
|
+
const roleId = row.roleId ?? row.role_id ?? row.id;
|
|
807
|
+
if (roleId === void 0 || roleId === null || roleId === "") return null;
|
|
808
|
+
return {
|
|
809
|
+
roleId: String(roleId),
|
|
810
|
+
name: String(row.name ?? "")
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
function validateUsername(username) {
|
|
814
|
+
const value = username.trim();
|
|
815
|
+
if (value.length < 6) return "\u8D26\u53F7\u957F\u5EA6\u4E0D\u5C11\u4E8E 6 \u4E2A\u5B57\u7B26";
|
|
816
|
+
if (!/[A-Za-z]/.test(value) || !/[0-9]/.test(value)) {
|
|
817
|
+
return "\u8D26\u53F7\u9700\u540C\u65F6\u5305\u542B\u5B57\u6BCD\u548C\u6570\u5B57";
|
|
818
|
+
}
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
function buildListUrl3(params) {
|
|
822
|
+
const parts = [];
|
|
823
|
+
appendQueryParam(parts, "keyword", params?.keyword ?? "");
|
|
824
|
+
if (params?.enabled !== void 0) {
|
|
825
|
+
appendQueryParam(parts, "enabled", String(params.enabled));
|
|
826
|
+
}
|
|
827
|
+
appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
|
|
828
|
+
appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
|
|
829
|
+
appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
|
|
830
|
+
return parts.length ? `/system/users?${parts.join("&")}` : "/system/users";
|
|
831
|
+
}
|
|
832
|
+
function buildKeywordUrl(base, keyword) {
|
|
833
|
+
const parts = [];
|
|
834
|
+
appendQueryParam(parts, "keyword", keyword ?? "");
|
|
835
|
+
return parts.length ? `${base}?${parts.join("&")}` : base;
|
|
836
|
+
}
|
|
837
|
+
function buildCreateUserBody(values) {
|
|
838
|
+
return {
|
|
839
|
+
username: values.username.trim(),
|
|
840
|
+
name: values.name.trim(),
|
|
841
|
+
password: values.password,
|
|
842
|
+
groupIds: [...new Set(values.groupIds.map(String))],
|
|
843
|
+
roleIds: [...new Set(values.roleIds.map(String))],
|
|
844
|
+
enabled: Boolean(values.enabled)
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
function buildUpdateUserBody(values) {
|
|
848
|
+
const body = {
|
|
849
|
+
username: values.username.trim(),
|
|
850
|
+
name: values.name.trim(),
|
|
851
|
+
groupIds: [...new Set(values.groupIds.map(String))],
|
|
852
|
+
roleIds: [...new Set(values.roleIds.map(String))],
|
|
853
|
+
enabled: Boolean(values.enabled)
|
|
854
|
+
};
|
|
855
|
+
if (values.password.trim()) {
|
|
856
|
+
body.password = values.password;
|
|
857
|
+
}
|
|
858
|
+
return body;
|
|
859
|
+
}
|
|
860
|
+
function createSystemUserApi(request) {
|
|
861
|
+
return {
|
|
862
|
+
async list(params, signal) {
|
|
863
|
+
const json = await request({
|
|
864
|
+
method: "GET",
|
|
865
|
+
url: buildListUrl3(params),
|
|
866
|
+
signal
|
|
867
|
+
});
|
|
868
|
+
const records = extractRecords(json).map(mapSystemUser).filter((item) => item !== null);
|
|
869
|
+
return {
|
|
870
|
+
records,
|
|
871
|
+
...extractPagination(json)
|
|
872
|
+
};
|
|
873
|
+
},
|
|
874
|
+
async create(values, signal) {
|
|
875
|
+
return request({
|
|
876
|
+
method: "POST",
|
|
877
|
+
url: "/system/users",
|
|
878
|
+
body: buildCreateUserBody(values),
|
|
879
|
+
signal
|
|
880
|
+
});
|
|
881
|
+
},
|
|
882
|
+
async update(userId, values, signal) {
|
|
883
|
+
return request({
|
|
884
|
+
method: "PATCH",
|
|
885
|
+
url: `/system/users/${encodeURIComponent(userId)}`,
|
|
886
|
+
body: buildUpdateUserBody(values),
|
|
887
|
+
signal
|
|
888
|
+
});
|
|
889
|
+
},
|
|
890
|
+
async remove(userId, signal) {
|
|
891
|
+
return request({
|
|
892
|
+
method: "DELETE",
|
|
893
|
+
url: `/system/users/${encodeURIComponent(userId)}`,
|
|
894
|
+
signal
|
|
895
|
+
});
|
|
896
|
+
},
|
|
897
|
+
async listGroups(params, signal) {
|
|
898
|
+
const json = await request({
|
|
899
|
+
method: "GET",
|
|
900
|
+
url: buildKeywordUrl("/system/groups", params?.keyword),
|
|
901
|
+
signal
|
|
902
|
+
});
|
|
903
|
+
return extractRecords(json).map(mapSystemGroupOption).filter((item) => item !== null);
|
|
904
|
+
},
|
|
905
|
+
async listRoleOptions(params, signal) {
|
|
906
|
+
const json = await request({
|
|
907
|
+
method: "GET",
|
|
908
|
+
url: buildKeywordUrl("/system/roles", params?.keyword),
|
|
909
|
+
signal
|
|
910
|
+
});
|
|
911
|
+
return extractRecords(json).map(mapSystemRoleOption).filter((item) => item !== null);
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
|
|
686
916
|
exports.MENU_LEAF_NO = MENU_LEAF_NO;
|
|
687
917
|
exports.MENU_LEAF_YES = MENU_LEAF_YES;
|
|
688
918
|
exports.MENU_LIST_TYPE_PARAM = MENU_LIST_TYPE_PARAM;
|
|
@@ -706,27 +936,39 @@ exports.appendQueryParam = appendQueryParam;
|
|
|
706
936
|
exports.buildCreateBody = buildCreateBody;
|
|
707
937
|
exports.buildCreateMenuBody = buildCreateMenuBody;
|
|
708
938
|
exports.buildCreateRoleBody = buildCreateRoleBody;
|
|
939
|
+
exports.buildCreateUserBody = buildCreateUserBody;
|
|
940
|
+
exports.buildPermissionTreeIndex = buildPermissionTreeIndex;
|
|
709
941
|
exports.buildSavePermissionsBody = buildSavePermissionsBody;
|
|
710
942
|
exports.buildUpdateBody = buildUpdateBody;
|
|
711
943
|
exports.buildUpdateMenuBody = buildUpdateMenuBody;
|
|
712
944
|
exports.buildUpdateRoleBody = buildUpdateRoleBody;
|
|
945
|
+
exports.buildUpdateUserBody = buildUpdateUserBody;
|
|
713
946
|
exports.collectTreeResourceIds = collectTreeResourceIds;
|
|
947
|
+
exports.countCheckedDescendants = countCheckedDescendants;
|
|
714
948
|
exports.createAuthorizationResourceApi = createAuthorizationResourceApi;
|
|
715
949
|
exports.createDefaultResourceRequest = createDefaultResourceRequest;
|
|
716
950
|
exports.createMenuResourceApi = createMenuResourceApi;
|
|
717
951
|
exports.createPermissionStore = createPermissionStore;
|
|
718
952
|
exports.createSystemRoleApi = createSystemRoleApi;
|
|
953
|
+
exports.createSystemUserApi = createSystemUserApi;
|
|
719
954
|
exports.extractPagination = extractPagination;
|
|
720
955
|
exports.extractRecords = extractRecords;
|
|
721
956
|
exports.getAppClientId = getAppClientId;
|
|
722
957
|
exports.getDeviceWorkerId = getDeviceWorkerId;
|
|
958
|
+
exports.hasCheckedDescendant = hasCheckedDescendant;
|
|
723
959
|
exports.isMenuLeaf = isMenuLeaf;
|
|
960
|
+
exports.isPermissionNodeIndeterminate = isPermissionNodeIndeterminate;
|
|
724
961
|
exports.mapAuthorizationResource = mapAuthorizationResource;
|
|
725
962
|
exports.mapMenuResource = mapMenuResource;
|
|
726
963
|
exports.mapPermissionTreeNode = mapPermissionTreeNode;
|
|
727
964
|
exports.mapRolePermissions = mapRolePermissions;
|
|
965
|
+
exports.mapSystemGroupOption = mapSystemGroupOption;
|
|
728
966
|
exports.mapSystemRole = mapSystemRole;
|
|
967
|
+
exports.mapSystemRoleOption = mapSystemRoleOption;
|
|
968
|
+
exports.mapSystemUser = mapSystemUser;
|
|
729
969
|
exports.resolveMenuDepth = resolveMenuDepth;
|
|
730
970
|
exports.snowyflake = snowyflake;
|
|
971
|
+
exports.togglePermissionCheck = togglePermissionCheck;
|
|
972
|
+
exports.validateUsername = validateUsername;
|
|
731
973
|
//# sourceMappingURL=index.cjs.map
|
|
732
974
|
//# sourceMappingURL=index.cjs.map
|