/**
* 权限管理
*/
import React from 'react'
import { Tabs, Layout, Row, Col, Input, Menu, Table, Checkbox, message, Button, Icon } from 'antd'
import { connect } from 'dva'
import Loading from '../common/loading/index'
import './index.less'
const { Sider, Header, Content } = Layout
const { Search } = Input
const { TabPane } = Tabs
class Authority extends React.Component {
componentDidMount() {
const { dispatch } = this.props;
dispatch({ type: 'userGroup/fetchList' });
dispatch({ type: 'user/fetchList' });
dispatch({ type: 'dashboard/remoteMenuTree' });
}
checkIndeterminate = (treeList) => {
const { authority } = this.props;
const { dashboardList, dashboardFilterLabel } = authority;
let arr = treeList && treeList.length > 0 ? [ ...treeList ] : null;
for(let i = (arr ? (arr.length - 1) : 0); arr && i >= 0; i--) {
let l = arr[i];
if(l.type === 'menu') {
l.children = this.checkIndeterminate(l.children);
let checkedCount = l.children ? l.children.filter(c => c.type === 'dashboard').map(c => c.checked).filter(c => !!c).length : 0;
l.indeterminate = l.children ? (checkedCount > 0 && checkedCount < l.children.filter(c => c.type === 'dashboard').length) : false;
l.checked = l.children ? checkedCount !== 0 && checkedCount === l.children.filter(c => c.type === 'dashboard').length : false;
if((!l.children || l.children.length === 0) && !!dashboardFilterLabel && l.name.toLowerCase().indexOf(dashboardFilterLabel.toLowerCase()) === -1) {
arr.splice(i, 1);
}
}else {
l.children = null;
l.indeterminate = false;
l.checked = dashboardList.findIndex(d => d === l.code) > -1;
if(!!dashboardFilterLabel && l.name.toLowerCase().indexOf(dashboardFilterLabel.toLowerCase()) === -1) {
arr.splice(i, 1);
}
}
}
return arr;
}
changeTab = (key) => {
const { dispatch } = this.props;
dispatch({ type: 'authority/setFields', fields: [
{ name: 'tabActiveKey', value: key },
{ name: 'menuSelectedKeys', value: [] },
{ name: 'dashboardList', value: [] },
] });
}
render() {
const { dashboard, authority, userGroup, user, dispatch } = this.props;
const { panelLoading, menuSelectedKeys, tabActiveKey, groupFilterLabel, userFilterLabel, dashboardFilterLabel, groupLimit, userLimit } = authority;
const dashboardTreeList = this.checkIndeterminate(JSON.parse(JSON.stringify(dashboard.menuTree)));
return
{
dispatch({ type: 'authority/setFields', fields: [
{ name: 'groupLimit', value: 30 },
{ name: 'groupFilterLabel', value: val },
] })
}}
displayField='name'
valueField='code'
onItemClick={(item) => {
dispatch({ type: 'authority/batchActions', actions: [
{ type: 'setFields', fields: [
{ name: 'menuSelectedKeys', value: [item.code] },
] },
{ type: 'fetchDashboardTree', dtype: '0', code: item.code }
] });
}}
limit={groupLimit}
onScrollToBottom={() => {
window.clearTimeout(this.groupLimitKey);
this.groupLimitKey = window.setTimeout(() => {
dispatch({ type: 'authority/setFields', fields: [
{ name: 'groupLimit', value: (groupLimit + 10 > userGroup.list.length ? userGroup.list.length : groupLimit + 10) },
] })
}, 500);
}}
/>
{
dispatch({ type: 'authority/setFields', fields: [
{ name: 'userLimit', value: 30 },
{ name: 'userFilterLabel', value: val },
] })
}}
displayField='fullName'
valueField='code'
onItemClick={(item) => {
dispatch({ type: 'authority/batchActions', actions: [
{ type: 'setFields', fields: [ { name: 'menuSelectedKeys', value: [item.code] }, ]},
{ type: 'fetchDashboardTree', dtype: '1', code: item.code }
] });
}}
limit={userLimit}
onScrollToBottom={() => {
window.clearTimeout(this.userLimitKey);
this.userLimitKey = window.setTimeout(() => {
dispatch({ type: 'authority/setFields', fields: [
{ name: 'userLimit', value: (userLimit + 10 > user.list.length ? user.list.length : userLimit + 10) },
] })
}, 500);
}}
/>
{
let value = e.target.value;
dispatch({ type: 'authority/setFields', fields: [
{ name: 'dashboardFilterLabel', value },
] })
}}
/>
{
if(!!menuSelectedKeys[0]) {
if(record.type === 'menu') {
let dashboardCodes = record.children.filter(c => c.type === 'dashboard').map(c => c.code)
dispatch({ type: 'authority/' + (checked ? 'addAll': 'removeAll'), dtype: tabActiveKey === 'user' ? 1 : 0, code: menuSelectedKeys[0], dashboardCodes });
}else {
dispatch({ type: 'authority/' + (checked ? 'add': 'remove'), dtype: tabActiveKey === 'user' ? 1 : 0, code: menuSelectedKeys[0], dashboardCode: record.code });
}
}else {
message.error('请先选择左侧用户组/用户');
}
}}/>
}
}
class MenuList extends React.Component {
componentDidMount() {
this.addEvents();
}
addEvents = () => {
const { refName } = this.props;
let tabs = this['menuList-' + refName];
let menu = tabs.getElementsByClassName('ant-menu')[0];
menu.removeEventListener('scroll', this.onMenuScroll);
menu.addEventListener('scroll', this.onMenuScroll);
}
onMenuScroll = (e) => {
const { onScrollToBottom } = this.props;
let target = e.target;
if(target.scrollHeight - target.offsetHeight === target.scrollTop) { // 滚动到底了
typeof onScrollToBottom === 'function' && onScrollToBottom()
}
}
render() {
const { refName, selectedKeys, list, filterLabel: pFilterLabel, filterLabelChange, displayField, valueField, onItemClick, limit } = this.props;
const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
let filterLabel = (pFilterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
return
this['menuList-' + refName] = node} className='menu-list'>
{
let val = e.target.value + '';
typeof filterLabelChange === 'function' && filterLabelChange(val);
}}
/>
}
}
class DashBoardTree extends React.Component {
constructor(props) {
super(props);
this.state = {
tableScrollHeight: 0,
allExpanded: false,
expandedRowKeys: [],
}
}
componentDidMount() {
this.tableSize();
window.addEventListener('resize', this.tableSize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.tableSize);
}
tableSize = () => {
const content = document.getElementsByClassName('content-setting')[0];
const tableWrapper = content.getElementsByClassName('ant-table-wrapper')[0];
const tableContent = tableWrapper.getElementsByClassName('ant-spin-nested-loading')[0];
const tableHeader = tableContent.querySelector('thead');
const padding = tableContent.getBoundingClientRect().top - tableWrapper.getBoundingClientRect().top;
// 容器高度 - padding * 2 - 表头高度 - 边框线
let tableScrollHeight = tableWrapper.offsetHeight - padding * 2 - tableHeader.offsetHeight - 2;
this.setState({
tableScrollHeight,
});
}
onExpandedRowsChange = (expandedRowKeys) => {
this.setState({
expandedRowKeys
});
}
onExpandAll = () => {
const { dataSource } = this.props;
let expandedRowKeys = this.getAllKeys(dataSource);
this.setState({
allExpanded: true,
expandedRowKeys
});
}
collapseAll = () => {
this.setState({
allExpanded: false,
expandedRowKeys: []
});
}
getAllKeys = (list) => {
let keyArr = [];
for(let i = 0;!!list && i < list.length; i++) {
if(!!list[i].children) {
keyArr.push(list[i].key);
keyArr = keyArr.concat(this.getAllKeys(list[i].children, keyArr));
}
}
return keyArr
}
render() {
const { dataSource, onRowCheckChange, filterLabel } = this.props;
const { tableScrollHeight, expandedRowKeys, allExpanded } = this.state;
const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
const columns = [{
title: 报表目录,
dataIndex: 'name',
key: 'name',
width: '80%',
render: (text, record) => {
return
{
filterLabel ?
((text || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
return (
fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
{fragment} :
fragment
)
}
)) : text
}
}
}, {
title: '查看',
dataIndex: 'view',
key: 'view',
width: '20%',
render: (text, record, index) => {
return c.type === 'dashboard').length === 0)} indeterminate={record.indeterminate} checked={record.checked} onChange={(e) => {
let checked = e.target.checked;
typeof onRowCheckChange === 'function' && onRowCheckChange(record, checked);
}} />
}
}];
return
}
}
export default connect(({ present: { authority, userGroup, user, dashboard } }) => ({ authority, userGroup, user, dashboard }))(Authority)