import React, { Component } from 'react'
import { Tree, Modal, Input, Icon, Form, message, Menu, Dropdown } from 'antd'
import { removeGenericEmpty } from '@/libs/util'
import {
queryAllOrganization,
queryMember,
getMemberGroup,
getMemberByGroup
} from '@/api'
import './orgAGroupModal.scss'
const { TreeNode } = Tree
const { Search } = Input
function updateTreeData(list, key, children) {
return list.map((node) => {
if (node.key === key) {
return {
...node,
children: node.children ? node.children.concat(children) : children
}
}
if (node.children) {
return {
...node,
children: updateTreeData(node.children, key, children)
}
}
return node
})
}
function formatOrgData(ary) {
if (!ary) return
const newTree = ary.map((item) => ({
...item,
title: ${item.name} ${ item.numberOfMember ?
({item.id}` : item.id,
value: +item.id,
children: formatOrgData(item.children)
}))
return newTree
}
function formatGroupData(ary) {
if (!ary) return
const newTree = ary.map((item) => ({
...item,
title: ${item.name} ${ item.numberOfMember ?
({item.id}` : item.id,
children: formatGroupData(item.children)
}))
return newTree
}
interface Iprops {
visible: boolean
transfer: any
title: string
closeOrgAGroupModal: any
}
interface Istate {
expandedOrgKeys: string[]
autoOrgExpandParent: boolean
checkedOrgKeys: any[]
selectedOrgKeys: string[]
listType: number
firstSelectedOrgKey: string
orgData: any
groupsData: {
id: string | number
name: string
number?: string
numberOfMember?: number
remarks?: string
sortNumber?: number
updateTime?: string
}[]
groupRightAry: any[]
autoGroupExpandParent: boolean
expandedGroupKeys: string[]
checkedGroupKeys: any[]
selectedGroupKeys: string[]
firstSelectedGroupKey: string
personAry: any[]
}
class OrgAGroupModal extends Component<Iprops, Istate> {
constructor(props) {
super(props)
this.state = {
orgData: [],
expandedOrgKeys: ['1'],
firstSelectedOrgKey: '', // 第一次点击节点,防止重复点击
checkedOrgKeys: [], // 左侧的keys
selectedOrgKeys: [],
autoOrgExpandParent: true,
listType: 1, // 1 组织列表 2 人员分组
groupRightAry: [],
groupsData: [{ id: '', name: '' }],
autoGroupExpandParent: true,
expandedGroupKeys: ['1'],
checkedGroupKeys: [],
selectedGroupKeys: [],
firstSelectedGroupKey: '',
personAry: []
}
}
componentDidMount() {
this.fetchOrg()
this.fetchMemberGroup()
}
// 展开树节点
onOrgExpand = (expandedKeys, e) => {
this.setState({
expandedOrgKeys: expandedKeys,
autoOrgExpandParent: false
})
}
onOrgCheck = (checkedKeys, e) => {
const { personAry } = this.state
const orgPersonAry = e.checkedNodes
.filter((item, index) => !item.key.startsWith('p'))
.map((item) => ({
title: item.props.title,
key: item.key
}))
this.setState({
checkedOrgKeys: checkedKeys,
personAry: [...personAry, ...orgPersonAry]
})
}
// p 代表组织
onOrgSelect = (selectedKeys, e) => {
const { orgData, firstSelectedOrgKey } = this.state
const selectedKey = selectedKeys[0]
if (!selectedKey.startsWith('p') || selectedKey === firstSelectedOrgKey)
return
// 查找的时候位置节点的id需要去掉p
queryMember({ department: selectedKey.slice(1) }).then((res) => {
const processedTree = updateTreeData(
orgData,
selectedKey,
formatOrgData(res.data.records)
)
this.setState({
orgData: processedTree,
firstSelectedOrgKey: selectedKey
})
})
}
renderTreeNodes = (data) => {
return data.map((item) => {
if (item && item.children) {
return (
<TreeNode title={${item.title}
} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
)
}
return <TreeNode key={item.key} {...item} />
})
}
// 搜索组织列表
onOrgSearch = (value?: string) => {
this.fetchOrg(value)
}
// 删除选择的人员或位置
deleteCheckedNode = (key) => {
const { personAry } = this.state
const newPersonAry = personAry.filter((item) => item !== key)
this.setState({
personAry: newPersonAry
})
}
// 获取位置列表
fetchOrg = (name?: string) => {
queryAllOrganization(removeGenericEmpty({ name }), null, {}).then((res) => {
const { organization } = res.data
const orgAry = []
if (organization) {
// @ts-ignore
orgAry.push(organization)
}
this.setState({
orgData: formatOrgData(orgAry)
})
})
}
// 分组 --------------------------------
// 搜索分组列表
onGroupSearch = (value?: string) => {
this.fetchMemberGroup(value)
}
// 获取人员分组
fetchMemberGroup = (name?: string) => {
getMemberGroup({ name }).then((res) => {
if (res.data) {
const { records } = res.data
this.setState({ groupsData: formatGroupData(records) })
}
})
}
// 展开树节点
onGroupExpand = (expandedKeys, e) => {
this.setState({
expandedGroupKeys: expandedKeys,
autoGroupExpandParent: false
})
}
onGroupCheck = (checkedKeys, e) => {
const { personAry } = this.state
const groupPersonAry = e.checkedNodes
.filter((item, index) => !item.key.startsWith('g'))
.map((item) => ({
title: item.props.title,
key: item.key
}))
this.setState({
personAry: [...personAry, ...groupPersonAry],
checkedGroupKeys: checkedKeys
})
}
// 点击节点出现人员
onGroupSelect = (selectedKeys, e) => {
// 人员的key加上D区分位置的key
const { groupsData, firstSelectedGroupKey } = this.state
const selectedKey = selectedKeys[0]
if (!selectedKey.startsWith('g') || selectedKey === firstSelectedGroupKey)
return
getMemberByGroup({ memberGroupId: selectedKey.slice(1) }).then((res) => {
const processedTree = updateTreeData(
groupsData,
selectedKey,
formatGroupData(res.data.records)
)
this.setState({
groupsData: processedTree,
firstSelectedGroupKey: selectedKey
})
})
}
// 公共
closeOrgSelectTree = () => {
this.props.closeOrgAGroupModal()
}
handleSubmit = () => {
const { personAry } = this.state
if (personAry.length > 0) {
const personIdList = personAry.map((item) => item.key)
this.props.transfer({
personIdList
})
} else {
message.warning('请选择人员')
}
}
render() {
const { visible, title } = this.props
const {
orgData,
selectedOrgKeys,
expandedOrgKeys,
autoOrgExpandParent,
groupRightAry,
checkedOrgKeys,
listType,
groupsData,
autoGroupExpandParent,
expandedGroupKeys,
checkedGroupKeys,
selectedGroupKeys,
personAry
} = this.state
const menu = (
<Menu>
<Menu.Item>
<a
target="_blank"
rel="noopener noreferrer"
onClick={() => {
this.setState({ listType: 1 })
}}
>
组织列表
</a>
</Menu.Item>
<Menu.Item>
<a
target="_blank"
rel="noopener noreferrer"
onClick={() => {
this.setState({ listType: 2 })
}}
>
人员分组
</a>
</Menu.Item>
</Menu>
)
return (
<>
<Modal
title="添加人员"
visible={visible}
maskClosable={false}
width={855}
destroyOnClose
onOk={this.handleSubmit}
onCancel={this.closeOrgSelectTree}
>
<div className="box-wrapper">
<div>
<Dropdown overlay={menu}>
<a
style={{ color: '#666' }}
onClick={(e) => e.preventDefault()}
>
{listType === 1 ? '组织机构' : '人员分组'}{' '}
<Icon type="down" />
</a>
</Dropdown>
{listType === 1 ? (
<div className="small-box">
<Search
style={{ marginBottom: 8 }}
placeholder="请输入关键字查找"
onSearch={this.onOrgSearch}
/>
<Tree
checkable
onExpand={this.onOrgExpand}
defaultExpandAll
expandedKeys={expandedOrgKeys}
autoExpandParent={autoOrgExpandParent}
onCheck={this.onOrgCheck}
checkedKeys={checkedOrgKeys}
onSelect={this.onOrgSelect}
selectedKeys={selectedOrgKeys}
>
{this.renderTreeNodes(orgData)}
</Tree>
</div>
) : null}
{listType === 2 ? (
<div className="small-box">
<Search
style={{ marginBottom: 8 }}
placeholder="请输入关键字查找"
onSearch={this.onGroupSearch}
/>
<Tree
checkable
onExpand={this.onGroupExpand}
defaultExpandAll
expandedKeys={expandedGroupKeys}
autoExpandParent={autoGroupExpandParent}
onCheck={this.onGroupCheck}
checkedKeys={checkedGroupKeys}
onSelect={this.onGroupSelect}
selectedKeys={selectedGroupKeys}
>
{this.renderTreeNodes(groupsData)}
</Tree>
</div>
) : null}
</div>
<div>
<div>
已选择人员{' '}
<span style={{ color: '#ccc', marginLeft: 12 }}>
<Icon type="control" />{' '}
<span className="detail-color">{personAry.length}</span>个人员
</span>
</div>
<div className="small-box right">
{personAry.map((item, index) => (
<div key={item.id} className="flex-between">
<span>{item.title}</span>
<Icon
type="close"
className="close-icon"
onClick={() => {
this.deleteCheckedNode(item.key)
}}
/>
</div>
))}
</div>
</div>
</div>
</Modal>
</>
)
}
}
export default Form.create()(OrgAGroupModal)
css
.box-wrapper {
display: flex;
justify-content: space-around;
.small-box {
width: 380px;
height: 363px;
margin-top: 6px;
margin-bottom: 6px;
border: 1px solid #d9d9d9;
padding: 12px;
overflow: auto;
}
.right {
padding: 16px 30px;
.flex-between {
display: flex;
justify-content: space-between;
line-height: 28px;
.close-icon {
color: #999;
cursor: pointer;
&:hover {
color: #333
}
}
}
}
}
用法
<OrgAGroupModal
// @ts-ignore
title="添加人员"
visible={orgTreeVisible}
closeOrgAGroupModal={this.closeOrgTree}
transfer={this.receiveOrgTreeData}
/>