reghao 7 месяцев назад
Родитель
Сommit
52f28a7bb8
4 измененных файлов с 225 добавлено и 154 удалено
  1. 5 0
      src/api/exam.js
  2. 1 1
      src/router/exam.js
  3. 27 25
      src/views/exam/Exam.vue
  4. 192 128
      src/views/exam/ExamQuestionCard.vue

+ 5 - 0
src/api/exam.js

@@ -11,6 +11,7 @@ const examApi = {
   addPaper: '/api/content/exam/paper',
   addPaper: '/api/content/exam/paper',
   startExam: '/api/content/exam/start',
   startExam: '/api/content/exam/start',
   submitExam: '/api/content/exam/submit',
   submitExam: '/api/content/exam/submit',
+  cacheUserAnswer: '/api/content/exam/cache',
   getExamResult: '/api/content/exam/result/view',
   getExamResult: '/api/content/exam/result/view',
   getExamMark: '/api/content/exam/result/mark',
   getExamMark: '/api/content/exam/result/mark',
   submitExamMark: '/api/content/exam/result/mark'
   submitExamMark: '/api/content/exam/result/mark'
@@ -76,6 +77,10 @@ export function submitExam(data) {
   return post(examApi.submitExam, data)
   return post(examApi.submitExam, data)
 }
 }
 
 
+export function cacheUserAnswer(data) {
+  return post(examApi.cacheUserAnswer, data)
+}
+
 export function getExamResult(examId) {
 export function getExamResult(examId) {
   return get(examApi.getExamResult + '/' + examId)
   return get(examApi.getExamResult + '/' + examId)
 }
 }

+ 1 - 1
src/router/exam.js

