瀏覽代碼

在 ExamPaperPreview.vue 中修改做试卷时对答案处理
使用 el-radio-group 来处理单选和判断题
使用 el-checkbox-group 来处理多选和不定项选择题
使用 el-input 来处理填空题和问答题

现在可完成试卷并提交答案, 提交答案的数据格式也做了些许更改

reghao 1 年之前
父節點
當前提交
f39f795c0a

+ 4 - 0
src/api/exam.js

@@ -55,6 +55,10 @@ export function addPaper(data) {
   return post(examApi.addPaper, data)
 }
 
+export function deletePaper(paperId) {
+  return delete0(examApi.addPaper + '/' + paperId)
+}
+
 export function getExamInfo(paperId) {
   return get(examApi.startExam + '/' + paperId)
 }

+ 31 - 1
src/views/exam/ExamPaper.vue

@@ -76,6 +76,11 @@
               type="warning"
               @click="previewPaper(scope.$index, scope.row)"
             >预览</el-button>
+            <el-button
+              size="mini"
+              type="warning"
+              @click="handleDelete(scope.$index, scope.row)"
+            >删除</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -95,7 +100,8 @@
 </template>
 
 <script>
-import { getSubjectKV, getPapers } from '@/api/exam'
+import {getSubjectKV, getPapers, deletePaper} from '@/api/exam'
+import {deleteArticle} from "@/api/article";
 
 export default {
   name: 'ExamPaper',
@@ -166,6 +172,30 @@ export default {
       this.queryInfo.pageSize = this.pageSize
       this.getData(this.queryInfo)
     },
+    handleDelete(index, row) {
+      this.$confirm('确定要删除 ' + row.examName + '?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deletePaper(row.examId).then(resp => {
+          if (resp.code === 0) {
+            this.$notify({
+              title: '提示',
+              message: '稿件已删除',
+              type: 'warning',
+              duration: 3000
+            })
+            this.$router.go(0)
+          }
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
     previewPaper(index, row) {
       const paperId = row.examId
       this.$router.push('/exam/paper/preview/' + paperId)

+ 91 - 5
src/views/exam/ExamPaperAdd.vue

@@ -35,7 +35,7 @@
         <div v-show="makeModel === 1" style="margin-top: 25px">
           <el-button icon="el-icon-plus" size="mini" @click="showAddDialog">添加试题</el-button>
           <el-table :data="addExamQuestion1" border style="margin-top: 10px">
-            <el-table-column type="index" label="顺序"/>
+            <el-table-column type="index" label="顺序" />
             <el-table-column label="题目内容" align="center">
               <template slot-scope="scope">
                 {{ scope.row.content.substr(0, 20) }}
@@ -48,7 +48,15 @@
             />
             <el-table-column label="单题分数" align="center">
               <template slot-scope="scope">
-                <el-input-number v-model="scope.row.score" :min="1" :max="20" style="margin-left: 5px" />
+                <div v-if="scope.row.typeCode !== 8">
+                  <el-input-number v-model="scope.row.score" :min="1" :max="20" style="margin-left: 5px" />
+                </div>
+                <div v-else>
+                  <el-button icon="el-icon-plus" size="mini" @click="showGroupDialog(scope.row.questionId)">
+                    设置组合题分数
+                  </el-button>
+                  <span>{{scope.row.score}}</span>
+                </div>
               </template>
             </el-table-column>
             <el-table-column label="操作" width="80" align="center">
@@ -276,11 +284,51 @@
         @next-click="handleCurrentChange"
       />
     </el-dialog>
+    <el-dialog title="组合题分数设置" :visible.sync="showGroupQuestionDialog" width="80%" center>
+      <el-button icon="el-icon-plus" size="mini" @click="confirmChildScore">确定</el-button>
+      <el-table
+        highlight-current-row
+        :border="true"
+        :data="groupQuestionList"
+        tooltip-effect="dark"
+        style="width: 100%;margin-top: 25px;"
+      >
+        <el-table-column
+          align="center"
+          type="selection"
+          width="55"
+        />
+        <el-table-column
+          align="center"
+          label="题目类型"
+          prop="type"
+        />
+        <el-table-column align="center" label="题目内容">
+          <template slot-scope="scope">
+            <span class="quContent">{{ scope.row.content.substr(0, 20) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          align="center"
+          label="单题分数"
+          prop="score"
+        >
+          <template slot-scope="scope">
+            <el-input-number v-model="scope.row.score" :min="1" :max="20" style="margin-left: 5px" />
+          </template>
+        </el-table-column>
+        <el-table-column
+          align="center"
+          prop="subject"
+          label="所属科目"
+        />
+      </el-table>
+    </el-dialog>
   </el-container>
 </template>
 
 <script>
-import { getQuestions, getQuestionType, getSubjectKV, addPaper } from '@/api/exam'
+import { getQuestions, getQuestionType, getSubjectKV, addPaper, getQuestion } from '@/api/exam'
 import { validFormAndInvoke } from '@/utils/util'
 
 export default {
@@ -312,7 +360,10 @@ export default {
       // 添加考试题目信息(makeModel = 2 的时候)
       addExamQuestion2: [],
       // 所有题目的对话框
+      groupQuestionId: null,
       showQuestionDialog: false,
+      showGroupQuestionDialog: false,
+      groupQuestionList: [],
       // 对话框中题目表格的加载
       loading: true,
       // 所有题目的信息
@@ -519,7 +570,9 @@ export default {
             'questionId': item.questionId,
             'content': item.content,
             'type': item.type,
-            'score': 1
+            'typeCode': item.typeCode,
+            'score': 1,
+            'children': []
           })
         }
       })
@@ -567,7 +620,8 @@ export default {
             questions.push({
               pos: item.pos,
               questionId: item.questionId,
-              score: item.score
+              score: item.score,
+              children: item.children
             })
             questionIds.push(item.questionId)
             scores.push(item.score)
@@ -616,6 +670,38 @@ export default {
           duration: 3000
         })
       })
+    },
+    showGroupDialog(questionId) {
+      this.groupQuestionId = questionId
+      this.showGroupQuestionDialog = true
+      getQuestion(questionId).then(resp => {
+        if (resp.code === 0) {
+          this.groupQuestionList = resp.data.children
+          for (const item of this.groupQuestionList) {
+            item.score = 0
+          }
+        }
+      })
+    },
+    confirmChildScore() {
+      this.showGroupQuestionDialog = false
+      var childIds = []
+      var score = 0
+      for (const item of this.groupQuestionList) {
+        score += item.score
+        childIds.push({
+          pid: this.groupQuestionId,
+          questionId: item.questionId,
+          score: item.score
+        })
+      }
+
+      for (const item of this.addExamQuestion1) {
+        if (item.questionId === this.groupQuestionId) {
+          item.score = score
+          item.children = childIds
+        }
+      }
     }
   }
 }

