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