diff --git a/admin-web/src/models/admin/adminList.js b/admin-web/src/models/admin/adminList.js index a21faa0d3..6adf934fe 100644 --- a/admin-web/src/models/admin/adminList.js +++ b/admin-web/src/models/admin/adminList.js @@ -1,11 +1,15 @@ import { message } from 'antd'; +import { buildTreeNode, findCheckedKeys } from '../../utils/tree.utils'; import { addAdmin, updateAdmin, updateAdminStatus, deleteAdmin, queryAdmin, + queryAdminRoleList, + adminRoleAssign, } from '../../services/admin'; +import { arrayToStringParams } from '../../utils/request.qs'; export default { namespace: 'adminList', @@ -15,6 +19,10 @@ export default { count: 0, pageNo: 0, pageSize: 10, + + roleList: [], + roleCheckedKeys: [], + roleAssignLoading: false, }, effects: { @@ -78,6 +86,40 @@ export default { }, }); }, + *queryRoleList({ payload }, { call, put }) { + yield put({ + type: 'changeRoleAssignLoading', + payload: true, + }); + + const response = yield call(queryAdminRoleList, payload); + const roleList = response.data; + const roleTreeData = buildTreeNode(roleList, 'name', 'id'); + const roleCheckedKeys = findCheckedKeys(roleList); + + yield put({ + type: 'querySuccess', + payload: { + roleList: roleTreeData, + roleCheckedKeys, + }, + }); + + yield put({ + type: 'changeRoleAssignLoading', + payload: false, + }); + }, + *roleAssign({ payload }, { call }) { + const params = { + id: payload.id, + roleIds: arrayToStringParams(payload.roleIds), + }; + const response = yield call(adminRoleAssign, params); + if (response.code === 0) { + message.info('操作成功!'); + } + }, }, reducers: { @@ -87,5 +129,17 @@ export default { ...payload, }; }, + changeRoleCheckedKeys(state, { payload }) { + return { + ...state, + roleCheckedKeys: payload, + }; + }, + changeRoleAssignLoading(state, { payload }) { + return { + ...state, + roleAssignLoading: payload, + }; + }, }, }; diff --git a/admin-web/src/models/admin/roleList.js b/admin-web/src/models/admin/roleList.js index 32071b535..fcec9a9b7 100644 --- a/admin-web/src/models/admin/roleList.js +++ b/admin-web/src/models/admin/roleList.js @@ -1,5 +1,6 @@ import { message } from 'antd'; import { arrayToStringParams } from '../../utils/request.qs'; +import { buildTreeNode, findAllNodes, findCheckedKeys } from '../../utils/tree.utils'; import { addRole, updateRole, @@ -9,71 +10,6 @@ import { roleAssignResource, } 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 findNodes(id, nodes) { - const res = []; - for (let i = 0; i < nodes.length; i += 1) { - const node = nodes[i]; - if (node.key === id) { - res.push(node.key); - break; - } else { - const childNodes = findNodes(id, node.children); - if (childNodes.length) { - res.push(node.key); - for (let j = 0; j < childNodes.length; j += 1) { - res.push(childNodes[j]); - } - break; - } - } - } - return res; -} - -function findAllNodes(resourceIds, nodes) { - const findNodesArray = []; - for (let i = 0; i < resourceIds.length; i += 1) { - const findNodesData = findNodes(resourceIds[i], nodes); - if (findNodesData) { - for (let j = 0; j < findNodesData.length; j += 1) { - const jD = findNodesData[j]; - if (findNodesArray.indexOf(jD) === -1) { - findNodesArray.push(jD); - } - } - } - } - return findNodesArray; -} - -function findCheckedKeys(nodes) { - let res = []; - for (let i = 0; i < nodes.length; i += 1) { - const node = nodes[i]; - if (node.children) { - const findChildrenNodes = findCheckedKeys(node.children); - if (findChildrenNodes) { - res = res.concat(findChildrenNodes); - } - } else if (node.assigned === true) { - res.push(node.id); - } - } - return res; -} - export default { namespace: 'roleList', diff --git a/admin-web/src/pages/Admin/AdminList.js b/admin-web/src/pages/Admin/AdminList.js index ab25d77c7..d2da4e2ab 100644 --- a/admin-web/src/pages/Admin/AdminList.js +++ b/admin-web/src/pages/Admin/AdminList.js @@ -2,14 +2,13 @@ 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, Button, Modal, message, Table, Divider, Tree, Spin } from 'antd'; import PageHeaderWrapper from '@/components/PageHeaderWrapper'; import styles from './AdminList.less'; const FormItem = Form.Item; -const { Option } = Select; +const { TreeNode } = Tree; const status = ['未知', '正常', '禁用']; // 添加 form 表单 @@ -64,6 +63,78 @@ const CreateForm = Form.create()(props => { ); }); +// 角色分配 +const RoleAssignModal = 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)} + + ); +}); + @connect(({ adminList, loading }) => ({ list: adminList.list, data: adminList, @@ -75,6 +146,9 @@ class ResourceList extends PureComponent { modalVisible: false, modalType: 'add', //add update initValues: {}, + + modalRoleVisible: false, + modalRoleRow: {}, }; componentDidMount() { @@ -160,9 +234,87 @@ class ResourceList extends PureComponent { }); } + handleDelete(row) { + const { dispatch, data } = this.props; + const queryParams = { + pageNo: data.pageNo, + pageSize: data.pageSize, + }; + + Modal.confirm({ + title: `确认删除?`, + content: `${row.username}`, + onOk() { + dispatch({ + type: 'adminList/delete', + payload: { + body: { + id: row.id, + }, + queryParams, + }, + }); + }, + onCancel() {}, + }); + } + + handleRoleAssign = row => { + const { dispatch } = this.props; + this.setState({ + modalRoleVisible: !!true, + modalRoleRow: row, + }); + + dispatch({ + type: 'adminList/queryRoleList', + payload: { + id: row.id, + }, + }); + }; + + handleRoleAssignCheckBoxClick = checkedKeys => { + const { dispatch } = this.props; + const newCheckedKeys = checkedKeys.map(item => { + return parseInt(item); + }); + dispatch({ + type: 'adminList/changeRoleCheckedKeys', + payload: newCheckedKeys, + }); + }; + + handleRoleAssignOK = () => { + const { dispatch, data } = this.props; + const { modalRoleRow } = this.state; + dispatch({ + type: 'adminList/roleAssign', + payload: { + id: modalRoleRow.id, + roleIds: data.roleCheckedKeys, + }, + }); + this.handleRoleAssignModalVisibleClose(false); + }; + + handleRoleAssignModalVisibleClose = fag => { + this.setState({ + modalRoleVisible: !!fag, + }); + }; + render() { - const { list } = this.props; - const { modalVisible, modalType, initValues, defaultExpandAllRows } = this.state; + const { list, data } = this.props; + const { roleList, roleCheckedKeys, roleAssignLoading } = data; + const { + modalVisible, + modalType, + initValues, + defaultExpandAllRows, + modalRoleVisible, + } = this.state; + const parentMethods = { handleAdd: this.handleAdd, handleModalVisible: this.handleModalVisible, @@ -194,12 +346,15 @@ class ResourceList extends PureComponent { }, { title: '操作', + width: 300, render: (text, record) => { const statusText = record.status === 1 ? '确认禁用' : '取消禁用'; return ( this.handleModalVisible(true, 'update', record)}>更新 + this.handleRoleAssign(record)}>角色分配 + this.handleStatus(record)}> {statusText} @@ -235,6 +390,16 @@ class ResourceList extends PureComponent { /> + + this.handleRoleAssignModalVisibleClose(false)} + /> ); } diff --git a/admin-web/src/services/admin.js b/admin-web/src/services/admin.js index deb177f4c..35efff580 100644 --- a/admin-web/src/services/admin.js +++ b/admin-web/src/services/admin.js @@ -43,6 +43,18 @@ export async function deleteAdmin(params) { }); } +export async function queryAdminRoleList(params) { + return request(`/admin-api/admins/admin/role_list?${stringify(params)}`, { + method: 'GET', + }); +} + +export async function adminRoleAssign(params) { + return request(`/admin-api/admins/admin/assign_role?${stringify(params)}`, { + method: 'POST', + }); +} + // resource export async function addResource(params) { diff --git a/admin-web/src/utils/tree.utils.js b/admin-web/src/utils/tree.utils.js new file mode 100644 index 000000000..bb0653ff5 --- /dev/null +++ b/admin-web/src/utils/tree.utils.js @@ -0,0 +1,67 @@ +// tree 工具 + +export 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; + }); +} + +// @primary +function findNodes(id, nodes) { + const res = []; + for (let i = 0; i < nodes.length; i += 1) { + const node = nodes[i]; + if (node.key === id) { + res.push(node.key); + break; + } else { + const childNodes = findNodes(id, node.children); + if (childNodes.length) { + res.push(node.key); + for (let j = 0; j < childNodes.length; j += 1) { + res.push(childNodes[j]); + } + break; + } + } + } + return res; +} + +export function findAllNodes(resourceIds, nodes) { + const findNodesArray = []; + for (let i = 0; i < resourceIds.length; i += 1) { + const findNodesData = findNodes(resourceIds[i], nodes); + if (findNodesData) { + for (let j = 0; j < findNodesData.length; j += 1) { + const jD = findNodesData[j]; + if (findNodesArray.indexOf(jD) === -1) { + findNodesArray.push(jD); + } + } + } + } + return findNodesArray; +} + +export function findCheckedKeys(nodes) { + let res = []; + for (let i = 0; i < nodes.length; i += 1) { + const node = nodes[i]; + if (node.children) { + const findChildrenNodes = findCheckedKeys(node.children); + if (findChildrenNodes) { + res = res.concat(findChildrenNodes); + } + } else if (node.assigned === true) { + res.push(node.id); + } + } + return res; +}