dev_202412
yujialong 8 months ago
parent 3ea12dca58
commit 838a5b9ed7
  1. 8
      src/libs/util.js
  2. 2
      src/pages/match/details/index.vue
  3. 2
      src/pages/match/list/index.vue
  4. 206
      src/pages/match/theoryExam/index.vue

@ -1,10 +1,10 @@
import cookies from "./util.cookies";
import { _local, _session } from "./util.db";
import { Message } from "element-ui";
import store from "@/store";
import axios from "axios";
import api from "@/api";
import Setting from "@/setting";
import store from '@/store'
import axios from 'axios'
import api from '@/api'
import Setting from '@/setting'
let logout = false;
// 文件后缀集合

@ -1645,7 +1645,7 @@ export default {
//
if (method === 1) {
this.$router.push(`theoryExam?id=${form.id}&stageId=${stageId}`)
this.$router.push(`/match/theoryExam?id=${form.id}&stageId=${stageId}&teamId=${teamId}`)
} else {
let token = Util.local.get(Setting.tokenKey);
if (systemId == 11) {

@ -973,7 +973,7 @@ export default {
//
if (method === 1) {
this.$router.push(`theoryExam?id=${form.id}&stageId=${stageId}`)
this.$router.push(`/match/theoryExam?id=${form.id}&stageId=${stageId}&teamId=${teamId}`)
} else {
let token = Util.local.get(Setting.tokenKey)
if (systemId == 11) {

@ -1,5 +1,5 @@
<template>
<div class="index">
<div class="index" v-loading="loading || submiting">
<div class="top">
<div class="item">
<p class="names">{{ curStage.stageName }}{{ curStage.paperName }}</p>
@ -22,7 +22,7 @@
<span>{{ timeSum.seconds }}</span>
</div>
<el-button class="submit" :loading="submiting" @click="confirmSubmit">提交</el-button>
<el-button class="submit" :loading="submiting" :disabled="submited" @click="confirmSubmit">提交</el-button>
<img class="exit" src="@/assets/img/exit.svg" alt="" @click="$router.back()">
</div>
</div>
@ -32,24 +32,29 @@
<h6 class="title">答题卡</h6>
<div class="progress">
<p class="fs-14">答题进度</p>
<el-progress class="m-t-5 m-b-5" :percentage="50"></el-progress>
<el-progress class="m-t-5 m-b-5" :percentage="progress" :format="progressFormat"></el-progress>
<p>{{ form.questionCount }}满分{{ form.score }}</p>
</div>
<div v-if="form.paperOutline" class="type-wrap">
<div v-for="(item, i) in form.paperOutline" :key="i" class="type">
<h6 class="stem">{{ arabicToChinese(i + 1) }}{{ item.questionTypeName }}本题共{{ item.questionNum }}小题{{
item.targetScore }}</h6>
<ul class="serials">
<template v-for="(ques, j) in item.examQuestions">
<li
v-if="!sheetStatus || (sheetStatus === 1 && !ques.answered) || (sheetStatus === 2 && ques.answered) || (sheetStatus === 3 && ques.partAnswer) || (sheetStatus === 4 && ques.sign)"
:key="j" :class="{ answered: ques.answered, partAnswer: ques.partAnswer }">
<img v-if="ques.sign" class="tag" src="@/assets/img/tag-active.svg" alt="">
{{ j + 1 }}
</li>
</template>
</ul>
</div>
<template v-for="(item, i) in form.paperOutline">
<div
v-if="item.examQuestions.length && (!sheetStatus || item.examQuestions.some(e => (sheetStatus === 1 && !e.answered) || (sheetStatus === 2 && e.answered) || (sheetStatus === 3 && e.partAnswer) || (sheetStatus === 4 && e.sign)))"
:key="i" class="type">
<h6 class="stem">{{ arabicToChinese(i + 1) }}{{ item.questionTypeName }}本题共{{ item.questionNum }}小题{{
item.targetScore }}</h6>
<ul class="serials">
<template v-for="(ques, j) in item.examQuestions">
<li
v-if="!sheetStatus || (sheetStatus === 1 && !ques.answered) || (sheetStatus === 2 && ques.answered) || (sheetStatus === 3 && ques.partAnswer) || (sheetStatus === 4 && ques.sign)"
:key="j" :class="{ answered: ques.answered, partAnswer: ques.partAnswer }"
@click="scrollToQues(ques)">
<img v-if="ques.sign" class="tag" src="@/assets/img/tag-active.svg" alt="">
{{ j + 1 }}
</li>
</template>
</ul>
</div>
</template>
</div>
<ul class="status-filter">
<li :class="{ active: sheetStatus === 1 }" @click="filterStatus(1)">未作答</li>
@ -60,7 +65,7 @@
</ul>
</div>
<ul v-if="form.paperOutline" class="ques-wrap">
<ul v-if="form.paperOutline" class="ques-wrap" id="quesWrap">
<li v-for="(item, i) in form.paperOutline" :key="i">
<div class="outline">
{{ arabicToChinese(i + 1) }}{{ item.questionTypeName }}本题共{{ item.questionNum }}小题{{
@ -69,12 +74,14 @@
@click="item.shrink = !item.shrink">
</div>
<div :class="['ques', { hide: item.shrink }]">
<div v-for="(ques, j) in item.examQuestions" :key="j" class="item">
<div v-for="(ques, j) in item.examQuestions" :key="j" class="item" :id="'ques' + ques.id">
<div class="stem-wrap">
<span class="label">{{ j + 1 }} / {{ item.questionNum }}</span>
<span class="label">{{ item.questionTypeName }}</span>
<div :id="'stem' + ques.id" v-html="getQuesStem(ques)"></div>
<p v-if="item.questionType !== 'fill_blank'">{{ ques.score }}</p>
<div class="labels">
<span class="label">{{ j + 1 }} / {{ item.questionNum }}</span>
<span class="label">{{ item.questionTypeName }}</span>
</div>
<div class="stem" :id="'stem' + ques.id" v-html="getQuesStem(ques)"></div>
<p>{{ ques.score }}</p>
<img class="tag" :src="require('@/assets/img/' + (ques.sign ? 'tag-active' : 'tag') + '.svg')" alt=""
@click="ques.sign = ques.sign ? 0 : 1">
</div>
@ -100,11 +107,10 @@
</div>
<UeditorPlus :ref="'essayAnswer' + ques.id" v-model="ques.answer"
@ready="editor => essayAnswerReady(editor, ques)" />
<!-- v-if="ques.allowAttachment" -->
<div class="m-t-20">
<div v-if="form.uploadInstructions" class="flex m-b-10 fs-12">
<div v-if="ques.allowAttachment" class="m-t-20">
<div v-if="ques.uploadInstructions" class="flex m-b-10 fs-12">
<span>上传附件</span>
<div v-html="form.uploadInstructions"></div>
<div v-html="ques.uploadInstructions"></div>
</div>
<Upload style="max-width: 700px;" accept=".csv,.xlsx,.xls,.docx,.doc,.pdf,.jpg,.png,.zip,.rar,.7z"
:max-size="50" :file-list="ques.uploadList" :on-remove="e => handleRemove(ques)"
@ -142,7 +148,7 @@ export default {
},
data () {
return {
routes: [],
loading: false,
per: 2, // (0 1 2)
questionTypes: QuesConst.questionTypes,
numToLetter: Util.numToLetter,
@ -153,12 +159,13 @@ export default {
token: Util.local.get(Setting.tokenKey),
id: +this.$route.query.id, // id
stageId: +this.$route.query.stageId,
teamId: this.$route.query.teamId || '',
entryTime: '',
curStage: {
stageName: '',
paperName: '',
},
counterTimer: null, // setInterval
counterTimer: null,
countVal: 0,
//
counterVal: {
@ -175,16 +182,21 @@ export default {
minutes: 0,
hour: 0,
},
totalAnswered: 0,
progress: 0,
sheetStatus: '',
form: {},
form: {
questionCount: 0,
},
submiting: false,
submited: false,
warned: 0,
};
},
mounted () {
this.$once('hook:beforeDestroy', function () {
clearInterval(this.counterTimer)
this.submiting || this.submit(0)
this.submited || this.submit(0)
})
this.getCompetition()
@ -192,7 +204,7 @@ export default {
methods: {
//
async getCompetition () {
// clearInterval(this.timer)
this.loading = true
const { competition } = await this.$post(`${this.api.getCompetition}?competitionId=${this.id}`)
const stages = competition.contentList
if (stages) {
@ -207,6 +219,7 @@ export default {
const now = await Util.getNow()
//
if (now >= endTime) {
this.loading = false
this.$alert('竞赛时间已到,系统已自动交卷', '提示', {
confirmButtonText: '确定'
})
@ -226,12 +239,11 @@ export default {
const { examPaper } = await this.$get(this.api.examPaperDetails, { id: paperId })
//
const res = await this.$post(this.api.getExamPaperCache, {
const { examSubmitReq: cache } = await this.$post(this.api.getExamPaperCache, {
competitionId: this.id,
paperId,
stageId
})
const cache = res.examSubmitReq
let cacheQues = []
if (cache) {
this.entryTime = new Date(cache.startTime)
@ -253,16 +265,19 @@ export default {
Object.assign(n, n.question)
const curQues = cacheQues.find(m => m.outlineId === e.outlineId && m.questionVersionId === n.questionVersionId) //
n.sign = curQues ? curQues.sign : 0
if (type !== 'fill_blank' && type !== 'essay' && n.questionAnswerVersionsList) { //
n.questionAnswerVersionsList.map(m => {
const opts = n.questionAnswerVersionsList
if (type !== 'fill_blank' && type !== 'essay' && opts) { //
opts.map(m => {
m.answer = curQues && curQues.answer && curQues.answer.length && curQues.answer.some(n => n == m.optionNumber) ? 1 : 0
})
if (n.questionAnswerVersionsList.some(m => m.answer)) n.answered = 1
if (opts.some(m => m.answer)) n.answered = 1
} else if (type === 'fill_blank') { //
n.fills = curQues && curQues.answer && curQues.answer.length ? curQues.answer : ''
if (n.fills) n.answered = 1
} else { //
n.fills = curQues && curQues.answer && curQues.answer.length && curQues.answer.some(m => m) ? curQues.answer : ''
let { answerData } = opts[0]
if (answerData) answerData = JSON.parse(answerData)
n.answered = n.fills && answerData && answerData.length === n.fills.filter(m => m).length ? 1 : 0
n.partAnswer = n.fills && answerData && answerData.length !== n.fills.filter(m => m).length ? 1 : 0
} else if (type === 'essay') { //
n.answer = type === 'essay' && curQues ? curQues.answerContent : ''
n.attachmentName = curQues ? curQues.attachmentName : ''
n.attachmentUrl = curQues ? curQues.attachmentUrl : ''
@ -279,6 +294,7 @@ export default {
})
})
this.form = r
this.loading = false
// input
this.$nextTick(() => {
@ -304,10 +320,13 @@ export default {
}
})
})
this.calcProgress()
})
console.log("🚀 ~ getPaper ~ r:", r)
}
} catch (e) { }
} catch (e) {
this.loading = false
}
},
//
handleCounter (counterTime, isCount) {
@ -364,6 +383,39 @@ export default {
timeFormat (param) {
return param < 10 ? '0' + param : param
},
//
calcProgress () {
let answered = 0
this.form.paperOutline.map(e => {
answered += e.examQuestions.filter(n => n.answered).length
})
this.totalAnswered = answered
this.progress = +(answered / this.form.questionCount * 100).toFixed(1)
},
//
progressFormat (e) {
return this.totalAnswered + '/' + this.form.questionCount
},
scrollToSmooth (position, duration) {
let startTime = Date.now()
function scroll () {
let now = Date.now()
let progress = Math.min(1, (now - startTime) / duration)
document.querySelector('#quesWrap').scrollTo(0, position * progress)
if (progress < 1) {
window.requestAnimationFrame(scroll)
}
}
window.requestAnimationFrame(scroll)
},
//
scrollToQues (e) {
const el = document.querySelector('#ques' + e.id)
el && this.scrollToSmooth(el.offsetTop - document.querySelector('#quesWrap').offsetTop, 200)
},
//
filterStatus (e) {
this.sheetStatus = this.sheetStatus === e ? '' : e
@ -397,17 +449,20 @@ export default {
ques.questionAnswerVersionsList[j].answer = 1
ques.answered = 1
this.calcProgress()
},
//
mulChange (ques) {
ques.answered = ques.questionAnswerVersionsList.some(e => e.answer)
this.calcProgress()
},
//
essayAnswerReady (editor, ques) {
editor.ques = ques
editor.addListener('contentChange', () => {
ques.answered = editor.getContent() ? 1 : 0
ques.answered = editor.hasContents() ? 1 : 0
this.calcProgress()
})
ques.answer && editor.setContent(ques.answer)
},
@ -473,7 +528,6 @@ export default {
const stem = document.querySelector(`#stem` + n.id)
if (stem) {
const inputs = stem.querySelectorAll('.fill-input')
console.log("🚀 ~ submit ~ editor333:", stem, inputs)
if (inputs) {
for (const e of inputs) {
answer.push(e.value)
@ -497,11 +551,12 @@ export default {
})
const timeSum = Math.ceil((now - entryTime) / 60000) //
const submitTime = Util.formatDate('yyyy-MM-dd hh:mm:ss', now)
// debugger
//
const res = await this.$post(this.api[isSubmit ? 'submitTheExamPaper' : 'examPaperRecordCache'], {
await this.$post(this.api[isSubmit ? 'submitTheExamPaper' : 'examPaperRecordCache'], {
competitionId: this.id,
stageId: curStage.stageId,
teamId: this.teamId,
startTime: Util.formatDate('yyyy-MM-dd hh:mm:ss', entryTime), //
endTime: this.per ? curStage.endTime : submitTime, //
submitTime, // 3
@ -511,20 +566,25 @@ export default {
examSubmitJudgeList: ques,
})
//
if (this.id) {
const time = curStage.resultAnnouncementTime
const msg =
time === '0' ? '提交成功!成绩将在比赛结束后公布,请前往参赛信息模块查看' : time > 0 ? `提交成功!成绩将在比赛结束后${time}小时公布,请前往参赛信息模块查看` : '提交成功';
this.$alert(msg, '提示', {
confirmButtonText: '确定',
type: 'success',
callback: () => {
this.$router.back()
}
})
} else {
this.$message.success('提交成功!')
clearInterval(this.counterTimer)
this.submiting = false
this.submited = true
if (isSubmit) {
//
if (this.id) {
const time = curStage.resultAnnouncementTime
const msg =
time === '0' ? '提交成功!成绩将在比赛结束后公布,请前往参赛信息模块查看' : time > 0 ? `提交成功!成绩将在比赛结束后${time}小时公布,请前往参赛信息模块查看` : '提交成功';
this.$alert(msg, '提示', {
confirmButtonText: '确定',
type: 'success',
callback: () => {
this.$router.back()
}
})
} else {
this.$message.success('提交成功!')
}
}
} catch (e) {
this.submiting = false
@ -573,7 +633,7 @@ export default {
padding: 15px;
.left {
width: 300px;
width: 293px;
margin-right: 15px;
background-color: #fff;
@ -612,13 +672,18 @@ export default {
li {
position: relative;
width: 35px;
width: 30px;
margin: 7px 9px;
font-size: 13px;
text-align: center;
line-height: 35px;
line-height: 30px;
color: #505050;
border: 1px solid #d3d3d3;
cursor: pointer;
&:hover {
opacity: .9;
}
&.answered {
color: #fff;
@ -685,10 +750,11 @@ export default {
}
.ques-wrap {
width: calc(100% - 315px);
width: calc(100% - 308px);
height: calc(100vh - 192px);
background-color: #fff;
overflow: auto;
outline: none;
&>li {
margin-bottom: 15px;
@ -734,7 +800,7 @@ export default {
.stem-wrap {
display: flex;
align-items: center;
align-items: baseline;
margin-bottom: 10px;
}
@ -747,16 +813,26 @@ export default {
}
}
.labels {
display: inline-flex;
align-items: center;
}
.label {
padding: 3px 5px;
margin-right: 10px;
font-size: 12px;
line-height: 1;
color: $main-color;
white-space: nowrap;
border: 1px solid;
border-radius: 2px;
}
.stem {
max-width: calc(100% - 191px);
}
.fill-input {
width: 100px;
height: 28px;

Loading…
Cancel
Save