|
|
@@ -0,0 +1,129 @@
|
|
|
+<template>
|
|
|
+ <v-main class="indigo lighten-5 pa-0">
|
|
|
+ <v-container fluid class="pa-2">
|
|
|
+ <v-card class="questionCard">
|
|
|
+ <div v-if="!fetchingStem">
|
|
|
+ <blank-pane
|
|
|
+ v-if="
|
|
|
+ questionType() === 'blank' || questionType() === 'short_answer'
|
|
|
+ "
|
|
|
+ :question="question"
|
|
|
+ @saveAnswer="saveObjectiveAnswer"
|
|
|
+ >
|
|
|
+ </blank-pane>
|
|
|
+ <choice-pane
|
|
|
+ v-else-if="
|
|
|
+ questionType() === 'choice' ||
|
|
|
+ questionType() === 'multi_choice' ||
|
|
|
+ questionType() === 'true_false'
|
|
|
+ "
|
|
|
+ :question="question"
|
|
|
+ @saveAnswer="saveObjectiveAnswer"
|
|
|
+ >
|
|
|
+ </choice-pane>
|
|
|
+ </div>
|
|
|
+ <div class="pa-2 text--secondary justify-center d-flex">
|
|
|
+ <v-dialog v-model="submitDialog" persistent max-width="290">
|
|
|
+ <template v-slot:activator="{ on, attrs }">
|
|
|
+ <v-btn color="success" v-bind="attrs" v-on="on">提交答案</v-btn>
|
|
|
+ </template>
|
|
|
+ <v-card>
|
|
|
+ <v-card-title class="headline">
|
|
|
+ 确认提交答案?
|
|
|
+ </v-card-title>
|
|
|
+ <v-card-text>提交后将无法再次进入</v-card-text>
|
|
|
+ <v-card-actions>
|
|
|
+ <v-spacer></v-spacer>
|
|
|
+ <v-btn
|
|
|
+ color="success darken-1"
|
|
|
+ text
|
|
|
+ @click="submitDialog = false"
|
|
|
+ >
|
|
|
+ 否
|
|
|
+ </v-btn>
|
|
|
+ <v-btn color="error darken-1" text @click="submitAnswer">
|
|
|
+ 是
|
|
|
+ </v-btn>
|
|
|
+ </v-card-actions>
|
|
|
+ </v-card>
|
|
|
+ </v-dialog>
|
|
|
+ </div>
|
|
|
+ </v-card>
|
|
|
+ </v-container>
|
|
|
+ <v-snackbar v-model="errorBar" absolute top color="error">
|
|
|
+ {{ errorMsg }}
|
|
|
+ </v-snackbar>
|
|
|
+ </v-main>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+import Vue from 'vue'
|
|
|
+import ChoicePane from '@/views/exam/components/ChoicePane.vue'
|
|
|
+import BlankPane from '@/views/exam/components/BlankPane.vue'
|
|
|
+import { QuestionSerializer, QuestionType } from '@/api/types'
|
|
|
+import { getQuestionStem } from '@/api/question'
|
|
|
+
|
|
|
+export default Vue.extend({
|
|
|
+ name: 'SingleQuestion',
|
|
|
+ components: {
|
|
|
+ ChoicePane,
|
|
|
+ BlankPane
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ fetchingStem: true,
|
|
|
+ submitDialog: false,
|
|
|
+ question: (null as unknown) as QuestionSerializer,
|
|
|
+ answer: '',
|
|
|
+ errorMsg: '',
|
|
|
+ errorBar: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ questionType(): QuestionType {
|
|
|
+ return this.question.type
|
|
|
+ },
|
|
|
+ saveObjectiveAnswer(answer: string) {
|
|
|
+ this.answer = answer
|
|
|
+ },
|
|
|
+ redirect() {
|
|
|
+ let redirect_uri = this.$route.query.redirect_uri ?? ''
|
|
|
+ let href = decodeURIComponent(redirect_uri as string)
|
|
|
+ let params = encodeURIComponent(this.answer)
|
|
|
+ window.location.href = href + '?answer=' + params
|
|
|
+ },
|
|
|
+ submitAnswer() {
|
|
|
+ this.submitDialog = false
|
|
|
+ this.redirect()
|
|
|
+ },
|
|
|
+ fetchData() {
|
|
|
+ let questionId = this.$route.params.questionId
|
|
|
+ if (questionId) {
|
|
|
+ getQuestionStem(questionId)
|
|
|
+ .then(({ data }) => {
|
|
|
+ this.question = data.result
|
|
|
+ this.fetchingStem = false
|
|
|
+ })
|
|
|
+ .catch(({ data }) => {
|
|
|
+ this.errorMsg = data.msg
|
|
|
+ this.errorBar = true
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.fetchData()
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.questionCard {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin: 4vh 10vw;
|
|
|
+ min-height: 90vh;
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+</style>
|