+ 392 - 258
src/views/exam/ExamPaperPreview.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-container v-if="show">
+  <el-container v-if="showPaper">
     <el-header>
       <el-row>
         <el-col style="border-bottom: 1px solid #f5f5f5">
@@ -7,6 +7,13 @@
           <span style="color: red;font-size: 18px;">{{ examInfo.examId }}</span>
           <span class="examTitle">考试时长:</span>
           <span style="color: red;font-size: 18px;">{{ examInfo.examDuration }} 分钟</span>
+          <el-button
+            type="warning"
+            round
+            style="background-color: #ffd550;float: right;color: black;font-weight: 800"
+            @click="uploadExamToAdmin"
+          >提交试卷
+          </el-button>
         </el-col>
       </el-row>
     </el-header>
@@ -14,222 +21,253 @@
     <el-main>
       <el-row>
         <el-col :span="16">
-          <el-card v-for="(item, index) in questionList" :key="index">
-            <!-- 题目信息 -->
-            <div>
-              <span v-if="item.questionType === 1">【单选题】</span>
-              <span v-else-if="item.questionType === 2">【多选题】</span>
-              <span v-else-if="item.questionType === 3">【不定项选择题】</span>
-              <span v-else-if="item.questionType === 4">【判断题】</span>
-              <span v-else-if="item.questionType === 5">【填空题】</span>
-              <span v-else-if="item.questionType === 6">【问答题】</span>
-              <span v-else-if="item.questionType === 7">【理解题】</span>
-              <span v-else>【综合题】</span>
-              <br>
-              <br>
-              <i class="num">{{ index + 1 }}</i>
-              <span v-html="item.questionContent" />
-            </div>
-            <!--题目中的配图-->
-            <img
-              v-for="url in item.images"
-              :src="url"
-              title="点击查看大图"
-              alt="题目图片"
-              style="width: 100px;height: 100px;cursor: pointer"
-              @click="showBigImg(url)"
-            >
+          <el-row v-for="(item, index) in questionMap" :key="index">
+            <el-row class="card-style">
+              <el-card>
+                <!--                <span>{{item[0]}}</span>-->
+                <!--                <span>{{item[1]}}</span>-->
+                <!-- 题目信息 -->
+                <div>
+                  <span v-if="item[1].questionType === 1">【单选题】</span>
+                  <span v-else-if="item[1].questionType === 2">【多选题】</span>
+                  <span v-else-if="item[1].questionType === 3">【不定项选择题】</span>
+                  <span v-else-if="item[1].questionType === 4">【判断题】</span>
+                  <span v-else-if="item[1].questionType === 5">【填空题】</span>
+                  <span v-else-if="item[1].questionType === 6">【问答题】</span>
+                  <span v-else-if="item[1].questionType === 7">【理解题】</span>
+                  <span v-else>【综合题】</span>
+                  <br>
+                  <br>
+                  <i class="num">{{ item[1].pos }}</i>
+                  <span v-html="item[1].questionContent" />
+                  <div v-if="item[1].questionType === 8">
+                    <div v-for="(child, childIndex) in item[1].children" :key="childIndex">
+                      <div>
+                        <span v-html="child.questionContent" />
+                      </div>
+                      <!-- 单选和判断题候选答案列表 -->
+                      <div
+                        v-show="child.questionType === 1 || child.questionType === 4"
+                        style="margin-top: 25px"
+                      >
+                        <el-radio-group
+                          v-for="(ans,ans_index) in child.answer"
+                          :key="ans_index"
+                          v-model="singleChecks[ans.questionId]"
+                          @change="singleCheckChange(child)"
+                        >
+                          <el-radio :label="ans_index">
+                            <span>{{ optionName[ans_index] + '、' + ans.answer }}</span>
+                          </el-radio>
+                        </el-radio-group>
+                      </div>
 
