Your Name преди 2 години
родител
ревизия
92b137fb8d
променени са 2 файла, в които са добавени 69 реда и са изтрити 28 реда
  1. 65
    27
      src/pages/roles/menus.jsx
  2. 4
    1
      src/services/role.js

+ 65
- 27
src/pages/roles/menus.jsx Целия файл

@@ -2,59 +2,95 @@ import React from 'react';
2 2
 import { Button, Card, Tree, message } from 'antd';
3 3
 import useBool from '@/utils/hooks/useBool';
4 4
 import { arr2Tree, uniq } from '@/utils/array';
5
-import { getResourceList } from '@/services/role';
5
+import { getResourceList, authRoleResource } from '@/services/role';
6 6
 
7 7
 export default (props) => {
8 8
   const { role } = props;
9 9
   
10 10
   const [loading, startLoading, cancelLoading] = useBool();
11 11
   const [list, setList] = React.useState([]);
12
+  const [expandedKeys, setExpandedKeys] = React.useState([]);
12 13
   const [treeData, setTreeData] = React.useState([]);
13 14
   const treeDictRef = React.useRef();
14
-  const [checkedKeys, setCheckedKeys] = React.useState([]);
15
-  const checkedNodesRef = React.useState([]);
15
+  const [checkedKeys, setCheckedKeys] = React.useState({ checked: [], halfChecked: [] });
16
+  const keys = checkedKeys.checked.concat(checkedKeys.halfChecked);
16 17
 
17 18
   const title = role ? `${role.name} - 授权菜单` : '授权菜单';
18 19
 
19
-  const onCheck = (keys, info) => {
20
-    const { checkedNodes } = info;
21
-    checkedNodesRef.current = checkedNodes;
22
-    // const keys = checkedNodes.map(node => getKeysWithParent(node, treeDictRef.current));
23
-    // setCheckedKeys(uniq(keys));
24
-    setCheckedKeys(keys);
20
+  const getListData = () => {
21
+    return new Promise((resolve, reject) => {
22
+      getResourceList({ type: 'menu' }).then((res = []) => {
23
+        setList(res);
24
+        resolve(res)
25
+      }).catch(reject);
26
+    });
27
+  }
28
+
29
+  const onCheck = (keys, { halfCheckedKeys }) => {
30
+    setCheckedKeys({ checked: keys, halfChecked: halfCheckedKeys });
25 31
   };
26 32
 
27 33
   const onSubmit = () => {
28
-    if (!checkedNodesRef.current) {
29
-      return;
30
-    }
31
-
32
-    if (checkedNodesRef.current.length !== checkedKeys.length) {
33
-      message.warn('未知错误, 请刷新重试');
34
-      return;
34
+    // 如果一个都不选,代表清空授权
35
+    const data = [];
36
+    const roleId = role.id;
37
+    for (let resourceId of keys) {
38
+      data.push({ roleId, resourceId });
35 39
     }
36
-
37
-    const keys = checkedNodesRef.current.map(node => getKeysWithParent(node, treeDictRef.current));
38
-
39
-  }
40
-
41
-  React.useEffect(() => {
42 40
     startLoading();
43
-    getResourceList({ pageSize: 500, type: 'menu' }).then((res) => {
41
+    authRoleResource(roleId, data).then((res) => {
44 42
       cancelLoading();
45
-      setList(res.records || []);
46 43
     }).catch(() => {
47 44
       cancelLoading();
48 45
     })
46
+  }
47
+
48
+  React.useEffect(() => {
49 49
   }, []);
50 50
 
51 51
   React.useEffect(() => {
52
-    if (!role) {
53
-      setList([]);
52
+    const p = !list.length ? getListData : () => Promise.resolve(list);
53
+    if (!role || !role.id) {
54
+      p();
55
+    } else {
56
+      startLoading();
57
+      p().then((allData) => {
58
+        getResourceList({ type: 'menu', roleId: role.id }).then((res = []) => {
59
+          cancelLoading();
60
+          
61
+          // 数据分为2部分, 一部分叶子节点, 一部分非叶子节点
62
+          const checked = [], halfChecked = [];
63
+          for (let item of res) {
64
+            // 获取子节点, 没有的话则为叶子节点, 否则为非叶子节点
65
+            const children = allData.filter(x => x.parentId === item.id);
66
+            if (!children.length) {
67
+              // 没有子节点, 则为叶子节点, 算入选中节点
68
+              checked.push(item.id);
69
+            } else {
70
+              // 获取选中子节点
71
+              const checkedChildren = res.filter(x => x.parentId === item.id);
72
+              if (checkedChildren.length === children.length) {
73
+                // 非叶子节点如果 子节点全部包含, 那么算入选中节点
74
+                checked.push(item.id);
75
+              } else {
76
+                halfChecked.push(item.id);
77
+              }
78
+            }
79
+          }
80
+
81
+          setCheckedKeys({ checked, halfChecked });
82
+        }).catch(() => {
83
+          cancelLoading();
84
+        })
85
+      }).catch(() => {
86
+        cancelLoading();
87
+      })
54 88
     }
55 89
   }, [role]);
56 90
   
57 91
   React.useEffect(() => {
92
+    // 展开节点
93
+    setExpandedKeys((list).filter(x => x.parentId === -1).map(x => x.id));
58 94
     // 先转为需要的格式
59 95
     const arr = list.map(x => ({ title: x.name, key: x.id, parentId: x.parentId }));
60 96
     // 再转为 tree
@@ -67,15 +103,17 @@ export default (props) => {
67 103
     <Card
68 104
       loading={loading}
69 105
       title={title}
70
-      extra={<Button type='primary' ghost onClick={onSubmit}>保存</Button>}
106
+      extra={<Button type='primary' disabled={!role || !role.id} ghost onClick={onSubmit}>保存</Button>}
71 107
     >
72 108
       <Tree
73 109
         checkable
74 110
         autoExpandParent
111
+        expandedKeys={expandedKeys}
75 112
         checkStrictly={false}
76 113
         selectable={false}
77 114
         checkedKeys={checkedKeys}
78 115
         onCheck={onCheck}
116
+        onExpand={setExpandedKeys}
79 117
         treeData={treeData}
80 118
       />
81 119
     </Card>

+ 4
- 1
src/services/role.js Целия файл

@@ -1,4 +1,4 @@
1
-import { restful } from '@/utils/request';
1
+import request,  { restful } from '@/utils/request';
2 2
 
3 3
 /**
4 4
  * 构造 Service
@@ -35,3 +35,6 @@ import { restful } from '@/utils/request';
35 35
   updateResource,
36 36
   deleteResource,
37 37
  }
38
+
39
+// 授权菜单
40
+ export const authRoleResource = (roleId, data) => request.post(`/role/${roleId}/Resources`, data);