@@ -114,7 +114,7 @@ export default {
       meta: { needAuth: true }
       meta: { needAuth: true }
     },
     },
     {
     {
-      path: '/exam/paper/card',
+      path: '/exam/paper/card/:paperId',
       name: 'ExamPaperCard',
       name: 'ExamPaperCard',
       component: ExamPaperCard,
       component: ExamPaperCard,
       meta: { needAuth: true }
       meta: { needAuth: true }

+ 27 - 25
src/views/exam/Exam.vue

@@ -11,33 +11,11 @@
           </li>
           </li>
         </ul>
         </ul>
       </el-col>
       </el-col>
-      <el-dropdown>
-        <img
-          :src="user.avatarUrl"
-          class="el-avatar--circle el-avatar--medium"
-          style="margin-right: 10px; margin-top: 15px"
-          alt=""
-        >
-        <el-dropdown-menu slot="dropdown">
-          <el-dropdown-item
-            icon="el-icon-s-platform"
-            class="size"
-            @click.native="goToHome"
-          >主站</el-dropdown-item>
-          <el-dropdown-item
-            icon="el-icon-error"
-            class="size"
-            @click.native="goToLogout"
-          >退出</el-dropdown-item>
-        </el-dropdown-menu>
-      </el-dropdown>
-    </el-header>
-    <el-container>
-      <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
+      <el-col :md="20">
         <el-menu
         <el-menu
           :default-active="this.$route.path"
           :default-active="this.$route.path"
           router
           router
-          class="el-menu-vertical-demo"
+          mode="horizontal"
           :unique-opened="true"
           :unique-opened="true"
         >
         >
           <el-submenu index="/exam/my">
           <el-submenu index="/exam/my">
@@ -85,7 +63,31 @@
             </el-menu-item-group>
             </el-menu-item-group>
           </el-submenu>
           </el-submenu>
         </el-menu>
         </el-menu>
-      </el-aside>
+      </el-col>
+      <el-col :md="2">
+        <el-dropdown>
+          <img
+            :src="user.avatarUrl"
+            class="el-avatar--circle el-avatar--medium"
+            style="margin-right: 10px; margin-top: 15px"
+            alt=""
+          >
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item
+              icon="el-icon-s-platform"
+              class="size"
+              @click.native="goToHome"
+            >主站</el-dropdown-item>
+            <el-dropdown-item
+              icon="el-icon-error"
+              class="size"
+              @click.native="goToLogout"
+            >退出</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </el-col>
+    </el-header>
+    <el-container>
       <el-main>
       <el-main>
         <router-view />
         <router-view />
       </el-main>
       </el-main>

+ 192 - 128
src/views/exam/ExamQuestionCard.vue

@@ -2,106 +2,134 @@
   <el-container>
   <el-container>
     <el-header height="220">
     <el-header height="220">
       <el-row style="margin-top: 10px">
       <el-row style="margin-top: 10px">
-        <el-button type="primary" icon="el-icon-upload" style="float: right; padding: 3px 0" plain @click="onSubmitPaper">
-          提交试卷
-        </el-button>
+        <h1 style="color: blue; text-align: center">{{ paperInfo.name }}</h1>
+        <h1 style="color: blue; text-align: center">
+          {{ paperInfo.duration }} 分钟 | {{ paperInfo.totalScore }} 分
+        </h1>
       </el-row>
       </el-row>
     </el-header>
     </el-header>
-    <el-main v-if="questionMap !== null">
-      <!-- 回答试题区域 -->
-      <div v-for="(values, key) in questionMap" :key="key">
-        <div v-if="key === '1'">
-          <h1>单项选择题</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
-            <el-radio-group
-              v-model="selectRadioArr[index1]"
-              @change="(val) => {
-                onRadioChange(val, item1)
-              }"
-            >
-              <el-radio :label="1">A</el-radio>
-              <el-radio :label="2">B</el-radio>
-              <el-radio :label="3">C</el-radio>
-              <el-radio :label="4">D</el-radio>
-            </el-radio-group>
+    <el-main v-if="userAnswerMap !== null">
+      <el-col :md="12">
+        <!-- 回答试题区域 -->
+        <div v-for="(values, key) in questionMap" :key="key">
+          <div v-if="key === '1'">
+            <h1>单项选择题</h1>
+            <div v-for="(item1, index1) in values" :key="index1" class="movie-list">
+              <el-card class="box-card">
+                <div class="text item">
+                  <span v-html="item1.questionContent" />
+                  <el-divider />
+                  <el-radio-group
+                    v-model="userAnswerMap[item1.questionId][0]"
+                    @change="(val) => {
+                      onRadioChange(val, item1)
+                    }"
+                  >
+                    <el-radio :label="1">A</el-radio>
+                    <el-radio :label="2">B</el-radio>
+                    <el-radio :label="3">C</el-radio>
+                    <el-radio :label="4">D</el-radio>
+                  </el-radio-group>
+                </div>
+              </el-card>
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
-        </div>
-        <div v-else-if="key === '2' || key === '3'">
-          <h1>多项选择题/不定项选择题</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
-            <el-checkbox-group
-              v-model="checkList"
-              @change="(val) => {
-                onCheckboxChange(val, item1)
-              }"
-            >
-              <el-checkbox label="1">A</el-checkbox>
-              <el-checkbox label="2">B</el-checkbox>
-              <el-checkbox label="3">C</el-checkbox>
-              <el-checkbox label="4">D</el-checkbox>
-            </el-checkbox-group>
+          <div v-else-if="key === '2' || key === '3'">
+            <h1>多项选择题/不定项选择题</h1>
+            <div v-for="(item1, index1) in values" :key="index1">
+              <span v-html="item1.questionContent" />
+              <el-checkbox-group
+                v-model="userAnswerMap[item1.questionId]"
+                @change="(val) => {
+                  onCheckboxChange(val, item1)
+                }"
+              >
+                <el-checkbox label="1">A</el-checkbox>
+                <el-checkbox label="2">B</el-checkbox>
+                <el-checkbox label="3">C</el-checkbox>
+                <el-checkbox label="4">D</el-checkbox>
+              </el-checkbox-group>
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
-        </div>
-        <div v-else-if="key === '4'">
-          <h1>判断题</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
-            <el-radio-group
-              v-model="judgeRadioArr[item1.pos]"
-              @change="(val) => {
-                onRadioChange(val, item1)
-              }"
-            >
-              <el-radio :label="1">正确</el-radio>
-              <el-radio :label="2">错误</el-radio>
-            </el-radio-group>
+          <div v-else-if="key === '4'">
+            <h1>判断题</h1>
+            <div v-for="(item1, index1) in values" :key="index1">
+              <span v-html="item1.questionContent" />
+              <el-radio-group
+                v-model="userAnswerMap[item1.questionId][0]"
+                @change="(val) => {
+                  onRadioChange(val, item1)
+                }"
+              >
+                <el-radio :label="1">正确</el-radio>
+                <el-radio :label="2">错误</el-radio>
+              </el-radio-group>
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
-        </div>
-        <div v-else-if="key === '5'">
-          <h1>填空题</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
-            <el-input
-              v-model="inputContent"
-              type="text"
-              placeholder="请输入答案"
-              style="width: 20%; padding-right: 2px"
-              @blur="(val) => {
-                onInputBlur(val, item1)
-              }"
-            />
+          <div v-else-if="key === '5'">
+            <h1>填空题</h1>
+            <div v-for="(item1, index1) in values" :key="index1">
+              <span v-html="item1.questionContent" />
+              <div v-for="(item2, index2) in userAnswerMap[item1.questionId]" :key="index2">
+                <span style="left: 0;margin-right: 1px;color: black;">第 {{ index2 + 1 }} 题</span>
+                <el-input
+                  v-model="userAnswerMap[item1.questionId][index2]"
+                  type="text"
+                  placeholder="请输入答案"
+                  style="width: 20%; padding-right: 2px"
+                  @blur="(val) => {
+                    onInputBlur(val, item1)
+                  }"
+                />
+              </div>
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
-        </div>
-        <div v-else-if="key === '6'">
-          <h1>问答题</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
-            <editor id="tinymce" v-model="editorContent" :init="init" style="width: 50%" />
+          <div v-else-if="key === '6'">
+            <h1>问答题</h1>
+            <div v-for="(item1, index1) in values" :key="index1" class="movie-list">
+              <el-card class="box-card">
+                <div class="text item">
+                  <span v-html="item1.questionContent" />
+                  <el-divider />
+                  <editor
+                    :id="item1.questionId+''"
+                    v-model="userAnswerMap[item1.questionId][0]"
+                    :init="init"
+                    style="width: 50%"
+                  />
+                </div>
+              </el-card>
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
-        </div>
-        <div v-else-if="key === '8'">
-          <h1>组合题</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
+          <div v-else-if="key === '8'">
+            <h1>组合题</h1>
+            <div v-for="(item1, index1) in values" :key="index1">
+              <span v-html="item1.questionContent" />
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
-        </div>
-        <div v-else>
-          <h1>未知试题类型</h1>
-          <div v-for="(item1, index1) in values" :key="index1">
-            <span v-html="item1.questionContent" />
+          <div v-else>
+            <h1>未知试题类型</h1>
+            <div v-for="(item1, index1) in values" :key="index1">
+              <span v-html="item1.questionContent" />
+            </div>
+            <el-divider />
           </div>
           </div>