-            <!-- 单选和判断题候选答案列表 -->
-            <div
-              v-show="item.questionType === 1
-                  || item.questionType === 4"
-              style="margin-top: 25px"
-            >
-              <div class="el-radio-group">
-                <label
-                  v-for="(item,index) in item.answer"
-                  :class="index === userAnswer[curIndex] ? 'active' : ''"
-                  @click="checkSingleAnswer(index)"
+                      <!-- 多选和不定项选择题的候选答案列表 -->
+                      <div
+                        v-show="child.questionType === 2 || child.questionType === 3"
+                        style="margin-top: 25px"
+                      >
+                        <el-checkbox-group
+                          v-for="(ans,ans_index) in child.answer"
+                          :key="ans_index"
+                          v-model="multipleChecked[item[1].pos]"
+                          @change="multipleCheckChange(child)"
+                        >
+                          <el-checkbox :label="ans_index">
+                            <span>{{ optionName[ans_index] + '、' + ans.answer }}</span>
+                          </el-checkbox>
+                        </el-checkbox-group>
+                      </div>
+
+                      <!-- 填空题和问答题的回答区 -->
+                      <div
+                        v-show="child.questionType === 5 || child.questionType === 6"
+                        style="margin-top: 25px"
+                      >
+                        <el-input
+                          v-model="userAnswer[curIndex]"
+                          type="textarea"
+                          :rows="8"
+                          placeholder="请输入答案"
+                        />
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+                <!-- 单选和判断题候选答案列表 -->
+                <div
+                  v-show="item[1].questionType === 1 || item[1].questionType === 4"
+                  style="margin-top: 25px"
                 >
