张延森 il y a 4 ans
Parent
révision
4675a60ae8

+ 2
- 1
config/routes.js Voir le fichier

@@ -236,12 +236,13 @@ export default [
236 236
                     name: '角色编辑',
237 237
                     menuCode: 'system.role',
238 238
                     component: './System/Role/Edit',
239
+                    hideInMenu: true,
239 240
                   },
240 241
                   {
241 242
                     path: '/system/params',
242 243
                     name: '系统参数',
243 244
                     menuCode: 'system.params',
244
-                    component: '../layouts/BlankLayout',
245
+                    component: './System/Params',
245 246
                   },
246 247
               
247 248
                   {

+ 71
- 0
src/pages/System/Params/index.jsx Voir le fichier

@@ -0,0 +1,71 @@
1
+import React, { useRef, useState } from 'react'
2
+import { PageContainer } from '@ant-design/pro-layout';
3
+import ProTable from '@ant-design/pro-table';
4
+import { Modal, Input, notification } from 'antd';
5
+import request, { queryTable } from '@/utils/request';
6
+
7
+export default () => {
8
+  const tableRef = useRef()
9
+  const [current, setCurrent] = useState()
10
+  const [inputVal, setInputVal] = useState([])
11
+  const [show, setShow] = useState(false)
12
+
13
+  const columns = [
14
+    {
15
+      title: '编码',
16
+      key: 'code',
17
+      dataIndex: 'code',
18
+    },
19
+    {
20
+      title: '描述',
21
+      key: 'description',
22
+      dataIndex: 'description',
23
+    },
24
+    {
25
+      title: '参数值',
26
+      key: 'value',
27
+      dataIndex: 'value',
28
+    },
29
+    {
30
+      title: '操作',
31
+      key: 'option',
32
+      valueType: 'option',
33
+      width: 240,
34
+      render: (_, role) => [
35
+        <a key="edit" onClick={() => handleEdit(role)}>修改</a>,
36
+      ]
37
+    },
38
+  ]
39
+
40
+  const handleEdit = (config) => {
41
+    setCurrent(config)
42
+    setInputVal(config.value)
43
+    setShow(true)
44
+  }
45
+
46
+  const handleSubmit = () => {
47
+    setShow(false)
48
+    request(`/sys-config/${current.serialNo}`, { method: 'put', data: { ...current, value: inputVal } }).then(() => {
49
+      tableRef.current.reload()
50
+      notification.success({ message: '修改成功' })
51
+    }).catch((e) => {
52
+      notification.error({ message: e.message })
53
+    })
54
+  }
55
+  
56
+  return (
57
+    <PageContainer>
58
+      <ProTable
59
+        actionRef={tableRef}
60
+        columns={columns}
61
+        request={queryTable('/sys-config')}
62
+        rowKey="code"
63
+        headerTitle="参数列表"
64
+        search={false}
65
+      />
66
+      <Modal title="修改参数值" visible={show} onOk={handleSubmit} onCancel={() => setShow(false)} >
67
+        <Input size="large" value={inputVal} onChange={(e) => setInputVal(e.target.value)} />
68
+      </Modal>
69
+    </PageContainer>
70
+  )
71
+}

+ 35
- 3
src/pages/System/Role/Edit.jsx Voir le fichier

@@ -3,15 +3,41 @@ import { PageContainer } from '@ant-design/pro-layout';
3 3
 import { Button, Card, Divider, notification } from 'antd';
4 4
 import request from '@/utils/request';
5 5
 import RoleForm from './components/Form'
6
+import RoleMenu from './components/Menu'
6 7
 
7
-export default (props) => {
8
+export default  (props) => {
8 9
   const { id } = props.location.query;
9 10
   const [loading, setLoading] = useState(false);
11
+  const [saveLoading, setSaveLoading] = useState(false);
10 12
   const [role, setRole] = useState({});
13
+  // 数据库授权菜单
14
+  const [roleMenu, setRoleMenu] = useState([])
15
+  // 待保存菜单
16
+  const [menuData, setMenuData] = useState([])
11 17
   
12 18
   const handleFormChange = (newRole) => {
13 19
     setRole(newRole);
14 20
   };
21
+
22
+  const handleMenuChange = (menuList) => {
23
+    setMenuData(menuList)
24
+  }
25
+
26
+  const handleMenuSave = () => {
27
+    const data = menuData.map((m) => ({ roleId: id, menuId: m.menuId }))
28
+    setSaveLoading(true)
29
+    request(`/role-menu/${id}`, { method: 'post', data })
30
+      .then(() => {
31
+        setRoleMenu(data)
32
+        setMenuData([])
33
+        setSaveLoading(false);
34
+        notification.success({ message: '操作成功' });
35
+      })
36
+      .catch((e) => {
37
+        setSaveLoading(false);
38
+        notification.error({ message: e.message });
39
+      });
40
+  }
15 41
   
16 42
   useEffect(() => {
17 43
     if (id) {
@@ -19,6 +45,8 @@ export default (props) => {
19 45
       request(`/role/${id}`)
20 46
         .then((res) => {
21 47
           setRole(res);
48
+          setRoleMenu(res.menuList||[])
49
+          setMenuData([])
22 50
           setLoading(false);
23 51
         })
24 52
         .catch((e) => {
@@ -34,8 +62,12 @@ export default (props) => {
34 62
         <RoleForm role={role} onChange={handleFormChange} />
35 63
       </Card>
36 64
 
37
-      <Card title="授权菜单" style={{ width: '100%', marginTop: '2em' }}>
38
-        
65
+      <Card
66
+        title="授权菜单"
67
+        style={{ width: '100%', marginTop: '2em' }}
68
+        extra={<Button type="primary" disabled={!menuData.length} loading={saveLoading} onClick={handleMenuSave}>保存</Button>}
69
+      >
70
+        <RoleMenu roleMenu={roleMenu} onChange={handleMenuChange} />
39 71
       </Card>
40 72
     </PageContainer>
41 73
   )

+ 119
- 0
src/pages/System/Role/components/Menu.jsx Voir le fichier

@@ -0,0 +1,119 @@
1
+import React, { useEffect, useState } from 'react'
2
+import { Tree, Spin } from 'antd'
3
+import { connect } from 'umi'
4
+
5
+const convert2Tree = (arr) => {
6
+  const rootId = -1
7
+  const tree = []
8
+
9
+  arr.forEach((menu) => {
10
+    const node = {
11
+      title: menu.name,
12
+      key: menu.menuId,
13
+      data: menu,
14
+    }
15
+
16
+    if (menu.children) {
17
+      node.children = menu.children
18
+    } else {
19
+      node.children = []
20
+      // eslint-disable-next-line
21
+      menu.children = node.children
22
+    }
23
+
24
+    // 如果是根节点
25
+    if (menu.menuPId === rootId) {
26
+      tree.push(node)
27
+    } else {
28
+      // 否则查询父节点
29
+      let parent = null
30
+      for(let i = 0; i < arr.length; i += 1) {
31
+        if (arr[i].menuId === menu.menuPId) {
32
+          parent = arr[i]
33
+          break
34
+        }
35
+      }
36
+
37
+      // 找到父节点, 则处理
38
+      // 否则直接丢弃
39
+      if (parent) {
40
+        if (parent.children) {
41
+          parent.children.push(node)
42
+        } else {
43
+          parent.children = [node]
44
+        }
45
+      }
46
+    }
47
+  })
48
+
49
+  return tree
50
+}
51
+
52
+const RoelMenu = (props) => {
53
+  const [treeData, setTreeData] = useState([])
54
+  const [expandedKeys, setExpandedKeys] = useState([])
55
+  const [checkedKeys, setCheckedKeys] = useState({ checked: [], halfChecked: [] })
56
+
57
+  const handleChecked = (keys, e) => {
58
+    setCheckedKeys({ checked: keys, halfChecked: e.halfCheckedKeys })
59
+
60
+    const allChecked = [...keys, ...e.halfCheckedKeys ]
61
+    const allMenus = props.menuList || []
62
+    const checkedMenus = allChecked.map((x) => allMenus.filter((m) => m.menuId === x)[0])
63
+    props.onChange(checkedMenus)
64
+  }
65
+
66
+  useEffect(() => {
67
+    // 因为 convert2Tree 方法有对 Object 的写入操作
68
+    // 此方法会触发 treeData 反复生成异常
69
+    // 所以需要进行一次解构操作
70
+    const list = (props.menuList || []).map((x) => ({ ...x, children: undefined }))
71
+    //
72
+    setTreeData(convert2Tree(list))
73
+
74
+    // 默认展开全部
75
+    setExpandedKeys(list.map((x) => x.menuId))
76
+  }, [props.menuList])
77
+
78
+  useEffect(() => {
79
+    const checked = []
80
+    const halfChecked = []
81
+    const menus = props.roleMenu || []
82
+    const allMenus = props.menuList || []
83
+
84
+    menus.forEach((menu) => {
85
+      // 当前选中的子节点
86
+      const checkedChildren = menus.filter((m) => m.menuPId === menu.menuId)
87
+      // 所有的子节点
88
+      const allChildren = allMenus.filter((m) => m.menuPId === menu.menuId)
89
+      // 如果当前选中的子节点全部都在选择列表中
90
+      if (checkedChildren.length === allChildren.length) {
91
+        checked.push(menu.menuId)
92
+      } else {
93
+        halfChecked.push(menu.menuId)
94
+      }
95
+    })
96
+
97
+    setCheckedKeys(checked, halfChecked)
98
+    // setCheckedKeys((props.roleMenu || []).map((x) => x.menuId))
99
+  }, [props.roleMenu, props.menuList])
100
+
101
+  return (
102
+    <div>
103
+      {
104
+        treeData.length && (
105
+          <Tree
106
+            checkable
107
+            checkedKeys={checkedKeys}
108
+            treeData={treeData}
109
+            defaultExpandedKeys={expandedKeys}
110
+            onCheck={handleChecked}
111
+          />
112
+        )
113
+      }
114
+      { !treeData.length && <Spin />}
115
+    </div>
116
+  )
117
+}
118
+
119
+export default connect((s) => ({ menuList: s.user.menus }))(RoelMenu)

+ 2
- 0
src/pages/System/Role/index.jsx Voir le fichier

@@ -34,11 +34,13 @@ export default () => {
34 34
       key: 'createDate',
35 35
       dataIndex: 'createDate',
36 36
       valueType: 'date',
37
+      width: 360,
37 38
     },
38 39
     {
39 40
       title: '操作',
40 41
       key: 'option',
41 42
       valueType: 'option',
43
+      width: 240,
42 44
       // 不能操作超级管理员
43 45
       render: (_, role) => [
44 46
         role.roleId !== '1' && <a key="edit" onClick={() => handleEdit(role)}>修改</a>,