-          <el-divider />
         </div>
         </div>
-      </div>
+      </el-col>
     </el-main>
     </el-main>
+    <el-footer height="220">
+      <el-row style="margin-top: 10px">
+        <el-button type="primary" icon="el-icon-upload" style="float: right; padding: 3px 0" plain @click="onSubmitPaper">
+          提交试卷
+        </el-button>
+      </el-row>
+    </el-footer>
   </el-container>
   </el-container>
 </template>
 </template>
 
 
@@ -115,21 +143,16 @@ import 'tinymce/themes/silver/theme.min.js'
 import 'tinymce/icons/default/icons'
 import 'tinymce/icons/default/icons'
 import Editor from '@tinymce/tinymce-vue'
 import Editor from '@tinymce/tinymce-vue'
 
 
-import { getPaper } from '@/api/exam'
+import { cacheUserAnswer, getPaper, submitExam } from '@/api/exam'
 
 
 export default {
 export default {
   name: 'ExamQuestionCard',
   name: 'ExamQuestionCard',
   components: { Editor },
   components: { Editor },
   data() {
   data() {
     return {
     return {
-      radioMap: new Map(),
-      // 单选题
-      selectRadioArr: [],
-      // 判断题
-      judgeRadioArr: [],
-      radio: '',
-      radio1: '',
-      checkList: [],
+      radio: '3',
+      checkList: ['2', '3'],
+      checkList1: [2, 3],
       inputContent: '',
       inputContent: '',
       editorContent: '',
       editorContent: '',
       // 屏幕宽度, 为了控制分页条的大小
       // 屏幕宽度, 为了控制分页条的大小
@@ -151,7 +174,7 @@ export default {
         branding: false,
         branding: false,
         init_instance_callback: (editor) => {
         init_instance_callback: (editor) => {
           editor.on('focus', (e) => {
           editor.on('focus', (e) => {
-            this.$message.info('editor focus')
+            // this.$message.info('editor focus')
           })
           })
           editor.on('blur', (e) => {
           editor.on('blur', (e) => {
             var content = editor.getContent()
             var content = editor.getContent()
@@ -180,14 +203,23 @@ export default {
           answer: []
           answer: []
         }
         }
       ],
       ],
-      answerMap: new Map()
+      userAnswerMap: null,
+      paperId: 0,
+      paperInfo: {
+        name: '',
+        duration: 0,
+        totalScore: 0
+      },
+      paperViewType: [
+        '预览', '答卷', '阅卷', '结果'
+      ]
     }
     }
   },
   },
   created() {
   created() {
     document.title = '试卷详情'
     document.title = '试卷详情'
 
 
-    const paperId = 3
-    this.getPaperDetail(paperId)
+    this.paperId = this.$route.params.paperId
+    this.getPaperDetail(this.paperId)
   },
   },
   methods: {
   methods: {
     renderByMathjax() {
     renderByMathjax() {
@@ -204,26 +236,12 @@ export default {
       getPaper(paperId).then((resp) => {
       getPaper(paperId).then((resp) => {
         if (resp.code === 0) {
         if (resp.code === 0) {
           const respData = resp.data
           const respData = resp.data
-          /* this.examInfo.paperId = respData.paperId
-          this.examInfo.name = respData.name
-          this.examInfo.description = respData.description
-          this.examInfo.duration = respData.duration
-          this.examInfo.totalScore = respData.totalScore*/
+          this.paperInfo.name = respData.name
+          this.paperInfo.duration = respData.duration
+          this.paperInfo.totalScore = respData.totalScore
 
 
           this.questionMap = respData.questionMap
           this.questionMap = respData.questionMap
-          for (var key in this.questionMap) {
-            for (var item of this.questionMap[key]) {
-              this.answerMap.set(item.questionId, {
-                questionId: item.questionId,
-                answers: []
-              })
-            }
-          }
-          /* this.questionList = respData.questions
-          // 重置问题的顺序 单选 ->  -> 判断 -> 简答
-          this.questionList = this.questionList.sort(function(a, b) {
-            return a.questionType - b.questionType
-          })*/
+          this.userAnswerMap = respData.userResult.cachedUserAnswers
           this.renderByMathjax()
           this.renderByMathjax()
         } else {
         } else {
           this.$message.error(resp.msg)
           this.$message.error(resp.msg)
@@ -236,6 +254,7 @@ export default {
         cancelButtonText: '取消',
         cancelButtonText: '取消',
         type: 'warning'
         type: 'warning'
       }).then(() => {
       }).then(() => {
+        this.submitPaper()
         this.$notify({
         this.$notify({
           title: 'Tips',
           title: 'Tips',
           message: '试卷已提交, 继续加油! *^▽^*',
           message: '试卷已提交, 继续加油! *^▽^*',
@@ -252,24 +271,69 @@ export default {
       })
       })
     },
     },
     onRadioChange(val, item) {
     onRadioChange(val, item) {
-      this.$message.info('change event: ' + val + ' -> ' + item.questionId)
-      this.$set(this.radioMap, item.questionId, val)
-      this.selectRadioArr[item.pos - 1] = val
-      this.answerMap.get(item.questionId).answers[0] = val
-      console.log(this.answerMap)
+      // this.$message.info('change event: ' + val + ' -> ' + item.questionId)
+      this.cacheAnswer()
     },
     },
     onCheckboxChange(val, item) {
     onCheckboxChange(val, item) {
-      this.$message.info('change event: ' + val + ' -> ' + item.questionId)
+      // this.$message.info('change event: ' + val + ' -> ' + item.questionId)
+      this.cacheAnswer()
     },
     },
     onInputBlur(val, item) {
     onInputBlur(val, item) {
-      this.$message.info('blur event: ' + val + ' -> ' + item.questionId)
+      // this.$message.info('blur event: ' + val + ' -> ' + item.questionId)
+      this.cacheAnswer()
     },
     },
     onEditorBlur(val) {
     onEditorBlur(val) {
-      this.$message.info('editor blur -> ' + this.editorContent)
+      // this.$message.info('editor blur -> ' + this.editorContent)
+      this.cacheAnswer()
+    },
+    cacheAnswer() {
+      var userAnswers = []
+      for (const key in this.userAnswerMap) {
+        const userAnswer = {}
+        userAnswer.questionId = key
+        userAnswer.answers = this.userAnswerMap[key]
+        userAnswers.push(userAnswer)
+      }
+
+      var userResult = {}
+      userResult.paperId = this.paperId
+      userResult.userAnswers = userAnswers
+      cacheUserAnswer(userResult).then(resp => {
+        if (resp.code !== 0) {
+          console.log(resp.msg)
+        }
+      }).catch((e) => {
+        console.log(e)
+      })
+    },
+    submitPaper() {
+      var userAnswers = []
+      for (const key in this.userAnswerMap) {
+        const userAnswer = {}
+        userAnswer.questionId = key
+        userAnswer.answers = this.userAnswerMap[key]
+        userAnswers.push(userAnswer)
+      }
+
+      var userResult = {}
+      userResult.paperId = this.paperId
+      userResult.userAnswers = userAnswers
+      submitExam(userResult).then(resp => {
+        if (resp.code !== 0) {
+          console.log(resp.msg)
+        }
+      }).catch((e) => {
+        console.log(e)
+      })
     }
     }
   }
   }
 }
 }
 </script>
 </script>
 
 
 <style>
 <style>
+.movie-list {
+  padding-top: 3px;
+  padding-left: 3px;
+  padding-right: 3px;
+}
 </style>
 </style>