فهرست منبع

代码题持久化

ChengYuXuan 5 سال پیش
والد
کامیت
1428576b45
3فایلهای تغییر یافته به همراه43 افزوده شده و 13 حذف شده
  1. 19 4
      src/store/index.ts
  2. 12 9
      src/views/exam/ExamPane.vue
  3. 12 0
      src/views/exam/components/CodePane.vue

+ 19 - 4
src/store/index.ts

@@ -1,6 +1,6 @@
 import Vue from 'vue'
 import Vuex, { GetterTree, MutationTree } from 'vuex'
-import { ID, Record, UserSerializer } from '@/api/types'
+import { CodeTuple, ID, Record, UserSerializer } from '@/api/types'
 import createPersistedState from 'vuex-persistedstate'
 
 Vue.use(Vuex)
@@ -10,20 +10,34 @@ export type RootState = {
   token?: string
   examAnswers?: Object
   examId?: ID
+  examCodesCache?: Object
 }
 
 export const state = (): RootState => ({
   user: (null as unknown) as UserSerializer,
   token: '',
   examAnswers: (null as unknown) as Object,
-  examId: (null as unknown) as ID
+  examId: (null as unknown) as ID,
+  examCodesCache: (null as unknown) as Object
 })
 
 export const mutations: MutationTree<RootState> = {
   setToken: (state, token) => (state.token = token),
   setUser: (state, user) => (state.user = user),
   setExamAnswers: (state, answers) => (state.examAnswers = answers),
-  setExamId: (state, examId) => (state.examId = examId)
+  setExamId: (state, examId) => (state.examId = examId),
+  setExamCodes: (state, { questionId, codeCache }) => {
+    if (
+      state.examCodesCache &&
+      Object.keys(state.examCodesCache).find(questionId)
+    ) {
+      let entries = Object.entries(state.examCodesCache)
+      entries.push([questionId, codeCache])
+      state.examCodesCache = Object.fromEntries(entries)
+    } else {
+      state.examCodesCache = Object.fromEntries([questionId, codeCache])
+    }
+  }
 }
 
 export const getters: GetterTree<RootState, RootState> = {
@@ -32,7 +46,8 @@ export const getters: GetterTree<RootState, RootState> = {
   getId: (state) => state.user.id,
   isLogin: (state) => Boolean(state.token),
   getExamAnswers: (state) => state.examAnswers,
-  getExamId: (state) => state.examId
+  getExamId: (state) => state.examId,
+  getExamCodes: (state) => state.examCodesCache
 }
 
 export default new Vuex.Store({

+ 12 - 9
src/views/exam/ExamPane.vue

@@ -263,7 +263,7 @@ export default Vue.extend({
       examQuestions: (null as unknown) as ExamQuestionSerializer,
       currentQuestion: (null as unknown) as QuestionSerializer,
       currentQuestionIndex: -1,
-      objectiveAnswers: {},
+      objectiveAnswers: {} as Map<ID, Record>,
       questionIds: [] as Array<string>,
       questionStartTime: dayjs().format(TIME_FORMAT) as LocalDateTime,
       examId: 0 as ID,
@@ -322,13 +322,13 @@ export default Vue.extend({
     saveObjectiveAnswer(answer: string) {
       let questionEndTime = dayjs().format(TIME_FORMAT)
 
-      this.objectiveAnswers[this.questionIds[this.currentQuestionIndex]] = {
+      this.objectiveAnswers.set(this.questionIds[this.currentQuestionIndex], {
         answer,
         startAt: this.questionStartTime,
         endAt: questionEndTime
-      }
+      })
 
-      this.setExamAnswers(this.objectiveAnswers)
+      this.setExamAnswers(Object.fromEntries(this.objectiveAnswers))
     },
     leaveExam() {
       this.exitDialog = false
@@ -340,7 +340,7 @@ export default Vue.extend({
       console.log(this.objectiveAnswers)
       console.log(this.questionIds)
 
-      objectiveJudge(this.examId, this.objectiveAnswers)
+      objectiveJudge(this.examId, Object.fromEntries(this.objectiveAnswers))
         .then(() => {
           setTimeout(() => {
             this.$router.push({
@@ -373,7 +373,9 @@ export default Vue.extend({
 
       if (this.currentQuestionIndex < this.totalQuestionNum - 1) {
         if (
-          !this.objectiveAnswers[this.questionIds[this.currentQuestionIndex]]
+          !this.objectiveAnswers.get(
+            this.questionIds[this.currentQuestionIndex]
+          )
         ) {
           //TODO 是否需要提示未作答?
         }
@@ -432,9 +434,10 @@ export default Vue.extend({
                 this.currentQuestionIndex = 0
                 this.fetchQuestionStem(0)
               } else {
-                this.objectiveAnswers = this.getExamAnswers()
-                this.currentQuestionIndex =
-                  Object.keys(this.objectiveAnswers).length - 1
+                this.objectiveAnswers = new Map(
+                  Object.entries(this.getExamAnswers())
+                )
+                this.currentQuestionIndex = this.objectiveAnswers.size - 1
 
                 if (this.currentQuestionIndex < this.objectiveQuestionNum) {
                   this.fetchQuestionStem(this.currentQuestionIndex)

+ 12 - 0
src/views/exam/components/CodePane.vue

@@ -146,6 +146,7 @@ import {
 } from '@/api/types'
 import { codeJudge } from '@/api/judge'
 import { getExamQuestionSubmitRecord } from '@/api/record'
+import { mapGetters, mapMutations } from 'vuex'
 
 interface CodeJudgeInfo extends CodeJudgeResult {
   id: ID
@@ -229,6 +230,8 @@ export default Vue.extend({
     // ]
   },
   methods: {
+    ...mapMutations(['setExamCodes']),
+    ...mapGetters(['getExamCodes']),
     submitCode(): void {
       this.tab = 1
       const examId = this.$route.params.examId
@@ -274,6 +277,15 @@ export default Vue.extend({
     },
     nextQuestion() {
       this.$emit('nextQuestion')
+    },
+    persistCodeAnswers() {
+      this.setExamCodes({
+        questionId: this.question.id,
+        codeCache: this.codeCache
+      })
+    },
+    recoverCodeAnswers() {
+      this.codeCache = this.getExamCodes()
     }
   }
 })