-                  <span>{{ optionName[index] + '、' + item.answer }}</span>
-                  <img
-                    v-for="i2 in item.images"
-                    v-if="item.images !== null"
-                    style="position: absolute;left:100%;top:50%;transform: translateY(-50%);width: 40px;height: 40px;float: right;cursor: pointer;"
-                    title="点击查看大图"
-                    :src="i2"
-                    alt=""
-                    @mouseover="showBigImg(i2)"
+                  <el-radio-group
+                    v-for="(ans,ans_index) in item[1].answer"
+                    :key="ans_index"
+                    v-model="singleChecks[ans.questionId]"
+                    @change="singleCheckChange(item[1])"
                   >
-                </label>
-              </div>
-            </div>
+                    <el-radio :label="ans_index">
+                      <span>{{ optionName[ans_index] + '、' + ans.answer }}</span>
+                    </el-radio>
+                  </el-radio-group>
+                </div>
 
-            <!-- 多选和不定项选择题的候选答案列表 -->
-            <div
-              v-show="item.questionType === 2
-                  || item.questionType === 3"
-              style="margin-top: 25px"
-            >
-              <div class="el-radio-group">
-                <label
-                  v-for="(item,index) in item.answer"
-                  :class="(userAnswer[curIndex]+'').indexOf(index+'') !== -1? 'active' : ''"
-                  @click="selectedMultipleAnswer(index)"
+                <!-- 多选和不定项选择题的候选答案列表 -->
+                <div
+                  v-show="item[1].questionType === 2 || item[1].questionType === 3"
+                  style="margin-top: 25px"
                 >
-                  <span>{{ optionName[index] + '、' + item.answer }}</span>
-                  <img
-                    v-for="i2 in item.images"
-                    v-if="item.images !== null"
-                    style="position: absolute;left:100%;top:50%;transform: translateY(-50%);
-                  width: 40px;height: 40px;float: right;cursor: pointer;"
-                    title="点击查看大图"
-                    :src="i2"
-                    alt=""
-                    @mouseover="showBigImg(i2)"
+                  <el-checkbox-group
+                    v-for="(ans,ans_index) in item[1].answer"
+                    :key="ans_index"
+                    v-model="multipleChecked[item[1].pos]"
+                    @change="multipleCheckChange(item[1])"
                   >
-                </label>
-              </div>
-            </div>
-
-            <!-- 填空题和问答题的回答区 -->
-            <div
-              v-show="item.questionType === 5
-                  || item.questionType === 6"
-              style="margin-top: 25px"
-            >
-              <el-input
-                v-model="userAnswer[curIndex]"
-                type="textarea"
-                :rows="8"
-                placeholder="请输入答案"
-              />
-            </div>
+                    <el-checkbox :label="ans_index">
+                      <span>{{ optionName[ans_index] + '、' + ans.answer }}</span>
+                    </el-checkbox>
+                  </el-checkbox-group>
+                </div>
 
