| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- /* eslint-disable consistent-return */
- import { Button, Transfer, Tree } from 'antd'
- import React, { useState, useEffect } from 'react'
- import styles from './ConnectCompany/index.less'
- import { CloseOutlined } from '@ant-design/icons'
- import consts from '@/basic/consts'
- import { useDispatch } from 'umi'
- import { queryDepartmentStaffList } from '@/services/department'
- import { useWindowSizeFn } from '@/hooks/event/useWindomSizeFn'
- const isChecked = (selectedKeys, eventKey) => selectedKeys.includes(eventKey)
- const itemIsChecked = onItemSelectAll => (selectedKeys, checkedKeys, checked, nodeList) => {
- if (!checked) {
- onItemSelectAll(nodeList, checked)
- } else {
- const keys = selectedKeys
- .filter(({ isDepartment }) => !isDepartment)
- .filter(({ key }) => !isChecked(checkedKeys, key))
- .map(({ key }) => key)
- onItemSelectAll(keys, checked)
- }
- }
- const generateTree = (treeNodes = [], checkedKeys = []) =>
- treeNodes.map(({ children, ...props }) => {
- const node = {
- ...props,
- disabled: checkedKeys.length && checkedKeys.includes(props.key),
- children: generateTree(children, checkedKeys)
- }
- if (props.isDepartment) {
- node.disabled = children?.every(
- item => checkedKeys.includes(item.key) || item.children?.every(u => !u.children?.length)
- )
- }
- return node
- })
- const CustomPerm = () => {
- const [state, setState] = useState({
- dataSource: [],
- treeKeys: [],
- targetKeys: [],
- transferDataSource: [],
- height: 0
- })
- function calcTreeHeight() {
- const node = document.querySelector('.ant-transfer-list-body')
- if (node) {
- return node.clientHeight - 56
- }
- return null
- }
- useEffect(() => {
- const transferDataSource = []
- function flatten(list = []) {
- list.forEach(item => {
- transferDataSource.push({
- key: item.key,
- title: item.title,
- parentId: item.parentId,
- children: item.children,
- isDepartment: item.isDepartment
- })
- item.children?.length && flatten(item.children)
- })
- }
- async function fetchList() {
- const { code = -1, data = [] } = await queryDepartmentStaffList()
- if (code === consts.RET_CODE.SUCCESS) {
- const height = calcTreeHeight()
- flatten(data)
- setState({ ...state, dataSource: data, transferDataSource, height })
- }
- }
- fetchList()
- }, [])
- useWindowSizeFn(() => {
- const height = calcTreeHeight()
- setState({ ...state, height })
- })
- const dispatch = useDispatch()
- const closeModal = () => {
- dispatch({
- type: 'single/changeModal'
- })
- }
- const handleOnSearch = (direction, value) => {
- console.log(direction, value)
- }
- const onChange = (keys, direction, moveKeys) => {
- if (direction === 'left') {
- const currKeys = state.targetKeys.filter(key => !moveKeys.includes(key))
- setState({
- ...state,
- targetKeys: currKeys,
- treeKeys: state.treeKeys.filter(item => {
- const node = state.transferDataSource.find(i => i.key === item)
- if (node?.isDepartment) {
- const childrenKey = node?.children.map(c => c.key).filter(c => !currKeys.includes(c))
- if (childrenKey?.every(w => !currKeys.includes(w))) {
- return !moveKeys.includes(item) && item !== node.key
- }
- }
- return !moveKeys.includes(item)
- })
- })
- } else {
- setState({ ...state, targetKeys: [...state.targetKeys, ...keys] })
- }
- }
- const handleUnCheckItem = (checkedKeys, key) => {
- const node = state.transferDataSource.find(item => item.key === key)
- if (node?.isDepartment) {
- const filterKeys = state.transferDataSource
- .filter(item => item.parentId === node.key)
- .map(item => item.key)
- setState({
- ...state,
- treeKeys: state.treeKeys.filter(item => ![key, ...filterKeys].includes(item))
- })
- } else {
- const pNode = state.transferDataSource.find(item => item.key === node.parentId)
- if (checkedKeys.includes(pNode.key)) {
- // 说明 父节点已经被选中
- setState({
- ...state,
- treeKeys: state.treeKeys.filter(item => item !== pNode.key && item !== key)
- })
- } else {
- setState({
- ...state,
- treeKeys: state.treeKeys.filter(item => item !== key)
- })
- }
- }
- }
- return (
- <div className={['ant-modal-content', styles.modalContainer].join(' ')}>
- <div className={styles.modalHeader}>
- <span>自定义展示数据</span>
- <span className={styles.closeIcon}>
- <CloseOutlined onClick={closeModal} />
- </span>
- </div>
- <div className={styles.modalContent}>
- <Transfer
- showSearch
- oneWay={true}
- className="h-full"
- render={item => item.title}
- onSearch={handleOnSearch}
- targetKeys={state.targetKeys}
- onChange={onChange}
- dataSource={state.transferDataSource}
- showSelectAll={false}>
- {({ direction, onItemSelectAll, onItemSelect }) => {
- if (direction === 'left') {
- const checkedKeys = [...state.targetKeys, ...state.treeKeys]
- return state.dataSource?.length ? (
- <Tree
- blockNode
- checkable
- defaultExpandAll
- height={state.height}
- checkedKeys={checkedKeys}
- treeData={generateTree(state.dataSource, state.targetKeys)}
- onCheck={(_, { checked, checkedNodes, node: { isDepartment, key } }) => {
- if (!checked) {
- handleUnCheckItem(checkedKeys, key)
- } else {
- setState({
- ...state,
- treeKeys: checkedNodes.map(item => item.key)
- })
- }
- if (isDepartment) {
- itemIsChecked(onItemSelectAll)(
- checkedNodes,
- checkedKeys,
- checked,
- state.transferDataSource
- .filter(item => item.parentId === key)
- .map(item => item.key)
- )
- } else {
- onItemSelect(key, !isChecked(checkedKeys, key))
- }
- }}
- onSelect={(_, { checkedNodes, node: { isDepartment, key } }) => {
- if (isDepartment) {
- itemIsChecked(onItemSelectAll)(checkedNodes, checkedKeys)
- } else {
- onItemSelect(key, !isChecked(checkedKeys, key))
- }
- }}
- />
- ) : null
- }
- }}
- </Transfer>
- </div>
- <div className={[styles.modalFooter, 'text-right'].join(' ')}>
- <Button className="mr-4" onClick={closeModal}>
- 取消
- </Button>
- <Button type="primary">确定</Button>
- </div>
- </div>
- )
- }
- export default CustomPerm
|