Commit 93d2c143 by yuananting

feat:编辑培训计划接口联调

parent 658b3bf3
@font-face {
font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_obblua8v3q.woff2?t=1628151518578') format('woff2'),
url('//at.alicdn.com/t/font_2223403_obblua8v3q.woff?t=1628151518578') format('woff'),
url('//at.alicdn.com/t/font_2223403_obblua8v3q.ttf?t=1628151518578') format('truetype');
src: url('//at.alicdn.com/t/font_2223403_fvwdwtefte9.woff2?t=1628842764237') format('woff2'),
url('//at.alicdn.com/t/font_2223403_fvwdwtefte9.woff?t=1628842764237') format('woff'),
url('//at.alicdn.com/t/font_2223403_fvwdwtefte9.ttf?t=1628842764237') format('truetype');
}
.iconfont {
font-family: 'iconfont' !important;
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-06 17:35:35
* @LastEditors: yuananting
* @LastEditTime: 2021-08-12 16:03:58
* @LastEditTime: 2021-08-13 18:06:35
* @Description: 任务中心接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -44,3 +44,7 @@ export function updateTrainingTask(params: object) {
export function getTaskCustomerDetail(params: object) {
return Service.Hades('public/hades/getTaskCustomerDetail', params);
}
export function updateTrainingTaskAssign(params: object) {
return Service.Hades('public/hades/updateTrainingTaskAssign', params);
}
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-06 17:32:41
* @LastEditors: yuananting
* @LastEditTime: 2021-08-12 16:04:42
* @LastEditTime: 2021-08-13 18:07:06
* @Description: 任务中心-培训任务接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -17,6 +17,7 @@ import {
getTrainingTaskDetail,
updateTrainingTask,
getTaskCustomerDetail,
updateTrainingTaskAssign,
} from '@/data-source/taskCenter/request-apis';
export default class TaskCenterService {
......@@ -64,4 +65,9 @@ export default class TaskCenterService {
static getTaskCustomerDetail(params: any) {
return getTaskCustomerDetail(params);
}
// 修改培训任务的指派信息
static updateTrainingTaskAssign(params: any) {
return updateTrainingTaskAssign(params);
}
}
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @LastEditors: yuananting
* @LastEditTime: 2021-08-11 15:06:32
* @LastEditTime: 2021-08-13 16:19:45
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
......@@ -29,7 +29,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_obblua8v3q.css" />
<link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_fvwdwtefte9.css" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-05 11:26:25
* @LastEditors: yuananting
* @LastEditTime: 2021-08-13 10:57:19
* @LastEditTime: 2021-08-13 19:17:49
* @Description: 个人学习详情-全部tab页
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -54,16 +54,16 @@ function WholeData(props) {
// 渲染学习内容信息
function renderContentInfo(contentItem, contentIndex, index) {
const { contentName, contentType, courseChapterNum, courseState, learnFinishPercentage } = contentItem;
const { contentName, contentType, courseChapterNum, courseState, learnFinishPercentage, courseType } = contentItem;
return (
<div className='content-info__item'>
<div className='basic-info'>
<img src={ENUM.LearningContentIcon[contentType]} />
<img src={ENUM.LearningContentIcon[courseType || contentType]} />
<span className='content-name'>
{contentIndex + 1}.{index + 1} {contentName}
</span>
{contentType === 'LIVE' && <span className='extra-info'>{courseStateShow[courseState].title}</span>}
{contentType === 'VOICE' && <span className='extra-info'>(共{courseChapterNum || 1}小节)</span>}
{courseType === 'LIVE' && <span className='extra-info'>{courseStateShow[courseState].title}</span>}
{courseType === 'VOICE' && <span className='extra-info'>(共{courseChapterNum || 1}小节)</span>}
</div>
<div className='percent-info'>
{learnFinishPercentage === 100 ? (
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-29 13:57:03
* @LastEditors: yuananting
* @LastEditTime: 2021-08-13 15:11:56
* @LastEditTime: 2021-08-13 19:37:07
* @Description: 任务中心-培训任务-新建页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -80,6 +80,7 @@ function AddTrainTask() {
}).then((res) => {
const {
result: {
createId,
taskName,
courseMediaVOS,
helpStoreUsers,
......@@ -97,6 +98,8 @@ function AddTrainTask() {
const _assignList = assignList.map((item) => {
item.checkedId = item.assignId;
item.checkedName = item.assignName;
item.checkedType = item.assignType;
return item;
});
......@@ -111,6 +114,7 @@ function AddTrainTask() {
});
const ITEM_BASIC_INFO = {
createId,
assignList: _assignList,
taskName,
coverUrl,
......@@ -191,7 +195,7 @@ function AddTrainTask() {
// 确认保存新建
function submitRemote(introduceId, issue) {
const { assignList, endTime, helpStoreUserIds, learnType, startTime, taskName, timeType, coverId, coverUrl } = basicInfo;
const { assignList, endTime, helpStoreUserIds, learnType, startTime, taskName, timeType, coverId } = basicInfo;
const { percentCompleteLive, percentCompletePicture, percentCompleteVideo } = finishStandard;
......
......@@ -2,12 +2,12 @@
* @Author: yuananting
* @Date: 2021-07-29 14:32:24
* @LastEditors: yuananting
* @LastEditTime: 2021-08-13 15:09:56
* @LastEditTime: 2021-08-13 19:38:30
* @Description: 任务中心-培训任务-新建-基本信息
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import { Form, Button, Input, Space, DatePicker, Radio, Tag, message, Tooltip } from 'antd';
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal';
import Upload from '@/core/upload';
......@@ -18,6 +18,7 @@ import './BasicInfo.less';
import ChooseAssignorModal from '../modal/ChooseAssignorModal';
import ChooseCollaboratorModal from '../modal/ChooseCollaboratorModal';
import WWOpenDataCom from '@/components/WWOpenDataCom';
import User from '@/common/js/user';
const { RangePicker } = DatePicker;
......@@ -28,9 +29,9 @@ function BasicInfo(props) {
const type = getParameterByName('type');
const { basicInfo, startCheck } = props;
const { taskName, coverUrl, helpStoreUserIds, timeType, startTime, endTime, learnType, assignList, introduce, loadintroduce } = basicInfo;
const depAssignList = assignList.filter((item) => [0, 1].includes(item.depLevel));
const userAssignList = assignList.filter((item) => ![0, 1].includes(item.depLevel));
const { createId, taskName, coverUrl, helpStoreUserIds, timeType, startTime, endTime, learnType, assignList, introduce, loadintroduce } = basicInfo;
const depAssignList = assignList.filter((item) => item.checkedType !== 'CUSTOMER');
const userAssignList = assignList.filter((item) => item.checkedType === 'CUSTOMER');
const [imageFile, setImageFile] = useState(null); // 需要被截取的图片
const [showSelectFileModal, setShowSelectFileModal] = useState(false);
const [imgClipVisible, setImgClipVisible] = useState(false);
......@@ -104,6 +105,7 @@ function BasicInfo(props) {
function confirmAddAssignor(data) {
props.onChange('assignList', data);
props.onClose();
}
function removeSelectedCollaborator(tag) {
......@@ -242,7 +244,7 @@ function BasicInfo(props) {
}
required
validateStatus={startCheck && assignList.length === 0 ? 'error' : ''}
help={startCheck && assignList.length === 0 && '请选择培训时间'}>
help={startCheck && assignList.length === 0 && '请选择指派对象'}>
<Button
style={{ display: 'block' }}
onClick={() => {
......@@ -258,8 +260,12 @@ function BasicInfo(props) {
<div className='tag-box'>
{_.map(depAssignList, (tag) => {
return (
<Tag key={tag.checkedId} onClose={() => removeCheckedAssignor(tag)} closable>
<WWOpenDataCom type='departmentName' openid={tag.name} />
<Tag
key={tag.checkedId}
closeIcon={<span className='icon iconfont close-icon'>&#xe626;</span>}
onClose={() => removeCheckedAssignor(tag)}
closable>
<WWOpenDataCom type='departmentName' openid={tag.checkedName} />
</Tag>
);
})}
......@@ -272,8 +278,12 @@ function BasicInfo(props) {
<div className='tag-box'>
{_.map(userAssignList, (tag) => {
return (
<Tag key={tag.checkedId} onClose={() => removeCheckedAssignor(tag)} closable>
<WWOpenDataCom type='userName' openid={tag.userName} />
<Tag
key={tag.checkedId}
closeIcon={<span className='icon iconfont close-icon'>&#xe626;</span>}
onClose={() => removeCheckedAssignor(tag)}
closable>
<WWOpenDataCom type='userName' openid={tag.checkedName} />
</Tag>
);
})}
......@@ -313,7 +323,12 @@ function BasicInfo(props) {
<div className='select-obj'>
{_.map(helpStoreUserIds, (tag) => {
return (
<Tag key={tag.userId} onClose={() => removeSelectedCollaborator(tag)} closable>
<Tag
key={tag.checkedId}
closeIcon={<span className='icon iconfont close-icon'>&#xe626;</span>}
className={tag.checkedId === createId && 'disabled'}
onClose={() => removeSelectedCollaborator(tag)}
closable>
<WWOpenDataCom type='userName' openid={tag.checkedName} />
</Tag>
);
......@@ -377,6 +392,7 @@ function BasicInfo(props) {
)}
{collaboratorModalVisible && (
<ChooseCollaboratorModal
createId={createId}
currentCollaboratorList={helpStoreUserIds}
visible={collaboratorModalVisible}
onClose={() => {
......
......@@ -82,6 +82,10 @@
flex-shrink: 0;
}
}
.close-icon {
font-size: 14px;
color: #cccccc;
}
}
.learning-model-tips {
......
......@@ -16,7 +16,7 @@ const { Search } = Input;
const DEFAULT_QUERY = {
// 头部筛选默认值
planName: null,
taskName: null,
createId: null, // 创建人
startTime: null,
endTime: null,
......@@ -76,7 +76,7 @@ function TrainFilter(props) {
_query[field] = value;
}
setQuery(_query);
if (field === 'planName') return;
if (field === 'taskName') return;
props.onChange(_query);
}
......@@ -93,10 +93,10 @@ function TrainFilter(props) {
<div className='search-condition__item'>
<span>培训任务:</span>
<Search
value={query.planName}
value={query.taskName}
placeholder='搜索培训任务名称'
onChange={(e) => {
handleChangeQuery('planName', e.target.value.trim());
handleChangeQuery('taskName', e.target.value.trim());
}}
onSearch={() => {
props.onChange(query);
......
......@@ -2,11 +2,11 @@
* @Author: yuananting
* @Date: 2021-07-28 14:56:52
* @LastEditors: yuananting
* @LastEditTime: 2021-08-11 11:01:49
* @LastEditTime: 2021-08-13 18:30:47
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import { Route, withRouter } from 'react-router-dom';
import { Tooltip, Checkbox, Dropdown, Radio, Button, Space, Modal, message } from 'antd';
import './TrainList.less';
......@@ -15,6 +15,7 @@ import User from '@/common/js/user';
import ENUM from '../../enum';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import ShareTrainTaskModal from '../modal/ShareTrainTaskModal';
import ChooseAssignorModal from '../modal/ChooseAssignorModal';
import { LIVE_SHARE } from '@/domains/course-domain/constants';
import Bus from '@/core/bus';
......@@ -26,6 +27,7 @@ function TrainList(props) {
} = props;
const [shareTrainTaskModal, setShareTrainTaskModal] = useState(null);
const [chooseAssignorModal, setChooseAssignorModal] = useState(null);
// 发布或取消发布培训任务
function updateIssueStateTrain(taskId, issueState) {
......@@ -78,6 +80,30 @@ function TrainList(props) {
});
}
// 显示指派弹窗
function handleShowAssignModal(item) {
const assignList = item.assignList.map((childItem) => {
childItem.checkedId = childItem.assignId;
childItem.checkedName = childItem.assignName;
childItem.checkedType = childItem.assignType;
return childItem;
});
const chooseAssignorModal = (
<ChooseAssignorModal
currentAssignorList={assignList}
visible={true}
onClose={() => {
setChooseAssignorModal(null);
}}
onConfirm={(data) => {
confirmUpdatedAssignor(data, item.taskId);
}}
/>
);
setChooseAssignorModal(chooseAssignorModal);
}
// 显示分享弹窗
function handleShowShareModal(item) {
const htmlUrl = `${LIVE_SHARE}training_task_detail/${item.taskId}?id=${User.getStoreId()}&storeUserId=${User.getStoreUserId()}`;
......@@ -95,6 +121,30 @@ function TrainList(props) {
setShareTrainTaskModal(shareTrainTaskModal);
}
// 确定指派人员
function confirmUpdatedAssignor(data, id) {
const assignList = data.map((item) => {
return {
assignType: item.checkedType,
assignId: item.checkedId,
};
});
const params = {
assignList,
id,
};
if (assignList.length === 0) {
return message.warning('指派列表不能为空');
}
TaskCenterService.updateTrainingTaskAssign(params).then((res) => {
message.success('指派成功');
Bus.trigger('getTrainingTaskPage');
setChooseAssignorModal(null);
});
}
function renderMoreOperate(item) {
const isUnableIssue = item.issueState === 'YES'; // 已发布
const isUnableAbleEdit = item.issueState === 'YES' || item.taskState === 'FINISH'; // 已发布或已结束
......@@ -296,7 +346,7 @@ function TrainList(props) {
<div
className={`operate__item ${record.taskState === 'FINISH' && 'disabled'} `}
onClick={() => {
// handleShowShareModal(record);
handleShowAssignModal(record);
}}>
指派
</div>
......@@ -443,6 +493,7 @@ function TrainList(props) {
</div>
</div>
{shareTrainTaskModal}
{chooseAssignorModal}
</div>
);
}
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-05 17:09:36
* @LastEditors: yuananting
* @LastEditTime: 2021-08-12 19:37:35
* @LastEditTime: 2021-08-13 19:18:54
* @Description: 新建培训任务-选择指派对象
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -61,13 +61,14 @@ function ChooseAssignorModal(props) {
function handleStructureData(dataArray) {
const _dataArray = dataArray.map((item, index) => {
item.title = '';
item.checkedId = [0, 1].includes(item.depLevel) ? item.id : item.storeCustomerId;
item.checkedId = item.storeCustomerId || item.id;
item.checkedType = item.storeCustomerId ? 'CUSTOMER' : AssignTypeEnum[activeKey];
item.checkedName = item.storeCustomerId ? item.userName : item.name;
item.key = item.checkedId;
item.children = [];
if (activeKey !== 'departMentTab' && item.depLevel === 0) {
item.disableCheckbox = true;
}
item.assignType = [0, 1].includes(item.depLevel) ? AssignTypeEnum[activeKey] : 'CUSTOMER';
if (item.departmentUserVOList) {
item.children = item.departmentUserVOList;
}
......@@ -104,7 +105,7 @@ function ChooseAssignorModal(props) {
}
function removeCheckedAssignor(item) {
const _checkedAssignorList = checkedAssignorList.filter((innerItem) => innerItem.checkedId !== item.checkedId);
const _checkedAssignorList = checkedAssignorList.filter((childItem) => childItem.checkedId !== item.checkedId);
const _checkedAssignorKeys = _checkedAssignorList.map((item) => item.checkedId);
setCheckedAssignorKeys(_checkedAssignorKeys);
setCheckedAssignorList(_checkedAssignorList);
......@@ -255,7 +256,6 @@ function ChooseAssignorModal(props) {
onCancel={props.onClose}
onOk={() => {
props.onConfirm(checkedAssignorList);
props.onClose();
}}
width={680}
maskClosable={false}>
......@@ -302,18 +302,18 @@ function ChooseAssignorModal(props) {
titleRender={(nodeData) => {
return (
<div className='node-title-div'>
{[0, 1].includes(nodeData.depLevel) ? (
{nodeData.checkedType === 'CUSTOMER' ? (
<div>
<span className='icon iconfont title-icon'>&#xe604;</span>
<span className='icon iconfont title-icon'>&#xe603;</span>
<span className='title-name'>
<WWOpenDataCom type='departmentName' openid={nodeData.name} />
<WWOpenDataCom type='userName' openid={nodeData.checkedName} />
</span>
</div>
) : (
<div>
<span className='icon iconfont title-icon'>&#xe603;</span>
<span className='icon iconfont title-icon'>&#xe604;</span>
<span className='title-name'>
<WWOpenDataCom type='userName' openid={nodeData.userName} />
<WWOpenDataCom type='departmentName' openid={nodeData.checkedName} />
</span>
</div>
)}
......@@ -336,21 +336,21 @@ function ChooseAssignorModal(props) {
return (
<div className='selected-item'>
<span className='item-title'>
{[0, 1].indexOf(item.depLevel) === -1 ? (
{item.checkedType === 'CUSTOMER' ? (
<div>
<span className='icon iconfont title-icon'>&#xe603;</span>
<Tooltip title={<WWOpenDataCom type='userName' openid={item.userName} />}>
<Tooltip title={<WWOpenDataCom type='userName' openid={item.checkedName} />}>
<span className='title-name'>
<WWOpenDataCom type='userName' openid={item.userName} />
<WWOpenDataCom type='userName' openid={item.checkedName} />
</span>
</Tooltip>
</div>
) : (
<div>
<span className='icon iconfont title-icon'>&#xe604;</span>
<Tooltip title={<WWOpenDataCom type='departmentName' openid={item.name} />}>
<Tooltip title={<WWOpenDataCom type='departmentName' openid={item.checkedName} />}>
<span className='title-name'>
<WWOpenDataCom type='departmentName' openid={item.name} />
<WWOpenDataCom type='departmentName' openid={item.checkedName} />
</span>
</Tooltip>
</div>
......
/*
* @Author: wanghaofeng
* @date: 2020/11/14 17:42
* @Description:权限管理-选择成员弹窗
* @Author: yuananting
* @Date: 2021-08-12 16:27:38
* @LastEditors: yuananting
* @LastEditTime: 2021-08-13 19:39:34
* @Description: 新建培训任务-选择协同人员
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useState, useEffect } from 'react';
......@@ -42,7 +46,7 @@ function ChooseCollaboratorModal(props) {
const { records } = res.result;
records.map((item) => {
item.checkedName = item.nickName;
item.checkedId = item.userId;
item.checkedId = item.id;
item.checked = checkedCollaboratorKeys.includes(item.checkedId);
return item;
});
......@@ -117,12 +121,13 @@ function ChooseCollaboratorModal(props) {
function clearCheckedCollaborator() {
const _employeeList = employeeList.map((item) => {
item.checked = false;
item.checked = item.checkedId === props.createId;
return item;
});
const createrItem = checkedCollaboratorList.filter((item) => item.checkedId === props.createId);
setEmployeeList(_employeeList);
setCheckedCollaboratorList([]);
setCheckedCollaboratorKeys([]);
setCheckedCollaboratorList(createrItem);
setCheckedCollaboratorKeys([props.createId]);
setAllChecked(false);
}
......@@ -140,10 +145,10 @@ function ChooseCollaboratorModal(props) {
_checkedCollaboratorList = checkedCollaboratorList.concat([...filterList]);
} else {
_employeeList = employeeList.map((item) => {
item.checked = false;
item.checked = item.checkedId === props.createId;
return item;
});
const removeIds = _employeeList.map((item) => item.checkedId);
const removeIds = _employeeList.filter((item) => !item.checked).map((childItem) => childItem.checkedId);
_checkedCollaboratorList = checkedCollaboratorList.filter((item) => {
return !removeIds.includes(item.checkedId);
});
......@@ -190,7 +195,12 @@ function ChooseCollaboratorModal(props) {
dataSource={employeeList}
renderItem={(item, index) => (
<List.Item>
<Checkbox checked={item.checked} value={item} key={item.checkedId} onChange={handleCheckedCollaborator}>
<Checkbox
checked={item.checked}
value={item}
key={item.checkedId}
disabled={item.checkedId === props.createId}
onChange={handleCheckedCollaborator}>
<div className='employee-item'>
<span className='item-title'>
<span className='icon iconfont title-icon'>&#xe84a;</span>
......@@ -227,7 +237,9 @@ function ChooseCollaboratorModal(props) {
</span>
</Tooltip>
</span>
<span className='icon iconfont clear-icon' onClick={() => removeCheckedCollaborator(item)}>
<span
className={`icon iconfont clear-icon ${item.checkedId === props.createId && 'disabled'}`}
onClick={() => removeCheckedCollaborator(item)}>
&#xe717;
</span>
</div>
......
......@@ -88,6 +88,11 @@
color: #999999;
vertical-align: middle;
cursor: pointer;
&.disabled {
color: #ccc;
cursor: not-allowed;
pointer-events: none;
}
}
}
}
......
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