Commit 07d95621 by guomingpang

Merge branch 'dev' of…

Merge branch 'dev' of ssh://xmgit.ixm5.cn:10022/xiaomai-cloud-class/xiaomai-cloud-class-web into dev
parents 394dc6d5 fded7da2
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
} }
} }
.operate{ .operate{
display:inline-block;
margin-top:24px; margin-top:24px;
.btn { .btn {
padding:5px 12px; padding:5px 12px;
......
...@@ -133,13 +133,13 @@ const FileTypeIcon = { ...@@ -133,13 +133,13 @@ const FileTypeIcon = {
PPTX: "https://image.xiaomaiketang.com/xm/847pFAdYGW.png", PPTX: "https://image.xiaomaiketang.com/xm/847pFAdYGW.png",
PDF: "https://image.xiaomaiketang.com/xm/rrEJMNkhTG.png", PDF: "https://image.xiaomaiketang.com/xm/rrEJMNkhTG.png",
MP3: "https://image.xiaomaiketang.com/xm/ykjnSWDyQ6.png", MP3: "https://image.xiaomaiketang.com/xm/ykjnSWDyQ6.png",
MP4: "https://image.xiaomaiketang.com/xm/TKwbQGYDBR.png", MP4: "https://image.xiaomaiketang.com/xm/yK3ASiS8ch.png",
JPG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png", JPG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
JPEG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png", JPEG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
PNG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png", PNG: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
GIF: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png", GIF: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
BMP: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png", BMP: "https://image.xiaomaiketang.com/xm/XRkX8JBTPs.png",
VIDEO: "https://image.xiaomaiketang.com/xm/TKwbQGYDBR.png" VIDEO: 'https://image.xiaomaiketang.com/xm/yK3ASiS8ch.png'
}; };
const UploadIcon = "https://image.xiaomaiketang.com/xm/4DXNrZWWsd.png"; const UploadIcon = "https://image.xiaomaiketang.com/xm/4DXNrZWWsd.png";
......
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-31 09:34:31 * @Date: 2020-08-31 09:34:31
* @LastEditors: Please set LastEditors * @LastEditors: yuananting
* @LastEditTime: 2021-06-24 19:34:21 * @LastEditTime: 2021-07-12 17:40:26
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -115,6 +115,10 @@ class Axios { ...@@ -115,6 +115,10 @@ class Axios {
window.RCHistory.replace('/login'); window.RCHistory.replace('/login');
return Promise.reject(); return Promise.reject();
break; break;
case 504:
message.error('网络状况不稳定,如果出现数据异常,请刷新页面');
Promise.reject();
break;
default: default:
message.error(error.message); message.error(error.message);
break; break;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-12-01 17:21:21 * @Date: 2020-12-01 17:21:21
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-22 14:56:34 * @LastEditTime: 2021-07-09 15:33:33
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -62,6 +62,9 @@ export function saveYoZoFileVersionId(params: object) { ...@@ -62,6 +62,9 @@ export function saveYoZoFileVersionId(params: object) {
export function yoZoUpload(ossUrl:String,appId:String,uploadSign:String){ export function yoZoUpload(ossUrl:String,appId:String,uploadSign:String){
return axios.post(`https://dmc.yozocloud.cn/api/file/http?fileUrl=${ossUrl}&appId=${appId}&sign=${uploadSign}`) return axios.post(`https://dmc.yozocloud.cn/api/file/http?fileUrl=${ossUrl}&appId=${appId}&sign=${uploadSign}`)
} }
export function saveFileVersionIdByCourseChapter(params: object) {
return Service.Hades('public/hades/saveFileVersionIdByCourseChapter', params);
}
export const getOssClient = ( export const getOssClient = (
data: object, data: object,
instId: string, instId: string,
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-12-01 17:20:49 * @Date: 2020-12-01 17:20:49
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-22 14:57:01 * @LastEditTime: 2021-07-09 15:33:59
* @Description: Description * @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion, getEnterpriseUser,getWXWorkLoginNoCheck,getLesseeVersionMsg,getYoZoSign,saveYoZoFileVersionId,yoZoUpload} from '@/data-source/base/request-apis'; import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion, getEnterpriseUser,getWXWorkLoginNoCheck,getLesseeVersionMsg,getYoZoSign,saveYoZoFileVersionId,yoZoUpload,saveFileVersionIdByCourseChapter} from '@/data-source/base/request-apis';
export default class StoreService { export default class StoreService {
// 获取员工列表 // 获取员工列表
...@@ -73,4 +73,7 @@ export default class StoreService { ...@@ -73,4 +73,7 @@ export default class StoreService {
static yoZoUpload(ossUrl:String,appId:String,uploadSign:String){ static yoZoUpload(ossUrl:String,appId:String,uploadSign:String){
return yoZoUpload(ossUrl,appId,uploadSign); return yoZoUpload(ossUrl,appId,uploadSign);
} }
static saveFileVersionIdByCourseChapter(params: any){
return saveFileVersionIdByCourseChapter(params);
}
} }
\ No newline at end of file
...@@ -169,7 +169,7 @@ class PreviewCourseModal extends React.Component { ...@@ -169,7 +169,7 @@ class PreviewCourseModal extends React.Component {
<video <video
controls controls
src={courseChapterList.length && courseChapterList[0].mediaUrl || scheduleVideoUrl } src={courseChapterList.length && courseChapterList[0].mediaUrl || scheduleVideoUrl }
poster={coverUrl ? coverUrl : `https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png`} poster={coverUrl ? coverUrl : `https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png`}
className='course-url' className='course-url'
/> />
</When> </When>
......
...@@ -116,7 +116,7 @@ class ShareLiveModal extends React.Component { ...@@ -116,7 +116,7 @@ class ShareLiveModal extends React.Component {
} }
break; break;
case 'videoClass': // 视频课 case 'videoClass': // 视频课
coverImgSrc = coverUrl || 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'; coverImgSrc = coverUrl || 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png';
break; break;
case 'graphicsClass': // 图文课 case 'graphicsClass': // 图文课
coverImgSrc = coverUrl || 'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png'; coverImgSrc = coverUrl || 'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png';
......
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-05 10:07:47 * @Date: 2020-08-05 10:07:47
* @LastEditors: yuananting * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-12 15:16:50 * @LastEditTime: 2021-07-13 15:25:32
* @Description: 线上课新增/编辑页 * @Description: 线上课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
import React from 'react' import React from 'react'
import { Button, Input, message, Modal, Cascader, Tooltip, Form, Popconfirm } from 'antd' import { Button, Input, message, Modal, Cascader, Tooltip, Form, Popconfirm,Menu,Dropdown} from 'antd'
import { FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum' import { FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum'
import ShowTips from '@/components/ShowTips' import ShowTips from '@/components/ShowTips'
import Breadcrumbs from '@/components/Breadcrumbs' import Breadcrumbs from '@/components/Breadcrumbs'
...@@ -85,9 +85,11 @@ class AddVideoCourse extends React.Component { ...@@ -85,9 +85,11 @@ class AddVideoCourse extends React.Component {
introduce: '', introduce: '',
courseChapterList:[ courseChapterList:[
], // 课节列表 ], // 课节列表
videoType: "MP4", // videoType: "MP4",
mediaNameAlias: '', // 任一视频重命名的名称(气泡框) mediaNameAlias: '', // 任一视频重命名的名称(气泡框)
popConfirmVisible: false popConfirmVisible: false,
selectTypeList:['MP4'],
accept:'video/mp4'
} }
} }
...@@ -137,8 +139,8 @@ class AddVideoCourse extends React.Component { ...@@ -137,8 +139,8 @@ class AddVideoCourse extends React.Component {
const { courseName, shelfState, whetherVisitorsJoin, courseMediaVOS, categoryOneName, categoryTwoName, categoryId, courseChapterVOList =[] } = result const { courseName, shelfState, whetherVisitorsJoin, courseMediaVOS, categoryOneName, categoryTwoName, categoryId, courseChapterVOList =[] } = result
let coverId let coverId
let coverUrl let coverUrl
let videoDuration // let videoDuration
let videoName // let videoName
let scheduleMedia = [] let scheduleMedia = []
let scheduleVideoUrl let scheduleVideoUrl
let hasIntro let hasIntro
...@@ -176,8 +178,8 @@ class AddVideoCourse extends React.Component { ...@@ -176,8 +178,8 @@ class AddVideoCourse extends React.Component {
loadintroduce: !hasIntro, loadintroduce: !hasIntro,
coverId, coverId,
coverUrl, coverUrl,
videoName, // videoName,
videoDuration, // videoDuration,
scheduleMedia, scheduleMedia,
courseName, courseName,
scheduleVideoUrl, scheduleVideoUrl,
...@@ -203,10 +205,8 @@ class AddVideoCourse extends React.Component { ...@@ -203,10 +205,8 @@ class AddVideoCourse extends React.Component {
} }
handleGoBack = () => { handleGoBack = () => {
const { coverId, videoName, videoDuration, courseName, scheduleMedia, courseChapterList, categoryId, shelfState, whetherVisitorsJoin } = this.state const { coverId,courseName, scheduleMedia, courseChapterList, categoryId, shelfState, whetherVisitorsJoin } = this.state
if ( if (
videoName ||
videoDuration ||
!courseChapterList.length || !courseChapterList.length ||
!_.isEqual(scheduleMedia, defaultScheduleMedia) || !_.isEqual(scheduleMedia, defaultScheduleMedia) ||
categoryId || categoryId ||
...@@ -275,13 +275,11 @@ class AddVideoCourse extends React.Component { ...@@ -275,13 +275,11 @@ class AddVideoCourse extends React.Component {
// 显示预览弹窗 // 显示预览弹窗
handleShowPreviewModal = () => { handleShowPreviewModal = () => {
const { coverUrl, scheduleVideoUrl, courseName, scheduleMedia, videoDuration, introduce, courseChapterList, categoryName } = this.state const { coverUrl, scheduleVideoUrl, courseName, scheduleMedia,introduce, courseChapterList, categoryName } = this.state
const courseBasinInfo = { const courseBasinInfo = {
coverUrl, coverUrl,
scheduleVideoUrl, scheduleVideoUrl,
courseName, courseName,
videoDuration
} }
const courseIntroInfo = { const courseIntroInfo = {
liveCourseMediaRequests: scheduleMedia, liveCourseMediaRequests: scheduleMedia,
...@@ -320,8 +318,10 @@ class AddVideoCourse extends React.Component { ...@@ -320,8 +318,10 @@ class AddVideoCourse extends React.Component {
return; return;
} }
selectedFileList.map((file,index) => { selectedFileList.map((file,index) => {
console.log('')
const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file; const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file;
console.log('folderFormat',folderFormat);
if(folderFormat === 'MP4'){
const videoDom = document.createElement('video') const videoDom = document.createElement('video')
videoDom.src = ossUrl videoDom.src = ossUrl
videoDom.onloadedmetadata = () => { videoDom.onloadedmetadata = () => {
...@@ -335,14 +335,29 @@ class AddVideoCourse extends React.Component { ...@@ -335,14 +335,29 @@ class AddVideoCourse extends React.Component {
mediaUrl: ossUrl, mediaUrl: ossUrl,
sort: _courseChapterList.length sort: _courseChapterList.length
}) })
this.setState({ this.setState({
size: folderSize, // size: folderSize,
videoName: folderName, // videoName: folderName,
videoType: folderFormat, // videoType: folderFormat,
courseChapterList: _courseChapterList courseChapterList: _courseChapterList
}) })
} }
}else{
const suffix = _.last(folderName.split('.')).toUpperCase();
_courseChapterList.push({
mediaContent: resourceId,
contentType: 'SCHEDULE',
mediaType: suffix,
mediaName: folderName,
id: resourceId,
mediaUrl: ossUrl,
sort: _courseChapterList.length
})
this.setState({
courseChapterList: _courseChapterList
})
}
}) })
} }
...@@ -396,8 +411,8 @@ class AddVideoCourse extends React.Component { ...@@ -396,8 +411,8 @@ class AddVideoCourse extends React.Component {
id, id,
coverId, coverId,
pageType, pageType,
videoName, // videoName,
videoDuration, // videoDuration,
courseName, courseName,
scheduleMedia, scheduleMedia,
categoryId, categoryId,
...@@ -409,8 +424,8 @@ class AddVideoCourse extends React.Component { ...@@ -409,8 +424,8 @@ class AddVideoCourse extends React.Component {
} = this.state } = this.state
const commonParams = { const commonParams = {
videoName, // videoName,
videoDuration, videoDuration:0, //后端的必要参数,不能传空
scheduleMedia: scheduleMedia.filter((item) => !!item.mediaContent), scheduleMedia: scheduleMedia.filter((item) => !!item.mediaContent),
categoryId, categoryId,
courseName, courseName,
...@@ -629,7 +644,40 @@ class AddVideoCourse extends React.Component { ...@@ -629,7 +644,40 @@ class AddVideoCourse extends React.Component {
courseChapterList: _courseChapterList courseChapterList: _courseChapterList
}) })
} }
renderTypemenu =()=>{
return <Menu>
<Menu.Item>
<span onClick={()=>{this.selectFileType("VIDEO")}}>
视频文件
</span>
</Menu.Item>
<Menu.Item>
<span onClick={()=>{this.selectFileType("WORD_PDF")}}>
资料文件
</span>
</Menu.Item>
</Menu>
}
selectFileType = (type) =>{
const { courseChapterList } = this.state;
if(courseChapterList.length >= 20) {
message.warning(`最多只能上传20个文件`);
return;
}
if(type==="VIDEO"){
this.setState({
showSelectFileModal: true,
selectTypeList:['MP4'],
accept:'video/mp4'
})
}else{
this.setState({
showSelectFileModal: true,
selectTypeList:['DOC','DOCX','PDF'],
accept:'.doc,.docx,.pdf'
})
}
}
render() { render() {
const { const {
pageType, pageType,
...@@ -638,7 +686,7 @@ class AddVideoCourse extends React.Component { ...@@ -638,7 +686,7 @@ class AddVideoCourse extends React.Component {
scheduleMedia, scheduleMedia,
showSelectFileModal, showSelectFileModal,
diskList, diskList,
videoType, // videoType,
shelfState, shelfState,
categoryName, categoryName,
courseCatalogList, courseCatalogList,
...@@ -652,11 +700,11 @@ class AddVideoCourse extends React.Component { ...@@ -652,11 +700,11 @@ class AddVideoCourse extends React.Component {
id, id,
courseChapterList, courseChapterList,
imageFile, imageFile,
popConfirmVisible popConfirmVisible,
selectTypeList,
accept
} = this.state } = this.state
const defaultCover = 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png';
const courseWareIcon = FileVerifyMap[videoType] ? FileTypeIcon[FileVerifyMap[videoType].type] : FileTypeIcon[videoType]
const defaultCover = 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png';
const isDefaultCover = coverUrl === defaultCover || coverUrl == null; const isDefaultCover = coverUrl === defaultCover || coverUrl == null;
return ( return (
...@@ -684,11 +732,11 @@ class AddVideoCourse extends React.Component { ...@@ -684,11 +732,11 @@ class AddVideoCourse extends React.Component {
<div className='upload-video mt16'> <div className='upload-video mt16'>
<div className='content flex'> <div className='content flex'>
<span className='label required'>视频上传</span> <span className='label required'>上传课节</span>
</div> </div>
<div className='sub-content'> <div className='sub-content'>
<div className="btn-wrap"> <div className="btn-wrap">
<Button {/* <Button
onClick={() => { onClick={() => {
if(courseChapterList.length >= 20) { if(courseChapterList.length >= 20) {
message.warning(`最多只能上传20个文件`); message.warning(`最多只能上传20个文件`);
...@@ -697,10 +745,20 @@ class AddVideoCourse extends React.Component { ...@@ -697,10 +745,20 @@ class AddVideoCourse extends React.Component {
this.setState({ this.setState({
showSelectFileModal: true showSelectFileModal: true
}) })
}}>添加视频</Button> }}>添加视频</Button> */}
<div className='select-file'>
<Dropdown overlay={this.renderTypemenu()}>
<Button>选择文件</Button>
</Dropdown>
</div>
<div className='course-ware--empty'>从资料云盘中选择视频</div> <div className='course-ware--empty'>从资料云盘中选择视频</div>
</div> </div>
<div className='tips'>视频数量限制20个,每个视频文件大小不超过2G</div> <div className='tips'>
课节数量限制20个,文件规格说明
<Tooltip title="视频支持mp4格式,大小不超过2G;文件支持PDF、docx、doc格式,大小不超过100M">
<i className='icon iconfont' style={{ cursor: 'pointer', color: '#bfbfbf', fontSize: '14px'}}> &#xe61d;</i>
</Tooltip>
</div>
</div> </div>
</div> </div>
...@@ -712,7 +770,7 @@ class AddVideoCourse extends React.Component { ...@@ -712,7 +770,7 @@ class AddVideoCourse extends React.Component {
_.map(courseChapterList,(item,index) => { _.map(courseChapterList,(item,index) => {
return <div className='course-ware' key={index}> return <div className='course-ware' key={index}>
<div className="course-ware__index">{index < 9 ? `0${index + 1 } ` : `${index + 1 } `}</div> <div className="course-ware__index">{index < 9 ? `0${index + 1 } ` : `${index + 1 } `}</div>
<img className='course-ware__img' src={courseWareIcon} alt='' /> <img className='course-ware__img' src={FileTypeIcon[item.mediaType]} alt='' />
<div className='course-ware__name'>{item.mediaName && item.mediaName.length > 24 ? <Tooltip title={item.mediaName}>{item.mediaName}</Tooltip>:item.mediaName}</div> <div className='course-ware__name'>{item.mediaName && item.mediaName.length > 24 ? <Tooltip title={item.mediaName}>{item.mediaName}</Tooltip>:item.mediaName}</div>
<div className="course-chapter__opt" id={item.resourceId}> <div className="course-chapter__opt" id={item.resourceId}>
<div className={`up ${Number(index) === 0 ? 'disabled':''}`} onClick={()=> this.handleChangeIndex(true,item.sort,item.resourceId)}>上移</div> <div className={`up ${Number(index) === 0 ? 'disabled':''}`} onClick={()=> this.handleChangeIndex(true,item.sort,item.resourceId)}>上移</div>
...@@ -784,7 +842,7 @@ class AddVideoCourse extends React.Component { ...@@ -784,7 +842,7 @@ class AddVideoCourse extends React.Component {
isDefaultCover && <span className="tag">默认图</span> isDefaultCover && <span className="tag">默认图</span>
} }
{/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */} {/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */}
<img src={coverUrl || `https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png`} alt='' /> <img src={coverUrl || `https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png`} alt='' />
</div> </div>
</div> </div>
</div> </div>
...@@ -852,13 +910,14 @@ class AddVideoCourse extends React.Component { ...@@ -852,13 +910,14 @@ class AddVideoCourse extends React.Component {
<SelectPrepareFileModal <SelectPrepareFileModal
multiple={true} multiple={true}
operateType='select' operateType='select'
selectTypeList={['MP4']} selectTypeList={selectTypeList}
accept='video/mp4' accept={accept}
queryTypeEnum={'ONLINE'}
confirm={{ confirm={{
title: '文件过大,无法上传', title: '文件过大,无法上传',
content: '为保障学员的观看体验,上传的视频大小不能超过2G' content: '为保障学员的观看体验,上传的视频大小不能超过2G'
}} }}
tooltip={'格式支持mp4,大小不超过2G'} tooltip={''}
isOpen={showSelectFileModal} isOpen={showSelectFileModal}
diskList={diskList} diskList={diskList}
addVideo={true} addVideo={true}
......
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-04-28 18:05:30 * @Date: 2020-04-28 18:05:30
* @LastEditors: yuananting * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-09 16:21:13 * @LastEditTime: 2021-07-13 15:26:11
* @Description: 线上课课程课节详情 * @Description: 线上课课程课节详情
*/ */
...@@ -12,12 +12,15 @@ import { withRouter } from "react-router-dom"; ...@@ -12,12 +12,15 @@ import { withRouter } from "react-router-dom";
import CourseService from '@/domains/course-domain/CourseService' import CourseService from '@/domains/course-domain/CourseService'
import underscore from 'underscore'; import underscore from 'underscore';
import ScanFileModal from '@/modules/resource-disk/modal/ScanFileModal.jsx'; import ScanFileModal from '@/modules/resource-disk/modal/ScanFileModal.jsx';
import { FileTypeIcon } from '@/common/constants/academic/lessonEnum'
import BaseService from "@/domains/basic-domain/baseService";
import {YZ_APPId,YZ_PREVIEW_URL} from '@/domains/basic-domain/constants';
import PreviewFileModal from '@/bu-components/PreviewFileModal';
import './VideoCourseDetail.less'; import './VideoCourseDetail.less';
declare var getParameterByName: any; declare var getParameterByName: any;
declare var window: any; declare var window: any;
const FileTypeIconMap:any = FileTypeIcon
function VideoCourseDetail(){ function VideoCourseDetail(){
const courseId = window.getParameterByName("courseId"); // 课程ID const courseId = window.getParameterByName("courseId"); // 课程ID
const [coverUrl,setCoverUrl] = useState(""); const [coverUrl,setCoverUrl] = useState("");
...@@ -27,7 +30,11 @@ function VideoCourseDetail(){ ...@@ -27,7 +30,11 @@ function VideoCourseDetail(){
const [courseName,setCourseName] = useState(""); const [courseName,setCourseName] = useState("");
const [categoryName,setCategoryName] = useState(""); const [categoryName,setCategoryName] = useState("");
const [scanFileModal,setScanFileModal] = useState<any>(null); const [scanFileModal,setScanFileModal] = useState<any>(null);
const [showPreviewModal,setShowPreviewModal] = useState(false); //是否显示loading
// const [previewing,setPreviewing] = useState(false); //是否正在预览
const [previewStatus,setPreviewStatus] = useState('UPLOAD'); //预览文件的生成状态
const [url,setUrl] = useState('');
let previewing = false;
useEffect(()=>{ useEffect(()=>{
handleFetchScheudleDetail(courseId); handleFetchScheudleDetail(courseId);
},[courseId]) },[courseId])
...@@ -73,9 +80,9 @@ function VideoCourseDetail(){ ...@@ -73,9 +80,9 @@ function VideoCourseDetail(){
setCourseChapterList(courseChapterVOList); setCourseChapterList(courseChapterVOList);
}) })
} }
async function handleScanFileModal(fileType: string = "MP4", fileObj:any){
function handleScanFileModal(fileType: string = "MP4", fileObj: Object){ const {fileVersionId,name,mediaUrl,id} = fileObj;
if(fileType === "VIDEO"){
const scanFileModal = ( const scanFileModal = (
<ScanFileModal <ScanFileModal
fileType={fileType} fileType={fileType}
...@@ -86,6 +93,65 @@ function VideoCourseDetail(){ ...@@ -86,6 +93,65 @@ function VideoCourseDetail(){
/> />
); );
setScanFileModal(scanFileModal) setScanFileModal(scanFileModal)
}else{
if(!fileVersionId){
setShowPreviewModal(true);
previewing = true;
setPreviewStatus('UPLOAD');
const uploadParams ={
fileUrl:mediaUrl,
yoZoTypeEnum:'UPLOAD'
}
const uploadSign:any = await BaseService.getYoZoSign(uploadParams);
BaseService.yoZoUpload(mediaUrl,YZ_APPId,uploadSign).then(async function (response){
const saveParams ={
fileVersionId:response.data.data.fileVersionId,
courseChapterId:id
}
BaseService.saveFileVersionIdByCourseChapter(saveParams);
if(previewing){
const previewParams ={
fileVersionId:response.data.data.fileVersionId,
yoZoTypeEnum:'VIEW',
htmlTitle:name
}
const previewSign = await BaseService.getYoZoSign(previewParams);
const url = `${YZ_PREVIEW_URL}?fileVersionId=${response.data.data.fileVersionId}&appId=${YZ_APPId}&sign=${previewSign}&htmlTitle=${name}`
setPreviewStatus('UPLOAD_SUCCESS');
setUrl(url)
}
})
}else{
const previewParams ={
fileVersionId,
yoZoTypeEnum:'VIEW',
htmlTitle:name
}
const previewSign = await BaseService.getYoZoSign(previewParams);
const url = `${YZ_PREVIEW_URL}?fileVersionId=${fileVersionId}&appId=${YZ_APPId}&sign=${previewSign}&htmlTitle=${name}`
const a = document.createElement('a');
document.body.appendChild(a);
a.setAttribute('href', url);
a.setAttribute('target', '_blank');
a.click();
document.body.removeChild(a)
}
}
}
// function previewingSet(){
// return new Promise(async (resolve) => {
// setShowPreviewModal(true);
// setPreviewing(true);
// setPreviewStatus('UPLOAD');
// resolve(true);
// })
// }
function cancelPreview(){
setShowPreviewModal(false);
// setPreviewing(false);
previewing = false;
setPreviewStatus('UPLOAD');
} }
...@@ -101,7 +167,7 @@ function VideoCourseDetail(){ ...@@ -101,7 +167,7 @@ function VideoCourseDetail(){
<div className="course-detail"> <div className="course-detail">
<div className='course-detail__img'> <div className='course-detail__img'>
{/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */} {/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */}
<img src={coverUrl || `https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png`} alt='' /> <img src={coverUrl || `https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png`} alt='' />
</div> </div>
<div className="course-detail__info"> <div className="course-detail__info">
<div className="info__title">{courseName}</div> <div className="info__title">{courseName}</div>
...@@ -116,9 +182,9 @@ function VideoCourseDetail(){ ...@@ -116,9 +182,9 @@ function VideoCourseDetail(){
<If condition={courseChapterList.length > 0}> <If condition={courseChapterList.length > 0}>
{ {
underscore.map(courseChapterList,(item: any,index: number) => { underscore.map(courseChapterList,(item: any,index: number) => {
return <div className='course-ware' onClick={()=>{handleScanFileModal("MP4",item)}} key={index}> return <div className='course-ware' onClick={()=>{handleScanFileModal(item.mediaType,item)}} key={index}>
<div className="course-ware__index">{index < 9 ? `0${index + 1 } ` : index + 1}</div> <div className="course-ware__index">{index < 9 ? `0${index + 1 } ` : index + 1}</div>
<img className='course-ware__img' src='https://image.xiaomaiketang.com/xm/TKwbQGYDBR.png' alt='' /> <img className='course-ware__img' src={FileTypeIconMap[item.mediaType]} alt='' />
<div className='course-ware__name'>{item.name}</div> <div className='course-ware__name'>{item.name}</div>
</div> </div>
}) })
...@@ -127,6 +193,9 @@ function VideoCourseDetail(){ ...@@ -127,6 +193,9 @@ function VideoCourseDetail(){
</div> </div>
</div> </div>
</div> </div>
{ showPreviewModal &&
<PreviewFileModal onCancel={()=>cancelPreview()} previewStatus={previewStatus} url={url}/>
}
{scanFileModal} {scanFileModal}
</div> </div>
} }
......
...@@ -12,7 +12,9 @@ function ChapterList(props){ ...@@ -12,7 +12,9 @@ function ChapterList(props){
<div className='course-ware__index'>{index < 9 ? `0${index + 1 } ` : `${index + 1 } `}</div> <div className='course-ware__index'>{index < 9 ? `0${index + 1 } ` : `${index + 1 } `}</div>
<div className="course-ware__detail"> <div className="course-ware__detail">
<div className='course-ware__detail__name'>{item.mediaName}</div> <div className='course-ware__detail__name'>{item.mediaName}</div>
{ item.mediaType === 'VIDEO' &&
<div className='course-ware__detail__duration'>{window.formatDuration(item.videoDuration)}</div> <div className='course-ware__detail__duration'>{window.formatDuration(item.videoDuration)}</div>
}
</div> </div>
</div> </div>
}) })
......
...@@ -2,6 +2,7 @@ import User from "@/common/js/user"; ...@@ -2,6 +2,7 @@ import User from "@/common/js/user";
import CourseService from "@/domains/course-domain/CourseService"; import CourseService from "@/domains/course-domain/CourseService";
import React from "react"; import React from "react";
import { Modal } from "antd"; import { Modal } from "antd";
import { FileTypeIcon } from '@/common/constants/academic/lessonEnum'
import "./LearningDetailModal.less"; import "./LearningDetailModal.less";
class LearningDetailModal extends React.Component { class LearningDetailModal extends React.Component {
...@@ -58,11 +59,7 @@ class LearningDetailModal extends React.Component { ...@@ -58,11 +59,7 @@ class LearningDetailModal extends React.Component {
<div className="course-ware__index">{`${ <div className="course-ware__index">{`${
index > 9 ? index + 1 : `0${index + 1}` index > 9 ? index + 1 : `0${index + 1}`
} `}</div> } `}</div>
<img <img className='course-ware__img' src={FileTypeIcon[item.mediaType]} alt='' />
className="course-ware__img"
src="https://image.xiaomaiketang.com/xm/TKwbQGYDBR.png"
alt=""
/>
<div className="course-ware__name">{item.courseChapterName && item.courseChapterName.replace('.MP4','')}</div> <div className="course-ware__name">{item.courseChapterName && item.courseChapterName.replace('.MP4','')}</div>
</div> </div>
......
...@@ -65,7 +65,13 @@ class VideoCourseList extends React.Component { ...@@ -65,7 +65,13 @@ class VideoCourseList extends React.Component {
const { coverUrl } = record; const { coverUrl } = record;
return ( return (
<div className='record__item'> <div className='record__item'>
<img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'} alt='封面图' /> <img
className='course-cover'
src={
coverUrl || 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png'
}
alt='封面图'
/>
<Choose> <Choose>
<When condition={record.courseName.length > 25}> <When condition={record.courseName.length > 25}>
<Tooltip title={record.courseName}> <Tooltip title={record.courseName}>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* @Author: zangsuyun * @Author: zangsuyun
* @Date: 2021-03-12 14:49:40 * @Date: 2021-03-12 14:49:40
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-11 16:44:59 * @LastEditTime: 2021-07-13 15:28:04
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
......
...@@ -421,7 +421,7 @@ class AddCourse extends React.Component { ...@@ -421,7 +421,7 @@ class AddCourse extends React.Component {
coverUrl || coverUrl ||
(videoCourseDivision === 'internal' (videoCourseDivision === 'internal'
? `${mediaCourseUrl}?x-oss-process=video/snapshot,t_0,m_fast` ? `${mediaCourseUrl}?x-oss-process=video/snapshot,t_0,m_fast`
: 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png') : 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png')
} }
alt='' alt=''
/> />
......
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-07-05 10:50:30 * @Date: 2021-07-05 10:50:30
* @LastEditors: yuananting * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-06 15:16:47 * @LastEditTime: 2021-07-09 17:36:15
* @Description: 描述一下咯 * @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -13,6 +13,7 @@ import PlanService from '@/domains/plan-domain/planService'; ...@@ -13,6 +13,7 @@ import PlanService from '@/domains/plan-domain/planService';
import User from '@/common/js/user'; import User from '@/common/js/user';
import './UserLearnDetailModal.less'; import './UserLearnDetailModal.less';
import _ from 'underscore'; import _ from 'underscore';
import { FileTypeIcon } from '@/common/constants/academic/lessonEnum'
const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png'; const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
const CourseType = { const CourseType = {
LIVE: { LIVE: {
...@@ -195,7 +196,7 @@ class UserLearnDetailModal extends React.Component { ...@@ -195,7 +196,7 @@ class UserLearnDetailModal extends React.Component {
<span> <span>
{chapterIndex + 1}.{index + 1}&nbsp; {chapterIndex + 1}.{index + 1}&nbsp;
</span> </span>
<img className='chapter-img' src='https://image.xiaomaiketang.com/xm/TKwbQGYDBR.png' /> <img className='chapter-img' src={FileTypeIcon[record.mediaType]} />
<span>{record.name}</span> <span>{record.name}</span>
</div> </div>
); );
......
...@@ -397,7 +397,7 @@ class SelectOperatorModal extends React.Component { ...@@ -397,7 +397,7 @@ class SelectOperatorModal extends React.Component {
const { coverUrl } = record; const { coverUrl } = record;
return ( return (
<div className='course-info'> <div className='course-info'>
<img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'} alt='' /> <img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png'} alt='' />
<div className='course-name'>{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
</div> </div>
); );
......
...@@ -101,7 +101,7 @@ class SelectPrepareFileModal extends React.Component { ...@@ -101,7 +101,7 @@ class SelectPrepareFileModal extends React.Component {
// 获取文件列表 // 获取文件列表
handleFetchFolderList = (params = {}, loadMore = false) => { handleFetchFolderList = (params = {}, loadMore = false) => {
// 根据当前根节点获取文件列表 // 根据当前根节点获取文件列表
const { selectTypeList } = this.props; const { selectTypeList,queryTypeEnum} = this.props;
const { query, folderList, currentRootDisk } = this.state; const { query, folderList, currentRootDisk } = this.state;
const _params = { const _params = {
...query, ...query,
...@@ -114,6 +114,9 @@ class SelectPrepareFileModal extends React.Component { ...@@ -114,6 +114,9 @@ class SelectPrepareFileModal extends React.Component {
if (selectTypeList) { if (selectTypeList) {
_params.folderFileType = selectTypeList _params.folderFileType = selectTypeList
} }
if(queryTypeEnum){
_params.queryTypeEnum = queryTypeEnum
}
Service.Hades(FOLDERLIST_URL_MAP[currentRootDisk.disk], _params).then((res) => { Service.Hades(FOLDERLIST_URL_MAP[currentRootDisk.disk], _params).then((res) => {
const { result = {} } = res; const { result = {} } = res;
......
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 10:59:43 * @Date: 2021-02-22 10:59:43
* @LastEditors: fusanqiasng * @LastEditors: yuananting
* @LastEditTime: 2021-06-15 11:20:48 * @LastEditTime: 2021-07-13 11:54:21
* @Description: 助学工具-侧边课程分类树 * @Description: 助学工具-侧边课程分类树
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -20,7 +20,7 @@ class CourseCategorySiderTree extends Component { ...@@ -20,7 +20,7 @@ class CourseCategorySiderTree extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
selectedKeys: ['QUESTION_INDEX', 'PAPER_INDEX'].includes(props.fromModule) ? [getParameterByName('categoryId') || 'null'] : ['null'], selectedKeys: ['null'],
treeData: props.treeData || [], treeData: props.treeData || [],
autoExpandParent: false, autoExpandParent: false,
}; };
......
import React, { useState, useRef, useEffect, useContext } from 'react'; import React, { useState, useRef, useEffect, useContext } from 'react'
import Breadcrumbs from '@/components/Breadcrumbs'; import Breadcrumbs from "@/components/Breadcrumbs";
import { Form, Alert, Input, Button, InputNumber, DatePicker, Switch, Radio, message, Modal, Tooltip } from 'antd'; import { Form, Alert, Input, Button, InputNumber, DatePicker, Switch, Radio, message, Modal, Tooltip } from 'antd';
import { Route, withRouter } from 'react-router-dom'; import { Route, withRouter } from 'react-router-dom';
import User from '@/common/js/user'; import User from "@/common/js/user";
import moment from 'moment'; import moment from 'moment'
import Service from '@/common/js/service'; import Service from "@/common/js/service";
import _ from 'underscore'; import _ from 'underscore'
import GraphicsEditor from '../../course-manage/components/GraphicsEditor'; import GraphicsEditor from '../../course-manage/components/GraphicsEditor';
import SelectPaperModal from './SelectPaperModal'; import SelectPaperModal from './SelectPaperModal'
import PreviewModal from './PreviewModal'; import PreviewModal from './PreviewModal'
import ShowTips from '@/components/ShowTips'; import ShowTips from "@/components/ShowTips";
import './AddExam.less'; import './AddExam.less';
...@@ -20,7 +20,7 @@ function AddExam(props: any) { ...@@ -20,7 +20,7 @@ function AddExam(props: any) {
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);
const [paperInfo, setPaperInfo] = useState(paperInfoInit); const [paperInfo, setPaperInfo] = useState(paperInfoInit);
const [paperId, setPaperId] = useState(''); const [paperId, setPaperId] = useState('');
const [passRate, setPassRate] = useState(60); //及格线 const [passRate, setPassRate] = useState(60);//及格线
const [examStartTime, setStartTime] = useState(''); const [examStartTime, setStartTime] = useState('');
const [examEndTime, setExamEndTime] = useState(''); const [examEndTime, setExamEndTime] = useState('');
const [examName, setExamName] = useState(''); const [examName, setExamName] = useState('');
...@@ -36,70 +36,91 @@ function AddExam(props: any) { ...@@ -36,70 +36,91 @@ function AddExam(props: any) {
const [getData, setGetData] = useState(false); const [getData, setGetData] = useState(false);
const [preview, setPreview] = useState(false); const [preview, setPreview] = 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 { match } = props;
const [examDuration, setExamDuration] = useState(undefined); const [examDuration, setExamDuration] = useState(undefined);
useEffect(() => { useEffect(() => {
queryExamList();
switch (props.type) { switch (props.type) {
case 'copy': // 考试列表-复制考试进入 case "copy": // 考试列表-复制考试进入
case 'edit': // 考试列表-编辑考试进入 case "edit": // 考试列表-编辑考试进入
queryExamDetail(); queryExamDetail();
break; break;
case 'organizeExam': // 试卷列表-组织考试进入 case "organizeExam": // 试卷列表-组织考试进入
case 'newPaperToAddExam': // 组卷页面-新建保存试卷并组织考试 case "newPaperToAddExam": // 组卷页面-新建保存试卷并组织考试
case 'editPaperToAddExam': // 组卷页面-编辑保存试卷并组织考试 case "editPaperToAddExam": // 组卷页面-编辑保存试卷并组织考试
setGetData(true); setGetData(true);
setPaperInfo(props.paperInfo); setPaperInfo(props.paperInfo);
setExamName(props.paperInfo?.paperName)
break; break;
} }
}, []); }, [])
useEffect(() => { useEffect(() => {
setPaperId(paperInfo.paperId); setPaperId(paperInfo.paperId)
setPassRate(paperInfo.passRate); setPassRate(paperInfo.passRate)
}, [paperInfo.paperId]);
}, [paperInfo.paperId])
useEffect(() => { useEffect(() => {
setPassScore(Math.round((((paperInfo.totalScore || 0) * (passRate || 0)) as any) / 100)); setPassScore(Math.round((paperInfo.totalScore || 0) * (passRate || 0) as any / 100))
setExamTotal(paperInfo.singleChoiceCnt + paperInfo.multiChoiceCnt + paperInfo.judgeCnt + paperInfo.gapFillingCnt + paperInfo.indefiniteChoiceCnt || 0); setExamTotal(paperInfo.singleChoiceCnt + paperInfo.multiChoiceCnt + paperInfo.judgeCnt + paperInfo.gapFillingCnt + paperInfo.indefiniteChoiceCnt || 0)
}, [paperInfo.paperId, passRate]); }, [paperInfo.paperId, passRate])
function disabledDate(current: any) { function disabledDate(current: any) {
// Can not select days before today and today // Can not select days before today and today
return current && current < moment().startOf('day'); return current && current < moment().startOf('day');
} }
function queryExamList() {
let param = {
current: 1,
size: 9999,
order: 'EXAM_START_TIME_DESC',
userId: User.getStoreUserId(),
tenantId: User.getStoreId(),
source: 0,
}
Service.Hades('public/hades/queryExamPageList', param).then(res=> {
console.log(res)
const { result = {} } = res;
setExamList(result.records)
})
}
function queryExamDetail() { function queryExamDetail() {
Service.Hades('public/hades/queryExamDetail', { Service.Hades("public/hades/queryExamDetail", {
examId: match.params.id, examId: match.params.id,
tenantId: User.getStoreId(), tenantId: User.getStoreId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
source: 0, source: 0
}).then((res) => { }).then((res) => {
const { result } = res; const { result } = res
setPaperInfo(result.examPaper); setPaperInfo(result.examPaper)
setPaperId(result.examPaper.paperId); setPaperId(result.examPaper.paperId)
setStartTime(props.type === 'edit' ? result.examStartTime : ''); setStartTime(props.type === 'edit' ? result.examStartTime : '')
setExamEndTime(props.type === 'edit' ? result.examEndTime : ''); setExamEndTime(props.type === 'edit' ? result.examEndTime : '')
setExamName(props.type === 'edit' ? result.examName : `${result.examName}(复制)`); setExamName(props.type === 'edit' ? result.examName : `${result.examName}(复制)`)
setPassRate(result.passRate * 100); setPassRate(result.passRate * 100)
setNeedPhone(result.needPhone); setNeedPhone(result.needPhone)
setExamDesc(result.examDesc); setExamDesc(result.examDesc)
setExamDuration((result.examDuration / 60 / 1000) as any); setExamDuration(result.examDuration / 60 / 1000 as any)
setAnswerAnalysis(result.answerAnalysis); setAnswerAnalysis(result.answerAnalysis)
setNeedOptionDisorder(result.needOptionDisorder); setNeedOptionDisorder(result.needOptionDisorder)
setPassScore(result.passScore); setPassScore(result.passScore)
setResultContent(result.resultContent); setResultContent(result.resultContent)
setResultShow(result.resultShow); setResultShow(result.resultShow)
setGetData(true); setGetData(true)
});
})
} }
function handleSave() { function handleSave() {
if (request.current) { if (request.current) {
return; return
} }
setCheck(true); setCheck(true);
...@@ -122,82 +143,92 @@ function AddExam(props: any) { ...@@ -122,82 +143,92 @@ function AddExam(props: any) {
tenantId: User.getStoreId(), tenantId: User.getStoreId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
source: 0, source: 0,
examId: '', examId: ''
}; }
if (!param.examName) { if (!param.examName) {
message.warning('请输入考试名称'); message.warning('请输入考试名称');
return; return
} }
if (param.examName && param.examName.length > 40) { if (param.examName && param.examName.length > 40) {
message.warning('考试名称最多40字'); message.warning('考试名称最多40字');
return; return
}
if(checkExist(param.examName)) {
message.warning('此考试名称已存在');
return
} }
if (!paperId) { if (!paperId) {
message.warning('请选择试卷'); message.warning('请选择试卷');
return; return
} }
if (!passRate) { if (!passRate) {
message.warning('请输入及格线'); message.warning('请输入及格线');
return; return
} }
if (!examStartTime || !examEndTime) { if (!examStartTime || !examEndTime) {
message.warning('请选择考试起止时间'); message.warning('请选择考试起止时间');
return; return
} }
if (Number(examStartTime) < moment().valueOf()) { if (Number(examStartTime) < moment().valueOf()) {
message.warning('开始时间不能早于现在'); message.warning('开始时间不能早于现在');
return; return
} }
if (!examDuration) { if (!examDuration) {
message.warning('请输入考试时长'); message.warning('请输入考试时长');
return; return
} }
if (examStartTime + (examDuration as any) * 60 * 1000 > examEndTime) { if (examStartTime + (examDuration as any) * 60 * 1000 > examEndTime) {
message.warning('考试时长不得超过考试有效期时长'); message.warning('考试时长不得超过考试有效期时长');
return; return
} }
if (desclen > 1000) { if (desclen > 1000) {
message.warning('内容过长,不能超过1000字'); message.warning('内容过长,不能超过1000字');
return; return
} }
request.current = true; request.current = true;
setTimeout(() => { setTimeout(() => {
request.current = false; request.current = false
}, 2000); }, 2000)
if (props.type === 'edit') { if (props.type === 'edit') {
param.examId = match.params.id; param.examId = match.params.id;
} }
Service.Hades(props.type === 'edit' ? 'public/hades/editExam' : 'public/hades/createExam', param).then((res) => { Service.Hades(props.type === 'edit' ? 'public/hades/editExam' : "public/hades/createExam", param).then((res) => {
message.success(props.type === 'edit' ? '编辑成功' : '创建成功'); message.success(props.type === 'edit' ? '编辑成功' : '创建成功');
switch (props.type) { switch (props.type) {
case 'organizeExam': // 试卷列表-组织考试进入 case "organizeExam": // 试卷列表-组织考试进入
case 'newPaperToAddExam': // 组卷保存组织考试 case "newPaperToAddExam": // 组卷保存组织考试
case 'editPaperToAddExam': case "editPaperToAddExam":
window.RCHistory.push('/examination-manage-index'); window.RCHistory.push("/examination-manage-index")
break; break;
case 'add': case "add":
case 'edit': // 考试列表-新建或编辑 case "edit": // 考试列表-新建或编辑
case 'copy': // 考试列表-新建或编辑 case "copy": // 考试列表-新建或编辑
props.freshList(); props.freshList()
props.history.goBack(); props.history.goBack();
break; break;
} }
}); })
} }
function disabledRangeTime(date: any, type: any) { function disabledRangeTime(date: any, type: any) {
if (moment(date).isSame(moment(), 'day')) { if (moment(date).isSame(moment(), 'day')) {
return { return {
disabledHours: () => { disabledHours: () => {
...@@ -218,6 +249,7 @@ function AddExam(props: any) { ...@@ -218,6 +249,7 @@ function AddExam(props: any) {
} }
return minutes; return minutes;
}, },
}; };
} }
return { return {
...@@ -227,25 +259,47 @@ function AddExam(props: any) { ...@@ -227,25 +259,47 @@ function AddExam(props: any) {
}; };
} }
function handleGoBack() { function handleGoBack() {
Modal.confirm({ Modal.confirm({
title: '确定要返回吗?', title: '确定要返回吗?',
content: '返回后,本次编辑的内容将不被保存', content: '返回后,本次编辑的内容将不被保存',
okText: '确认返回', okText: '确认返回',
cancelText: '留在本页', cancelText: '留在本页',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>, icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => { onOk: () => {
window.RCHistory.push('/examination-manage-index'); window.RCHistory.push("/examination-manage-index")
}, }
}); })
} }
// 校验考试名称是否存在
function checkExist(examName: any) {
var result:any = null;
examList.forEach((item:any) => {
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;
};
let title = ''; let title = '';
switch (props.type) { switch (props.type) {
case 'add': case 'add':
case 'organizeExam': case "organizeExam":
case 'newPaperToAddExam': case "newPaperToAddExam":
case 'editPaperToAddExam': case "editPaperToAddExam":
title = '新建考试'; title = '新建考试';
break; break;
case 'edit': case 'edit':
...@@ -257,249 +311,213 @@ function AddExam(props: any) { ...@@ -257,249 +311,213 @@ function AddExam(props: any) {
default: default:
break; break;
} }
return ( return <div className="page examPage">
<div className='page examPage'>
<Breadcrumbs navList={title} goBack={handleGoBack} /> <Breadcrumbs navList={title} goBack={handleGoBack} />
<div className='box'> <div className="box">
<div className='show-tips'> <div className="show-tips">
<ShowTips message='请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利' /> <ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利" />
</div>{' '} </div> <div className="form">
<div className='form'> <div className="title">基本信息</div>
<div className='title'>基本信息</div> <Form
<Form labelCol={{ span: 3 }} wrapperCol={{ span: 14 }} layout='horizontal'> labelCol={{ span: 3 }}
<Form.Item wrapperCol={{ span: 14 }}
label='考试名称' layout="horizontal"
validateStatus={check && (!examName ? '请输入考试名称' : examName.length > 40 && '考试名称最多40字') ? 'error' : ''} >
help={check && (!examName ? '请输入考试名称' : examName.length > 40 && '考试名称最多40字')} <Form.Item label="考试名称"
validateStatus={(check && (!examName || (examName.length > 40 || checkExist(examName)) )) ? 'error' : ''}
help={check && (!examName ? '请输入考试名称' : (examName.length > 40 ? '考试名称最多40字' : (checkExist(examName) && '此考试名称已存在')))}
required> required>
<Input
placeholder='请输入考试名称(40字以内)' <Input placeholder='请输入考试名称(40字以内)' maxLength={40} value={examName} onChange={(e) => {
maxLength={40} setExamName(e.target.value)
value={examName} }} style={{ width: 320 }} />
onChange={(e) => {
setExamName(e.target.value);
}}
style={{ width: 320 }}
/>
</Form.Item> </Form.Item>
<Form.Item label='选择试卷' validateStatus={check && !paperId ? 'error' : ''} help={check && !paperId && '请选择试卷'} required> <Form.Item label="选择试卷"
<Button validateStatus={(check && !paperId) ? 'error' : ''}
onClick={() => { help={check && !paperId && '请选择试卷'}
setShowModal(true); required>
}}> <Button onClick={() => { setShowModal(true) }} >{paperInfo.paperId ? '重新选择' : '选择试卷'}</Button>
{paperInfo.paperId ? '重新选择' : '选择试卷'}
</Button> {
paperInfo.paperId && <div className="paperTitle"><img src="https://image.xiaomaiketang.com/xm/pY5imEhjzw.png" alt="" /> {paperInfo.paperName}</div>
{paperInfo.paperId && ( }
<div className='paperTitle'>
<img src='https://image.xiaomaiketang.com/xm/pY5imEhjzw.png' alt='' /> {paperInfo.paperName}
</div>
)} {
paperInfo.paperId && <div className="table">
{paperInfo.paperId && ( <div className="header">
<div className='table'> <div className="item">单选题</div>
<div className='header'> <div className="item">多选题</div>
<div className='item'>单选题</div> <div className="item">判断题</div>
<div className='item'>多选题</div> <div className="item">填空题</div>
<div className='item'>判断题</div> <div className="item long">不定项选择题</div>
<div className='item'>填空题</div> <div className="item">合计</div>
<div className='item long'>不定项选择题</div>
<div className='item'>合计</div>
</div> </div>
<div className='body-list'> <div className="body-list">
<div className='item'>{paperInfo.singleChoiceCnt || 0}</div> <div className="item">{paperInfo.singleChoiceCnt || 0}</div>
<div className='item'>{paperInfo.multiChoiceCnt || 0}</div> <div className="item">{paperInfo.multiChoiceCnt || 0}</div>
<div className='item'>{paperInfo.judgeCnt || 0}</div> <div className="item">{paperInfo.judgeCnt || 0}</div>
<div className='item'>{paperInfo.gapFillingCnt || 0}</div> <div className="item">{paperInfo.gapFillingCnt || 0}</div>
<div className='item long'>{paperInfo.indefiniteChoiceCnt || 0}</div> <div className="item long">{paperInfo.indefiniteChoiceCnt || 0}</div>
<div className='item'>{examTotal}</div> <div className="item">{examTotal}</div>
</div> </div>
<div className='body-list'> <div className="body-list">
<div className='item'>{paperInfo.singleChoiceScore || 0}</div> <div className="item">{paperInfo.singleChoiceScore || 0}</div>
<div className='item'>{paperInfo.multiChoiceScore || 0}</div> <div className="item">{paperInfo.multiChoiceScore || 0}</div>
<div className='item'>{paperInfo.judgeScore || 0}</div> <div className="item">{paperInfo.judgeScore || 0}</div>
<div className='item'>{paperInfo.gapFillingScore || 0}</div> <div className="item">{paperInfo.gapFillingScore || 0}</div>
<div className='item long'>{paperInfo.indefiniteChoiceScore || 0}</div> <div className="item long">{paperInfo.indefiniteChoiceScore || 0}</div>
<div className='item'>{paperInfo.totalScore || 0}</div> <div className="item">{paperInfo.totalScore || 0}</div>
</div> </div>
</div> </div>
)} }
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={ label={<div>
<div>
<span>及格线</span> <span>及格线</span>
<Tooltip title='默认为选中试卷所设置的及格线,可修改'> <Tooltip title="默认为选中试卷所设置的及格线,可修改">
<span className='icon iconfont' style={{ color: '#BFBFBF', marginLeft: 4 }}> <span className="icon iconfont" style={{ color: '#BFBFBF', marginLeft: 4 }}>&#xe61d;</span>
&#xe61d;
</span>
</Tooltip> </Tooltip>
</div> </div>}
}
style={{ marginTop: 24 }} style={{ marginTop: 24 }}
validateStatus={check && !passRate ? 'error' : ''} validateStatus={(check && !passRate) ? 'error' : ''}
help={check && !passRate && '请输入及格线'} help={check && !passRate && '请输入及格线'}
required> required
<InputNumber >
value={passRate} <InputNumber value={passRate} min={0} max={100} onChange={(value: any) => { setPassRate(parseInt(value)) }} style={{ width: 100 }} />
min={0} <span style={{ marginLeft: 4 }}>%
max={100}
onChange={(value: any) => {
setPassRate(parseInt(value));
}}
style={{ width: 100 }}
/>
<span style={{ marginLeft: 4 }}>%</span>
<span style={{ marginLeft: 16, color: '#999' }}>
{` 总分(${paperInfo.totalScore || 0})*及格线(${passRate || 0}%)=及格分数(${passScore})`}
</span> </span>
<span style={{ marginLeft: 16, color: "#999" }}>
{` 总分(${paperInfo.totalScore || 0})*及格线(${passRate || 0}%)=及格分数(${passScore})`}</span>
</Form.Item> </Form.Item>
<Form.Item <Form.Item label="考试有效期"
label='考试有效期' validateStatus={(check && !examStartTime) ? 'error' : ''}
validateStatus={check && !examStartTime ? 'error' : ''}
help={check && !examStartTime && '请选择考试起止时间'} help={check && !examStartTime && '请选择考试起止时间'}
required> required>
<RangePicker <RangePicker
style={{ width: 320 }} style={{ width: 320 }}
showTime={{ defaultValue: [moment().add(5, 'minutes'), moment().add(5, 'minutes')] }} showTime={{ defaultValue: [moment().add(5, 'minutes'), moment().add(5, 'minutes')] }}
ranges={{ ranges={{
近七天: [moment().add(5, 'minute'), moment().add(6, 'day').endOf('day')], '近七天': [moment().add(5, 'minute'), moment().add(6, 'day').endOf('day')],
1个月: [moment().add(5, 'minute'), moment().add(1, 'month').endOf('day')], '近1个月': [moment().add(5, 'minute'), moment().add(1, 'month').endOf('day')],
3个月: [moment().add(5, 'minute'), moment().add(3, 'month').endOf('day')], '近3个月': [moment().add(5, 'minute'), moment().add(3, 'month').endOf('day')],
}} }}
disabledDate={disabledDate} disabledDate={disabledDate}
value={[examStartTime ? moment(Number(examStartTime)) : null, examEndTime ? moment(Number(examEndTime)) : null]} value={[
examStartTime ? moment(Number(examStartTime)) : null,
examEndTime ? moment(Number(examEndTime)) : null
]}
disabledTime={disabledRangeTime} disabledTime={disabledRangeTime}
format='YYYY/MM/DD HH:mm' format="YYYY/MM/DD HH:mm"
onChange={(date: any) => { onChange={(date: any) => {
setStartTime(date && date[0]?.valueOf()); setStartTime(date && date[0]?.valueOf());
setExamEndTime(date && date[1]?.valueOf()); setExamEndTime(date && date[1]?.valueOf());
}} }}
/> />
</Form.Item> </Form.Item>
<Form.Item label='考试时长' validateStatus={check && !examDuration ? 'error' : ''} help={check && !examDuration && '请输入考试时长'} required> <Form.Item label="考试时长"
<InputNumber validateStatus={(check && !examDuration) ? 'error' : ''}
value={examDuration} help={check && !examDuration && '请输入考试时长'}
max={1440} required>
min={1} <InputNumber value={examDuration} max={1440} min={1} onChange={(value: any) => { setExamDuration(parseInt(value) as any) }} style={{ width: 100 }} />
onChange={(value: any) => { <span style={{ marginLeft: 4 }}>分钟
setExamDuration(parseInt(value) as any); </span>
}} <span style={{ marginLeft: 16, color: "#999" }}>
style={{ width: 100 }} {` 时长不能超过1440分钟(24小时)`}</span>
/>
<span style={{ marginLeft: 4 }}>分钟</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="考试说明"
{(getData || props.type === 'add') && ( validateStatus={(check && (desclen > 1000)) ? 'error' : ''}
<GraphicsEditor help={check && (desclen > 1000) && '最多只能输入1000个字'}
>
{
(getData || (props.type === 'add')) && <GraphicsEditor
maxLimit={1000} maxLimit={1000}
isIntro={true} isIntro={true}
detail={{ detail={{
content: examDesc, content: examDesc
}}
onChange={(val: any, len: any) => {
setExamDesc(val);
setDescLen(len);
}} }}
onChange={(val: any, len: any) => { setExamDesc(val); setDescLen(len) }}
/> />
)} }
</Form.Item> </Form.Item>
<div className='title' style={{ marginTop: 40 }}> <div className="title" style={{ marginTop: 40 }}>考试设置</div>
考试设置 <Form.Item label="身份验证" required>
</div> <div style={{ display: 'flex', marginLeft: 4, }}>
<Form.Item label='身份验证' required> <Switch style={{ position: 'relative', top: 6 }}
<div style={{ display: 'flex', marginLeft: 4 }}>
<Switch
checked={needPhone == 'NEED_PHONE_VERIFY'} checked={needPhone == 'NEED_PHONE_VERIFY'}
onChange={(val) => { onChange={(val) => { setNeedPhone(val ? 'NEED_PHONE_VERIFY' : 'DO_NOT_NEED_PHONE_VERIFY') }}
setNeedPhone(val ? 'NEED_PHONE_VERIFY' : 'DO_NOT_NEED_PHONE_VERIFY'); ></Switch>
}}></Switch> <div style={{ position: 'relative', top: 3, left: 8, color: "#999" }}><p>开启:需要绑定手机号的学员才能参加考试</p>
<div style={{ position: 'relative', left: 8, color: '#999' }}> <p>关闭:微信/企业微信登陆直接参加考试</p></div>
{needPhone == 'NEED_PHONE_VERIFY' ? '已开启,学员需绑定手机号才可参与考试' : '已关闭,学员无需绑定手机号即可参与考试'}
</div>
</div> </div>
</Form.Item> </Form.Item>
<Form.Item label='选项乱序' required> <Form.Item label="选项乱序" required>
<div style={{ display: 'flex', marginLeft: 4 }}> <div style={{ display: 'flex', marginLeft: 4, }}>
<Switch <Switch style={{ position: 'relative', top: 6 }}
checked={needOptionDisorder == 'OPTION_RANDOM'} checked={needOptionDisorder == 'OPTION_RANDOM'}
onChange={(val) => { onChange={(val) => { setNeedOptionDisorder(val ? 'OPTION_RANDOM' : 'OPTION_SORT') }}
setNeedOptionDisorder(val ? 'OPTION_RANDOM' : 'OPTION_SORT'); ></Switch>
}}></Switch> <div style={{ position: 'relative', top: 3, left: 8, color: "#999" }}><p>开启:选择题的选项随机排序</p>
<div style={{ position: 'relative', left: 8, color: '#999' }}> <p>关闭:选择题按题目原有顺序展示</p></div>
{needOptionDisorder == 'OPTION_RANDOM' ? '已开启,选项随机排序' : '已关闭,选项按设置顺序排序'}
</div>
</div> </div>
</Form.Item> </Form.Item>
<Form.Item label='考试结果查看' required> <Form.Item label="考试结果查看" required>
<Radio.Group <Radio.Group onChange={(e: any) => { setResultShow(e.target.value) }} value={resultShow}>
onChange={(e: any) => {
setResultShow(e.target.value);
}}
value={resultShow}>
<Radio value={'IMMEDIATELY'}>交卷后立即显示考试结果</Radio> <Radio value={'IMMEDIATELY'}>交卷后立即显示考试结果</Radio>
<Radio value={'AFTER_EXAM_END'}>到达考试截止日期才显示结果</Radio> <Radio value={'AFTER_EXAM_END'}>到达考试截止日期才显示结果</Radio>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>
<Form.Item label=' 考试结果内容' required> <Form.Item label=" 考试结果内容" required>
<Radio.Group <Radio.Group onChange={(e: any) => { setResultContent(e.target.value) }} value={resultContent}>
onChange={(e: any) => {
setResultContent(e.target.value);
}}
value={resultContent}>
<Radio value={'PASS_AND_SCORE'}>显示考试分数和是否及格</Radio> <Radio value={'PASS_AND_SCORE'}>显示考试分数和是否及格</Radio>
<Radio value={'ONLY_SCORE'}>仅显示考试分数</Radio> <Radio value={'ONLY_SCORE'}>仅显示考试分数</Radio>
<Radio value={'ONLY_PASS'}>仅显示是否及格</Radio> <Radio value={'ONLY_PASS'}>仅显示是否及格</Radio>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>
<Form.Item label='答案与解析' required> <Form.Item label="答案与解析" required>
<Radio.Group <Radio.Group onChange={(e: any) => { setAnswerAnalysis(e.target.value) }} value={answerAnalysis}>
onChange={(e: any) => {
setAnswerAnalysis(e.target.value);
}}
value={answerAnalysis}>
<Radio value={'ANALYSE_AND_RIGHT_OR_WRONG'}>显示对错与解析</Radio> <Radio value={'ANALYSE_AND_RIGHT_OR_WRONG'}>显示对错与解析</Radio>
<Radio value={'RIGHT_OR_WRONG'}>仅显示对错</Radio> <Radio value={'RIGHT_OR_WRONG'}>仅显示对错</Radio>
<Radio value={'CAN_NOT_CHECK'}>都不显示</Radio> <Radio value={'CAN_NOT_CHECK'}>都不显示</Radio>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>
</Form> </Form>
</div> </div>
</div> </div>
{showModal && ( {
<SelectPaperModal showModal && <SelectPaperModal onSelect={(info: any) => {
onSelect={(info: any) => { setPaperInfo(info)
setPaperInfo(info); }} paperInfo={paperInfo} close={() => { setShowModal(false) }}></SelectPaperModal>
}} }
paperInfo={paperInfo} <div className="footer shrink-footer">
close={() => {
setShowModal(false);
}}></SelectPaperModal>
)}
<div className='footer shrink-footer'>
<Button onClick={handleGoBack}>取消</Button> <Button onClick={handleGoBack}>取消</Button>
<Button <Button onClick={() => { setPreview(true) }}>预览</Button>
onClick={() => { <Button type="primary" onClick={handleSave}>保存</Button>
setPreview(true);
}}>
预览
</Button>
<Button type='primary' onClick={handleSave}>
保存
</Button>
</div> </div>
{preview && ( {
<PreviewModal preview && <PreviewModal
info={{ info={{
paperId, paperId,
startTime: examStartTime, startTime: examStartTime,
...@@ -517,14 +535,12 @@ function AddExam(props: any) { ...@@ -517,14 +535,12 @@ function AddExam(props: any) {
examDuration, examDuration,
passScore, passScore,
examTotal, examTotal,
totalScore: paperInfo.totalScore, totalScore: paperInfo.totalScore
}} }}
onClose={() => { onClose={() => { setPreview(false) }}></PreviewModal>
setPreview(false); }
}}></PreviewModal>
)}
</div> </div>
);
} }
export default withRouter(AddExam); export default withRouter(AddExam);
\ No newline at end of file
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-03-27 16:15:13 * @Date: 2021-03-27 16:15:13
* @LastEditors: fusanqiasng * @LastEditors: yuananting
* @LastEditTime: 2021-07-01 16:30:38 * @LastEditTime: 2021-07-13 12:01:37
* @Description: 助学工具-新建/复制/编辑试卷 * @Description: 助学工具-新建/复制/编辑试卷
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -118,7 +118,7 @@ class OperatePaper extends Component { ...@@ -118,7 +118,7 @@ class OperatePaper extends Component {
portionScore: 0, portionScore: 0,
totalQuestion: 0, totalQuestion: 0,
}, },
] ],
}; };
} }
...@@ -352,20 +352,6 @@ class OperatePaper extends Component { ...@@ -352,20 +352,6 @@ class OperatePaper extends Component {
return result; return result;
}; };
validatePaperName = (paperName) => {
if (this.state.check && !paperName) {
return '请输入试卷名称';
}
if (this.checkExist(paperName)) {
return '该试卷名称已存在';
}
if (paperName && paperName.length > 40) {
return '试卷名称最多40字';
}
};
// 保存试卷 // 保存试卷
savePaper = (saveType) => { savePaper = (saveType) => {
this.setState({ check: true }); this.setState({ check: true });
...@@ -373,8 +359,17 @@ class OperatePaper extends Component { ...@@ -373,8 +359,17 @@ class OperatePaper extends Component {
const categoryId = getParameterByName('categoryId'); const categoryId = getParameterByName('categoryId');
const { match } = this.props; const { match } = this.props;
let questionList = []; let questionList = [];
if (!formData.passRate || !formData.paperName || this.checkExist(formData.paperName) || (formData.paperName && formData.paperName.length > 40)) { if(!formData.paperName) {
return; return message.warning('请输入试卷名称')
}
if(formData.paperName.length > 40) {
return message.warning('试卷名称最多40字')
}
if (this.checkExist(formData.paperName)) {
return message.warning('该试卷名称已存在')
}
if(!formData.passRate) {
return message.warning('请输入及格线')
} }
if (selectQuestionList.length === 0) { if (selectQuestionList.length === 0) {
return message.warning('请选择题目'); return message.warning('请选择题目');
...@@ -410,18 +405,14 @@ class OperatePaper extends Component { ...@@ -410,18 +405,14 @@ class OperatePaper extends Component {
}); });
} else { } else {
message.success(currentOperate === 'new' ? '新建成功' : '复制成功'); message.success(currentOperate === 'new' ? '新建成功' : '复制成功');
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/paper-manage-index?categoryId=${categoryId}`,
});
Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length); Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length);
Bus.trigger('queryCategoryTree', 'remain'); Bus.trigger('queryCategoryTree', 'remain');
} }
} }
}) })
.catch((e) => { .catch((e) => {
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/paper-manage-index?categoryId=${categoryId}`,
});
Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length); Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length);
Bus.trigger('queryCategoryTree', 'remain'); Bus.trigger('queryCategoryTree', 'remain');
}); });
...@@ -438,17 +429,13 @@ class OperatePaper extends Component { ...@@ -438,17 +429,13 @@ class OperatePaper extends Component {
}); });
} else { } else {
message.success('编辑成功'); message.success('编辑成功');
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/paper-manage-index?categoryId=${categoryId}`,
});
Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length); Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length);
} }
} }
}) })
.catch((e) => { .catch((e) => {
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/paper-manage-index?categoryId=${categoryId}`,
});
Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length); Bus.trigger('queryPaperPageList', categoryId, selectQuestionList.length);
}); });
} }
...@@ -482,9 +469,7 @@ class OperatePaper extends Component { ...@@ -482,9 +469,7 @@ class OperatePaper extends Component {
cancelText: '留在本页', cancelText: '留在本页',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>, icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => { onOk: () => {
window.RCHistory.push({ window.RCHistory.goBack()
pathname: `/paper-manage-index?categoryId=${getParameterByName('categoryId')}`,
});
Bus.trigger('queryCategoryTree', 'remain'); Bus.trigger('queryCategoryTree', 'remain');
Bus.trigger('queryPaperPageList', getParameterByName('categoryId'), 0); Bus.trigger('queryPaperPageList', getParameterByName('categoryId'), 0);
}, },
...@@ -822,8 +807,8 @@ class OperatePaper extends Component { ...@@ -822,8 +807,8 @@ class OperatePaper extends Component {
name='paperName' name='paperName'
label='试卷名称:' label='试卷名称:'
required required
validateStatus={this.validatePaperName(paperName) ? 'error' : ''} validateStatus={(check && (!paperName || paperName.length > 40 || this.checkExist(paperName))) ? 'error' : ''}
help={this.validatePaperName(paperName)}> help={check && (!paperName ? '请输入试卷名称' : (paperName.length > 40 ? '试卷名称最多40字' : (this.checkExist(paperName) && '该试卷名称已存在')))}>
<Input <Input
value={paperName} value={paperName}
autoComplete='off' autoComplete='off'
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 11:23:47 * @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-06-03 17:13:30 * @LastEditTime: 2021-07-13 15:16:52
* @Description: 助学工具-题库-试卷列表数据 * @Description: 助学工具-题库-试卷列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -362,9 +362,9 @@ class PaperList extends Component { ...@@ -362,9 +362,9 @@ class PaperList extends Component {
{isPermiss && ( {isPermiss && (
<div <div
className="record-operate__item" className="record-operate__item"
onClick={() => this.copyPaper(record)} onClick={() => this.organizeExam(record)}
> >
复制 组织考试
</div> </div>
)} )}
{isPermiss && ( {isPermiss && (
...@@ -391,7 +391,7 @@ class PaperList extends Component { ...@@ -391,7 +391,7 @@ class PaperList extends Component {
<span onClick={() => this.editPaper(item)}>编辑</span> <span onClick={() => this.editPaper(item)}>编辑</span>
</Menu.Item> </Menu.Item>
<Menu.Item key="organizeExam"> <Menu.Item key="organizeExam">
<span onClick={() => this.organizeExam(item)}>组织考试</span> <span onClick={() => this.copyPaper(item)}>复制</span>
</Menu.Item> </Menu.Item>
<Menu.Item key="del"> <Menu.Item key="del">
<span onClick={() => this.confirmDeletePaper(item)}>删除</span> <span onClick={() => this.confirmDeletePaper(item)}>删除</span>
......
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 13:46:35 * @Date: 2021-02-25 13:46:35
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-05-24 11:32:47 * @LastEditTime: 2021-07-13 11:51:56
* @Description: 助学工具-题库-新建/编辑题目 * @Description: 助学工具-题库-新建/编辑题目
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -161,9 +161,7 @@ class OperateQuestion extends Component { ...@@ -161,9 +161,7 @@ class OperateQuestion extends Component {
<span className="icon iconfont default-confirm-icon">&#xe6f4;</span> <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>
), ),
onOk: () => { onOk: () => {
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/question-manage-index?categoryId=${getParameterByName("categoryId")}`,
});
Bus.trigger("queryCategoryTree", "remain"); Bus.trigger("queryCategoryTree", "remain");
Bus.trigger("queryQuestionPageList", getParameterByName("categoryId")); Bus.trigger("queryQuestionPageList", getParameterByName("categoryId"));
}, },
...@@ -248,9 +246,7 @@ class OperateQuestion extends Component { ...@@ -248,9 +246,7 @@ class OperateQuestion extends Component {
this.handleRest(type); this.handleRest(type);
} }
if (next === "close") { if (next === "close") {
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/question-manage-index?categoryId=${categoryId}`,
});
Bus.trigger("queryCategoryTree", "remain") Bus.trigger("queryCategoryTree", "remain")
Bus.trigger("queryQuestionPageList", categoryId) Bus.trigger("queryQuestionPageList", categoryId)
} }
...@@ -271,9 +267,7 @@ class OperateQuestion extends Component { ...@@ -271,9 +267,7 @@ class OperateQuestion extends Component {
this.handleRest(type); this.handleRest(type);
} }
if (next === "close") { if (next === "close") {
window.RCHistory.push({ window.RCHistory.goBack();
pathname: `/question-manage-index?categoryId=${categoryId}`,
});
Bus.trigger("queryCategoryTree", "remain") Bus.trigger("queryCategoryTree", "remain")
Bus.trigger("queryQuestionPageList", categoryId) Bus.trigger("queryQuestionPageList", categoryId)
} }
......
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