-            <!-- 综合题的回答区 -->
-            <div
-              v-show="item.questionType === 8"
-              style="margin-top: 25px"
-            >
-              <el-input
-                v-model="userAnswer[curIndex]"
-                type="textarea"
-                :rows="8"
-                placeholder="请输入答案"
-              />
-            </div>
-          </el-card>
+                <!-- 填空题的回答区 -->
+                <div
+                  v-show="item[1].questionType === 5"
+                  style="margin-top: 25px"
+                >
+                  <el-input
+                    v-model="question5[item[1].questionId]"
+                    type="text"
+                    placeholder="请输入答案"
+                    @blur="onInputBlur(item[1])"
+                  />
+                </div>
+                <!-- 问答题的回答区 -->
+                <div
+                  v-show="item[1].questionType === 6"
+                  style="margin-top: 25px"
+                >
+                  <el-input
+                    v-model="question6[item[1].questionId]"
+                    type="textarea"
+                    :rows="8"
+                    placeholder="请输入答案"
+                    @blur="onInputBlur(item[1])"
+                  />
+                </div>
+              </el-card>
+            </el-row>
+          </el-row>
         </el-col>
         <!-- 答题卡 -->
         <el-col :span="8">
-          <el-card>
-            <div>
-              <p style="font-size: 18px;">答题卡</p>
-            </div>
-            <!-- 单选的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">单选题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 1"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-                :class="questionList[item-1].questionType === 1 && userAnswer[item-1] !== undefined ?
+          <el-row class="card-style">
+            <el-card>
+              <div>
+                <p style="font-size: 18px;">答题卡</p>
+              </div>
+              <!-- 单选的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">单选题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 1"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                  :class="questionList[item-1].questionType === 1 && userAnswer[item-1] !== undefined ?
                     'done' : userAnswer[item-1] === undefined ? curIndex === (item-1) ? 'orange' : 'noAnswer' : 'noAnswer'"
-              >{{ item }}
-              </el-button>
-            </div>
-
-            <!-- 多选的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">多选题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 2"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-              >{{ item }}
-              </el-button>
-            </div>
-            <!-- 不定项选择题的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">不定项选择题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 3"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-                :class="questionList[item-1].questionType === 3 && userAnswer[item-1] !== undefined ?
+                >{{ item }}
+                </el-button>
+              </div>
+              <!-- 多选的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">多选题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 2"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                >{{ item }}
+                </el-button>
+              </div>
+              <!-- 不定项选择题的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">不定项选择题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 3"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                  :class="questionList[item-1].questionType === 3 && userAnswer[item-1] !== undefined ?
                     'done' : userAnswer[item-1] === undefined ? curIndex === (item-1) ? 'orange' : 'noAnswer' : 'noAnswer'"
-              >{{ item }}
-              </el-button>
-            </div>
+                >{{ item }}
+                </el-button>
+              </div>
 
-            <!-- 判断题的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">判断题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 4"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-                :class="questionList[item-1].questionType === 4 && userAnswer[item-1] !== undefined ?
+              <!-- 判断题的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">判断题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 4"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                  :class="questionList[item-1].questionType === 4 && userAnswer[item-1] !== undefined ?
                     'done' : userAnswer[item-1] === undefined ? curIndex === (item-1) ? 'orange' : 'noAnswer' : 'noAnswer'"
-              >{{ item }}
-              </el-button>
-            </div>
+                >{{ item }}
+                </el-button>
+              </div>
 
-            <!-- 填空题的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">填空题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 5"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-                :class="questionList[item-1].questionType === 5 && userAnswer[item-1] !== undefined ?
+              <!-- 填空题的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">填空题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 5"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                  :class="questionList[item-1].questionType === 5 && userAnswer[item-1] !== undefined ?
                     'done' : userAnswer[item-1] === undefined ? curIndex === (item-1) ? 'orange' : 'noAnswer' : 'noAnswer'"
-              >{{ item }}
-              </el-button>
-            </div>
+                >{{ item }}
+                </el-button>
+              </div>
 
-            <!-- 问答题的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">问答题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 6"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-                :class="questionList[item-1].questionType === 6 && userAnswer[item-1] !== undefined ?
+              <!-- 问答题的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">问答题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 6"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                  :class="questionList[item-1].questionType === 6 && userAnswer[item-1] !== undefined ?
                     'done' : userAnswer[item-1] === undefined ? curIndex === (item-1) ? 'orange' : 'noAnswer' : 'noAnswer'"
-              >{{ item }}
-              </el-button>
-            </div>
+                >{{ item }}
+                </el-button>
+              </div>
 
