Commit d8339d76 by yuananting

Merge branch 'feature/yuananting/20210801/task-center' into dev

parents e9664081 ff4c1d39
...@@ -2,18 +2,20 @@ ...@@ -2,18 +2,20 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-05 17:09:36 * @Date: 2021-08-05 17:09:36
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-16 14:47:51 * @LastEditTime: 2021-08-16 20:30:31
* @Description: 新建培训任务-选择指派对象 * @Description: 新建培训任务-选择指派对象
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { useState, useEffect, useRef } from 'react'; 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 User from '@/common/js/user';
import { DepType } from '@/domains/store-domain/constants'; import { DepType } from '@/domains/store-domain/constants';
import StoreService from '@/domains/store-domain/storeService'; import StoreService from '@/domains/store-domain/storeService';
import WWOpenDataCom from '@/components/WWOpenDataCom'; import WWOpenDataCom from '@/components/WWOpenDataCom';
import _ from 'underscore';
import './ChooseAssignorModal.less'; import './ChooseAssignorModal.less';
import $ from 'jquery';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
...@@ -25,33 +27,43 @@ function ChooseAssignorModal(props) { ...@@ -25,33 +27,43 @@ function ChooseAssignorModal(props) {
postGrouptab: 'POST', postGrouptab: 'POST',
customGroupTab: 'CUSTOM', customGroupTab: 'CUSTOM',
}; };
const DeptTypeEnum = {
departMentTab: ['部门'],
postGrouptab: ['岗位', '岗位组'],
customGroupTab: ['分组', '分组集合'],
};
const [dropDownVisible, setDropDownVisible] = useState(false);
const [structureData, setStructureData] = useState([]); const [structureData, setStructureData] = useState([]);
const [activeKey, setActiveKey] = useState('departMentTab'); const [activeKey, setActiveKey] = useState('departMentTab');
const [checkedAssignorList, setCheckedAssignorList] = useState(props.currentAssignorList || []); // 勾选的指派对象 const [checkedAssignorList, setCheckedAssignorList] = useState(props.currentAssignorList || []); // 勾选的指派对象
const [checkedAssignorKeys, setCheckedAssignorKeys] = useState(props.currentAssignorList.map((item) => item.checkedId) || []); const [checkedAssignorKeys, setCheckedAssignorKeys] = useState(props.currentAssignorList.map((item) => item.checkedId) || []);
const [completeOptions, setCompleteOption] = useState([]);
const [open, setOpen] = useState(false);
const [queryName, setQueryName] = useState(''); // 搜索框内的值 const [queryName, setQueryName] = useState(''); // 搜索框内的值
const [departmentUserVOList, setDepartmentUserVOList] = useState([]);
const [departmentVOList, setDepartmentVOList] = useState([]);
const [subLevelDepartmentVOList, setSubLevelDepartmentVOList] = useState([]);
const queryNameRef = useRef(null); const queryNameRef = useRef(null);
const timer = useRef(null); const timer = useRef(null);
useEffect(() => { useEffect(() => {
queryNameRef.current = queryName; queryNameRef.current = queryName;
setOpen(!!queryName);
clearTimeout(timer.current); clearTimeout(timer.current);
timer.current = setTimeout(() => { timer.current = setTimeout(() => {
if (!!queryName) return getCompleteOptionData(queryNameRef.current); if (!!queryName) return getCompleteOptionData(queryNameRef.current);
setCompleteOption([]);
}, 500); }, 500);
}, [queryName]); }, [queryName]);
useEffect(() => { useEffect(() => {
setQueryName(''); // 切换tab时搜索置空 setQueryName(''); // 切换tab时搜索置空
setCompleteOption([]);
setStructureData([]); setStructureData([]);
getStructureData(); getStructureData();
}, [activeKey]); }, [activeKey]);
useEffect(() => {
documentClick();
}, []);
function getStructureData() { function getStructureData() {
const params = { const params = {
depType: DepType[activeKey], depType: DepType[activeKey],
...@@ -132,59 +144,7 @@ function ChooseAssignorModal(props) { ...@@ -132,59 +144,7 @@ function ChooseAssignorModal(props) {
setCheckedAssignorList([]); 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) { function getCompleteOptionData(value) {
setCompleteOption([]);
const params = { const params = {
depType: DepType[activeKey], depType: DepType[activeKey],
queryName: value, queryName: value,
...@@ -197,67 +157,37 @@ function ChooseAssignorModal(props) { ...@@ -197,67 +157,37 @@ function ChooseAssignorModal(props) {
queryType: 'CUSTOMER', queryType: 'CUSTOMER',
}; };
StoreService.getDepartmentUser(params).then((res) => { StoreService.getDepartmentUser(params).then((res) => {
const _completeOptions = [];
const userObj = {};
const departmentGroupObj = {};
const postobj = {};
const { result = {} } = res; const { result = {} } = res;
const { departmentUserVOList = [], departmentVOList = [], subLevelDepartmentVOList = [] } = result; const { departmentUserVOList = [], departmentVOList = [], subLevelDepartmentVOList = [] } = result;
if (departmentUserVOList.length > 0) { const _departmentUserVOList = departmentUserVOList.map((item) => {
userObj.label = renderTitle('学员'); item.checkedName = item.userName;
userObj.options = departmentUserVOList.map((item, index) => { item.checkedId = item.storeCustomerId;
return renderItem(item, 'user'); item.checked = checkedAssignorKeys.includes(item.checkedId);
}); item.checkedType = 'CUSTOMER';
} return item;
if (departmentVOList.length > 0) { });
switch (activeKey) { const _departmentVOList = departmentVOList.map((item) => {
case 'departMentTab': item.checkedName = item.name;
departmentGroupObj.label = renderTitle('部门'); item.checkedId = item.id;
break; item.checked = checkedAssignorKeys.includes(item.checkedId);
case 'postGrouptab': item.checkedType = AssignTypeEnum[activeKey];
departmentGroupObj.label = renderTitle('岗位组'); return item;
break; });
case 'customGroupTab': const _subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
departmentGroupObj.label = renderTitle('分组集合'); item.checkedName = item.name;
break; item.checkedId = item.id;
default: item.checked = checkedAssignorKeys.includes(item.checkedId);
break; item.checkedType = AssignTypeEnum[activeKey];
} return item;
departmentGroupObj.options = departmentVOList.map((item, index) => { });
return renderItem(item, 'group'); setDepartmentUserVOList(_departmentUserVOList);
}); setDepartmentVOList(_departmentVOList);
} setSubLevelDepartmentVOList(_subLevelDepartmentVOList);
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');
});
}
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);
}); });
} }
// 搜索空状态渲染; // 搜索空状态渲染;
function notFoundContentNode() { function renderEmptyContent() {
return ( return (
<div className='empty-con'> <div className='empty-con'>
<img src='https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png' className='empty-img' /> <img src='https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png' className='empty-img' />
...@@ -266,16 +196,78 @@ function ChooseAssignorModal(props) { ...@@ -266,16 +196,78 @@ function ChooseAssignorModal(props) {
); );
} }
function confirmSearchSelect(value, option) { function handleCheckedSearchAssignor(e, type) {
const param = {}; const { value, checked } = e.target;
setOpen(false); let _departmentUserVOList = [...departmentUserVOList];
setQueryName(value); let _departmentVOList = [...departmentVOList];
if (option.label.props.type === 'user') { let _subLevelDepartmentVOList = [...subLevelDepartmentVOList];
param.queryName = value; let _checkedAssignorList = [...checkedAssignorList];
} else { if (type === 'CUSTOMER') {
param.id = option.label.props.depId; 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);
} }
props.searchUserList(param, activeKey, 1);
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 {
_subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = false;
}
return item;
});
_checkedAssignorList = subLevelDepartmentVOList.filter((item) => item.checkedId !== value.checkedId);
}
setSubLevelDepartmentVOList(_subLevelDepartmentVOList);
}
const _checkedAssignorKeys = _checkedAssignorList.map((item) => item.checkedId);
setCheckedAssignorKeys(_checkedAssignorKeys);
setCheckedAssignorList(_checkedAssignorList);
} }
// 弱提示渲染 // 弱提示渲染
...@@ -308,6 +300,83 @@ function ChooseAssignorModal(props) { ...@@ -308,6 +300,83 @@ function ChooseAssignorModal(props) {
return depArrayDom; 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 ( return (
<Modal <Modal
className='choose-assignor-modal' className='choose-assignor-modal'
...@@ -321,28 +390,18 @@ function ChooseAssignorModal(props) { ...@@ -321,28 +390,18 @@ function ChooseAssignorModal(props) {
maskClosable={false}> maskClosable={false}>
<div className='assignor-container'> <div className='assignor-container'>
<div className='left-list'> <div className='left-list'>
<AutoComplete <Search
dropdownClassName='left-search-dropdown' style={{ width: 272 }}
dropdownMatchSelectWidth={272} placeholder={handlePlaceHolder()}
allowClear
onChange={(value) => setQueryName(value)}
notFoundContent={notFoundContentNode()}
value={queryName} value={queryName}
open={open} enterButton={<span className='icon iconfont'>&#xe832;</span>}
onFocus={() => { // onFocus={() => setDropDownVisible(true)}
setOpen(true); onChange={(e) => {
}} setQueryName(e.target.value);
onBlur={() => { setDropDownVisible(!!e.target.value);
setOpen(false);
}}
style={{
width: 272,
}} }}
options={completeOptions} />
// onSelect={confirmSearchSelect} {dropDownVisible && renderOptions()}
placeholder={handlePlaceHolder()}>
<Search style={{ width: 272 }} enterButton={<span className='icon iconfont'>&#xe832;</span>} />
</AutoComplete>
<div className='data-body'> <div className='data-body'>
<Tabs size={'small'} onChange={(key) => setActiveKey(key)}> <Tabs size={'small'} onChange={(key) => setActiveKey(key)}>
<TabPane key='departMentTab' tab='部门'></TabPane> <TabPane key='departMentTab' tab='部门'></TabPane>
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
display: flex; display: flex;
height: 417px; height: 417px;
.left-list { .left-list {
position: relative;
width: 50%; width: 50%;
margin-right: 24px; margin-right: 24px;
padding: 12px 0 12px 16px; padding: 12px 0 12px 16px;
...@@ -11,6 +12,64 @@ ...@@ -11,6 +12,64 @@
font-size: 14px; font-size: 14px;
right: 15px; 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 { .data-body {
.ant-tabs-nav { .ant-tabs-nav {
margin: 0 !important; margin: 0 !important;
...@@ -106,51 +165,3 @@ ...@@ -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