|
|
@@ -9,7 +9,7 @@
|
|
|
<count-down
|
|
|
class="align-self-center"
|
|
|
:current-time="currentTime"
|
|
|
- :end-time="`${currentTime + 10000}`"
|
|
|
+ :end-time="endTime"
|
|
|
></count-down>
|
|
|
</v-col>
|
|
|
</v-row>
|
|
|
@@ -35,11 +35,13 @@
|
|
|
<h2>单选题</h2>
|
|
|
</div>
|
|
|
<v-btn
|
|
|
- v-for="i in answeredChoices.slice(0, singleChoiceNum)"
|
|
|
+ v-for="i in answerStatus.slice(0, singleChoiceNum)"
|
|
|
:key="i.index"
|
|
|
class="ml-2 mt-2 pa-0 d-inline"
|
|
|
x-small
|
|
|
:disabled="i.answered"
|
|
|
+ :color="currentQuestionIndex + 1 === i.index ? 'secondary' : ''"
|
|
|
+ @click="onSelectQuestion(i.index)"
|
|
|
>
|
|
|
{{ i.index }}
|
|
|
</v-btn>
|
|
|
@@ -49,14 +51,16 @@
|
|
|
<h2>多选题</h2>
|
|
|
</div>
|
|
|
<v-btn
|
|
|
- v-for="i in answeredChoices.slice(
|
|
|
+ v-for="i in answerStatus.slice(
|
|
|
singleChoiceNum,
|
|
|
- singleChoiceNum + multiChoiceNum
|
|
|
+ choiceQuestionNum
|
|
|
)"
|
|
|
:key="i.index"
|
|
|
class="ml-2 mt-2 pa-0 d-inline"
|
|
|
x-small
|
|
|
:disabled="i.answered"
|
|
|
+ :color="currentQuestionIndex + 1 === i.index ? 'secondary' : ''"
|
|
|
+ @click="onSelectQuestion(i.index)"
|
|
|
>
|
|
|
{{ i.index }}
|
|
|
</v-btn>
|
|
|
@@ -66,11 +70,13 @@
|
|
|
<h2>代码题</h2>
|
|
|
</div>
|
|
|
<v-btn
|
|
|
- v-for="i in answeredCodes"
|
|
|
+ v-for="i in answerStatus.slice(choiceQuestionNum)"
|
|
|
:key="i.index"
|
|
|
class="ml-2 mt-2 pa-0 d-inline"
|
|
|
x-small
|
|
|
:disabled="i.answered"
|
|
|
+ :color="currentQuestionIndex + 1 === i.index ? 'secondary' : ''"
|
|
|
+ @click="onSelectQuestion(i.index)"
|
|
|
>
|
|
|
{{ i.index }}
|
|
|
</v-btn>
|
|
|
@@ -132,18 +138,19 @@
|
|
|
</div>
|
|
|
</v-navigation-drawer>
|
|
|
<v-main class="indigo lighten-5 pa-0">
|
|
|
- <v-container fluid class="pa-2">
|
|
|
- <code-pane
|
|
|
- v-if="!isChoiceProblem"
|
|
|
- v-on:nextQuestion="nextQuestion"
|
|
|
- :question="curQuestion"
|
|
|
- ></code-pane>
|
|
|
+ <v-container fluid class="pa-2" v-if="currentQuestionIndex >= 0">
|
|
|
<choice-pane
|
|
|
v-if="isChoiceProblem"
|
|
|
- v-on:nextQuestion="nextQuestion(answer)"
|
|
|
- :total-question-num="multiChoiceNum"
|
|
|
- :question="curQuestion"
|
|
|
+ v-on:nextQuestion="nextQuestion"
|
|
|
+ :total-question-num="curTypeQuestionNum"
|
|
|
+ :question="curChoice"
|
|
|
></choice-pane>
|
|
|
+ <code-pane
|
|
|
+ v-else
|
|
|
+ v-on:nextQuestion="nextQuestion"
|
|
|
+ :question="curCode"
|
|
|
+ :total-question-num="curTypeQuestionNum"
|
|
|
+ ></code-pane>
|
|
|
</v-container>
|
|
|
</v-main>
|
|
|
</div>
|
|
|
@@ -160,7 +167,7 @@ import {
|
|
|
ExamQuestionSerializer,
|
|
|
QuestionSerializer
|
|
|
} from '@/api/types'
|
|
|
-import { getExamQuestions } from '@/api/exam'
|
|
|
+import { getExamById, getExamQuestions } from '@/api/exam'
|
|
|
|
|
|
export default Vue.extend({
|
|
|
name: 'ExamPane',
|
|
|
@@ -175,20 +182,27 @@ export default Vue.extend({
|
|
|
submitDialog: false,
|
|
|
submitted: false,
|
|
|
currentTime: new Date().getTime(),
|
|
|
+ endTime: 0,
|
|
|
choiceAnswers: [] as Array<{ num: number; answer: string }>, // TODO codeAnswers
|
|
|
examId: 0,
|
|
|
- examQuestionsObject: {} as ExamQuestionSerializer,
|
|
|
singleChoiceQuestions: [] as Array<ChoiceQuestionSerializer>,
|
|
|
multiChoiceQuestions: [] as Array<ChoiceQuestionSerializer>,
|
|
|
codeQuestions: [] as Array<CodeQuestionSerializer>,
|
|
|
allQuestions: [] as Array<QuestionSerializer>,
|
|
|
answeredChoices: [] as Array<{ index: number; answered: boolean }>,
|
|
|
answeredCodes: [] as Array<{ index: number; answered: boolean }>,
|
|
|
-
|
|
|
- currentQuestionIndex: 0
|
|
|
+ answerStatus: [] as Array<{ index: number; answered: boolean }>,
|
|
|
+ currentQuestionIndex: -1
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
+ curTypeQuestionNum(): number {
|
|
|
+ return this.isChoiceProblem
|
|
|
+ ? this.isSingleChoice
|
|
|
+ ? this.singleChoiceNum
|
|
|
+ : this.multiChoiceNum
|
|
|
+ : this.codeQuestionNum
|
|
|
+ },
|
|
|
isChoiceProblem(): boolean {
|
|
|
return this.currentQuestionIndex < this.choiceQuestionNum
|
|
|
},
|
|
|
@@ -207,8 +221,26 @@ export default Vue.extend({
|
|
|
choiceQuestionNum(): number {
|
|
|
return this.singleChoiceNum + this.multiChoiceNum
|
|
|
},
|
|
|
- curQuestion(): QuestionSerializer {
|
|
|
- return this.allQuestions[this.currentQuestionIndex]
|
|
|
+
|
|
|
+ curChoice(): ChoiceQuestionSerializer {
|
|
|
+ if (!this.isChoiceProblem) {
|
|
|
+ return null
|
|
|
+ }
|
|
|
+ if (this.isSingleChoice) {
|
|
|
+ return this.singleChoiceQuestions[this.currentQuestionIndex]
|
|
|
+ } else {
|
|
|
+ return this.multiChoiceQuestions[
|
|
|
+ this.currentQuestionIndex - this.singleChoiceNum
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ curCode(): CodeQuestionSerializer {
|
|
|
+ if (!this.isChoiceProblem) {
|
|
|
+ return this.codeQuestions[
|
|
|
+ this.currentQuestionIndex - this.choiceQuestionNum
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ return null
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
@@ -224,6 +256,9 @@ export default Vue.extend({
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
+ onSelectQuestion(index: number) {
|
|
|
+ this.currentQuestionIndex = index - 1
|
|
|
+ },
|
|
|
leaveExam() {
|
|
|
this.exitDialog = false
|
|
|
this.$router.back()
|
|
|
@@ -234,20 +269,35 @@ export default Vue.extend({
|
|
|
},
|
|
|
nextQuestion(answer: String) {
|
|
|
// this.choiceAnswers.push(answer)
|
|
|
- this.isChoiceProblem = !this.isChoiceProblem
|
|
|
this.currentQuestionIndex += 1
|
|
|
},
|
|
|
fetchData() {
|
|
|
this.examId = parseInt(this.$route.params.id)
|
|
|
- console.log(this.examId)
|
|
|
+ getExamById(this.endId).then(({ data }) => {
|
|
|
+ this.endTime = Date.parse(data.res.endAt)
|
|
|
+ console.log(this.endTime)
|
|
|
+ })
|
|
|
+
|
|
|
getExamQuestions(this.examId)
|
|
|
.then(({ data }) => {
|
|
|
- this.examQuestionsObject = data.res ?? {}
|
|
|
- this.singleChoiceQuestions =
|
|
|
- this.examQuestionsObject?.singleChoiceQuestions ?? []
|
|
|
- this.multiChoiceQuestions =
|
|
|
- this.examQuestionsObject?.multiChoiceQuestions ?? []
|
|
|
- this.codeQuestions = this.examQuestionsObject?.codeQuestions ?? []
|
|
|
+ const examQuestionsObject: ExamQuestionSerializer = data.res
|
|
|
+
|
|
|
+ this.singleChoiceQuestions = examQuestionsObject.singleChoiceQuestions?.map(
|
|
|
+ (value, index) => {
|
|
|
+ return { ...value, id: index + 1 }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ this.multiChoiceQuestions = examQuestionsObject.multiChoiceQuestions?.map(
|
|
|
+ (value, index) => {
|
|
|
+ return { ...value, id: index + 1 }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ this.codeQuestions = examQuestionsObject.codeQuestions?.map(
|
|
|
+ (value, index) => {
|
|
|
+ return { ...value, id: index + 1 }
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
this.allQuestions = [
|
|
|
...this.singleChoiceQuestions,
|
|
|
...this.multiChoiceQuestions,
|
|
|
@@ -257,8 +307,17 @@ export default Vue.extend({
|
|
|
...this.singleChoiceQuestions,
|
|
|
...this.multiChoiceQuestions
|
|
|
].map((value, index) => {
|
|
|
- return { num: index + 1, answer: '' }
|
|
|
+ return { index: index + 1, answer: '' }
|
|
|
})
|
|
|
+
|
|
|
+ this.answerStatus = this.allQuestions.map((value, index) => {
|
|
|
+ return {
|
|
|
+ index: index + 1,
|
|
|
+ answered: false
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.currentQuestionIndex = 0 // 表示数据初始化完成
|
|
|
})
|
|
|
.catch(() => {
|
|
|
console.log('No data')
|