Commit 3ebe2c4f by yuananting

feat:培训任务列表接口联调

parent 246ca3f7
/*
* @Author: yuananting
* @Date: 2021-08-06 17:35:35
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 14:23:07
* @Description: 任务中心接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from '@/common/js/service';
export function getTrainingTaskPage(params: object) {
return Service.Hades('public/hades/getTrainingTaskPage', params);
}
export function createTrainingExam(params: object) {
return Service.Hades('public/hades/createTrainingExam', params);
}
export function createTrainingTask(params: object) {
return Service.Hades('public/hades/createTrainingTask', params);
}
/*
* @Author: yuananting
* @Date: 2021-08-06 17:32:41
* @LastEditors: yuananting
* @LastEditTime: 2021-08-09 14:23:33
* @Description: 任务中心-培训任务接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import { getTrainingTaskPage, createTrainingExam, createTrainingTask } from '@/data-source/taskCenter/request-apis';
export default class TaskCenterService {
// 获取培训任务列表
static getTrainingTaskPage(params: any) {
return getTrainingTaskPage(params);
}
// 培训任务创建考试
static createTrainingExam(params: any) {
return createTrainingExam(params);
}
// 企培创建培训任务
static createTrainingTask(params: any) {
return createTrainingTask(params);
}
}
......@@ -2,40 +2,37 @@
* @Author: yuananting
* @Date: 2021-07-29 13:57:03
* @LastEditors: yuananting
* @LastEditTime: 2021-08-04 17:47:51
* @LastEditTime: 2021-08-09 17:39:56
* @Description: 任务中心-培训任务-新建页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useEffect, useState } from 'react';
import { Button, Tabs, message, Modal, Space } from 'antd';
import { Button, message, Modal, Space } from 'antd';
import ShowTips from '@/components/ShowTips';
import Breadcrumbs from '@/components/Breadcrumbs';
import BasicInfo from './components/BasicInfo';
import TrainContent from './components/TrainContent';
// import ExpiredCourseList from './components/ExpiredCourseList';
import PlanService from '@/domains/plan-domain/planService';
import User from '@/common/js/user';
import _ from 'underscore';
import './AddTrainTask.less';
import Bus from '@/core/bus';
const { TabPane } = Tabs;
import Upload from '@/core/upload';
import { randomString } from '@/domains/basic-domain/utils';
const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
const DEFAULT_BASIC_INFO = {
taskName: '', // 培训任务名称
// createId: User.getStoreUserId(), // 创建人id
// storeId: User.getStoreId(), // 学院id
// issueState: 'YES', // 是否发布此计划(底部按钮区分)
// scheduleMediaRequests: [], // 封面图-(简介待定)
coverUrl: '',
taskName: '1', // 培训任务名称
coverUrl: defaultCover,
coverId: null,
trainingStageList: [], // 培训内容
helpStoreUserIds: [], // 指定协同者id
timeType: 'VALIDITY', // 培训时间,默认永久有效
timeType: 'FOREVER', // 培训时间,默认永久有效
startTime: null, // 固定时间段-开始时间
endTime: null, // 固定时间段-结束时间
learnType: 'FREEDOM', // 学习模式,默认自由学习
assignList: [], // 指派列表-assignId assignType
instro: null, // 培训目的
introduce: null, // 培训目的
};
const DEFAULT_STAGE_LIST = [
......@@ -60,9 +57,10 @@ function AddTrainTask() {
const [finishStandard, setFinishStandard] = useState(DEFAULT_FINISH_STANDARD); // 完成百分比
const [startCheck, setStartCheck] = useState(false); // 是否启动校验
useEffect(() => {
console.log('basicInfo:', basicInfo);
}, [basicInfo]);
// useEffect(() => {
// }, [basicInfo]);
console.log('basicInfo=====>', basicInfo);
function renderFooter() {
return (
......@@ -70,8 +68,8 @@ function AddTrainTask() {
<When condition={activeStep === 'BASIC_INFO'}>
<div className='footer shrink-footer'>
<Button onClick={handleGoBack}>取消</Button>
<Button onClick={handleSubmit}>保存</Button>
<Button type='primary' onClick={() => console.log('下一步')}>
<Button onClick={() => handleSubmit('NO')}>保存</Button>
<Button type='primary' onClick={() => setActiveStep('TRAIN_CONTENT')}>
下一步
</Button>
{/* disabled={submitDisabled} */}
......@@ -80,9 +78,9 @@ function AddTrainTask() {
<Otherwise>
<div className='footer shrink-footer'>
<Button onClick={handleGoBack}>取消</Button>
<Button onClick={() => console.log('上一步')}>上一步</Button>
<Button onClick={handleSubmit}>保存</Button>
<Button type='primary' onClick={() => console.log('提交')}>
<Button onClick={() => setActiveStep('BASIC_INFO')}>上一步</Button>
<Button onClick={() => handleSubmit('NO')}>保存</Button>
<Button type='primary' onClick={() => handleSubmit('YES')}>
保存并发布
</Button>
{/* disabled={submitDisabled} */}
......@@ -92,11 +90,61 @@ function AddTrainTask() {
);
}
function handleSubmit() {
function submitRemote(introduceId, issue) {
const { endTime, helpStoreUserIds, learnType, startTime, taskName, timeType, coverId, coverUrl } = basicInfo;
const { percentCompleteLive, percentCompletePicture, percentCompleteVideo } = finishStandard;
const commonParams = {
assignList: [
// 指派对象
{
assignId: '',
assignName: '',
assignType: '',
},
],
createId: User.getUserId(),
endTime,
helpStoreUserIds, // 协同者集合
issueState: issue, // 是否发布
learnType, // 学习模式
scheduleMediaRequests: [
{
contentType: 'COVER',
mediaContent: coverId,
mediaType: 'PICTURE',
mediaUrl: coverUrl,
},
],
startTime,
storeId: User.getStoreId(),
taskName,
timeType,
percentCompleteLive,
percentCompletePicture,
percentCompleteVideo,
introduceId,
};
console.log('commonParams:', commonParams);
}
function handleSubmit(issue) {
setStartCheck(true);
if (stageList.length === 0) {
return message.warning('请添加阶段');
}
Upload.uploadTextToOSS(
basicInfo.introduce,
`${randomString()}.txt`,
(introduceId) => {
submitRemote(introduceId, issue);
},
() => message.warning('上传培训目的失败')
);
}
function handleGoBack() {
......@@ -104,20 +152,34 @@ function AddTrainTask() {
}
function handleChangeBasicInfo(field, value) {
if (field === 'trainDate') {
console.log('handleChangeBasicInfo====>', basicInfo, field, value);
if (field === 'coverUrl') {
setBasicInfo({
...basicInfo,
coverUrl: value.fileUrl,
coverId: value.resourceId,
});
} else if (field === 'trainDate') {
// 固定培训时间,设置起始
setBasicInfo({
...basicInfo,
startTime: value && value[0]?.valueOf(),
endTime: value && value[1]?.valueOf(),
});
} else {
} else if (field === 'timeType' && value === 'FOREVER') {
setBasicInfo({
...basicInfo,
[field]: value,
startTime: null,
endTime: null,
});
} else {
let a = {
...basicInfo,
[field]: value,
};
console.log('a====>', a);
setBasicInfo(a);
}
}
......@@ -158,7 +220,7 @@ function AddTrainTask() {
</div>
{activeStep === 'BASIC_INFO' && <BasicInfo basicInfo={basicInfo} startCheck={startCheck} onChange={handleChangeBasicInfo} />}
{activeStep === 'TRAIN_CONTENT' && (
<TrainContent stageList={stageList} startCheck={startCheck} finishStandard={finishStandard} onChange={handleChangeStageInfo} />
<TrainContent stageList={stageList} basicInfo={basicInfo} startCheck={startCheck} finishStandard={finishStandard} onChange={handleChangeStageInfo} />
)}
</div>
{renderFooter()}
......
......@@ -2,37 +2,45 @@
* @Author: yuananting
* @Date: 2021-07-28 11:25:58
* @LastEditors: yuananting
* @LastEditTime: 2021-08-05 16:33:23
* @LastEditTime: 2021-08-09 11:41:40
* @Description: 任务中心-培训任务
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useEffect, useState } from 'react';
import TrainFilter from './components/TrainFilter';
import { Route, withRouter } from 'react-router-dom'
import { Route, withRouter } from 'react-router-dom';
import TrainList from './components/TrainList';
// import PlanList from './components/PlanList'
import PlanService from '@/domains/plan-domain/planService';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import DataCenter from '../data-center/Index';
import User from '@/common/js/user';
function TrainTaskPage(props) {
const [trainListData, setTrainListData] = useState([]); // 培训任务列表
const [query, setQuery] = useState({
issueState: 'ALL', // 发布状态
myAssist: false, // 是否协同
current: 1,
endTime: null,
issueState: 'ALL', // 发布状态
myAssist: false, // 是否由我协同
size: 10,
sortMap: {}, // 排序
startTime: null,
storeId: User.getStoreId(),
storeUserId: User.getStoreUserId(),
taskName: '',
});
const [totalCount, setTotalCount] = useState(0); // 总数
const { match } = props;
useEffect(() => {
handleFetchTrainList();
getTrainingTaskPage();
}, [query]);
//动态获取计划列表
function handleFetchTrainList() {
PlanService.getTrainingPlanPage(query).then((res) => {
// 获取计划列表
function getTrainingTaskPage() {
let _query = _.clone(query);
if (_query.issueState === 'ALL') {
delete _query.issueState;
}
TaskCenterService.getTrainingTaskPage(_query).then((res) => {
const {
result: { records = [], total },
} = res;
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-29 14:32:24
* @LastEditors: yuananting
* @LastEditTime: 2021-08-06 13:59:25
* @LastEditTime: 2021-08-09 17:46:08
* @Description: 任务中心-培训任务-新建-基本信息
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -25,12 +25,10 @@ const FormItem = Form.Item;
function BasicInfo(props) {
const { basicInfo, startCheck } = props;
const { taskName, coverUrl, helpStoreUserIds, timeType, startTime, endTime, learnType, assignList, instro } = basicInfo;
const { taskName, coverUrl, helpStoreUserIds, timeType, startTime, endTime, learnType, assignList, introduce } = basicInfo;
const [imageFile, setImageFile] = useState(null); // 需要被截取的图片
const [showSelectFileModal, setShowSelectFileModal] = useState(false);
const [imgClipVisible, setImgClipVisible] = useState(false);
const [coverClicpPath, setCoverClicpPath] = useState(null);
const [coverId, setCoverId] = useState(null);
// 当前是否使用的是默认图片
const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
const isDefaultCover = coverUrl === defaultCover;
......@@ -38,14 +36,10 @@ function BasicInfo(props) {
const [assignorModalVisible, setAssignorModalVisible] = useState(false); // 指派对象弹窗显隐
const [collaboratorModalVisible, setCollaboratorModalVisible] = useState(false); // 协同者弹窗显隐
useEffect(() => {
updateCover();
}, [coverId]);
// 使用默认封面图
function handleResetCoverUrl() {
message.success('已替换为默认图');
props.onChange('coverUrl', defaultCover);
props.onChange('coverUrl', { fileUrl: defaultCover });
}
// 从云盘选择封面
......@@ -56,15 +50,11 @@ function BasicInfo(props) {
function getSignature(blob, fileName) {
Upload.uploadBlobToOSS(blob, 'cover' + new Date().valueOf(), null, 'signInfo').then((signInfo) => {
setCoverClicpPath(signInfo.fileUrl);
setCoverId(signInfo.resourceId);
const { fileUrl, resourceId } = signInfo;
setImgClipVisible(false);
});
}
function updateCover() {
setShowSelectFileModal(false);
props.onChange('coverUrl', coverClicpPath || coverUrl || defaultCover);
props.onChange('coverUrl', { fileUrl, resourceId });
});
}
// 禁选日期
......@@ -104,15 +94,19 @@ function BasicInfo(props) {
}
function confirmAddCollaborator(data) {
props.onChange('helpStoreUserIds', data);
const helpStoreUserIds = data.map((item) => item.userId);
props.onChange('helpStoreUserIds', helpStoreUserIds);
}
function removeSelectedCollaborator(tag, index) {
console.log('vaaaaa', tag, index);
const _helpStoreUserIds = helpStoreUserIds.filter((item) => item !== tag);
console.log(_helpStoreUserIds);
props.onChange('helpStoreUserIds', _helpStoreUserIds);
}
function test(data) {
console.log(data);
props.onChange('introduce', data);
// props.onChange('introduce', data);
}
return (
<div className='basic-info__form'>
......@@ -152,14 +146,18 @@ function BasicInfo(props) {
</FormItem>
<FormItem label='培训时间'>
<div className='duration__wrap'>
<Radio.Group value={timeType} onChange={(e) => props.onChange('timeType', e.target.value)}>
<Radio.Group
value={timeType}
onChange={(e) => {
props.onChange('timeType', e.target.value);
}}>
<Space direction='vertical' size={16}>
<Radio value='VALIDITY'>
<Radio value='FOREVER'>
永久有效<span className='tips'>设置为“永久有效”,发布后任务开始生效,取消发布后失效</span>
</Radio>
<Radio value='FIXED_DURATION'>
<Radio value='VALIDITY'>
固定时间段
{timeType === 'FIXED_DURATION' && (
{timeType === 'VALIDITY' && (
<div className='picker-box'>
<FormItem
validateStatus={startCheck && !startTime && !endTime ? 'error' : ''}
......@@ -310,10 +308,10 @@ function BasicInfo(props) {
isIntro={true}
placeholder='请输入培训目的'
detail={{
content: instro,
content: introduce,
}}
onChange={(val) => {
// changeIntro(val);
onChange={(val, length) => {
test(val);
}}
/>
</FormItem>
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-01 17:28:30
* @LastEditors: yuananting
* @LastEditTime: 2021-08-04 16:13:46
* @LastEditTime: 2021-08-09 14:25:18
* @Description: 新建培训任务-关联课程抽屉
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -352,7 +352,6 @@ class RelatedCourseDrawer extends Component {
key: 'courseChapterNum',
dataIndex: 'courseChapterNum',
width: '20%',
align: 'right',
render: (val, record) => {
return <span>{val || 1}</span>;
},
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-08-03 17:05:32
* @LastEditors: yuananting
* @LastEditTime: 2021-08-04 10:40:11
* @LastEditTime: 2021-08-09 14:36:05
* @Description: 新建培训任务-关联考试抽屉
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -14,31 +14,35 @@ import moment from 'moment';
import './RelatedExamDrawer.less';
import SelectPaperModal from '@/modules/teach-tool/examination-manager/SelectPaperModal';
import User from '@/common/js/user';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import Bus from '@/core/bus';
function RelatedExamDrawer(props) {
const paperInfoInit = { passScore: 60 };
const [showPaperModal, setShowPaperModal] = useState(false);
const [paperInfo, setPaperInfo] = useState(paperInfoInit);
const [paperId, setPaperId] = useState('');
const [passRate, setPassRate] = useState(60); //及格线
const [examStartTime, setStartTime] = useState('');
const [examEndTime, setExamEndTime] = useState('');
const [examName, setExamName] = useState('');
const [needPhone, setNeedPhone] = useState('DO_NOT_NEED_PHONE_VERIFY');
const [needOptionDisorder, setNeedOptionDisorder] = useState('OPTION_SORT');
const [resultContent, setResultContent] = useState('PASS_AND_SCORE');
const [answerAnalysis, setAnswerAnalysis] = useState('RIGHT_OR_WRONG');
const [resultShow, setResultShow] = useState('IMMEDIATELY');
const [examDesc, setExamDesc] = useState('');
const [passScore, setPassScore] = useState(100);
const [desclen, setDescLen] = useState(0);
const [paperInfo, setPaperInfo] = useState({});
const [basicInfo, setBasicInfo] = useState(props.basicInfo);
const [answerAnalysis, setAnswerAnalysis] = useState('RIGHT_OR_WRONG'); // 答案与解析-默认仅显示对错
const [examDesc, setExamDesc] = useState(''); // 考试说明
const [examDuration, setExamDuration] = useState(null); // 考试时长
const [examName, setExamName] = useState(''); // 考试名称
const [needOptionDisorder, setNeedOptionDisorder] = useState('OPTION_SORT'); // 选项乱序-默认正常顺序
const [paperId, setPaperId] = useState(null); // 选择的试卷id
const [passRate, setPassRate] = useState(0); // 及格比例
const [passScore, setPassScore] = useState(60); // 及格分数
const [resultContent, setResultContent] = useState('PASS_AND_SCORE'); // 考试结果内容
const [resultShow, setResultShow] = useState('IMMEDIATELY'); // 考试结果查看-卷后立即显示考试结果
const [editorTextLength, setEditorTextLength] = useState(0); // 考试说明长度
const [check, setCheck] = useState(false);
const [examTotal, setExamTotal] = useState(0);
const [examList, setExamList] = useState([]);
const request = useRef(false);
const { match } = props;
const [examDuration, setExamDuration] = useState(undefined);
useEffect(() => {
Bus.bind('editorLimit', (editorTextLength) => {
setEditorTextLength(editorTextLength);
});
}, []);
useEffect(() => {
setPaperId(paperInfo.paperId);
......@@ -60,77 +64,35 @@ function RelatedExamDrawer(props) {
if (request.current) {
return;
}
setCheck(true);
const param = {
const params = {
paperId,
startTime: examStartTime,
endTime: examEndTime,
examName,
passRate: passRate / 100,
examStartTime,
examEndTime,
passRate,
examDuration,
examDesc,
needPhone,
needOptionDisorder,
resultShow,
resultContent,
answerAnalysis,
resultShow,
examDuration: (examDuration || 0) * 60 * 1000,
examEndTime: basicInfo.endTime,
examStartTime: basicInfo.startTime || new Date().valueOf(), // 新建(永久)取当前时间,固定取培训开始,编辑取培训创建的时间
passScore,
source: 0,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
examId: '',
};
if (!param.examName) {
message.warning('请输入考试名称');
return;
}
if (param.examName && param.examName.length > 40) {
message.warning('考试名称最多40字');
return;
}
if (checkExist(param.examName)) {
message.warning('此考试名称已存在');
return;
}
if (!paperId) {
message.warning('请选择试卷');
return;
}
if (!passRate) {
message.warning('请输入及格线');
return;
}
if (!examStartTime || !examEndTime) {
message.warning('请选择考试起止时间');
return;
}
if (Number(examStartTime) < moment().valueOf()) {
message.warning('开始时间不能早于现在');
return;
}
if (!examDuration) {
message.warning('请输入考试时长');
return;
}
if (examStartTime + examDuration * 60 * 1000 > examEndTime) {
message.warning('考试时长不得超过考试有效期时长');
return;
}
if (desclen > 1000) {
message.warning('内容过长,不能超过1000字');
console.log('sfkajsdfiohasiudfhaiusdfhiaus', params);
if (
!paperId ||
!examName ||
examName.length > 40 ||
!passRate ||
!examDuration ||
editorTextLength > 1000 ||
(basicInfo.timeType === 'VALIDITY' && basicInfo.startTime && basicInfo.endTime && basicInfo.startTime + examDuration * 60 * 1000 > basicInfo.endTime)
) {
return;
}
......@@ -139,78 +101,11 @@ function RelatedExamDrawer(props) {
request.current = false;
}, 2000);
if (props.type === 'edit') {
param.examId = match.params.id;
}
Service.Hades(props.type === 'edit' ? 'public/hades/editExam' : 'public/hades/createExam', param).then((res) => {
message.success(props.type === 'edit' ? '编辑成功' : '创建成功');
switch (props.type) {
case 'organizeExam': // 试卷列表-组织考试进入
case 'newPaperToAddExam': // 组卷保存组织考试
case 'editPaperToAddExam':
window.RCHistory.push('/examination-manage-index');
break;
case 'add':
case 'edit': // 考试列表-新建或编辑
case 'copy': // 考试列表-新建或编辑
props.freshList();
props.history.goBack();
break;
}
TaskCenterService.createTrainingExam(params).then((res) => {
console.log(res);
});
}
function disabledRangeTime(date, type) {
if (moment(date).isSame(moment(), 'day')) {
return {
disabledHours: () => {
const hours = [];
for (let i = 0; i < moment().hour(); i++) {
hours.push(i);
}
return hours;
},
disabledMinutes: () => {
const currentMinute = moment().minute();
const currentHour = moment(date).hour();
const minutes = [];
if (currentHour === moment().hour()) {
for (let i = 0; i < currentMinute; i++) {
minutes.push(i);
}
}
return minutes;
},
};
}
return {
disabledHours: () => [],
disabledMinutes: () => [],
disabledSeconds: () => [],
};
}
// 校验考试名称是否存在
function checkExist(examName) {
var result = null;
examList.length > 0 &&
examList.forEach((item) => {
if (result != null) {
return result;
}
if (props.type === 'edit') {
if (item.examName === examName && item.examId !== match.params.id) {
result = item;
}
} else {
if (item.examName === examName) {
result = item;
}
}
});
return result;
}
return (
<Drawer title='添加考试' width={720} maskClosable={false} closable={true} onClose={props.onClose} visible={true} mask className='related-exam-drawer'>
<Form labelCol={{ span: 4 }} wrapperCol={{ span: 20 }} layout='horizontal'>
......@@ -259,8 +154,8 @@ function RelatedExamDrawer(props) {
<Form.Item
label='考试名称'
validateStatus={check && (!examName || examName.length > 40 || checkExist(examName)) ? 'error' : ''}
help={check && (!examName ? '请输入考试名称' : examName.length > 40 ? '考试名称最多40字' : checkExist(examName) && '此考试名称已存在')}
validateStatus={check && (!examName || examName.length > 40) ? 'error' : ''}
help={check && ((!examName && '请输入考试名称') || (examName.length > 40 && '考试名称最多40字'))}
required>
<Input
placeholder='请输入考试名称(40字以内)'
......@@ -299,7 +194,28 @@ function RelatedExamDrawer(props) {
<span style={{ marginLeft: 8 }}>%</span>
<span style={{ marginLeft: 16, color: '#999' }}>{` 总分(${paperInfo.totalScore || 0})*及格线(${passRate || 0}%)=及格分数(${passScore})`}</span>
</Form.Item>
<Form.Item label='考试时长' validateStatus={check && !examDuration ? 'error' : ''} help={check && !examDuration && '请输入考试时长'} required>
<Form.Item
label='考试时长'
validateStatus={
check &&
(!examDuration ||
(basicInfo.timeType === 'VALIDITY' &&
basicInfo.startTime &&
basicInfo.endTime &&
basicInfo.startTime + examDuration * 60 * 1000 > basicInfo.endTime))
? 'error'
: ''
}
help={
check &&
((!examDuration && '请输入考试时长') ||
(basicInfo.timeType === 'VALIDITY' &&
basicInfo.startTime &&
basicInfo.endTime &&
basicInfo.startTime + examDuration * 60 * 1000 > basicInfo.endTime &&
'考试时长不得超过培训有效期时长'))
}
required>
<InputNumber
value={examDuration}
max={1440}
......@@ -312,16 +228,15 @@ function RelatedExamDrawer(props) {
<span style={{ marginLeft: 8 }}>分钟</span>
<span style={{ marginLeft: 16, color: '#999' }}>{` 时长不能超过1440分钟(24小时)`}</span>
</Form.Item>
<Form.Item label='考试说明' validateStatus={check && desclen > 1000 ? 'error' : ''} help={check && desclen > 1000 && '最多只能输入1000个字'}>
<Form.Item label='考试说明'>
<GraphicsEditor
maxLimit={1000}
isIntro={true}
detail={{
content: examDesc,
}}
onChange={(val, len) => {
onChange={(val) => {
setExamDesc(val);
setDescLen(len);
}}
/>
</Form.Item>
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-30 16:33:58
* @LastEditors: yuananting
* @LastEditTime: 2021-08-05 14:21:19
* @LastEditTime: 2021-08-09 13:56:24
* @Description: 任务中心-培训任务-新建-培训内容
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
......@@ -53,6 +53,7 @@ class TrainContent extends Component {
constructor(props) {
super(props);
this.state = {
basicInfo: props.basicInfo,
stageList: props.stageList,
finishStandard: props.finishStandard,
showCourseDrawer: false,
......@@ -476,7 +477,7 @@ class TrainContent extends Component {
};
render() {
const { stageList, showCourseDrawer, showExamDrawer, expiredCourseList, showStandardDetail, finishStandard } = this.state;
const { stageList, showCourseDrawer, showExamDrawer, expiredCourseList, showStandardDetail, finishStandard, basicInfo } = this.state;
const { percentCompleteLive, percentCompleteVideo, percentCompletePicture } = finishStandard;
const { startCheck } = this.props;
......@@ -495,7 +496,7 @@ class TrainContent extends Component {
</div>
)}
{showCourseDrawer && <RelatedCourseDrawer data={stageList} onClose={this.onCloseCourseDrawer} onSelect={this.confirmSelectCourse} />}
{showExamDrawer && <RelatedExamDrawer onClose={this.onCloseExamDrawer} />}
{showExamDrawer && <RelatedExamDrawer basicInfo={basicInfo} onClose={this.onCloseExamDrawer} />}
</div>
<div className='expired-info__wrap'>
<div className='module-title'>失效课程</div>
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-28 14:56:52
* @LastEditors: yuananting
* @LastEditTime: 2021-08-05 16:33:02
* @LastEditTime: 2021-08-09 11:13:14
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -12,12 +12,13 @@ import { Tooltip, Checkbox, Dropdown, Radio, Button, Space, Badge } from 'antd';
import './TrainList.less';
import { XMTable, PageControl } from '@/components';
import User from '@/common/js/user';
import ENUM from '../../enum';
function TrainList(props) {
const {
query: { issueState, myAssist, current, size },
totalCount,
match
match,
} = props;
function renderMoreOperate(item) {
......@@ -36,8 +37,8 @@ function TrainList(props) {
const columns = [
{
title: '培训任务',
key: 'planName',
dataIndex: 'planName',
key: 'taskName',
dataIndex: 'taskName',
width: '18%',
fixed: 'left',
render: (val, record) => {
......@@ -45,8 +46,8 @@ function TrainList(props) {
<div className='train-task-name'>
<img className='train-cover' src={record.coverUrl || 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png'} alt='' />
<Choose>
<When condition={record.planName.length > 25}>
<Tooltip title={record.planName}>
<When condition={record.taskName?.length > 25}>
<Tooltip title={record.taskName}>
<div className='train-name'>{val}</div>
</Tooltip>
</When>
......@@ -60,18 +61,23 @@ function TrainList(props) {
},
{
title: '任务状态',
width: '10%',
key: 'status',
dataIndex: 'status',
render: (val, record) => {
return <span>{'未开始'}</span>;
width: '12%',
key: 'taskState',
dataIndex: 'taskState',
render: (val) => {
return (
<div className='task-state'>
<span className='status-point' style={{ backgroundColor: ENUM.trainStatus[val || 'UN_START'].color }}></span>
<span>{ENUM.trainStatus[val || 'UN_START'].text}</span>
</div>
);
},
},
{
title: '任务数',
width: '8%',
key: 'courseNum',
dataIndex: 'courseNum',
key: 'contentNum',
dataIndex: 'contentNum',
render: (val, record) => {
return <span>{val}</span>;
},
......@@ -82,8 +88,19 @@ function TrainList(props) {
key: 'cultureCustomerNum',
dataIndex: 'cultureCustomerNum',
sorter: true,
render: (val) => {
return <span style={{ color: '#2966FF' }}>{val}</span>;
render: (val, record) => {
return (
<Tooltip
title={
<div>
<div>未完成:{record.startingCustomerNum}</div>
<div>已完成:{record.finishCustomerNum}</div>
<div>已逾期:{record.overdueCustomerNum}</div>
</div>
}>
<span style={{ color: '#2966FF' }}>{val}</span>
</Tooltip>
);
},
},
{
......@@ -106,20 +123,27 @@ function TrainList(props) {
</span>
),
width: '10%',
key: 'rate',
dataIndex: 'rate',
key: 'finishPercent',
dataIndex: 'finishPercent',
sorter: true,
render: (val) => {
return <span>100%</span>;
return <span>{val}%</span>;
},
},
{
title: '培训时间',
width: '14%',
key: 'created',
dataIndex: 'created',
render: (val) => {
return <span style={{ whiteSpace: 'nowrap' }}>{window.formatDate('YYYY-MM-DD H:i', val)}</span>;
key: 'trainTime',
dataIndex: 'trainTime',
render: (val, record) => {
if (record.timeType === 'FOREVER') {
return <span>不限时</span>;
}
return (
<span style={{ whiteSpace: 'nowrap' }}>
{window.formatDate('YYYY-MM-DD H:i', record.startTime)}~{window.formatDate('YYYY-MM-DD H:i', record.endTime)}
</span>
);
},
},
{
......@@ -161,8 +185,10 @@ function TrainList(props) {
render: (val, record) => {
return (
<div className='operate'>
<div className='operate__item' onClick={() => {
props.history.push(`${match.path}/data?planId=${record.planId}`)
<div
className='operate__item'
onClick={() => {
props.history.push(`${match.path}/data?planId=${record.planId}`);
}}>
数据
</div>
......@@ -200,6 +226,64 @@ function TrainList(props) {
props.onChange(_query);
}
function handleChangeTable(pagination, filters, sorter) {
const { columnKey, order } = sorter;
const { query } = props;
let _columnKey;
let _order;
if (columnKey == 'cultureCustomerNum' && order === 'ascend') {
// 按学习人数升序排序
_columnKey = 'CUSTOMER_NUM';
_order = 'SORT_ASC';
}
if (columnKey == 'cultureCustomerNum' && order === 'descend') {
// 按学习人数降序排序
_columnKey = 'CUSTOMER_NUM';
_order = 'SORT_DESC';
}
if (columnKey == 'finishPercent' && order === 'ascend') {
// 按完成率升序排序
_columnKey = 'FINISH_PERCENT';
_order = 'SORT_ASC';
}
if (columnKey == 'finishPercent' && order === 'descend') {
// 按完成率降序排序
_columnKey = 'FINISH_PERCENT';
_order = 'SORT_DESC';
}
if (columnKey === 'created' && order === 'ascend') {
// 按创建时间升序排序
_columnKey = 'CREATED';
_order = 'SORT_ASC';
}
if (columnKey === 'created' && order === 'descend') {
// 按创建时间降序排序
_columnKey = 'CREATED';
_order = 'SORT_DESC';
}
if (columnKey === 'updated' && order === 'ascend') {
// 按更新时间升序排序
_columnKey = 'UPDATED';
_order = 'SORT_ASC';
}
if (columnKey === 'updated' && order === 'descend') {
// 按更新时间降序排序
_columnKey = 'UPDATED';
_order = 'SORT_DESC';
}
const _query = {
...query,
sortMap: {},
};
_query.sortMap[_columnKey] = _order;
props.onChange(_query);
}
function handleCreatePlan() {
window.RCHistory.push({
pathname: '/create-train-task?type=add',
......@@ -237,7 +321,7 @@ function TrainList(props) {
dataSource={props.trainListData}
columns={parseColumns()}
pagination={false}
// onChange={handleChangeTable}
onChange={handleChangeTable}
bordered
size='middle'
scroll={{ x: 1600 }}
......
......@@ -29,7 +29,6 @@
border-radius: 2px;
margin-right: 8px;
}
.train-name {
width: 188px;
overflow: hidden;
......@@ -40,6 +39,18 @@
height: 40px;
}
}
.task-state {
* {
vertical-align: middle;
display: inline-block;
}
.status-point {
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 4px;
}
}
.operate {
display: flex;
......
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