-            <!-- 综合题的答题卡 -->
-            <div style="margin-top: 25px">
-              <p style="font-size: 18px;">综合题</p>
-              <el-button
-                v-for="item in questionList.length"
-                v-show="questionList[item-1].questionType === 8"
-                :key="item"
-                style="margin-top: 10px;margin-left: 15px"
-                size="mini"
-                :class="questionList[item-1].questionType === 8 && userAnswer[item-1] !== undefined ?
+              <!-- 综合题的答题卡 -->
+              <div style="margin-top: 25px">
+                <p style="font-size: 18px;">综合题</p>
+                <el-button
+                  v-for="item in questionList.length"
+                  v-show="questionList[item-1].questionType === 8"
+                  :key="item"
+                  style="margin-top: 10px;margin-left: 15px"
+                  size="mini"
+                  :class="questionList[item-1].questionType === 8 && userAnswer[item-1] !== undefined ?
                     'done' : userAnswer[item-1] === undefined ? curIndex === (item-1) ? 'orange' : 'noAnswer' : 'noAnswer'"
-                @click="curIndex = item-1"
-              >{{ item }}
-              </el-button>
-            </div>
-          </el-card>
+                  @click="curIndex = item-1"
+                >{{ item }}
+                </el-button>
+              </div>
+            </el-card>
+          </el-row>
         </el-col>
       </el-row>
     </el-main>
@@ -237,7 +275,7 @@
 </template>
 
 <script>
-import { getExamInfo, getPaperQuestions } from '@/api/exam'
+import {getExamInfo, getPaperQuestions, submitExam} from '@/api/exam'
 
 export default {
   name: 'ExamPaperPreview',
@@ -262,28 +300,45 @@ export default {
       // 页面数据加载
       loading: {},
       // 页面绘制是否开始
-      show: false,
+      showPaper: false,
       // 答案的选项名abcd数据
       optionName: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
       // 考试总时长
       duration: 0,
-      // 摄像头对象
-      mediaStreamTrack: null,
-      // 诚信照片的url
-      takePhotoUrl: [],
-      // 摄像头是否开启
-      cameraOn: false
+      answer: {
+        pos: null,
+        questionId: null,
+        questionType: null,
+        questionAnswer: null,
+        children: []
+      },
+      questionMap: new Map(),
+      childMap: new Map(),
+      userAnswers: new Map(),
+      singleChecks: {},
+      multipleCheck: [],
+      multipleChecked: [
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], [],
+        [], [], [], [], [], [], [], [], [], []
+      ],
+      multipleChecks: {},
+      question5: {},
+      question6: {}
     }
   },
   created() {
-    this.getExamInfo()
-    // 页面数据加载的等待状态栏
-    this.loading = this.$loading({
-      body: true,
-      lock: true,
-      text: '数据拼命加载中,(*╹▽╹*)',
-      spinner: 'el-icon-loading'
-    })
+    document.title = '试卷预览'
+    const paperId = this.$route.params.paperId
+    this.getQuestionInfo1(paperId)
+    this.getExamInfo(paperId)
   },
   methods: {
     renderByMathjax() {
@@ -297,68 +352,147 @@ export default {
       })
     },
     // 查询当前考试的信息
