|
@@ -1,15 +1,324 @@
|
|
<template>
|
|
<template>
|
|
- <div></div>
|
|
|
|
|
|
+ <div class="answer">
|
|
|
|
+ <header class="header">
|
|
|
|
+ <div class="back round" @click="$router.push('/personal_question')">
|
|
|
|
+ <i class="el-icon-arrow-left"></i>
|
|
|
|
+ <span>返回</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="question-info">
|
|
|
|
+ <div class="round">
|
|
|
|
+ <SvgIcon icon-class="list" />
|
|
|
|
+ <span>{{ curQuestionIndex + 1 }} / {{ questionList.length }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="round primary"><SvgIcon icon-class="hourglass" />{{ secondFormatConversion(time) }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </header>
|
|
|
|
+
|
|
|
|
+ <main class="main">
|
|
|
|
+ <StartQuestion
|
|
|
|
+ v-if="curQuestionIndex === -1"
|
|
|
|
+ :question-length="questionList.length"
|
|
|
|
+ :answer-time-limit-minute="answer_time_limit_minute"
|
|
|
|
+ @startAnswer="startAnswer"
|
|
|
|
+ />
|
|
|
|
+
|
|
|
|
+ <AnswerReport v-else-if="isSubmit" :answer-record-id="answer_record_id" @selectQuestion="selectQuestion" />
|
|
|
|
+
|
|
|
|
+ <template v-for="({ id }, i) in questionList" v-else>
|
|
|
|
+ <component
|
|
|
|
+ :is="curQuestionPage"
|
|
|
|
+ v-if="i === curQuestionIndex"
|
|
|
|
+ :key="id"
|
|
|
|
+ ref="exercise"
|
|
|
|
+ :data="currentQuestion"
|
|
|
|
+ />
|
|
|
|
+ </template>
|
|
|
|
+ </main>
|
|
|
|
+
|
|
|
|
+ <footer class="footer">
|
|
|
|
+ <div v-show="isAnnotations" class="annotations"><i class="el-icon-plus"></i>批注</div>
|
|
|
|
+
|
|
|
|
+ <div>
|
|
|
|
+ <template v-if="curQuestionIndex === -1">
|
|
|
|
+ <el-button type="primary" round @click="startAnswer">开始答题</el-button>
|
|
|
|
+ </template>
|
|
|
|
+
|
|
|
|
+ <template v-else-if="isSubmit">
|
|
|
|
+ <el-button v-if="answer_mode === 1" round type="primary" @click="startAnswer">开始答题</el-button>
|
|
|
|
+ </template>
|
|
|
|
+
|
|
|
|
+ <template v-else>
|
|
|
|
+ <el-button round @click="fillQuestionAnswer('pre')">上一题</el-button>
|
|
|
|
+ <el-button v-if="curQuestionIndex === questionList.length - 1" type="primary" round @click="submitAnswer">
|
|
|
|
+ 提交
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button v-else type="primary" round @click="fillQuestionAnswer('next')">下一题</el-button>
|
|
|
|
+ </template>
|
|
|
|
+ </div>
|
|
|
|
+ </footer>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
|
+import { secondFormatConversion } from '@/utils/transform';
|
|
|
|
+import {
|
|
|
|
+ GetExerciseQuestionIndexList,
|
|
|
|
+ GetQuestionInfo,
|
|
|
|
+ GetShareRecordInfo,
|
|
|
|
+ StartAnswer,
|
|
|
|
+ FillQuestionAnswer,
|
|
|
|
+ SubmitAnswer,
|
|
|
|
+ GetQuestionInfo_AnswerRecord,
|
|
|
|
+} from '@/api/exercise';
|
|
|
|
+
|
|
|
|
+import StartQuestion from './components/StartQuestion.vue';
|
|
|
|
+import AnswerReport from './components/AnswerReport.vue';
|
|
|
|
+import PreviewQuestionTypeMixin from '../data/PreviewQuestionTypeMixin';
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
name: 'AnswerPage',
|
|
name: 'AnswerPage',
|
|
|
|
+ components: {
|
|
|
|
+ StartQuestion,
|
|
|
|
+ AnswerReport,
|
|
|
|
+ },
|
|
|
|
+ mixins: [PreviewQuestionTypeMixin],
|
|
data() {
|
|
data() {
|
|
- return {};
|
|
|
|
|
|
+ const { id, share_record_id } = this.$route.query;
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ exercise_id: id, // 练习题id
|
|
|
|
+ share_record_id, // 分享记录id
|
|
|
|
+ answer_record_id: '', // 答题记录id
|
|
|
|
+ secondFormatConversion,
|
|
|
|
+ user_answer_record_info: {
|
|
|
|
+ correct_answer_show_mode: 1, // 正确答案显示模式
|
|
|
|
+ }, // 当前用户的答题记录信息
|
|
|
|
+ // 问题列表
|
|
|
|
+ questionList: [],
|
|
|
|
+ // 当前问题
|
|
|
|
+ currentQuestion: {},
|
|
|
|
+ // 当前问题索引
|
|
|
|
+ curQuestionIndex: -1,
|
|
|
|
+ // 倒计时
|
|
|
|
+ countDownTimer: null,
|
|
|
|
+ answer_mode: 1, // 答题模式
|
|
|
|
+ answer_time_limit_minute: 30, // 答题时间限制
|
|
|
|
+ time: 1800,
|
|
|
|
+ isSubmit: false,
|
|
|
|
+ curQuestionPage: '', // 当前问题页面
|
|
|
|
+ isAnnotations: false, // 是否显示批注
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ curQuestionIndex() {
|
|
|
|
+ this.getQuestionInfo();
|
|
|
|
+ this.getQuestionInfo_AnswerRecord();
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ this.init();
|
|
|
|
+ },
|
|
|
|
+ beforeDestroy() {
|
|
|
|
+ if (this.countDownTimer) clearInterval(this.countDownTimer);
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ // 初始化
|
|
|
|
+ init() {
|
|
|
|
+ if (this.exercise_id) {
|
|
|
|
+ this.getExerciseQuestionIndexList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.share_record_id) {
|
|
|
|
+ GetShareRecordInfo({ share_record_id: this.share_record_id }).then(
|
|
|
|
+ ({ user_answer_record_info, share_record: { exercise_id } }) => {
|
|
|
|
+ this.user_answer_record_info = user_answer_record_info;
|
|
|
|
+ this.exercise_id = exercise_id;
|
|
|
|
+ this.getExerciseQuestionIndexList();
|
|
|
|
+ },
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ getExerciseQuestionIndexList() {
|
|
|
|
+ GetExerciseQuestionIndexList({ exercise_id: this.exercise_id }).then(({ index_list }) => {
|
|
|
|
+ this.questionList = index_list.map((item) => ({
|
|
|
|
+ ...item,
|
|
|
|
+ isFill: false,
|
|
|
|
+ }));
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 倒计时
|
|
|
|
+ countDown() {
|
|
|
|
+ this.countDownTimer = setInterval(() => {
|
|
|
|
+ this.time -= 1;
|
|
|
|
+ if (this.time === 0) {
|
|
|
|
+ clearInterval(this.countDownTimer);
|
|
|
|
+ }
|
|
|
|
+ }, 1000);
|
|
|
|
+ },
|
|
|
|
+ startAnswer() {
|
|
|
|
+ if (!this.share_record_id) {
|
|
|
|
+ this.curQuestionIndex = 0;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ StartAnswer({ exercise_id: this.exercise_id, share_record_id: this.share_record_id }).then(
|
|
|
|
+ ({ answer_time_limit_minute, answer_mode, answer_record_id }) => {
|
|
|
|
+ this.answer_record_id = answer_record_id;
|
|
|
|
+ this.answer_time_limit_minute = answer_time_limit_minute;
|
|
|
|
+ this.time = answer_time_limit_minute * 60;
|
|
|
|
+ this.countDown();
|
|
|
|
+ this.answer_mode = answer_mode;
|
|
|
|
+ this.curQuestionIndex = 0;
|
|
|
|
+ this.isSubmit = false;
|
|
|
|
+ },
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ preQuestion() {
|
|
|
|
+ if (this.curQuestionIndex === 0) return;
|
|
|
|
+ this.curQuestionIndex -= 1;
|
|
|
|
+ },
|
|
|
|
+ nextQuestion() {
|
|
|
|
+ if (this.curQuestionIndex === this.questionList.length - 1) return;
|
|
|
|
+ this.curQuestionIndex += 1;
|
|
|
|
+ },
|
|
|
|
+ // 获取题目信息
|
|
|
|
+ getQuestionInfo() {
|
|
|
|
+ GetQuestionInfo({ question_id: this.questionList[this.curQuestionIndex].id })
|
|
|
|
+ .then(({ question }) => {
|
|
|
|
+ if (!question.content) return;
|
|
|
|
+
|
|
|
|
+ this.currentQuestion = JSON.parse(question.content);
|
|
|
|
+ this.curQuestionPage =
|
|
|
|
+ this.questionList.length === 0 || this.curQuestionIndex < 0
|
|
|
|
+ ? ''
|
|
|
|
+ : this.previewComponents[this.questionList[this.curQuestionIndex].type];
|
|
|
|
+ })
|
|
|
|
+ .catch(() => {});
|
|
|
|
+ },
|
|
|
|
+ /**
|
|
|
|
+ * 填写答案
|
|
|
|
+ * @param {'pre' | 'next'} type 上一题/下一题
|
|
|
|
+ */
|
|
|
|
+ fillQuestionAnswer(type) {
|
|
|
|
+ if (type === 'pre' && this.curQuestionIndex <= 0) return;
|
|
|
|
+ if (type === 'next' && this.curQuestionIndex > this.questionList.length - 1) return;
|
|
|
|
+ if (!this.answer_record_id) {
|
|
|
|
+ this.curQuestionIndex = type === 'pre' ? this.curQuestionIndex - 1 : this.curQuestionIndex + 1;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (this.questionList[this.curQuestionIndex].isFill) {
|
|
|
|
+ if (type === 'pre') return this.preQuestion();
|
|
|
|
+ if (type === 'next') return this.nextQuestion();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let answer = this.$refs.exercise[0].answer;
|
|
|
|
+ return FillQuestionAnswer({
|
|
|
|
+ answer_record_id: this.answer_record_id,
|
|
|
|
+ question_id: this.questionList[this.curQuestionIndex].id,
|
|
|
|
+ answer: JSON.stringify(answer),
|
|
|
|
+ }).then(() => {
|
|
|
|
+ this.questionList[this.curQuestionIndex].isFill = true;
|
|
|
|
+ // if (type === 'pre') return this.preQuestion();
|
|
|
|
+ // if (type === 'next') return this.nextQuestion();
|
|
|
|
+ this.$refs.exercise[0].showAnswer(
|
|
|
|
+ this.answer_mode === 1,
|
|
|
|
+ this.user_answer_record_info.correct_answer_show_mode === 1,
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ getQuestionInfo_AnswerRecord() {
|
|
|
|
+ if (!this.questionList[this.curQuestionIndex].isFill) return;
|
|
|
|
+
|
|
|
|
+ GetQuestionInfo_AnswerRecord({
|
|
|
|
+ answer_record_id: this.answer_record_id,
|
|
|
|
+ question_id: this.questionList[this.curQuestionIndex].id,
|
|
|
|
+ }).then(({ user_answer: { is_fill_answer, content } }) => {
|
|
|
|
+ if (is_fill_answer === 'false') return;
|
|
|
|
+ this.$refs.exercise[0].showAnswer(
|
|
|
|
+ this.answer_mode === 1,
|
|
|
|
+ this.user_answer_record_info.correct_answer_show_mode === 1,
|
|
|
|
+ JSON.parse(content),
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 提交答题
|
|
|
|
+ submitAnswer() {
|
|
|
|
+ if (!this.answer_record_id) return;
|
|
|
|
+
|
|
|
|
+ // 如果已经填写过答案,直接提交
|
|
|
|
+ if (this.questionList[this.curQuestionIndex].isFill) {
|
|
|
|
+ SubmitAnswer({ answer_record_id: this.answer_record_id }).then(() => {
|
|
|
|
+ this.isSubmit = true;
|
|
|
|
+ });
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.fillQuestionAnswer('next').then(() => {
|
|
|
|
+ SubmitAnswer({ answer_record_id: this.answer_record_id }).then(() => {
|
|
|
|
+ this.isSubmit = true;
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ selectQuestion(i) {
|
|
|
|
+ console.log(i);
|
|
|
|
+ this.isSubmit = false;
|
|
|
|
+ this.curQuestionIndex = i;
|
|
|
|
+ },
|
|
},
|
|
},
|
|
- methods: {},
|
|
|
|
};
|
|
};
|
|
</script>
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped></style>
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.answer {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ row-gap: 16px;
|
|
|
|
+ height: 100%;
|
|
|
|
+ padding: 16px;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ border-radius: 24px;
|
|
|
|
+ box-shadow: 0 6px 30px 5px #0000000d;
|
|
|
|
+
|
|
|
|
+ .header {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ height: 38px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+
|
|
|
|
+ .back {
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .question-info {
|
|
|
|
+ display: flex;
|
|
|
|
+ column-gap: 12px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .main {
|
|
|
|
+ flex: 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .footer {
|
|
|
|
+ position: relative;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+
|
|
|
|
+ .annotations {
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 0;
|
|
|
|
+ display: flex;
|
|
|
|
+ column-gap: 8px;
|
|
|
|
+ align-items: center;
|
|
|
|
+ padding: 7px 16px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ background-color: $fill-color;
|
|
|
|
+ border-radius: 20px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .el-button {
|
|
|
|
+ padding: 9px 40px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|