权限分配

This commit is contained in:
sin 2019-03-11 13:44:04 +08:00
parent f02e4d26ef
commit 3cb4efd52e
5 changed files with 274 additions and 7 deletions

View File

@ -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,
};
},
},
};

View File

@ -65,6 +65,7 @@ const CreateForm = Form.create()(props => {
rules: [{ required: true, message: '请输入父级编号!' }],
initialValue: initValues.pid,
})(<Input placeholder="请输入" />)}
<span>根节点为 0</span>
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="排序">
{form.getFieldDecorator('sort', {

View File

@ -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 (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode title={item.title} key={item.key} dataRef={item} />;
});
};
const renderModalContent = treeData => {
const RenderTreeNodes = renderTreeNodes(treeData);
if (RenderTreeNodes) {
return (
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="角色名">
{form.getFieldDecorator('name', {})(
<Tree
defaultExpandAll={true}
checkable={true}
checkedKeys={checkedKeys}
onCheck={handleCheckBoxClick}
>
{renderTreeNodes(treeData)}
</Tree>
)}
</FormItem>
);
} else {
return null;
}
};
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
handleOk({
fields: fieldsValue,
});
});
};
return (
<Modal
destroyOnClose
title="更新权限"
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Spin spinning={loading}>{renderModalContent(treeData)}</Spin>
</Modal>
);
});
// 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) => (
<Fragment>
<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>
<Divider type="vertical" />
<a onClick={() => this.handleAssignModalVisible(true, record)}>分配权限</a>
<Divider type="vertical" />
<a className={styles.tableDelete} onClick={() => this.handleDelete(record)}>
删除
</a>
@ -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 (
<PageHeaderWrapper title="查询表格">
<Card bordered={false}>
@ -211,6 +348,15 @@ class RoleList extends PureComponent {
<Table columns={columns} dataSource={list} rowKey="id" />
</Card>
<CreateForm {...parentMethods} modalVisible={modalVisible} />
<AssignModal
loading={assignModalLoading}
treeData={resourceTreeData}
checkedKeys={checkedKeys}
handleOk={this.handleAssignOK}
modalVisible={roleAssignVisible}
handleCheckBoxClick={this.handleAssignCheckBoxClick}
handleModalVisible={() => this.handleAssignModalVisibleClose(false)}
/>
</PageHeaderWrapper>
);
}

View File

@ -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,
},
});
}

View File

@ -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));
}