-    getExamInfo() {
-      const paperId = this.$route.params.paperId
+    getExamInfo(paperId) {
       getExamInfo(paperId).then((resp) => {
         if (resp.code === 0) {
           this.examInfo = resp.data
-          var paperId = this.examInfo.examId
-          this.getQuestionInfo1(paperId)
         }
       })
     },
     // 查询考试的题目信息
-    async getQuestionInfo1(paperId) {
-      await getPaperQuestions(paperId).then(resp => {
+    getQuestionInfo1(paperId) {
+      getPaperQuestions(paperId).then(resp => {
         if (resp.code === 0) {
           this.questionList = resp.data || []
-          // 重置问题的顺序 单选 多选 判断 简答
+          // 重置问题的顺序 单选 ->  -> 判断 -> 简答
           this.questionList = this.questionList.sort(function(a, b) {
             return a.questionType - b.questionType
           })
 
+          for (const item of this.questionList) {
+            this.questionMap.set(item.questionId, item)
+            if (item.questionType === 2 || item.questionType === 3) {
+              this.$set(this.multipleChecks, item.questionId, [])
+            } else if (item.questionType === 5) {
+              this.$set(this.question5, item.questionId, null)
+            } else if (item.questionType === 6) {
+              this.$set(this.question6, item.questionId, null)
+            }
+
+            if (item.children !== undefined && item.children !== null) {
+              for (const child of item.children) {
+                this.childMap.set(child.questionId, item.questionId)
+                this.questionMap.set(item.questionId, item)
+                if (child.questionType === 2 || child.questionType === 3) {
+                  this.$set(this.multipleChecks, child.questionId, [])
+                } else if (child.questionType === 5) {
+                  this.$set(this.question5, child.questionId, null)
+                } else if (child.questionType === 6) {
+                  this.$set(this.question6, child.questionId, null)
+                }
+              }
+            }
+          }
+
+          this.showPaper = true
           this.renderByMathjax()
         }
       })
-      this.loading.close()
-      this.show = true
     },
     // ****************************************************************************************************************
-    // 检验单选题的用户选择的答案
-    checkSingleAnswer(index) {
-      this.$set(this.userAnswer, this.curIndex, index)
+    // 单选和判断
+    singleCheckChange(val) {
+      const questionId = val.questionId
+      var pid = this.getPid(questionId)
+      const answer = this.singleChecks[questionId]
+      this.setUserAnswers(val, answer, pid)
     },
-    // 多选题用户的答案选中
-    selectedMultipleAnswer(index) {
-      if (this.userAnswer[this.curIndex] === undefined) { // 当前是多选的第一个答案
-        this.$set(this.userAnswer, this.curIndex, index)
-      } else if (String(this.userAnswer[this.curIndex]).split(',').includes(index + '')) { // 取消选中
-        const newArr = []
-        String(this.userAnswer[this.curIndex]).split(',').forEach(item => {
-          if (item !== '' + index) newArr.push(item)
-        })
-        if (newArr.length === 0) {
-          this.$set(this.userAnswer, this.curIndex, undefined)
-        } else {
-          this.$set(this.userAnswer, this.curIndex, newArr.join(','))
-          // 答案格式化顺序DBAC -> ABCD
-          this.userAnswer[this.curIndex] = String(this.userAnswer[this.curIndex]).split(',').sort(function(a, b) {
-            return a - b
-          }).join(',')
-        }
-      } else if (!((this.userAnswer[this.curIndex] + '').split(',').includes(index + ''))) { // 第n个答案
-        this.$set(this.userAnswer, this.curIndex, this.userAnswer[this.curIndex] += ',' + index)
-        // 答案格式化顺序DBAC -> ABCD
-        this.userAnswer[this.curIndex] = String(this.userAnswer[this.curIndex]).split(',').sort(function(a, b) {
-          return a - b
-        }).join(',')
+    // 多选和不定项选择题
+    multipleCheckChange(val) {
+      var questionId = val.questionId
+      var pid = this.getPid(questionId)
+      var answer = this.multipleChecked[val.pos]
+      var answerStr = answer.join(',')
+      this.setUserAnswers(val, answerStr, pid)
+    },
+    // 填空和问答题
+    onInputBlur(val) {
+      var questionId = val.questionId
+      var pid = this.getPid(questionId)
+      var questionType = val.questionType
+      if (questionType === 5) {
+        const answer = this.question5[questionId]
+        this.setUserAnswers(val, answer, pid)
+      } else if (questionType === 6) {
+        const answer = this.question6[questionId]
+        this.setUserAnswers(val, answer, pid)
       }
     },
-    // ****************************************************************************************************************
-    // 上传用户考试信息进入后台
-    async uploadExamToAdmin() {
+    getPid(questionId) {
+      var pid = this.childMap.get(questionId)
+      if (pid !== undefined && pid !== null) {
+        return pid
+      } else {
+        return 0
+      }
     },
-    submitUserPayload(autoSubmit) {
+    setUserAnswers(question, answer, pid) {
+      const userAnswer = {}
+      userAnswer.questionId = question.questionId
+      userAnswer.questionType = question.questionType
+      userAnswer.pos = question.pos
+      userAnswer.answer = answer
+      userAnswer.pid = pid
+      this.userAnswers.set(userAnswer.questionId, userAnswer)
+    },
+    async uploadExamToAdmin() {
+      for (const item of this.questionMap) {
+        const questionId = item[0]
+        const question = item[1]
+        const questionType = question.questionType
+        if (questionType === 8) {
+          continue
+        }
+
+        const answer = this.userAnswers.get(questionId)
+        if (answer === undefined || answer === null) {
+          console.log(questionId)
+          this.$message.error('试题 ' + question.pos + ' 还未完成')
+        } else {
+          if (answer.answer === null || answer.answer === '') {
+            console.log(questionId)
+            this.$message.error('试题 ' + question.pos + ' 答案不能为空')
+          }
+        }
+      }
+
+      var submitAnswers = []
+      for (const item of this.userAnswers) {
+        submitAnswers.push(item[1])
+      }
+
+      const userResult = {}
+      userResult.paperId = this.examInfo.examId
+      userResult.userAnswers = submitAnswers
+      submitExam(userResult).then((resp) => {
+        if (resp.code === 0) {
+          this.$notify({
+            title: 'Tips',
+            message: '考试结果已提交',
+            type: 'success',
+            duration: 2000
+          })
+          const resultId = resp.data
+          this.$router.push('/exam/result/' + resultId)
+        }
+      }).catch(error => {
+        this.$notify({
+          title: '提示',
+          message: error.message,
+          type: 'error',
+          duration: 3000
+        })
+      })
     }
   }
 }
@@ -445,10 +579,10 @@ export default {
   margin-right: 15px;
 }
 
-.card-list {
-  padding-top: 3%;
-  padding-bottom: 3%;
-  padding-left: 3%;
-  padding-right: 3%;
+.card-style {
+  padding-top: 5px;
+  padding-bottom: 5px;
+  padding-left: 5px;
+  padding-right: 5px;
 }
 </style>

+ 4 - 1
src/views/exam/ExamQuestion.vue

@@ -33,7 +33,7 @@
         />
       </el-row>
       <el-row style="margin-top: 10px">
-        <el-button type="plain" icon="el-icon-plus" @click="addQuTableVisible = true">添加</el-button>
+        <el-button type="plain" icon="el-icon-plus" @click="addExamQuestion">添加</el-button>
       </el-row>
     </el-header>
     <el-main>
@@ -1151,6 +1151,9 @@ export default {
           })
         }
       })
+    },
+    addExamQuestion() {
+      this.$router.push('/exam/question/add')
     }
   }
 }

+ 7 - 5
src/views/exam/ExamQuestionAdd.vue

@@ -51,7 +51,7 @@
                               type="textarea"
                               :rows="5"
                             />-->
-              <editor id="tinymce" v-model='addQuForm.questionContent' :init="init"></editor>
+              <editor id="tinymce" v-model="addQuForm.questionContent" :init="init"></editor>
             </el-form-item>
             <el-form-item label="试题解析" label-width="120px" prop="analysis">
               <el-input
@@ -566,10 +566,12 @@ export default {
           return false
         }
 
-        if (!this.addQuForm.options.some(item => item.correct)) {
-          // 无答案
-          this.$message.error('必须提供答案')
-          return false
+        if (this.addQuForm.questionType !== 8) {
+          if (!this.addQuForm.options.some(item => item.correct)) {
+            // 无答案
+            this.$message.error('必须提供答案')
+            return false
+          }
         }
 
         this.submitExamQuestion()