From fb43d6d61f0ddd0312b26ddb19f477220a7a3dfb Mon Sep 17 00:00:00 2001 From: wyw <571921741@qq.com> Date: Fri, 6 Mar 2026 17:29:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=B9=E8=AE=AD=E7=AD=94=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20=E7=9C=8B=E8=A7=86=E9=A2=91=20=E9=99=84=E4=BB=B6=20?= =?UTF-8?q?=E6=8C=89=E8=AF=BE=E4=BB=B6=EF=BC=88=E9=99=84=E4=BB=B6=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=EF=BC=89=E7=AD=94=E9=A2=98=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=A0=E8=A7=86=E9=A2=91=E8=B7=AF=E5=BE=84=20=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E6=96=B9=E6=B3=95=20=E6=A0=B9=E6=8D=AE=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=20=E7=BB=84=E8=A3=85=20=E9=99=84=E4=BB=B6=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomPages/SE/SE018PaperPage.js | 273 +++++++++++++----- src/config.js | 3 + src/utils/common.js | 16 + 3 files changed, 217 insertions(+), 75 deletions(-) diff --git a/src/components/CustomPages/SE/SE018PaperPage.js b/src/components/CustomPages/SE/SE018PaperPage.js index 7ef89e6..8811f65 100644 --- a/src/components/CustomPages/SE/SE018PaperPage.js +++ b/src/components/CustomPages/SE/SE018PaperPage.js @@ -1,20 +1,20 @@ import { message } from "antd/lib/index"; import { Button, Popconfirm, Row, Col, Checkbox, Radio, Form, Input, Select, Table, Upload, Icon, PageHeader, Modal, Spin } from 'antd'; import React from 'react'; -import { initFilter, extendRule, extendInclude, setDataFieldValue, guid, initQueryFilter } from "../../../utils/common"; +import { initFilter, extendRule, extendInclude, setDataFieldValue, guid, initQueryFilter, showFiles, getFileShow } from "../../../utils/common"; import ReactToPrint from "react-to-print"; import styles from '../../CustomPages/HI/StepForm.css'; import SEstyles from './SE.css'; import XLSX from 'xlsx'; import { connect } from 'dva'; import moment from 'moment'; +import configc from "../../../config.js"; const Option = Select.Option; const answer = { color: 'blue', } - class SE018PaperPage extends React.Component { constructor(props) { super(props); @@ -22,6 +22,9 @@ class SE018PaperPage extends React.Component { if ((this.props.formParam && this.props.formParam.viewAll) || this.props.data.tableKey == undefined) { viewAll = true; } + this.player = null; + this.videoRef = React.createRef(); + this.lastTimeRef = React.createRef(0); this.state = { papers: [], viewAll, @@ -35,15 +38,43 @@ class SE018PaperPage extends React.Component { END_TIME: null, readonly: true, loading: false, + isCourEdit: false, //是否 有课件的考试 + isViedo: false, + isVideoEnd: true, + filepath: '', + filepathf: [], + btnText: '提交问卷', //'下一题' + perPaper: [], //每次的答题 wyw 20260306 + listPath: [], + indexCour: -1 //课件 }; }; componentDidMount() { + this.videoRef?.current?.addEventListener('timeupdate', this.handleTimeUpdate); if (window.navigator.userAgent.indexOf("Windows") < 1) { this.setState({ isMobile: true }) } if (this.props.data?.id) this.loadData(this.props.data?.id); } + componentWillUnmount() { + this.videoRef?.current?.removeEventListener('timeupdate', this.handleTimeUpdate); + + if (this.player) { + this.player.destroy(); + } + } + handleTimeUpdate = (event) => { + const currentTime = event.target.currentTime; + if (currentTime < this.state.lastTime) { + event.target.currentTime = this.state.lastTime; + } else { + this.setState({ + currentTime: currentTime, + lastTime: currentTime, + }); + } + } componentWillReceiveProps(NextProps) { if (this.props.data.USER_ID !== NextProps.data.USER_ID) { @@ -115,7 +146,7 @@ class SE018PaperPage extends React.Component { if (!this.props.data.TaskID) { scort = 'TEXT_ID' } - let json = initFilter(this.props.login.OrgId, '', scort, 1); + let json = initFilter(this.props.login.OrgId, this.props.data.TaskID, scort, 1); json.Parameter22 = this.props.data.ORG_ID_HV; json.OrgType = 2; if (this.props.data.TaskID) { @@ -132,8 +163,6 @@ class SE018PaperPage extends React.Component { extendInclude(json, 'Nav_Record.Nav_Notify.Nav_TrainType'); extendInclude(json, 'Nav_Record.Nav_Notify'); extendInclude(json, 'Nav_Record.Nav_Notify.Nav_TrainContentList.Nav_Point'); - - extendInclude(json, 'Nav_Test'); extendInclude(json, 'Nav_User'); this.state.loading = true; @@ -143,6 +172,16 @@ class SE018PaperPage extends React.Component { url: 'SE/SETrainRecord/GetUserPapers', onComplete: (ret) => { this.state.loading = false; + var isCourEdit = false + if (this.props.data.tableKey == '1' && ret.listPath != null && ret.listPath.length > 0) { + isCourEdit = true //考试 有 课件 + this.state.listPath = ret.listPath + } + if (ret.listPath.length > 1) { + this.state.btnText = '下一题' + } + // this.onSave() + if (ret && ret.Nav_Papers && ret.Nav_Papers.length > 0) { let papers = ret.Nav_Papers.sort((a, b) => { return a.Nav_Test.TYPE - b.Nav_Test.TYPE }); let config = ret.Nav_Config; @@ -155,18 +194,28 @@ class SE018PaperPage extends React.Component { hasAnswered = true; } } + + var perPaper = [] + if (isCourEdit == false) + perPaper = papers //提供显示 this.setState({ papers, + perPaper: perPaper, config, record, notify, readonly: hasAnswered, NAME: NAME, + isCourEdit: isCourEdit, + listPath: this.state.listPath, + btnText: this.state.btnText, }) + if (isCourEdit == true) { + this.onSave() + } } else { message.error('未能成功获取此用户的在线试卷,请稍后重试'); } - } }); } @@ -179,52 +228,105 @@ class SE018PaperPage extends React.Component { if (this.state.readonly) { return; } - let data = JSON.parse(JSON.stringify(this.state.papers)); - for (let i = 0; i < data.length; i++) { - if (data[i].ANSWER == 0) { - message.error(`第${i + 1}题尚未选择答题,请完成所有答题后再进行提交`); - return; - } - if (data[i].Nav_Test.TYPE === 2 && ([0, 1, 2, 4, 8].indexOf(data[i].ANSWER) !== -1)) { - message.error(`第${i + 1}题为多选题,请选择至少两个选项`); - return; - } - } - let saveData = () => { - let data = { - Nav_Config: JSON.parse(JSON.stringify(this.state.config)), - Nav_Papers: JSON.parse(JSON.stringify(this.state.papers)), - TaskID: this.props.data.TaskID, - TEXT_ID: this.props.data.id, - } - this.props.dispatch({ - type: 'app/getDataByPost', - payload: data, - url: 'SE/SETrainRecord/SavePapers', - onComplete: (ret) => { - if (ret && ret.IsOperateSuccessful) { - // message.success('提交成功'); - if (ret.IsPass) { - message.success(ret.Msg) - } else { - message.warn(ret.Msg) - } - } else { - message.error('提交失败,请稍后重试'); - } - this.BtnClose(); + if (this.state.indexCour > -1) { + let data = JSON.parse(JSON.stringify(this.state.perPaper)); + for (let i = 0; i < data.length; i++) { + if (data[i].ANSWER == 0) { + message.error(`第${i + 1}题尚未选择答题,请完成所有答题后再进行提交`); + return; } - }); + if (data[i].Nav_Test.TYPE === 2 && ([0, 1, 2, 4, 8].indexOf(data[i].ANSWER) !== -1)) { + message.error(`第${i + 1}题为多选题,请选择至少两个选项`); + return; + } + } + + var replaceModel = {} + this.state.papers.forEach(e => { + replaceModel = this.state.perPaper.filter(ep => e.ID == ep.ID) + if (replaceModel != null) { + e = replaceModel + } + }) + } + + if (this.state.btnText == "提交问卷" && this.state.indexCour > -1) { + //数据提交 + let saveData = () => { + let data = { + Nav_Config: JSON.parse(JSON.stringify(this.state.config)), + Nav_Papers: JSON.parse(JSON.stringify(this.state.papers)), + TaskID: this.props.data.TaskID, + TEXT_ID: this.props.data.id, + } + this.props.dispatch({ + type: 'app/getDataByPost', + payload: data, + url: 'SE/SETrainRecord/SavePapers', + onComplete: (ret) => { + if (ret && ret.IsOperateSuccessful) { + if (ret.IsPass) { + message.success(ret.Msg) + } else { + message.warn(ret.Msg) + } + } else { + message.error('提交失败,请稍后重试'); + } + this.BtnClose(); + } + }); + } + Modal.confirm({ + title: '提示', + content: '确定要提交当前问卷么?提交之后不可再次更改', + onOk: () => { + saveData(); + }, + onCancel() { + }, + }) + } else { + //下一题 + this.state.indexCour++ + //下一题 + if (this.state.indexCour == this.state.listPath.length - 1) { + this.state.btnText = '提交问卷' //最后一题 + } else { + this.state.btnText = '下一题' + } + this.state.filepath = this.state.listPath[this.state.indexCour] + var perPaper = this.state.papers.filter(e => e.FILE_PATH == this.state.filepath) + + if (this.state.filepath.indexOf('/VIDEO/') > -1) { + this.state.isViedo = true + this.state.isVideoEnd = false + this.state.filepath = configc.videoServerHost + this.state.filepath + this.state.filepathf = [] + } else if (this.state.filepath.indexOf('.mp4') > -1 || this.state.filepath + .indexOf('.avi') > -1) { + //暂时不应该进来 + this.state.isViedo = true + this.state.isVideoEnd = false + this.state.filepath = configc.picServerHost + this.state.filepath + this.state.filepathf = [] + } else { + this.state.isViedo = false + this.state.isVideoEnd = true + this.state.filepath = this.state.filepath + this.state.filepathf = getFileShow(this.state.filepath) + } + + this.setState({ + indexCour: this.state.indexCour, + btnText: this.state.btnText, + perPaper: perPaper, + filepath: this.state.filepath, + isViedo: this.state.isViedo, + isVideoEnd: this.state.isVideoEnd, + filepathf: this.state.filepathf, + }) } - Modal.confirm({ - title: '提示', - content: '确定要提交当前问卷么?提交之后不可再次更改', - onOk: () => { - saveData(); - }, - onCancel() { - }, - }) } fmtEnum(name, value) { const enums = this.props.app.enums; @@ -263,18 +365,18 @@ class SE018PaperPage extends React.Component { return arr; } doOptionChange = (it, index, mask, evt) => { - let papers = this.state.papers; + let perPaper = this.state.perPaper; if (evt.target.checked) { if (it.Nav_Test.TYPE === 2) { - papers[index].ANSWER |= mask; + perPaper[index].ANSWER |= mask; } else { - papers[index].ANSWER = mask; + perPaper[index].ANSWER = mask; } } else { - papers[index].ANSWER = papers[index].ANSWER & (~mask); + perPaper[index].ANSWER = perPaper[index].ANSWER & (~mask); } this.setState({ - papers, + perPaper, }) } returnModel(level) { @@ -354,8 +456,22 @@ class SE018PaperPage extends React.Component { } return ret; } + onEnd = () => { + this.setState({ + isVideoEnd: true + }) + } + TimeUpdate = () => { + const currentTime = this.videoRef.current.currentTime; + if (currentTime > this.lastTimeRef.current + 1) { + this.videoRef.current.currentTime = this.lastTimeRef.current + message.error(`禁止快进`); + } else { + this.lastTimeRef.current = currentTime + } + } render() { - const { record, papers, SelUsrID, UserList, notify } = this.state; + const { record, perPaper, SelUsrID, UserList, notify, btnText, filepath, isViedo, isCourEdit, isVideoEnd, filepathf } = this.state; const SelUsr = SelUsrID && UserList.find(it => it.ID === SelUsrID); return
@@ -391,9 +507,7 @@ class SE018PaperPage extends React.Component { { !this.state.readonly && ( - + ) }
@@ -428,7 +542,6 @@ class SE018PaperPage extends React.Component { 培训形式 {notify ? this.returnModel(notify.TRAIN_MODEL) : null} 考核方式 - {/* {notify && notify.Nav_TrainCheckType ? notify.Nav_TrainCheckType.NAME : null} */} {notify && notify.CHECKTYPE && this.props.app.enums.PlanCheckType.enums[notify.CHECKTYPE]} @@ -447,11 +560,35 @@ class SE018PaperPage extends React.Component { 成绩 {this.CalcScore()} + {/* isViedo, isCourEdit */} + { + isCourEdit && isViedo ? + +
+ { + + } +
+ + : null + } + { + isCourEdit && !isViedo ? + 课件附件 + + { + showFiles(filepathf, configc.picServerHost, this) + } + + : null + } 问卷 { - papers.map((it, idx) => { + isVideoEnd && perPaper.map((it, idx) => { return ( @@ -469,8 +606,6 @@ class SE018PaperPage extends React.Component { it.Nav_Test.TYPE === 0 ? this.doOptionChange(it, idx, 1, evt)} >正确 - {/* this.doOptionChange(it, idx, 1, evt)} /> - 正确 */} : @@ -480,8 +615,6 @@ class SE018PaperPage extends React.Component { : this.doOptionChange(it, idx, 1, evt)} >A.{it.Nav_Test.OPTION_A} } - {/* A.{it.Nav_Test.OPTION_A} - */} } @@ -490,8 +623,6 @@ class SE018PaperPage extends React.Component { it.Nav_Test.TYPE === 0 ? this.doOptionChange(it, idx, 2, evt)} >错误 - {/* this.doOptionChange(it, idx, 2, evt)} /> - 错误 */} : @@ -501,8 +632,6 @@ class SE018PaperPage extends React.Component { : this.doOptionChange(it, idx, 2, evt)} >B.{it.Nav_Test.OPTION_B} } - {/* B.{it.Nav_Test.OPTION_B} - */} } @@ -516,8 +645,6 @@ class SE018PaperPage extends React.Component { : this.doOptionChange(it, idx, 4, evt)} >C.{it.Nav_Test.OPTION_C} } - {/* C. - {it.Nav_Test.OPTION_C} */} } @@ -531,8 +658,6 @@ class SE018PaperPage extends React.Component { : this.doOptionChange(it, idx, 8, evt)} >D.{it.Nav_Test.OPTION_D} } - {/* D. - {it.Nav_Test.OPTION_D} */} } @@ -546,8 +671,6 @@ class SE018PaperPage extends React.Component { : this.doOptionChange(it, idx, 16, evt)} >E.{it.Nav_Test.OPTION_E} } - {/* E. - {it.Nav_Test.OPTION_E} */} } diff --git a/src/config.js b/src/config.js index 6e1ffa8..e1e6fa1 100644 --- a/src/config.js +++ b/src/config.js @@ -26,6 +26,7 @@ const config = { hmiUrl: "http://localhost:8060/", webSocketHost: 'ws://localhost:3140/', picServerHost: 'http://localhost:5199', + videoServerHost: 'https://sps.cxtc.com:3199', dataVUrl: "http://localhost:8062/home", version: version, guideSeverHost: "http://121.41.2.71/jyapk/", @@ -42,6 +43,7 @@ const config = { hmiUrl: "http://124.117.209.78:8098/", webSocketHost: 'ws://124.117.209.78:3140/', picServerHost: 'http://124.117.209.78:5199', + videoServerHost: 'http://124.117.209.78:5199', dataVUrl: "http://124.117.209.78:3167/home", version: version, guideSeverHost: "http://124.117.209.78:5110/jyapk/", @@ -58,6 +60,7 @@ const config = { hmiUrl: "http://121.41.2.71:8098/", webSocketHost: 'ws://121.41.2.71:3140/', picServerHost: 'http://121.41.2.71:5199', + videoServerHost: 'http://121.41.2.71:5199', dataVUrl: "http://121.41.2.71:3167/home", version: version, guideSeverHost: "http://121.41.2.71/jyapk/", diff --git a/src/utils/common.js b/src/utils/common.js index 77dd3a8..dc3384f 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -1535,6 +1535,22 @@ function fileOnClick(file, callBack) { callBack(file) } +//适应 组件 对附件的显示 +export function getFileShow(FILE_PATH, FILE_NAME) { + const result = [] + if (!FILE_NAME) { + var listPath = FILE_PATH.split('/') + FILE_NAME = listPath[listPath.length - 1] + } + result.push({ + Nav_ImgFile: { + FILE_PATH: FILE_PATH, + FILE_NAME: FILE_NAME, + } + }) + return result; + +} //显示附件 export function showFiles(Nav_Files, imgHost, that, isShowNO, maxShow = 50) { var result = []