reghao 1 vuosi sitten
vanhempi
commit
13259be5bc
3 muutettua tiedostoa jossa 463 lisäystä ja 2 poistoa
  1. 7 0
      src/router/exam.js
  2. 2 2
      src/views/exam/ExamPaper.vue
  3. 454 0
      src/views/exam/ExamPaperPreview.vue

+ 7 - 0
src/router/exam.js

@@ -16,6 +16,7 @@ const ExamQuestion = () => import('views/exam/ExamQuestion')
 const ExamQuestionAdd = () => import('views/exam/ExamQuestionAdd')
 const ExamPaper = () => import('views/exam/ExamPaper')
 const ExamPaperAdd = () => import('views/exam/ExamPaperAdd')
+const ExamPaperPreview = () => import('views/exam/ExamPaperPreview')
 const ExamResultIndex = () => import('views/exam/ExamResultIndex')
 const ExamResultPage = () => import('views/exam/ExamResultPage')
 const ExamMarkIndex = () => import('views/exam/ExamMarkIndex')
@@ -81,6 +82,12 @@ export default {
       component: ExamPaperAdd,
       meta: { needAuth: true }
     },
+    {
+      path: '/exam/paper/preview/:paperId',
+      name: 'ExamPaperPreview',
+      component: ExamPaperPreview,
+      meta: { needAuth: true }
+    },
     {
       path: '/exam/marker',
       name: 'ExamMarkIndex',

+ 2 - 2
src/views/exam/ExamPaper.vue

@@ -120,7 +120,6 @@ export default {
     document.title = '试卷管理'
     this.getData(this.queryInfo)
     this.getSubjects()
-    this.getQuestionTypes()
   },
   methods: {
     handleCurrentChange(pageNumber) {
@@ -168,7 +167,8 @@ export default {
       this.getData(this.queryInfo)
     },
     previewPaper(index, row) {
-      this.$message('预览试卷')
+      const paperId = row.examId
+      this.$router.push('/exam/paper/preview/' + paperId)
     },
     addExamPaper() {
       this.$router.push('/exam/paper/add')

+ 454 - 0
src/views/exam/ExamPaperPreview.vue

@@ -0,0 +1,454 @@
+<template>
+  <el-container v-if="show">
+    <el-header>
+      <el-row>
+        <el-col style="border-bottom: 1px solid #f5f5f5">
+          <span class="startExam">试卷名字:</span>
+          <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-col>
+      </el-row>
+    </el-header>
+
+    <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)"
+            >
+
+            <!-- 单选和判断题候选答案列表 -->
+            <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)"
+                >
+                  <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)"
+                  >
+                </label>
+              </div>
+            </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)"
+                >
+                  <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)"
+                  >
+                </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>
+
+            <!-- 综合题的回答区 -->
+            <div
+              v-show="item.questionType === 8"
+              style="margin-top: 25px"
+            >
+              <el-input
+                v-model="userAnswer[curIndex]"
+                type="textarea"
+                :rows="8"
+                placeholder="请输入答案"
+              />
+            </div>
+          </el-card>
+        </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 ?
+                    '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 ?
+                    '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 === 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>
+
+            <!-- 填空题的答题卡 -->
+            <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>
+
+            <!-- 问答题的答题卡 -->
+            <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>
+
+            <!-- 综合题的答题卡 -->
+            <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>
+        </el-col>
+      </el-row>
+    </el-main>
+  </el-container>
+</template>
+
+<script>
+import { getExamInfo, getPaperQuestions } from '@/api/exam'
+
+export default {
+  name: 'ExamPaperPreview',
+  data() {
+    return {
+      // 当前考试的信息
+      examInfo: {},
+      // 当前的考试题目
+      questionList: [
+        {
+          questionType: ''
+        }
+      ],
+      // 当前题目的索引值
+      curIndex: 0,
+      // 控制大图的对话框
+      bigImgDialog: false,
+      // 当前要展示的大图的url
+      bigImgUrl: '',
+      // 用户选择的答案
+      userAnswer: [],
+      // 页面数据加载
+      loading: {},
+      // 页面绘制是否开始
+      show: false,
+      // 答案的选项名abcd数据
+      optionName: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
+      // 考试总时长
+      duration: 0,
+      // 摄像头对象
+      mediaStreamTrack: null,
+      // 诚信照片的url
+      takePhotoUrl: [],
+      // 摄像头是否开启
+      cameraOn: false
+    }
+  },
+  created() {
+    this.getExamInfo()
+    // 页面数据加载的等待状态栏
+    this.loading = this.$loading({
+      body: true,
+      lock: true,
+      text: '数据拼命加载中,(*╹▽╹*)',
+      spinner: 'el-icon-loading'
+    })
+  },
+  methods: {
+    renderByMathjax() {
+      // tinymce 的 mathjax 插件生成的 latex 格式公式放在 className 为 math-tex 的 span 标签内
+      const className = 'math-tex'
+      this.$nextTick(function() {
+        if (this.MathJax.isMathjaxConfig) {
+          this.MathJax.initMathjaxConfig()
+        }
+        this.MathJax.MathQueue1(className)
+      })
+    },
+    // 查询当前考试的信息
+    getExamInfo() {
+      const paperId = this.$route.params.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 => {
+        if (resp.code === 0) {
+          this.questionList = resp.data || []
+          // 重置问题的顺序 单选 多选 判断 简答
+          this.questionList = this.questionList.sort(function(a, b) {
+            return a.questionType - b.questionType
+          })
+
+          this.renderByMathjax()
+        }
+      })
+      this.loading.close()
+      this.show = true
+    },
+    // ****************************************************************************************************************
+    // 检验单选题的用户选择的答案
+    checkSingleAnswer(index) {
+      this.$set(this.userAnswer, this.curIndex, index)
+    },
+    // 多选题用户的答案选中
+    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(',')
+      }
+    },
+    // ****************************************************************************************************************
+    // 上传用户考试信息进入后台
+    async uploadExamToAdmin() {
+    },
+    submitUserPayload(autoSubmit) {
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+* {
+  font-weight: 800;
+}
+
+.el-container {
+  width: 100%;
+  height: 100%;
+}
+
+.startExam {
+  color: #160f58;
+  border-bottom: 4px solid #ffd550;
+  font-size: 18px;
+  font-weight: 700;
+  padding-bottom: 10px
+}
+
+.examTitle {
+  font-size: 18px;
+  color: #cbcacf;
+  margin-left: 20px;
+  font-weight: 700;
+}
+
+.el-radio-group label {
+  display: block;
+  width: 400px;
+  padding: 48px 20px 10px 20px;
+  border-radius: 4px;
+  border: 1px solid #dcdfe6;
+  margin-bottom: 10px;
+  cursor: pointer;
+  position: relative;
+
+  span {
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    font-size: 16px;
+  }
+}
+
+.el-radio-group label:hover {
+  background-color: rgb(245, 247, 250);
+}
+
+/*当前选中的答案*/
+.active {
+  border: 1px solid #1f90ff !important;
+  opacity: .5;
+}
+
+/*做过的题目的高亮颜色*/
+.done {
+  background-color: rgb(87, 148, 247);
+}
+
+/*未做题目的高亮颜色*/
+.noAnswer {
+  background-color: rgb(238, 238, 238);
+}
+
+/*当前在做的题目高亮的颜色*/
+.orange {
+  background-color: rgb(255, 213, 80);
+}
+
+.num {
+  display: inline-block;
+  background: url('../../assets/img/examTitle.png') no-repeat 95%;
+  background-size: contain;
+  height: 37px;
+  width: 37px;
+  line-height: 30px;
+  color: #fff;
+  font-size: 20px;
+  text-align: center;
+  margin-right: 15px;
+}
+
+.card-list {
+  padding-top: 3%;
+  padding-bottom: 3%;
+  padding-left: 3%;
+  padding-right: 3%;
+}
+</style>