diff --git a/admin-web/src/models/admin/roleList.js b/admin-web/src/models/admin/roleList.js index 591a6cf5e..dfd2b26f2 100644 --- a/admin-web/src/models/admin/roleList.js +++ b/admin-web/src/models/admin/roleList.js @@ -1,5 +1,32 @@ import { message } from 'antd'; -import { addRole, updateRole, deleteRole, queryRole } from '../../services/admin'; +import { arrayToStringParams } from '../../utils/request.qs'; +import { + addRole, + updateRole, + deleteRole, + queryRole, + queryRoleResourceTree, + roleAssignResource, + resourceTree, +} from '../../services/admin'; + +function buildTreeNode(nodes, titleKey, nodeKey) { + return nodes.map(item => { + const res = {}; + if (item.children) { + res.children = buildTreeNode(item.children, titleKey, nodeKey); + } + res.title = `${item.id}-${item[titleKey]}`; + res.key = item[nodeKey]; + return res; + }); +} + +function getKeys(treeData) { + return treeData.map(item => { + return item.key; + }); +} export default { namespace: 'roleList', @@ -9,6 +36,11 @@ export default { count: 0, pageNo: 0, pageSize: 10, + + roleTreeData: [], + resourceTreeData: [], + checkedKeys: [], + assignModalLoading: true, }, effects: { @@ -61,6 +93,56 @@ export default { }, }); }, + *queryRoleAssign({ payload }, { call, put }) { + yield put({ + type: 'changeAssignModalLoading', + payload: true, + }); + + const roleResourceResponse = yield call(queryRoleResourceTree, payload); + const resourceTreeResponse = yield call(resourceTree); + + const roleTreeData = buildTreeNode(roleResourceResponse.data, 'displayName', 'id'); + const resourceTreeData = buildTreeNode(resourceTreeResponse.data, 'displayName', 'id'); + const roleTreeIdKeys = getKeys(roleTreeData); + const resourceTreeIdKeys = getKeys(resourceTreeData); + + const checkedKeys = roleTreeIdKeys.filter(roleKey => { + let res = false; + resourceTreeIdKeys.map(key => { + if (key === roleKey) { + res = true; + } + return key; + }); + return res; + }); + + yield put({ + type: 'querySuccess', + payload: { + checkedKeys, + roleTreeData, + resourceTreeData, + }, + }); + + yield put({ + type: 'changeAssignModalLoading', + payload: false, + }); + }, + *roleAssignResource({ payload }, { call }) { + const { id, resourceIds } = payload; + const params = { + id, + resourceIds: arrayToStringParams(resourceIds), + }; + const response = yield call(roleAssignResource, params); + if (response.code === 0) { + message.info('操作成功!'); + } + }, }, reducers: { @@ -70,5 +152,17 @@ export default { ...payload, }; }, + changeCheckedKeys(state, { payload }) { + return { + ...state, + checkedKeys: payload, + }; + }, + changeAssignModalLoading(state, { payload }) { + return { + ...state, + assignModalLoading: payload, + }; + }, }, }; diff --git a/admin-web/src/pages/Admin/ResourceList.js b/admin-web/src/pages/Admin/ResourceList.js index 61b00cf1b..7557ecf9e 100644 --- a/admin-web/src/pages/Admin/ResourceList.js +++ b/admin-web/src/pages/Admin/ResourceList.js @@ -65,6 +65,7 @@ const CreateForm = Form.create()(props => { rules: [{ required: true, message: '请输入父级编号!' }], initialValue: initValues.pid, })()} + 根节点为 0 {form.getFieldDecorator('sort', { diff --git a/admin-web/src/pages/Admin/RoleList.js b/admin-web/src/pages/Admin/RoleList.js index a746f2249..3870d5399 100644 --- a/admin-web/src/pages/Admin/RoleList.js +++ b/admin-web/src/pages/Admin/RoleList.js @@ -3,13 +3,26 @@ import React, { PureComponent, Fragment } from 'react'; import { connect } from 'dva'; import moment from 'moment'; -import { Card, Form, Input, Select, Button, Modal, message, Table, Divider } from 'antd'; +import { + Card, + Form, + Input, + Select, + Spin, + Button, + Modal, + message, + Table, + Divider, + Tree, +} from 'antd'; import PageHeaderWrapper from '@/components/PageHeaderWrapper'; import styles from './RoleList.less'; const FormItem = Form.Item; const { Option } = Select; +const { TreeNode } = Tree; // 添加 form 表单 const CreateForm = Form.create()(props => { @@ -52,6 +65,78 @@ const CreateForm = Form.create()(props => { ); }); +// 添加 form 表单 +const AssignModal = Form.create()(props => { + const { + modalVisible, + form, + handleOk, + handleModalVisible, + treeData, + checkedKeys, + loading, + handleCheckBoxClick, + } = props; + + const renderTreeNodes = data => { + return data.map(item => { + if (item.children) { + return ( + + {renderTreeNodes(item.children)} + + ); + } + return ; + }); + }; + + const renderModalContent = treeData => { + const RenderTreeNodes = renderTreeNodes(treeData); + if (RenderTreeNodes) { + return ( + + {form.getFieldDecorator('name', {})( + + {renderTreeNodes(treeData)} + + )} + + ); + } else { + return null; + } + }; + + const okHandle = () => { + form.validateFields((err, fieldsValue) => { + if (err) return; + form.resetFields(); + handleOk({ + fields: fieldsValue, + }); + }); + }; + + return ( + handleModalVisible()} + > + {renderModalContent(treeData)} + + ); +}); + +// roleList @connect(({ roleList, loading }) => ({ roleList, list: roleList.list, @@ -64,6 +149,8 @@ class RoleList extends PureComponent { modalVisible: false, modalType: 'add', //add update initValues: {}, + roleAssignVisible: false, + roleAssignRecord: {}, }; componentDidMount() { @@ -86,8 +173,51 @@ class RoleList extends PureComponent { }); }; + handleAssignModalVisible = (flag, record) => { + const { dispatch } = this.props; + dispatch({ + type: 'roleList/queryRoleAssign', + payload: { + id: record.id, + }, + }); + this.setState({ + roleAssignVisible: !!flag, + roleAssignRecord: record, + }); + }; + + handleAssignModalVisibleClose(flag) { + this.setState({ + roleAssignVisible: !!flag, + }); + } + + handleAssignCheckBoxClick = checkedKeys => { + const { dispatch } = this.props; + const newCheckedKeys = checkedKeys.map(item => { + return parseInt(item); + }); + dispatch({ + type: 'roleList/changeCheckedKeys', + payload: newCheckedKeys, + }); + }; + + handleAssignOK = () => { + const { dispatch, data } = this.props; + const { roleAssignRecord } = this.state; + dispatch({ + type: 'roleList/roleAssignResource', + payload: { + id: roleAssignRecord.id, + resourceIds: data.checkedKeys, + }, + }); + this.handleAssignModalVisibleClose(false); + }; + handleAdd = ({ fields, modalType, initValues }) => { - console.log('add ->>>', fields); const { dispatch, data } = this.props; const queryParams = { pageNo: data.pageNo, @@ -151,7 +281,10 @@ class RoleList extends PureComponent { render() { const { list, data } = this.props; - const { modalVisible, modalType, initValues, defaultExpandAllRows } = this.state; + + const { pageNo, pageSize, count, resourceTreeData, checkedKeys, assignModalLoading } = data; + const { modalVisible, modalType, initValues, roleAssignVisible } = this.state; + const parentMethods = { handleAdd: this.handleAdd, handleModalVisible: this.handleModalVisible, @@ -177,10 +310,13 @@ class RoleList extends PureComponent { }, { title: '操作', + width: 200, render: (text, record) => ( this.handleModalVisible(true, 'update', record)}>更新 + this.handleAssignModalVisible(true, record)}>分配权限 + this.handleDelete(record)}> 删除 @@ -190,10 +326,11 @@ class RoleList extends PureComponent { ]; const paginationProps = { - current: data.pageNo, - pageSize: data.pageSize, - total: data.count, + current: pageNo, + pageSize: pageSize, + total: count, }; + return ( @@ -211,6 +348,15 @@ class RoleList extends PureComponent { + this.handleAssignModalVisibleClose(false)} + /> ); } diff --git a/admin-web/src/services/admin.js b/admin-web/src/services/admin.js index 2aa104b4d..deb177f4c 100644 --- a/admin-web/src/services/admin.js +++ b/admin-web/src/services/admin.js @@ -95,3 +95,18 @@ export async function updateRole(params) { body: {}, }); } + +export async function queryRoleResourceTree(params) { + return request(`/admin-api/admins/role/resource_tree?${stringify(params)}`, { + method: 'GET', + }); +} + +export async function roleAssignResource(params) { + return request(`/admin-api/admins/role/assign_resource?${stringify(params)}`, { + method: 'POST', + body: { + ...params, + }, + }); +} diff --git a/admin-web/src/utils/request.qs.js b/admin-web/src/utils/request.qs.js index bfcde845e..e101f963d 100644 --- a/admin-web/src/utils/request.qs.js +++ b/admin-web/src/utils/request.qs.js @@ -30,6 +30,17 @@ function filterEmptyStr(params) { } } +export function arrayToStringParams(array) { + let res = ''; + for (let i = 0; i < array.length; i++) { + res += array[i]; + if (i < array.length - 1) { + res += ','; + } + } + return res; +} + export function stringify(params) { return qs.stringify(filterEmptyStr(params)); }