Explorar o código

update views/exam

reghao hai 7 meses
pai
achega
04e954ac64

+ 25 - 9
src/api/exam.js

@@ -7,16 +7,20 @@ const examApi = {
   getQuestion: '/api/content/exam/question',
   addQuestion: '/api/content/exam/question',
   getPaper: '/api/content/exam/paper',
+  getPaperDetail: '/api/content/exam/paper/detail',
   getPaperKeyValue: '/api/content/exam/paper/kv',
   addPaper: '/api/content/exam/paper',
-  startExam: '/api/content/exam/start',
-  submitExam: '/api/content/exam/submit',
-  cacheUserAnswer: '/api/content/exam/cache',
-  getExamResult: '/api/content/exam/result/view',
+  examList: '/api/content/exam/eval/list',
+  startExam: '/api/content/exam/eval/start',
+  cacheUserAnswer: '/api/content/exam/eval/cache',
+  submitExam: '/api/content/exam/eval/submit',
+  getMarkView: '/api/content/exam/mark/view',
+  submitExamMark: '/api/content/exam/mark/submit',
   getExamMark: '/api/content/exam/result/mark',
-  submitExamMark: '/api/content/exam/result/mark'
 }
 
+// *********************************************************************************************************************
+// 科目接口
 export function getSubject() {
   return get(examApi.getSubject)
 }
@@ -25,6 +29,8 @@ export function getSubjectKV() {
   return get(examApi.getSubjectKV)
 }
 
+// *********************************************************************************************************************
+// 试题接口
 export function getQuestionType() {
   return get(examApi.getQuestionType)
 }
@@ -45,12 +51,14 @@ export function addQuestion(data) {
   return post(examApi.addQuestion, data)
 }
 
+// *********************************************************************************************************************
+// 试卷接口
 export function getPapers(param) {
   return get(examApi.getPaper, param)
 }
 
