Commit ff4c1d39 by yuananting

feat:指派对象弹窗搜索联调完毕

parent c54209d0
......@@ -2,18 +2,20 @@
* @Author: yuananting
* @Date: 2021-08-05 17:09:36
* @LastEditors: yuananting
* @LastEditTime: 2021-08-16 14:47:51
* @LastEditTime: 2021-08-16 20:30:31
* @Description: 新建培训任务-选择指派对象
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useState, useEffect, useRef } from 'react';
import { Modal, Tree, Tooltip, AutoComplete, Tabs, Input, Checkbox } from 'antd';
import { Modal, Tree, Tooltip, Tabs, Input, Checkbox } from 'antd';
import User from '@/common/js/user';
import { DepType } from '@/domains/store-domain/constants';
import StoreService from '@/domains/store-domain/storeService';
import WWOpenDataCom from '@/components/WWOpenDataCom';
import _ from 'underscore';
import './ChooseAssignorModal.less';
import $ from 'jquery';
const { TabPane } = Tabs;
const { DirectoryTree } = Tree;
......@@ -25,33 +27,43 @@ function ChooseAssignorModal(props) {
postGrouptab: 'POST',
customGroupTab: 'CUSTOM',
};
const DeptTypeEnum = {
departMentTab: ['部门'],
postGrouptab: ['岗位', '岗位组'],
customGroupTab: ['分组', '分组集合'],
};
const [dropDownVisible, setDropDownVisible] = useState(false);
const [structureData, setStructureData] = useState([]);
const [activeKey, setActiveKey] = useState('departMentTab');
const [checkedAssignorList, setCheckedAssignorList] = useState(props.currentAssignorList || []); // 勾选的指派对象
const [checkedAssignorKeys, setCheckedAssignorKeys] = useState(props.currentAssignorList.map((item) => item.checkedId) || []);
const [completeOptions, setCompleteOption] = useState([]);
const [open, setOpen] = useState(false);
const [queryName, setQueryName] = useState(''); // 搜索框内的值
const [departmentUserVOList, setDepartmentUserVOList] = useState([]);
const [departmentVOList, setDepartmentVOList] = useState([]);
const [subLevelDepartmentVOList, setSubLevelDepartmentVOList] = useState([]);
const queryNameRef = useRef(null);
const timer = useRef(null);
useEffect(() => {
queryNameRef.current = queryName;
setOpen(!!queryName);
clearTimeout(timer.current);
timer.current = setTimeout(() => {
if (!!queryName) return getCompleteOptionData(queryNameRef.current);
setCompleteOption([]);
}, 500);
}, [queryName]);
useEffect(() => {
setQueryName(''); // 切换tab时搜索置空
setCompleteOption([]);
setStructureData([]);
getStructureData();
}, [activeKey]);
useEffect(() => {
documentClick();
}, []);
function getStructureData() {
const params = {
depType: DepType[activeKey],
......@@ -132,59 +144,7 @@ function ChooseAssignorModal(props) {
setCheckedAssignorList([]);
}
function renderTitle(title) {
return <span className='catalog-title'>{title}</span>;
}
function renderItem(record, type) {
return {
value: record.userName || record.name,
label: (
<Checkbox>
<div
className='search-result-item'
style={{
display: 'flex',
justifyContent: 'space-between',
}}
depId={record.id}
type={type}>
{type === 'user' ? (
<div className='search-result-item__left'>
<WWOpenDataCom type='userName' openid={record.userName} />
</div>
) : (
<div className='search-result-item__left'>
{activeKey === 'departMentTab' ? <WWOpenDataCom type='departmentName' openid={record.name} /> : <span>{record.name}</span>}
</div>
)}
{type === 'user' && (
<div className='search-result-item__right'>
<Tooltip title={<div>{handleDepName(record.depNamesList)}</div>} placement='top' arrowPointAtCenter>
{record.depNamesList.map((item, index) => {
return (
<span>
<WWOpenDataCom type='departmentName' openid={item} />
{index < record.depNamesList.length - 1 ? ';' : ''}
</span>
);
})}
</Tooltip>
</div>
)}
{type === 'post' && (
<span type='post' openid={record.parentName}>
{record.parentName}
</span>
)}
</div>
</Checkbox>
),
};
}
function getCompleteOptionData(value) {
setCompleteOption([]);
const params = {
depType: DepType[activeKey],
queryName: value,
......@@ -197,67 +157,37 @@ function ChooseAssignorModal(props) {
queryType: 'CUSTOMER',
};
StoreService.getDepartmentUser(params).then((res) => {
const _completeOptions = [];
const userObj = {};
const departmentGroupObj = {};
const postobj = {};
const { result = {} } = res;
const { departmentUserVOList = [], departmentVOList = [], subLevelDepartmentVOList = [] } = result;
if (departmentUserVOList.length > 0) {
userObj.label = renderTitle('学员');
userObj.options = departmentUserVOList.map((item, index) => {
return renderItem(item, 'user');
const _departmentUserVOList = departmentUserVOList.map((item) => {
item.checkedName = item.userName;
item.checkedId = item.storeCustomerId;
item.checked = checkedAssignorKeys.includes(item.checkedId);
item.checkedType = 'CUSTOMER';
return item;
});
}
if (departmentVOList.length > 0) {
switch (activeKey) {
case 'departMentTab':
departmentGroupObj.label = renderTitle('部门');
break;
case 'postGrouptab':
departmentGroupObj.label = renderTitle('岗位组');
break;
case 'customGroupTab':
departmentGroupObj.label = renderTitle('分组集合');
break;
default:
break;
}
departmentGroupObj.options = departmentVOList.map((item, index) => {
return renderItem(item, 'group');
const _departmentVOList = departmentVOList.map((item) => {
item.checkedName = item.name;
item.checkedId = item.id;
item.checked = checkedAssignorKeys.includes(item.checkedId);
item.checkedType = AssignTypeEnum[activeKey];
return item;
});
}
if (subLevelDepartmentVOList.length > 0) {
switch (activeKey) {
case 'postGrouptab':
postobj.label = renderTitle('岗位');
break;
case 'customGroupTab':
postobj.label = renderTitle('分组');
break;
default:
break;
}
postobj.options = subLevelDepartmentVOList.map((item, index) => {
return renderItem(item, 'post');
const _subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
item.checkedName = item.name;
item.checkedId = item.id;
item.checked = checkedAssignorKeys.includes(item.checkedId);
item.checkedType = AssignTypeEnum[activeKey];
return item;
});
}
if (Object.keys(userObj).length !== 0) {
_completeOptions.push(userObj);
}
if (Object.keys(postobj).length !== 0) {
_completeOptions.push(postobj);
}
if (Object.keys(departmentGroupObj).length !== 0) {
_completeOptions.push(departmentGroupObj);
}
setCompleteOption(_completeOptions);
setDepartmentUserVOList(_departmentUserVOList);
setDepartmentVOList(_departmentVOList);
setSubLevelDepartmentVOList(_subLevelDepartmentVOList);
});
}
// 搜索空状态渲染;
function notFoundContentNode() {
function renderEmptyContent() {
return (
<div className='empty-con'>
<img src='https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png' className='empty-img' />
......@@ -266,16 +196,78 @@ function ChooseAssignorModal(props) {
);
}
function confirmSearchSelect(value, option) {
const param = {};
setOpen(false);
setQueryName(value);
if (option.label.props.type === 'user') {
param.queryName = value;
function handleCheckedSearchAssignor(e, type) {
const { value, checked } = e.target;
let _departmentUserVOList = [...departmentUserVOList];
let _departmentVOList = [...departmentVOList];
let _subLevelDepartmentVOList = [...subLevelDepartmentVOList];
let _checkedAssignorList = [...checkedAssignorList];
if (type === 'CUSTOMER') {
if (checked) {
_departmentUserVOList = departmentUserVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = true;
}
return item;
});
_checkedAssignorList.push({ ...value, checked: true });
} else {
_departmentUserVOList = departmentUserVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = false;
}
return item;
});
_checkedAssignorList = _checkedAssignorList.filter((item) => item.checkedId !== value.checkedId);
}
setDepartmentUserVOList(_departmentUserVOList);
}
if (type === 'DEPART') {
if (checked) {
_departmentVOList = departmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = true;
}
return item;
});
_checkedAssignorList.push({ ...value, checked: true });
} else {
_departmentVOList = departmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = false;
}
return item;
});
_checkedAssignorList = _checkedAssignorList.filter((item) => item.checkedId !== value.checkedId);
}
setDepartmentVOList(_departmentVOList);
}
if (type === 'GROUP') {
if (checked) {
_subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = true;
}
return item;
});
_checkedAssignorList.push({ ...value, checked: true });
} else {
param.id = option.label.props.depId;
_subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = false;
}
return item;
});
_checkedAssignorList = subLevelDepartmentVOList.filter((item) => item.checkedId !== value.checkedId);
}
props.searchUserList(param, activeKey, 1);
setSubLevelDepartmentVOList(_subLevelDepartmentVOList);
}
const _checkedAssignorKeys = _checkedAssignorList.map((item) => item.checkedId);
setCheckedAssignorKeys(_checkedAssignorKeys);
setCheckedAssignorList(_checkedAssignorList);
}
// 弱提示渲染
......@@ -308,6 +300,83 @@ function ChooseAssignorModal(props) {
return depArrayDom;
}
function renderOptions() {
return (
<div className='left-search-dropdown' id='left-search-dropdown'>
{departmentUserVOList.length > 0 && (
<div>
<div>学员</div>
{departmentUserVOList.map((record) => {
return (
<Checkbox checked={record.checked} value={record} key={record.checkedId} onChange={(e) => handleCheckedSearchAssignor(e, 'CUSTOMER')}>
<div className='search-result-item' depId={record.checkedId} type={type}>
<div className='search-result-item__left'>
<WWOpenDataCom type='userName' openid={record.userName} />
</div>
<div className='search-result-item__right'>
<Tooltip title={<div>{handleDepName(record.depNamesList)}</div>} placement='top' arrowPointAtCenter>
{record.depNamesList.map((item, index) => {
return (
<span>
<WWOpenDataCom type='departmentName' openid={item} />
{index < record.depNamesList.length - 1 ? ';' : ''}
</span>
);
})}
</Tooltip>
</div>
</div>
</Checkbox>
);
})}
</div>
)}
{departmentVOList.length > 0 && (
<div>
<div>{DeptTypeEnum[activeKey][0]}</div>
{departmentVOList.map((record) => {
return (
<Checkbox checked={record.checked} value={record} key={record.checkedId} onChange={(e) => handleCheckedSearchAssignor(e, 'DEPART')}>
<div className='search-result-item' depId={record.checkedId} type={type}>
<div className='search-result-item__left'>
{activeKey === 'departMentTab' ? <WWOpenDataCom type='departmentName' openid={record.name} /> : <span>{record.name}</span>}
</div>
<div className='search-result-item__right'>{activeKey === 'postGrouptab' && <span>{record.parentName}</span>}</div>
</div>
</Checkbox>
);
})}
</div>
)}
{subLevelDepartmentVOList.length > 0 && (
<div>
<div>{DeptTypeEnum[activeKey][1]}</div>
{subLevelDepartmentVOList.map((record) => {
return (
<Checkbox checked={record.checked} value={record} key={record.checkedId} onChange={(e) => handleCheckedSearchAssignor(e, 'GROUP')}>
<div className='search-result-item' depId={record.checkedId} type={type}>
<div className='search-result-item__left'>{<WWOpenDataCom type='departmentName' openid={record.name} />}</div>
</div>
</Checkbox>
);
})}
</div>
)}
{departmentUserVOList.length === 0 && departmentVOList.length === 0 && subLevelDepartmentVOList.length === 0 && renderEmptyContent()}
</div>
);
}
function documentClick() {
document.onclick = function (e) {
let _con = $('#left-search-dropdown');
if (!_con.is(e.target) && _con.has(e.target).length === 0) {
setDropDownVisible(false);
}
};
}
return (
<Modal
className='choose-assignor-modal'
......@@ -321,28 +390,18 @@ function ChooseAssignorModal(props) {
maskClosable={false}>
<div className='assignor-container'>
<div className='left-list'>
<AutoComplete
dropdownClassName='left-search-dropdown'
dropdownMatchSelectWidth={272}
allowClear
onChange={(value) => setQueryName(value)}
notFoundContent={notFoundContentNode()}
<Search
style={{ width: 272 }}
placeholder={handlePlaceHolder()}
value={queryName}
open={open}
onFocus={() => {
setOpen(true);
}}
onBlur={() => {
setOpen(false);
enterButton={<span className='icon iconfont'>&#xe832;</span>}
// onFocus={() => setDropDownVisible(true)}
onChange={(e) => {
setQueryName(e.target.value);
setDropDownVisible(!!e.target.value);
}}
style={{
width: 272,
}}
options={completeOptions}
// onSelect={confirmSearchSelect}
placeholder={handlePlaceHolder()}>
<Search style={{ width: 272 }} enterButton={<span className='icon iconfont'>&#xe832;</span>} />
</AutoComplete>
/>
{dropDownVisible && renderOptions()}
<div className='data-body'>
<Tabs size={'small'} onChange={(key) => setActiveKey(key)}>
<TabPane key='departMentTab' tab='部门'></TabPane>
......
......@@ -3,6 +3,7 @@
display: flex;
height: 417px;
.left-list {
position: relative;
width: 50%;
margin-right: 24px;
padding: 12px 0 12px 16px;
......@@ -11,6 +12,64 @@
font-size: 14px;
right: 15px;
}
.left-search-dropdown {
position: absolute;
padding: 16px;
background: #fff;
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.08);
z-index: 999;
border-radius: 2px;
width: 274px;
max-height: 280px;
overflow-y: scroll;
.catalog-title {
font-size: 14px;
color: #666;
margin-bottom: 14px;
}
.search-result-item {
padding: 14px 0;
color: #333;
width: 220px;
display: flex;
justify-content: space-between;
.title-icon {
color: #999;
margin-right: 3px;
}
.search-result-item__left {
font-size: 14px;
}
.search-result-item__right {
font-size: 14px;
width: 84px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #999;
text-align: right;
}
}
.ant-select-dropdown-menu-item-group-title {
color: #666;
font-weight: bold;
}
.ant-select-item-option-grouped {
padding-left: 12px;
}
.empty-con {
text-align: center;
.empty-img {
width: 150px;
height: 150px;
}
.empty-text {
color: #666;
}
}
}
.data-body {
.ant-tabs-nav {
margin: 0 !important;
......@@ -106,51 +165,3 @@
}
}
}
.left-search-dropdown {
.catalog-title {
font-size: 14px;
color: #666;
margin-bottom: 14px;
}
.search-result-item {
padding: 14px 0;
color: #333;
.title-icon {
color: #999;
margin-right: 3px;
}
.search-result-item__left {
font-size: 14px;
}
.search-result-item__right {
font-size: 14px;
width: 84px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #999;
text-align: right;
}
}
.ant-select-dropdown-menu-item-group-title {
color: #666;
font-weight: bold;
}
.ant-select-item-option-grouped {
padding-left: 12px;
}
.ant-select-item-option-content {
padding-left: 24px;
}
.empty-con {
text-align: center;
.empty-img {
width: 150px;
height: 150px;
}
.empty-text {
color: #666;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment