|
|
@ -25,8 +25,16 @@ |
|
|
|
<span>{{ timeSum.seconds }}</span>秒 |
|
|
|
<span>{{ timeSum.seconds }}</span>秒 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<el-button v-if="per === 0" class="submit" type="danger" @click="reload">重新开始</el-button> |
|
|
|
<template v-if="submited"> |
|
|
|
<el-button class="submit" :loading="submiting" :disabled="submited" @click="confirmSubmit">提交</el-button> |
|
|
|
<div class="score"> |
|
|
|
|
|
|
|
<span>暂得分</span> |
|
|
|
|
|
|
|
<div class="num">{{ score }}分</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<el-button class="btn" @click="toReport">查看成绩报告</el-button> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<el-button v-if="per === 0" class="btn" type="danger" @click="reload">重新开始</el-button> |
|
|
|
|
|
|
|
<el-button class="btn" :loading="submiting" :disabled="submited" @click="confirmSubmit">提交</el-button> |
|
|
|
<img class="exit" src="@/assets/img/exit.svg" alt="" @click="close"> |
|
|
|
<img class="exit" src="@/assets/img/exit.svg" alt="" @click="close"> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -144,6 +152,7 @@ |
|
|
|
import Util from '@/libs/util' |
|
|
|
import Util from '@/libs/util' |
|
|
|
import Setting from "@/setting" |
|
|
|
import Setting from "@/setting" |
|
|
|
import QuesConst from '@/const/ques' |
|
|
|
import QuesConst from '@/const/ques' |
|
|
|
|
|
|
|
import TestPaperConst from '@/const/testPaper' |
|
|
|
import _ from 'lodash' |
|
|
|
import _ from 'lodash' |
|
|
|
import Upload from '@/components/upload' |
|
|
|
import Upload from '@/components/upload' |
|
|
|
import UeditorPlus from '@/components/ueditorPlus' |
|
|
|
import UeditorPlus from '@/components/ueditorPlus' |
|
|
@ -174,7 +183,7 @@ export default { |
|
|
|
curriculumName: this.$route.query.curriculumName, |
|
|
|
curriculumName: this.$route.query.curriculumName, |
|
|
|
assessmentId: this.$route.query.assessmentId, // 考核id |
|
|
|
assessmentId: this.$route.query.assessmentId, // 考核id |
|
|
|
classId: this.$route.query.classId, |
|
|
|
classId: this.$route.query.classId, |
|
|
|
id: +this.$route.query.id, // 赛事id |
|
|
|
competitionId: +this.$route.query.competitionId, // 赛事id |
|
|
|
stageId: +this.$route.query.stageId, |
|
|
|
stageId: +this.$route.query.stageId, |
|
|
|
teamId: this.$route.query.teamId || '', |
|
|
|
teamId: this.$route.query.teamId || '', |
|
|
|
entryTime: '', |
|
|
|
entryTime: '', |
|
|
@ -215,6 +224,8 @@ export default { |
|
|
|
pdfVisible: false, |
|
|
|
pdfVisible: false, |
|
|
|
pdfSrc: '', |
|
|
|
pdfSrc: '', |
|
|
|
client: null, |
|
|
|
client: null, |
|
|
|
|
|
|
|
score: '', |
|
|
|
|
|
|
|
reportId: '', |
|
|
|
}; |
|
|
|
}; |
|
|
|
}, |
|
|
|
}, |
|
|
|
mounted () { |
|
|
|
mounted () { |
|
|
@ -227,7 +238,7 @@ export default { |
|
|
|
this.getCompetition() |
|
|
|
this.getCompetition() |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
this.per = this.id ? 2 : this.assessmentId ? 1 : 0 |
|
|
|
this.per = this.competitionId ? 2 : this.assessmentId ? 1 : 0 |
|
|
|
this.paperId ? this.getPracticePaper() : this.getCompetition(1) |
|
|
|
this.paperId ? this.getPracticePaper() : this.getCompetition(1) |
|
|
|
this.initOss() |
|
|
|
this.initOss() |
|
|
|
}, |
|
|
|
}, |
|
|
@ -235,7 +246,7 @@ export default { |
|
|
|
// 获取竞赛信息 |
|
|
|
// 获取竞赛信息 |
|
|
|
async getCompetition (load) { |
|
|
|
async getCompetition (load) { |
|
|
|
if (load) this.loading = true |
|
|
|
if (load) this.loading = true |
|
|
|
const { competition } = await this.$post(`${this.api.getCompetition}?competitionId=${this.id}`) |
|
|
|
const { competition } = await this.$post(`${this.api.getCompetition}?competitionId=${this.competitionId}`) |
|
|
|
const stages = competition.contentList |
|
|
|
const stages = competition.contentList |
|
|
|
if (stages) { |
|
|
|
if (stages) { |
|
|
|
const stage = stages.find(e => e.stageId === this.stageId) |
|
|
|
const stage = stages.find(e => e.stageId === this.stageId) |
|
|
@ -267,7 +278,7 @@ export default { |
|
|
|
|
|
|
|
|
|
|
|
// 缓存,如果有,则全部回显到页面上 |
|
|
|
// 缓存,如果有,则全部回显到页面上 |
|
|
|
const { examSubmitReq: cache } = await this.$post(this.api.getExamPaperCache, { |
|
|
|
const { examSubmitReq: cache } = await this.$post(this.api.getExamPaperCache, { |
|
|
|
competitionId: this.id, |
|
|
|
competitionId: this.competitionId, |
|
|
|
paperId, |
|
|
|
paperId, |
|
|
|
stageId |
|
|
|
stageId |
|
|
|
}) |
|
|
|
}) |
|
|
@ -296,10 +307,25 @@ export default { |
|
|
|
// 试卷详情 |
|
|
|
// 试卷详情 |
|
|
|
const { examPaper } = await this.$get(this.api.examPaperDetails, { id: paperId }) |
|
|
|
const { examPaper } = await this.$get(this.api.examPaperDetails, { id: paperId }) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 缓存,如果有,则全部回显到页面上 |
|
|
|
|
|
|
|
const { examSubmitReq: cache } = await this.$post(this.api.getTestPaperPracticeCache, { |
|
|
|
|
|
|
|
cid: this.cid, |
|
|
|
|
|
|
|
paperId: this.paperId, |
|
|
|
|
|
|
|
mallId: this.mallId, |
|
|
|
|
|
|
|
isContinueLastPractice: 1 |
|
|
|
|
|
|
|
}) |
|
|
|
const now = await Util.getNow() |
|
|
|
const now = await Util.getNow() |
|
|
|
|
|
|
|
let cacheQues |
|
|
|
|
|
|
|
if (cache) { |
|
|
|
|
|
|
|
this.entryTime = new Date(cache.startTime) |
|
|
|
|
|
|
|
this.timeSumVal = (now - new Date(cache.startTime)) / 1000 |
|
|
|
|
|
|
|
cacheQues = cache.examSubmitJudgeList |
|
|
|
|
|
|
|
} else { |
|
|
|
this.entryTime = now |
|
|
|
this.entryTime = now |
|
|
|
|
|
|
|
} |
|
|
|
this.startCount() |
|
|
|
this.startCount() |
|
|
|
this.handlePaper(examPaper) |
|
|
|
|
|
|
|
|
|
|
|
this.handlePaper(examPaper, cacheQues) |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
} catch (e) { |
|
|
|
this.loading = false |
|
|
|
this.loading = false |
|
|
@ -360,7 +386,7 @@ export default { |
|
|
|
|
|
|
|
|
|
|
|
// 给填空题的每个空监听input事件,用以显示已作答状态 |
|
|
|
// 给填空题的每个空监听input事件,用以显示已作答状态 |
|
|
|
this.$nextTick(() => { |
|
|
|
this.$nextTick(() => { |
|
|
|
if (!cacheQues && this.id) this.submit(0) // 如果没有缓存,则先缓存一次(只是为了缓存进入时间,因为只有在每个小题答题后才会调缓存接口,所以只能第一次进入就缓存一次进入时间) |
|
|
|
if (!cacheQues && this.per !== 1) this.submit(0) // 如果没有缓存,则先缓存一次(只是为了缓存进入时间,因为只有在每个小题答题后才会调缓存接口,所以只能第一次进入就缓存一次进入时间) |
|
|
|
paper.map(e => { |
|
|
|
paper.map(e => { |
|
|
|
e.examQuestions.map(n => { |
|
|
|
e.examQuestions.map(n => { |
|
|
|
if (e.questionType === 'fill_blank') { |
|
|
|
if (e.questionType === 'fill_blank') { |
|
|
@ -401,7 +427,6 @@ export default { |
|
|
|
}, |
|
|
|
}, |
|
|
|
// 计时器 |
|
|
|
// 计时器 |
|
|
|
handleCounter (counterTime, isCount) { |
|
|
|
handleCounter (counterTime, isCount) { |
|
|
|
console.log("🚀 ~ handleCounter ~ counterTime, isCount:", counterTime, isCount) |
|
|
|
|
|
|
|
let leave1 = counterTime % (24 * 3600) //计算天数后剩余的毫秒数 |
|
|
|
let leave1 = counterTime % (24 * 3600) //计算天数后剩余的毫秒数 |
|
|
|
let leave2 = leave1 % 3600 //计算小时数后剩余的毫秒数 |
|
|
|
let leave2 = leave1 % 3600 //计算小时数后剩余的毫秒数 |
|
|
|
let leave3 = leave2 % 60 //计算分钟数后剩余的毫秒数 |
|
|
|
let leave3 = leave2 % 60 //计算分钟数后剩余的毫秒数 |
|
|
@ -445,7 +470,7 @@ export default { |
|
|
|
startCount () { |
|
|
|
startCount () { |
|
|
|
clearInterval(this.counterTimer) |
|
|
|
clearInterval(this.counterTimer) |
|
|
|
this.counterTimer = setInterval(() => { |
|
|
|
this.counterTimer = setInterval(() => { |
|
|
|
this.id && this.counter(this.countVal--) |
|
|
|
this.competitionId && this.counter(this.countVal--) |
|
|
|
this.timeSumVal >= 0 && this.handleCounter(this.timeSumVal++) |
|
|
|
this.timeSumVal >= 0 && this.handleCounter(this.timeSumVal++) |
|
|
|
}, 1000) |
|
|
|
}, 1000) |
|
|
|
}, |
|
|
|
}, |
|
|
@ -634,6 +659,19 @@ export default { |
|
|
|
answerAnalysisReady (editor) { |
|
|
|
answerAnalysisReady (editor) { |
|
|
|
this.answerAnalysis && editor.setContent(this.answerAnalysis) |
|
|
|
this.answerAnalysis && editor.setContent(this.answerAnalysis) |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
// 查看成绩报告 |
|
|
|
|
|
|
|
toReport () { |
|
|
|
|
|
|
|
this.$router.push(`/match/theoryReport?reportId=${this.reportId}`) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
// 清除练习的缓存 |
|
|
|
|
|
|
|
clearPracticeCache () { |
|
|
|
|
|
|
|
this.$post(this.api.getTestPaperPracticeCache, { |
|
|
|
|
|
|
|
cid: this.cid, |
|
|
|
|
|
|
|
paperId: this.paperId, |
|
|
|
|
|
|
|
mallId: this.mallId, |
|
|
|
|
|
|
|
isContinueLastPractice: 0 |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
// 重新开始 |
|
|
|
// 重新开始 |
|
|
|
async reload () { |
|
|
|
async reload () { |
|
|
|
// 已提交状态则直接重新开始,未提交则询问弹框 |
|
|
|
// 已提交状态则直接重新开始,未提交则询问弹框 |
|
|
@ -641,13 +679,14 @@ export default { |
|
|
|
location.reload() |
|
|
|
location.reload() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
try { |
|
|
|
try { |
|
|
|
await this.$confirm('<p style="color: #f56c6c;">点击重新开始,之前操作会清空。</p><p>确定重新开始吗?</p>', '提示', { |
|
|
|
await this.$confirm('重新开始会清除答题记录,确定要继续吗?', '提示', { |
|
|
|
confirmButtonText: '确定', |
|
|
|
confirmButtonText: '确定', |
|
|
|
cancelButtonText: '取消', |
|
|
|
cancelButtonText: '取消', |
|
|
|
type: 'warning', |
|
|
|
type: 'warning', |
|
|
|
closeOnClickModal: false, |
|
|
|
closeOnClickModal: false, |
|
|
|
dangerouslyUseHTMLString: true, |
|
|
|
dangerouslyUseHTMLString: true, |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
await this.clearPracticeCache() |
|
|
|
location.reload() |
|
|
|
location.reload() |
|
|
|
} catch (e) { } |
|
|
|
} catch (e) { } |
|
|
|
} |
|
|
|
} |
|
|
@ -675,11 +714,11 @@ export default { |
|
|
|
}, |
|
|
|
}, |
|
|
|
// 提交 |
|
|
|
// 提交 |
|
|
|
async submit (isSubmit, autoSubmit) { |
|
|
|
async submit (isSubmit, autoSubmit) { |
|
|
|
if ((isSubmit && this.submiting) || (!isSubmit && this.paperId)) return false |
|
|
|
if ((isSubmit && this.submiting) || (!isSubmit && this.per === 1)) return false |
|
|
|
try { |
|
|
|
try { |
|
|
|
if (isSubmit) this.submiting = true |
|
|
|
if (isSubmit) this.submiting = true |
|
|
|
const form = _.cloneDeep(this.form) |
|
|
|
const form = _.cloneDeep(this.form) |
|
|
|
const { entryTime, curStage } = this |
|
|
|
const { entryTime, curStage, per } = this |
|
|
|
const ques = [] |
|
|
|
const ques = [] |
|
|
|
form.paperOutline.map(e => { |
|
|
|
form.paperOutline.map(e => { |
|
|
|
const type = e.questionType |
|
|
|
const type = e.questionType |
|
|
@ -709,7 +748,7 @@ export default { |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const data = { |
|
|
|
const data = { |
|
|
|
competitionId: this.id, |
|
|
|
competitionId: this.competitionId, |
|
|
|
stageId: curStage.stageId, |
|
|
|
stageId: curStage.stageId, |
|
|
|
teamId: this.teamId, |
|
|
|
teamId: this.teamId, |
|
|
|
startTime: Util.formatDate('yyyy-MM-dd hh:mm:ss', entryTime), // 取页面进入的时间 |
|
|
|
startTime: Util.formatDate('yyyy-MM-dd hh:mm:ss', entryTime), // 取页面进入的时间 |
|
|
@ -733,18 +772,26 @@ export default { |
|
|
|
data.assessmentId = this.assessmentId |
|
|
|
data.assessmentId = this.assessmentId |
|
|
|
data.classId = this.classId |
|
|
|
data.classId = this.classId |
|
|
|
} |
|
|
|
} |
|
|
|
// 缓存跟提交接口的参数一样 |
|
|
|
// 缓存跟提交接口的参数一样,(练习、考核、竞赛的提交是不同接口) |
|
|
|
await this.$post(this.api[this.assessmentId ? 'submitTheExamPaperForAssessment' : this.paperId ? 'submitTheExamPaperForPractice' : isSubmit ? 'submitTheExamPaper' : 'examPaperRecordCache'], data) |
|
|
|
const res = await this.$post(this.api[isSubmit ? (per === 1 ? |
|
|
|
|
|
|
|
'submitTheExamPaperForAssessment' : !per ? 'submitTheExamPaperForPractice' : 'submitTheExamPaper') : |
|
|
|
|
|
|
|
(!per ? 'recordTestPaperPracticeCache' : 'examPaperRecordCache')], data) |
|
|
|
|
|
|
|
|
|
|
|
if (isSubmit) { |
|
|
|
if (isSubmit) { |
|
|
|
window.opener && window.opener.location.reload() |
|
|
|
window.opener && window.opener.location.reload() |
|
|
|
clearInterval(this.counterTimer) |
|
|
|
clearInterval(this.counterTimer) |
|
|
|
this.submiting = false |
|
|
|
this.submiting = false |
|
|
|
|
|
|
|
if (res.reportId) { |
|
|
|
|
|
|
|
this.reportId = res.reportId |
|
|
|
|
|
|
|
this.score = res.score |
|
|
|
|
|
|
|
} |
|
|
|
this.submited = true |
|
|
|
this.submited = true |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
per !== 2 && clearPracticeCache() |
|
|
|
|
|
|
|
|
|
|
|
// 如果是时间到了自动提交,则提交完不弹框,直接关闭页面 |
|
|
|
// 如果是时间到了自动提交,则提交完不弹框,直接关闭页面 |
|
|
|
if (autoSubmit) { |
|
|
|
if (autoSubmit) { |
|
|
|
this.$alert(`${this.per == 2 ? '竞赛' : '考核'}时间已到,系统已自动交卷`, '提示', { |
|
|
|
this.$alert(`${per == 2 ? '竞赛' : '考核'}时间已到,系统已自动交卷`, '提示', { |
|
|
|
confirmButtonText: '确定', |
|
|
|
confirmButtonText: '确定', |
|
|
|
type: 'warning', |
|
|
|
type: 'warning', |
|
|
|
callback: _ => { |
|
|
|
callback: _ => { |
|
|
@ -753,7 +800,7 @@ export default { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// 如果是竞赛,并且勾选了公布成绩详情的选项,则弹框提示 |
|
|
|
// 如果是竞赛,并且勾选了公布成绩详情的选项,则弹框提示 |
|
|
|
if (this.id) { |
|
|
|
if (this.competitionId) { |
|
|
|
const time = curStage.resultAnnouncementTime |
|
|
|
const time = curStage.resultAnnouncementTime |
|
|
|
const msg = |
|
|
|
const msg = |
|
|
|
time === 0 ? '提交成功!成绩将在比赛结束后公布,请前往参赛信息模块查看' : time > 0 ? `提交成功!成绩将在比赛结束后${time}小时公布,请前往参赛信息模块查看` : '提交成功'; |
|
|
|
time === 0 ? '提交成功!成绩将在比赛结束后公布,请前往参赛信息模块查看' : time > 0 ? `提交成功!成绩将在比赛结束后${time}小时公布,请前往参赛信息模块查看` : '提交成功'; |
|
|
@ -807,8 +854,25 @@ export default { |
|
|
|
font-weight: 600; |
|
|
|
font-weight: 600; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.submit { |
|
|
|
.score { |
|
|
|
width: 106px; |
|
|
|
margin: 0 30px; |
|
|
|
|
|
|
|
display: inline-flex; |
|
|
|
|
|
|
|
align-items: center; |
|
|
|
|
|
|
|
font-size: 15px; |
|
|
|
|
|
|
|
color: #fff; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.num { |
|
|
|
|
|
|
|
padding: 0 8px; |
|
|
|
|
|
|
|
margin-left: 7px; |
|
|
|
|
|
|
|
color: #f00; |
|
|
|
|
|
|
|
line-height: 2.4; |
|
|
|
|
|
|
|
background-color: #fff; |
|
|
|
|
|
|
|
border-radius: 20px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.btn { |
|
|
|
|
|
|
|
min-width: 106px; |
|
|
|
font-size: 15px; |
|
|
|
font-size: 15px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|