-export function getPaper(paperId, viewType) {
-  return get(examApi.getPaper + '/' + paperId + '?viewType=' + viewType)
+export function getPaper(paperId, viewType, userId) {
+  return get(examApi.getPaperDetail + '?paperId=' + paperId + '&viewType=' + viewType + '&userId=' + userId)
 }
 
 export function getPaperKeyValues() {
@@ -65,6 +73,12 @@ export function deletePaper(paperId) {
   return delete0(examApi.addPaper + '/' + paperId)
 }
 
+// *********************************************************************************************************************
+// 考试接口
+export function getExamList() {
+  return get(examApi.examList)
+}
+
 export function getExamInfo(paperId) {
   return get(examApi.startExam + '/' + paperId)
 }
@@ -81,8 +95,10 @@ export function cacheUserAnswer(data) {
   return post(examApi.cacheUserAnswer, data)
 }
 
-export function getExamResult(examId) {
-  return get(examApi.getExamResult + '/' + examId)
+// *********************************************************************************************************************
+// 阅卷接口
+export function getMarkView(paperId) {
+  return get(examApi.getMarkView + '/' + paperId)
 }
 
 export function getExamMarkList(params) {

+ 17 - 18
src/router/exam.js

@@ -1,21 +1,20 @@
 // ********************************************************************************************************************
 // 后台主页
 // ********************************************************************************************************************
-const ExamIndex = () => import('views/exam/ExamIndex')
 const Exam = () => import('views/exam/Exam')
 const ExamDashboard = () => import('views/exam/ExamDashboard')
-const ExamList = () => import('views/exam/ExamList')
-const ExamCard = () => import('views/exam/ExamCard')
 const ExamSubject = () => import('views/exam/ExamSubject')
-const ExamQuestion = () => import('views/exam/ExamQuestion')
+const ExamQuestionList = () => import('views/exam/ExamQuestionList')
 const ExamQuestionAdd = () => import('views/exam/ExamQuestionAdd')
-const ExamPaper = () => import('views/exam/ExamPaper')
+const ExamPaperList = () => import('views/exam/ExamPaperList')
 const ExamPaperAdd = () => import('views/exam/ExamPaperAdd')
 const ExamPaperPreview = () => import('views/exam/ExamPaperPreview')
+const ExamEvalList = () => import('views/exam/ExamEvalList')
+const ExamCard = () => import('views/exam/ExamCard')
 const ExamScoreIndex = () => import('views/exam/ExamScoreIndex')
 const ExamPaperResult = () => import('views/exam/ExamPaperResult')
 const ExamMarkIndex = () => import('views/exam/ExamMarkIndex')
-const ExamPaperCard = () => import('views/exam/ExamQuestionCard')
+const ExamPaperDetail = () => import('views/exam/ExamPaperDetail')
 
 export default {
   path: '/exam',
@@ -25,8 +24,8 @@ export default {
   children: [
     {
       path: '',
-      name: 'ExamIndex',
-      component: ExamIndex,
+      name: 'ExamDashboard',
+      component: ExamDashboard,
       meta: { needAuth: true }
     },
     {
@@ -73,8 +72,8 @@ export default {
     },
     {
       path: '/exam/question',
-      name: 'ExamQuestion',
-      component: ExamQuestion,
+      name: 'ExamQuestionList',
+      component: ExamQuestionList,
       meta: { needAuth: true }
     },
     {
@@ -85,8 +84,8 @@ export default {
     },
     {
       path: '/exam/paper',
-      name: 'ExamPaper',
-      component: ExamPaper,
+      name: 'ExamPaperList',
+      component: ExamPaperList,
       meta: { needAuth: true }
     },
     {
@@ -102,9 +101,9 @@ export default {
       meta: { needAuth: true }
     },
     {
-      path: '/exam/list',
-      name: 'ExamList',
-      component: ExamList,
+      path: '/exam/eval',
+      name: 'ExamEvalList',
+      component: ExamEvalList,
       meta: { needAuth: true }
     },
     {
@@ -114,9 +113,9 @@ export default {
       meta: { needAuth: true }
     },
     {
-      path: '/exam/paper/card/:paperId',
-      name: 'ExamPaperCard',
-      component: ExamPaperCard,
+      path: '/exam/paper/detail',
+      name: 'ExamPaperDetail',
+      component: ExamPaperDetail,
       meta: { needAuth: true }
     }
   ]

+ 20 - 22
src/views/exam/Exam.vue

@@ -5,7 +5,7 @@
         <ul class="el-menu--horizontal el-menu">
           <li class="el-menu-item">
             <a href="/exam" style="text-decoration-line: none">
-              <img src="@/assets/img/icon/logo.png" class="el-avatar--circle el-avatar--medium" alt="img">
+              <img src="@/assets/img/icon/like.png" class="el-avatar--circle el-avatar--medium" alt="img">
               exam
             </a>
           </li>
@@ -18,23 +18,7 @@
           mode="horizontal"
           :unique-opened="true"
         >
-          <el-submenu index="/exam/my">
-            <template slot="title">
-              <i class="el-icon-user" />
-              <span slot="title">我的考试</span>
-            </template>
-            <el-menu-item-group>
-              <el-menu-item index="/exam/list">
-                <i class="el-icon-film" />
-                <span slot="title">考试列表</span>
-              </el-menu-item>
-              <el-menu-item index="/exam/score">
-                <i class="el-icon-film" />
-                <span slot="title">我的成绩</span>
-              </el-menu-item>
-            </el-menu-item-group>
-          </el-submenu>
-          <el-submenu index="/exam/question">
+          <el-submenu index="/exam/admin">
             <template slot="title">
               <i class="el-icon-user" />
               <span slot="title">考试管理</span>
@@ -62,6 +46,22 @@
               </el-menu-item>
             </el-menu-item-group>
           </el-submenu>
+          <el-submenu index="/exam/user">
+            <template slot="title">
+              <i class="el-icon-user" />
+              <span slot="title">我的考试</span>
+            </template>
+            <el-menu-item-group>
+              <el-menu-item index="/exam/eval">
+                <i class="el-icon-film" />
+                <span slot="title">考试列表</span>
+              </el-menu-item>
+              <el-menu-item index="/exam/score">
+                <i class="el-icon-film" />
+                <span slot="title">我的成绩</span>
+              </el-menu-item>
+            </el-menu-item-group>
+          </el-submenu>
         </el-menu>
       </el-col>
       <el-col :md="2">
@@ -100,6 +100,7 @@ import { userMixin } from 'assets/js/mixin'
 import { getAuthedUser } from '@/utils/auth'
 
 export default {
+  name: 'Exam',
   mixins: [userMixin],
   data() {
     return {
@@ -108,10 +109,7 @@ export default {
   },
   created() {
     document.title = '考试系统'
-    const userInfo = getAuthedUser()
-    if (userInfo !== null) {
-      this.user = userInfo
-    }
+    this.user = getAuthedUser()
   }
 }
 </script>

+ 56 - 42
src/views/exam/ExamDashboard.vue

@@ -1,27 +1,61 @@
 <template>
-  <el-container>
-    <el-row>
-      <el-row class="card-style">
+  <el-row>
+    <el-row class="movie-list">
+      <el-card>
+        <div slot="header" class="clearfix">
+          <span>ExamSysDiagram</span>
+        </div>
+        <div>
+          <el-steps active="0" simple>
+            <el-step title="管理员" icon="el-icon-s-custom" />
+            <el-step title="普通用户" icon="el-icon-user" />
+          </el-steps>
+          <el-steps active="0" finish-status="success" simple style="margin-top: 20px">
+            <el-step title="科目" icon="el-icon-s-grid" />
+            <el-step title="试题" icon="el-icon-tickets" />
+            <el-step title="试卷" icon="el-icon-notebook-2" />
+          </el-steps>
+          <el-steps active="0" finish-status="success" simple style="margin-top: 20px">
+            <el-step title="试卷列表" icon="el-icon-files" />
+            <el-step title="试卷测评" icon="el-icon-loading" />
+            <el-step title="试卷批改" icon="el-icon-edit" />
+            <el-step title="试卷结果" icon="el-icon-s-data" />
+          </el-steps>
+        </div>
+      </el-card>
+    </el-row>
+    <el-row class="movie-list">
+      <el-card>
+        <div slot="header" class="clearfix">
+          <span style="margin-right: 5px">选择图表</span>
+          <el-select
+            v-model="selectedValue"
+            clearable
+            placeholder="选择图表"
+            @change="onSelectChange"
+          >
+            <el-option label="考试通过率" value="1" />
+            <el-option label="考试次数占比" value="2" />
+            <el-option label="考试通过率折线图" value="3" />
+            <el-option label="新用户激活数" value="4" />
+          </el-select>
+        </div>
+        <div id="chart1" style="height:400px;" />
+      </el-card>
+    </el-row>
+    <el-row class="movie-list">
+      <el-col :md="12" class="movie-list">
         <el-card>
-          <div slot="header" class="clearfix">
-            <span>选择图表</span>
-            <el-select v-model="selectedValue" placeholder="选择图表" @change="onSelectChange">
-              <el-option label="考试通过率" value="1" />
-              <el-option label="考试次数占比" value="2" />
-              <el-option label="考试通过率折线图" value="3" />
-              <el-option label="新用户激活数" value="4" />
-            </el-select>
-          </div>
-          <div id="chart1" style="width: 800px;height:400px;" />
+          <div id="chart2" style="height:400px;" />
         </el-card>
-      </el-row>
-      <el-row class="card-style">
+      </el-col>
+      <el-col :md="12" class="movie-list">
         <el-card>
-          <div id="chart2" style="width: 800px;height:400px;" />
+          <div id="chart3" style="height:400px;" />
         </el-card>
-      </el-row>
+      </el-col>
     </el-row>
-  </el-container>
+  </el-row>
 </template>
 
 <script>
@@ -313,29 +347,9 @@ export default {
 </script>
 
 <style scoped lang="scss">
-.el-container {
-  width: 100%;
-  height: 100%;
-}
-.el-container {
-  animation: leftMoveIn .7s ease-in;
-}
-
-@keyframes leftMoveIn {
-  0% {
-    transform: translateX(-100%);
-    opacity: 0;
-  }
-  100% {
-    transform: translateX(0%);
-    opacity: 1;
-  }
-}
-
-.card-style {
-  padding-top: 3px;
-  padding-bottom: 3px;
-  padding-left: 3px;
-  padding-right: 3px;
+.movie-list {
+  padding-top: 5px;
+  padding-left: 5px;
+  padding-right: 5px;
 }
 </style>

+ 12 - 9
src/views/exam/ExamList.vue → src/views/exam/ExamEvalList.vue

@@ -56,7 +56,7 @@
         />
         <el-table-column
           prop="passScore"
-          label="及格分数"
+          label="我的分数"
         />
         <el-table-column
           fixed="right"
@@ -137,10 +137,10 @@
 </template>
 
 <script>
-import { getSubjectKV, getPapers } from '@/api/exam'
+import { getSubjectKV, getExamList } from '@/api/exam'
 
 export default {
-  name: 'ExamIndex',
+  name: 'ExamEvalList',
   data() {
     return {
       // 屏幕宽度, 为了控制分页条的大小
@@ -180,7 +180,7 @@ export default {
       scrollTo(0, 0)
     },
     getData(queryInfo) {
-      getPapers(queryInfo).then(resp => {
+      getExamList(queryInfo).then(resp => {
         if (resp.code === 0) {
           this.dataList = resp.data.list
           this.totalSize = resp.data.totalSize
@@ -238,8 +238,9 @@ export default {
     },
     startExam(paperId) {
       const routeUrl = this.$router.resolve({
-        path: '/exam/paper/card/' + paperId,
+        path: '/exam/paper/detail',
         query: {
+          paperId: paperId,
           viewType: 2
         }
       })
@@ -252,19 +253,21 @@ export default {
     markPaper(index, row) {
       const paperId = row.examId
       const routeUrl = this.$router.resolve({
-        path: '/exam/paper/card/' + paperId,
+        path: '/exam/paper/detail',
         query: {
-          viewType: 3
+          paperId: paperId,
+          viewType: 3,
+          userId: ''
         }
       })
       window.open(routeUrl.href, '_blank')
     },
     viewResult(index, row) {
       const paperId = row.examId
-      this.$message.info('查看结果 -> ' + paperId)
       const routeUrl = this.$router.resolve({
-        path: '/exam/paper/card/' + paperId,
+        path: '/exam/paper/detail',
         query: {
+          paperId: paperId,
           viewType: 4
         }
       })

+ 0 - 292
src/views/exam/ExamIndex.vue

@@ -1,292 +0,0 @@
-<template>
-  <el-container>
-    <el-row>
-      <el-row class="card-style">
-        <el-card>
-          <div id="chart2" style="width: 800px;height:400px;" />
-        </el-card>
-      </el-row>
-    </el-row>
-  </el-container>
-</template>
-
-<script>
-import { getExamCount } from '@/api/exam'
-
-export default {
-  name: 'ExamIndex',
-  data() {
-    return {
-      // 考试名称
-      examNames: [],
-      // 考试通过率
-      passRate: [],
-      // 饼图的数据
-      pieData: [],
-      selectedValue: '1',
-      chartOption: null
-    }
-  },
-  created() {
-    this.getExamNumbers()
-  },
-  methods: {
-    // 考试通过率柱状图
-    drawLine() {
-      this.chartOption = {
-        title: {
-          text: '考试通过率',
-          subtext: 'dashbord1',
-          x: 'center',
-          y: 'top',
-          textAlign: 'center'
-        },
-        tooltip: {},
-        xAxis: {
-          data: this.examNames
-        },
-        yAxis: {},
-        series: [{
-          name: '通过率',
-          type: 'bar',
-          data: this.passRate
-        }]
-      }
-    },
-    // 通过率的折线图
-    drawBrokenLine() {
-      this.chartOption = {
-        // 标题
-        title: {
-          text: '考试通过率折线图',
-          x: 'center'
-        },
-        // x轴
-        xAxis: {
-          data: this.examNames
-        },
-        // y轴没有显式设置,根据值自动生成y轴
-        yAxis: {},
-        // 数据-data是最终要显示的数据
-        series: [{
-          name: '通过率',
-          type: 'line',
-          areaStyle: {
-            normal: {}
-          },
-          data: this.passRate
-        }]
-      }
-    },
-    drawImg4() {
-      this.chartOption = {
-        color: ['#cd5c5c'],
-        textStyle: {
-          color: 'black'
-        },
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          },
-          formatter: '{a} <br/>{b} : {c}'
-        },
-        grid: {
-          containLabel: true
-        },
-        xAxis: {
-          type: 'value',
-          boundaryGap: [0, 0.01],
-          axisLine: {
-            lineStyle: {
-              color: '#fff'
-            }
-          },
-          'axisLabel': {
-            'interval': 0,
-            fontSize: 18,
-            formatter: '{value}'
-          }
-        },
-        yAxis: {
-          axisLine: {
-            lineStyle: {
-              color: '#fff'
-            }
-          },
-          'axisLabel': {
-            'interval': 0,
-            fontSize: 18
-          },
-          type: 'category',
-          data: this.examNames
-        },
-        series: [{
-          name: '通过率:',
-          type: 'bar',
-          data: this.passRate
-        }]
-      }
-    },
-    drawChart5() {
-      this.chartOption = {
-        title: {
-          text: '卡拉云新用户激活数据',
-          subtext: 'Demo 虚构数据',
-          x: 'center'
-        },
-        legend: { // 图例配置选项
-          orient: 'horizontal', // 图例布局方式:水平 'horizontal' 、垂直 'vertical'
-          x: 'left', // 横向放置位置,选项:'center'、'left'、'right'、'number'(横向值 px)
-          y: 'top', // 纵向放置位置,选项:'top'、'bottom'、'center'、'number'(纵向值 px)
-          data: ['猜想', '预期', '实际']
-        },
-        grid: { // 图表距离边框的距离,可用百分比和数字(px)配置
-          top: '20%',
-          left: '3%',
-          right: '10%',
-          bottom: '5%',
-          containLabel: true
-        },
-        xAxis: {
-          name: '月份',
-          type: 'category',
-          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
-        },
-        yAxis: {
-          name: '人次',
-          type: 'value',
-          min: 0, // 配置 Y 轴刻度最小值
-          max: 4000, // 配置 Y 轴刻度最大值
-          splitNumber: 7 // 配置 Y 轴数值间隔
-        },
-        series: [
-          {
-            name: '猜想',
-            data: [454, 226, 891, 978, 901, 581, 400, 543, 272, 955, 1294, 1581],
-            type: 'line',
-            symbolSize: function(value) { // 点的大小跟随数值增加而变大
-              return value / 150
-            },
-            symbol: 'circle',
-            itemStyle: {
-              normal: {
-                label: {
-                  show: true
-                },
-                lineStyle: {
-                  color: 'rgba(0,0,0,0)'// 折线颜色设置为0,即只显示点,不显示折线
-                }
-              }
-            }
-          },
-          {
-            name: '预期',
-            data: [2455, 2534, 2360, 2301, 2861, 2181, 1944, 2197, 1745, 1810, 2283, 2298],
-            type: 'line',
-            symbolSize: 8, // 设置折线上圆点大小
-            itemStyle: {
-              normal: {
-                label: {
-                  show: true // 在折线拐点上显示数据
-                },
-                lineStyle: {
-                  width: 3, // 设置虚线宽度
-                  type: 'dotted' // 虚线'dotted' 实线'solid'
-                }
-              }
-            }
-          },
-          {
-            name: '实际',
-            data: [1107, 1352, 1740, 1968, 1647, 1570, 1343, 1757, 2547, 2762, 3170, 3665],
-            type: 'line',
-            symbol: 'circle', // 实心圆点
-            smooth: 0.5 // 设置折线弧度
-          }
-        ],
-        color: ['#3366CC', '#FFCC99', '#99CC33'] // 三个折线的颜色
-      }
-    },
-    // 获取考试次数数据
-    async getExamNumbers() {
-      await getExamCount().then((resp) => {
-        const examNames = resp.data[0].split(',')
-        const examNumbers = resp.data[1].split(',')
-        examNames.forEach((item, index) => {
-          this.pieData.push({
-            name: item,
-            value: parseInt(examNumbers[index])
-          })
-        })
-        this.drawPie()
-      })
-    },
-    // 考试次数饼图
-    drawPie() {
-      // 基于准备好的dom,初始化echarts实例
-      const myChart = this.$echarts.init(document.getElementById('chart2'))
-      const option = {
-        title: {
-          text: '考试次数占比',
-          subtext: 'dashbord2',
-          x: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          formatter: '{a} <br/>{b} : {c}次 ({d}%)'
-        },
-        legend: {
-          orient: 'vertical',
-          left: 'left',
-          data: this.pieData
-        },
-        series: [
-          {
-            name: '考试次数',
-            type: 'pie',
-            radius: '55%',
-            data: this.pieData,
-            roseType: 'angle',
-            itemStyle: {
-              normal: {
-                shadowBlur: 200,
-                shadowColor: 'rgba(0, 0, 0, 0.5)'
-              }
-            }
-          }
-        ]
-      }
-      myChart.setOption(option)
-    }
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.el-container {
-  width: 100%;
-  height: 100%;
-}
-.el-container {
-  animation: leftMoveIn .7s ease-in;
-}
-
-@keyframes leftMoveIn {
-  0% {
-    transform: translateX(-100%);
-    opacity: 0;
-  }
-  100% {
-    transform: translateX(0%);
-    opacity: 1;
-  }
-}
-
-.card-style {
-  padding-top: 3px;
-  padding-bottom: 3px;
-  padding-left: 3px;
-  padding-right: 3px;
-}
-</style>

+ 12 - 3
src/views/exam/ExamMarkIndex.vue

@@ -58,7 +58,7 @@
               size="mini"
               type="warning"
               @click="markPaper(scope.$index, scope.row)"
-            >阅卷</el-button>
+            >去批改</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -152,8 +152,17 @@ export default {
       this.getData(this.queryInfo)
     },
     markPaper(index, row) {
-      const routeData = this.$router.resolve({ path: '/exam/mark/' + row.resultId })
-      window.open(routeData.href, '_blank')
+      const paperId = row.paperId
+      const userId = row.userId
+      const routeUrl = this.$router.resolve({
+        path: '/exam/paper/detail',
+        query: {
+          paperId: paperId,
+          viewType: 3,
+          userId: userId
+        }
+      })
+      window.open(routeUrl.href, '_blank')
     }
   }
 }

+ 146 - 62
src/views/exam/ExamQuestionCard.vue → src/views/exam/ExamPaperDetail.vue

@@ -28,10 +28,10 @@
                       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 :label="1" :disabled="paperInfo.viewType !== 2">A</el-radio>
+                    <el-radio :label="2" :disabled="paperInfo.viewType !== 2">B</el-radio>
+                    <el-radio :label="3" :disabled="paperInfo.viewType !== 2">C</el-radio>
+                    <el-radio :label="4" :disabled="paperInfo.viewType !== 2">D</el-radio>
                   </el-radio-group>
                   <el-row v-if="paperInfo.viewType !== 2">
                     <el-divider />
@@ -75,10 +75,10 @@
                       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 label="1" :disabled="paperInfo.viewType !== 2">A</el-checkbox>
+                    <el-checkbox label="2" :disabled="paperInfo.viewType !== 2">B</el-checkbox>
+                    <el-checkbox label="3" :disabled="paperInfo.viewType !== 2">C</el-checkbox>
+                    <el-checkbox label="4" :disabled="paperInfo.viewType !== 2">D</el-checkbox>
                   </el-checkbox-group>
                   <el-row v-if="paperInfo.viewType !== 2">
                     <el-divider />
@@ -119,8 +119,8 @@
                       onRadioChange(val, item1)
                     }"
                   >
-                    <el-radio :label="1">正确</el-radio>
-                    <el-radio :label="2">错误</el-radio>
+                    <el-radio :label="1" :disabled="paperInfo.viewType !== 2">正确</el-radio>
+                    <el-radio :label="2" :disabled="paperInfo.viewType !== 2">错误</el-radio>
                   </el-radio-group>
                   <el-row v-if="paperInfo.viewType !== 2">
                     <el-divider />
@@ -158,6 +158,7 @@
                   <div v-for="(item2, index2) in userAnswerMap[item1.questionId].submitAnswer" :key="index2">
                     <span style="left: 0;margin-right: 1px;color: black;">第 {{ index2 + 1 }} 题</span>
                     <el-input
+                      :disabled="paperInfo.viewType !== 2"
                       v-model="userAnswerMap[item1.questionId].submitAnswer[index2]"
                       type="text"
                       placeholder="请输入答案"
@@ -173,7 +174,9 @@
                       <span style="color: red">正确答案</span>
                     </el-row>
                     <el-row>
-                      {{ userAnswerMap[item1.questionId].correctAnswer[0] }}
+                      <div v-for="(answer, answerIndex) in userAnswerMap[item1.questionId].correctAnswer" :key="answerIndex">
+                        <span style="left: 0;margin-right: 1px;color: black;">第 {{ answerIndex + 1 }} 题:</span> {{ answer }}
+                      </div>
                     </el-row>
                     <el-row v-if="paperInfo.viewType >= 3">
                       <el-divider />
@@ -201,6 +204,7 @@
                   <span v-html="item1.questionContent" />
                   <el-divider />
                   <editor
+                    :disabled="paperInfo.viewType !== 2"
                     :id="item1.questionId+''"
                     v-model="userAnswerMap[item1.questionId].submitAnswer[0]"
                     :init="init"
@@ -295,10 +299,10 @@ import 'tinymce/themes/silver/theme.min.js'
 import 'tinymce/icons/default/icons'
 import Editor from '@tinymce/tinymce-vue'
 
-import { cacheUserAnswer, getPaper, submitExam, submitExamMark } from '@/api/exam'
+import { cacheUserAnswer, getExamInfo, getMarkView, getPaper, submitExam, submitExamMark } from '@/api/exam'
 
 export default {
-  name: 'ExamQuestionCard',
+  name: 'ExamPaperDetail',
   components: { Editor },
   data() {
     return {
@@ -356,22 +360,32 @@ export default {
       userAnswerMap: null,
       paperInfo: {
         paperId: 0,
-        name: '',
+        name: '未知试卷',
         viewType: 0,
         status: 0,
         duration: 0,
         totalScore: 0
       },
       paperViewType: [
-        '预览', '答卷', '阅卷', '结果'
-      ]
+        { '1': '预览' },
+        { '2': '答卷' },
+        { '3': '阅卷' },
+        { '4': '结果' }
+      ],
+      userId: '0'
     }
   },
   created() {
     document.title = '试卷详情'
-    this.paperInfo.paperId = this.$route.params.paperId
+    const paperIdStr = this.$route.query.paperId
+    this.paperInfo.paperId = parseInt(paperIdStr)
+
     const viewTypeStr = this.$route.query.viewType
     this.paperInfo.viewType = parseInt(viewTypeStr)
+
+    const userIdStr = this.$route.query.userId
+    this.userId = userIdStr
+
     if (this.paperInfo.viewType === 1) {
       document.title = '试卷预览'
     } else if (this.paperInfo.viewType === 2) {
@@ -381,7 +395,8 @@ export default {
       document.title = '试卷结果'
     }
 
-    this.getPaperDetail()
+    // this.getPaperDetail()
+    this.getPaperData()
   },
   methods: {
     renderByMathjax() {
@@ -394,18 +409,24 @@ export default {
         this.MathJax.MathQueue1(className)
       })
     },
+    getPaperData() {
+      if (this.paperInfo.viewType === 1) {
+        this.getPaperDetail()
+      } else if (this.paperInfo.viewType === 2) {
+        this.startExamPaper()
+      } else if (this.paperInfo.viewType === 3) {
+        this.startMarkPaper()
+      } else if (this.paperInfo.viewType === 4) {
+        this.getPaperDetail()
+      } else {
+        this.$message.error('viewType unknown')
+        return
+      }
+    },
     getPaperDetail() {
-      getPaper(this.paperInfo.paperId, this.paperInfo.viewType).then((resp) => {
+      getPaper(this.paperInfo.paperId, this.paperInfo.viewType, this.userId).then((resp) => {
         if (resp.code === 0) {
-          const respData = resp.data
-          this.paperInfo.name = respData.name
-          this.paperInfo.status = respData.status
-          this.paperInfo.duration = respData.duration
-          this.paperInfo.totalScore = respData.totalScore
-
-          this.questionMap = respData.questionMap
-          this.userAnswerMap = respData.userResult.cachedUserAnswers
-          this.renderByMathjax()
+          this.processPaperData(resp)
         } else {
           this.$message.error(resp.msg)
         }
@@ -418,6 +439,102 @@ export default {
         })
       })
     },
+    startExamPaper() {
+      getExamInfo(this.paperInfo.paperId).then((resp) => {
+        if (resp.code === 0) {
+          this.processPaperData(resp)
+        } else {
+          this.$message.error(resp.msg)
+        }
+      }).catch((error) => {
+        this.$notify({
+          title: 'Tips',
+          message: error.message,
+          type: 'error',
+          duration: 2000
+        })
+      })
+    },
+    startMarkPaper() {
+      getMarkView(this.paperInfo.paperId).then((resp) => {
+        if (resp.code === 0) {
+          this.processPaperData(resp)
+        } else {
+          this.$message.error(resp.msg)
+        }
+      }).catch((error) => {
+        this.$notify({
+          title: 'Tips',
+          message: error.message,
+          type: 'error',
+          duration: 2000
+        })
+      })
+    },
+    getPaperResult() {
+    },
+    processPaperData(resp) {
+      const respData = resp.data
+      const status = respData.status
+      if (status === 1) {
+        this.$message.error('用户没有访问试卷的权限')
+        return
+      } else if (status === 2) {
+        this.$message.error('用户只有管理的权限')
+        return
+      } else if (status === 3) {
+        this.$message.error('用户只有做题的权限')
+        return
+      } else if (status === 4) {
+        this.$message.error('试卷由用户自己批改')
+        return
+      } else if (status === 5) {
+        this.$message.error('试卷访问类型 viewType 未知')
+        return
+      }
+
+      this.paperInfo.name = respData.name
+      this.paperInfo.status = respData.status
+      this.paperInfo.duration = respData.duration
+      this.paperInfo.totalScore = respData.totalScore
+
+      this.questionMap = respData.questionMap
+      this.userAnswerMap = respData.userResult.cachedUserAnswers
+      this.renderByMathjax()
+    },
+    onRadioChange(val, item) {
+      // this.$message.info('change event: ' + val + ' -> ' + item.questionId)
+      this.cacheAnswer()
+    },
+    onCheckboxChange(val, item) {
+      this.cacheAnswer()
+    },
+    onInputBlur(val, item) {
+      this.cacheAnswer()
+    },
+    onEditorBlur(val) {
+      this.cacheAnswer()
+    },
+    cacheAnswer() {
+      var userAnswers = []
+      for (const key in this.userAnswerMap) {
+        const userAnswer = {}
+        userAnswer.questionId = key
+        userAnswer.submitAnswer = this.userAnswerMap[key]
+        userAnswers.push(this.userAnswerMap[key])
+      }
+
+      var userResult = {}
+      userResult.paperId = this.paperInfo.paperId
+      userResult.submitUserAnswers = userAnswers
+      cacheUserAnswer(userResult).then(resp => {
+        if (resp.code !== 0) {
+          console.log(resp.msg)
+        }
+      }).catch((e) => {
+        console.log(e)
+      })
+    },
     onSubmitPaper() {
       this.$confirm('当前试题暂未做完, 是否继续提交o(╥﹏╥)o ?', 'Tips', {
         confirmButtonText: '确定',
@@ -443,7 +560,7 @@ export default {
               type: 'success',
               duration: 2000
             })
-            this.$router.push('/exam/list')
+            this.$router.push('/exam/eval')
           }
         }).catch((error) => {
           this.$notify({
@@ -462,39 +579,6 @@ export default {
         })
       })
     },
-    onRadioChange(val, item) {
-      // this.$message.info('change event: ' + val + ' -> ' + item.questionId)
-      this.cacheAnswer()
-    },
-    onCheckboxChange(val, item) {
-      this.cacheAnswer()
-    },
-    onInputBlur(val, item) {
-      this.cacheAnswer()
-    },
-    onEditorBlur(val) {
-      this.cacheAnswer()
-    },
-    cacheAnswer() {
-      var userAnswers = []
-      for (const key in this.userAnswerMap) {
-        const userAnswer = {}
-        userAnswer.questionId = key
-        userAnswer.submitAnswer = this.userAnswerMap[key]
-        userAnswers.push(this.userAnswerMap[key])
-      }
-
-      var userResult = {}
-      userResult.paperId = this.paperInfo.paperId
-      userResult.submitUserAnswers = userAnswers
-      cacheUserAnswer(userResult).then(resp => {
-        if (resp.code !== 0) {
-          console.log(resp.msg)
-        }
-      }).catch((e) => {
-        console.log(e)
-      })
-    },
     onSubmitMarkPaper() {
       this.$confirm('当前试题暂未做完, 是否继续提交o(╥﹏╥)o ?', 'Tips', {
         confirmButtonText: '确定',

+ 5 - 3
src/views/exam/ExamPaper.vue → src/views/exam/ExamPaperList.vue

@@ -101,7 +101,7 @@
 import { getSubjectKV, getPapers, deletePaper } from '@/api/exam'
 
 export default {
-  name: 'ExamPaper',
+  name: 'ExamPaperList',
   data() {
     return {
       // 屏幕宽度, 为了控制分页条的大小
@@ -199,9 +199,11 @@ export default {
     previewPaper(index, row) {
       const paperId = row.examId
       const routeUrl = this.$router.resolve({
-        path: '/exam/paper/card/' + paperId,
+        path: '/exam/paper/detail',
         query: {
-          viewType: 1
+          paperId: paperId,
+          viewType: 1,
+          userId: ''
         }
       })
       window.open(routeUrl.href, '_blank')

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

@@ -471,7 +471,7 @@
 </template>
 
 <script>
-import { getExamResult, getPaperQuestions, submitExamMark } from '@/api/exam'
+import { getMarkView, getPaperQuestions, submitExamMark } from '@/api/exam'
 
 export default {
   name: 'ExamPaperResult',
@@ -556,7 +556,7 @@ export default {
       })
     },
     getExamResult(resultId) {
-      getExamResult(resultId).then((resp) => {
+      getMarkView(resultId).then((resp) => {
         if (resp.code === 0) {
           const respData = resp.data
           this.examInfo = {

+ 1 - 1
src/views/exam/ExamQuestion.vue → src/views/exam/ExamQuestionList.vue

@@ -473,7 +473,7 @@ import {
 import { validFormAndInvoke } from '@/utils/util'
 
 export default {
-  name: 'ExamQuestion',
+  name: 'ExamQuestionList',
   data() {
     return {
       radio: '',