reghao 1 rok pred
rodič
commit
e5ab31dea1

+ 12 - 8
src/api/exam.js

@@ -7,8 +7,8 @@ const examApi = {
   getExamQuestion1: '/api/content/exam/question/1',
   getExamQuestionType: '/api/content/exam/question/type',
   postExamQuestion: '/api/content/exam/question',
-  postExamPaper: '/api/content/exam/paper1',
-  getExamPapers: '/api/content/exam/paper1',
+  postExamPaper: '/api/content/exam/paper/submit',
+  getExamPapers: '/api/content/exam/start',
   getExamResult: '/api/content/exam/result',
   getExamPaperScore: '/api/content/exam/paper/score',
   getExam: '/api/content/exam',
@@ -24,10 +24,6 @@ export function getExamSubjectKV() {
   return get(examApi.getExamSubjectKV)
 }
 
-export function getExamQuestion() {
-  return get(examApi.getExamQuestion1)
-}
-
 export function getExamQuestionType() {
   return get(examApi.getExamQuestionType)
 }
@@ -56,14 +52,18 @@ export function getExam(paperId) {
   return get(examApi.getExam + '/' + paperId)
 }
 
-export function getExamInfoById(data) {
-  return get(examApi.getExamPapers, data)
+export function getExamInfoById(paperId) {
+  return get(examApi.getExamPapers + '/' + paperId)
 }
 
 export function getQuestionByIds(data) {
   return get(examApi.getExamQuestion, data)
 }
 
+export function getQuestionByPaperId(paperId) {
+  return get('/api/content/exam/paperquestion' + '/' + paperId)
+}
+
 export function submitExamPaper(data) {
   return post(examApi.postExamPaper, data)
 }
@@ -80,6 +80,10 @@ export function postPaper(data) {
   return post(examApi.postPaper, data)
 }
 
+export function getPapers(param) {
+  return get(examApi.getPaper, param)
+}
+
 export function getPaper(examId) {
   return get(examApi.getPaper + '/' + examId)
 }

+ 1 - 1
src/router/admin.js

@@ -33,7 +33,7 @@ export default {
       meta: { needAuth: true }
     },
     {
-      path: '/exam/paper1/:examId',
+      path: '/exam/start/:paperId',
       name: 'ExamCard',
       component: ExamCard,
       meta: { needAuth: true }

+ 101 - 27
src/views/exam/ExamCard.vue

@@ -26,11 +26,12 @@
               <div>
                 <span v-if="questionList[curIndex].questionType === 1">【单选题】</span>
                 <span v-else-if="questionList[curIndex].questionType === 2">【多选题】</span>
-                <span v-else-if="questionList[curIndex].questionType === 3">【判断题】</span>
-                <span v-else-if="questionList[curIndex].questionType === 4">【简答题】</span>
-                <span v-else-if="questionList[curIndex].questionType === 5">【判断题】</span>
+                <span v-else-if="questionList[curIndex].questionType === 3">【不定项选择题】</span>
+                <span v-else-if="questionList[curIndex].questionType === 4">【判断题】</span>
+                <span v-else-if="questionList[curIndex].questionType === 5">【填空题】</span>
                 <span v-else-if="questionList[curIndex].questionType === 6">【问答题】</span>
-                <span v-else>【理解题】</span>
+                <span v-else-if="questionList[curIndex].questionType === 7">【理解题】</span>
+                <span v-else>【综合题】</span>
                 <br>
                 <br>
                 <i class="num">{{ curIndex + 1 }}</i>
@@ -46,9 +47,10 @@
                 @click="showBigImg(url)"
               >
 
-              <!-- 单选和判断候选答案列表 -->
+              <!-- 单选和判断候选答案列表 -->
               <div
-                v-show="questionList[curIndex].questionType === 1 || questionList[curIndex].questionType === 3"
+                v-show="questionList[curIndex].questionType === 1
+                  || questionList[curIndex].questionType === 4"
                 style="margin-top: 25px"
               >
                 <div class="el-radio-group">
@@ -72,7 +74,11 @@
               </div>
 
               <!-- 多选和不定项选择题的候选答案列表 -->
-              <div v-show="questionList[curIndex].questionType === 2" style="margin-top: 25px">
+              <div
+                v-show="questionList[curIndex].questionType === 2
+                  || questionList[curIndex].questionType === 3"
+                style="margin-top: 25px"
+              >
                 <div class="el-radio-group">
                   <label
                     v-for="(item,index) in questionList[curIndex].answer"
@@ -94,8 +100,25 @@
                 </div>
               </div>
 
-              <!-- 简答题的回答区 -->
-              <div v-show="questionList[curIndex].questionType === 4" style="margin-top: 25px">
+              <!-- 填空题和问答题的回答区 -->
+              <div
+                v-show="questionList[curIndex].questionType === 5
+                  || questionList[curIndex].questionType === 6"
+                style="margin-top: 25px"
+              >
+                <el-input
+                  v-model="userAnswer[curIndex]"
+                  type="textarea"
+                  :rows="8"
+                  placeholder="请输入答案"
+                />
+              </div>
+
+              <!-- 综合题的回答区 -->
+              <div
+                v-show="questionList[curIndex].questionType === 8"
+                style="margin-top: 25px"
+              >
                 <el-input
                   v-model="userAnswer[curIndex]"
                   type="textarea"
@@ -163,10 +186,9 @@
                 >{{ item }}
                 </el-button>
               </div>
-
-              <!-- 判断的答题卡 -->
+              <!-- 不定项选择题的答题卡 -->
               <div style="margin-top: 25px">
-                <p style="font-size: 18px;">判断题</p>
+                <p style="font-size: 18px;">多选题</p>
                 <el-button
                   v-for="item in questionList.length"
                   v-show="questionList[item-1].questionType === 3"
@@ -180,9 +202,9 @@
                 </el-button>
               </div>
 
-              <!-- 简答题的答题卡 -->
+              <!-- 判断题的答题卡 -->
               <div style="margin-top: 25px">
-                <p style="font-size: 18px;">简答题</p>
+                <p style="font-size: 18px;">判断题</p>
                 <el-button
                   v-for="item in questionList.length"
                   v-show="questionList[item-1].questionType === 4"
@@ -195,6 +217,54 @@
                 >{{ 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'"
+                  @click="curIndex = item-1"
+                >{{ 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'"
+                  @click="curIndex = item-1"
+                >{{ 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-col>
@@ -214,11 +284,10 @@
       <img style="width: 100%" :src="bigImgUrl">
     </el-dialog>
   </el-container>
-
 </template>
 
 <script>
-import { submitExamPaper, getExamInfoById, getQuestionByIds } from '@/api/exam'
+import { submitExamPaper, getExamInfoById, getQuestionByPaperId } from '@/api/exam'
 
 export default {
   name: 'ExamCard',
@@ -322,7 +391,7 @@ export default {
     }
   },
   created() {
-    // this.getExamInfo()
+    this.getExamInfo()
     // 页面数据加载的等待状态栏
     this.loading = this.$loading({
       body: true,
@@ -379,8 +448,8 @@ export default {
   methods: {
     // 查询当前考试的信息
     getExamInfo() {
-      const examId = this.$route.params
-      getExamInfoById(examId).then((resp) => {
+      const paperId = this.$route.params.paperId
+      getExamInfoById(paperId).then((resp) => {
         if (resp.code === 0) {
           this.examInfo = resp.data
           // 设置定时(秒)
@@ -401,15 +470,14 @@ export default {
           this.timer = window.setInterval(() => {
             if (this.duration > 0) this.duration--
           }, 1000)
-
-          const questionIds = this.examInfo.questionIds.split(',')
-          this.getQuestionInfo(questionIds)
+          var paperId = this.examInfo.examId
+          this.getQuestionInfo1(paperId)
         }
       })
     },
     // 查询考试的题目信息
-    async getQuestionInfo(ids) {
-      await getQuestionByIds({ 'ids': ids.join(',') }).then(resp => {
+    async getQuestionInfo1(paperId) {
+      await getQuestionByPaperId(paperId).then(resp => {
         if (resp.code === 0) {
           this.questionList = resp.data || []
           // 重置问题的顺序 单选 多选 判断 简答
@@ -428,6 +496,7 @@ export default {
       this.bigImgUrl = url
       this.bigImgDialog = true
     },
+    // ****************************************************************************************************************
     // 检验单选题的用户选择的答案
     checkSingleAnswer(index) {
       this.$set(this.userAnswer, this.curIndex, index)
@@ -458,6 +527,7 @@ export default {
         }).join(',')
       }
     },
+    // ****************************************************************************************************************
     // 调用摄像头
     getCamera() {
       const constraints = {
@@ -525,14 +595,19 @@ export default {
       }
       return new File([ia], fileName, { type: mime })
     },
+    // ****************************************************************************************************************
     // 上传用户考试信息进入后台
     async uploadExamToAdmin() {
+      console.log(this.userAnswer)
       if (this.cameraOn) await this.takePhoto()// 结束的时候拍照上传一张
       // 正则
       var reg = new RegExp('-', 'g')
       // 去掉用户输入的非法分割符号(-),保证后端接受数据处理不报错
       this.userAnswer.forEach((item, index) => {
-        if (this.questionList[index].questionType === 4) { // 简答题答案处理
+        // 简答题答案处理
+        if (this.questionList[index].questionType === 5 ||
+          this.questionList[index].questionType === 6 ||
+          this.questionList[index].questionType === 7) {
           this.userAnswer[index] = item.replace(reg, ' ')
         }
       })
@@ -599,8 +674,7 @@ export default {
         })
         userPayload.userAnswers.split(0, userPayload.userAnswers.length - 1)
       }
-      userPayload.examId = parseInt(this.$route.params.examId)
-
+      userPayload.examId = parseInt(this.$route.params.paperId)
       userPayload.questionIds = userPayload.questionIds.join(',')
       userPayload.creditImgUrl = this.takePhotoUrl.join(',')
       submitExamPaper(userPayload).then((resp) => {

+ 36 - 45
src/views/exam/ExamPaper.vue

@@ -1,20 +1,28 @@
 <template>
-  <el-row>
-    <el-row>
-      <el-form :inline="true" :model="searchForm" class="demo-form-inline">
-        <el-form-item>
-          <el-select v-model="searchForm.type" placeholder="查询类型">
-            <el-option label="稿件标题" value="1" />
-            <el-option label="用户ID" value="2" />
-          </el-select>
-        </el-form-item>
-        <el-form-item>
-          <el-input v-model="searchForm.content" placeholder="" />
-        </el-form-item>
-        <el-form-item>
-          <el-button size="mini" type="warning" @click="search">查询</el-button>
-        </el-form-item>
-      </el-form>
+  <el-container>
+    <el-header height="220">
+      <el-row>
+        <el-form :inline="true" :model="searchForm" class="demo-form-inline">
+          <el-form-item>
+            <el-select v-model="searchForm.type" placeholder="查询类型">
+              <el-option label="稿件标题" value="1" />
+              <el-option label="用户ID" value="2" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-input v-model="searchForm.content" placeholder="" />
+          </el-form-item>
+          <el-form-item>
+            <el-button size="mini" type="warning" @click="search">查询</el-button>
+          </el-form-item>
+        </el-form>
+      </el-row>
+      <el-row style="margin-top: 10px">
+        <el-button type="plain" icon="el-icon-plus" @click="addExamPaper">添加</el-button>
+      </el-row>
+    </el-header>
+
+    <el-main>
       <el-table
         :data="dataList"
         border
@@ -67,8 +75,6 @@
           </template>
         </el-table-column>
       </el-table>
-    </el-row>
-    <el-row>
       <el-pagination
         background
         :small="screenWidth <= 768"
@@ -80,7 +86,7 @@
         @prev-click="handleCurrentChange"
         @next-click="handleCurrentChange"
       />
-    </el-row>
+    </el-main>
 
     <el-dialog
       title="考试提示"
@@ -111,11 +117,11 @@
         <el-button type="primary" @click="startExam(currentSelectedExam.examId)">开始考试</el-button>
       </span>
     </el-dialog>
-  </el-row>
+  </el-container>
 </template>
 
 <script>
-import {getExamPapers, getExams} from '@/api/exam'
+import {getExamPapers, getExams, getPapers} from '@/api/exam'
 
 export default {
   name: 'ExamPaper',
@@ -154,7 +160,10 @@ export default {
     },
     getData(searchForm) {
       this.dataList = []
-      getExams(this.currentPage).then(resp => {
+      var param = {}
+      param.pageNumber = this.currentPage
+      param.pageSize = this.pageSize
+      getPapers(param).then(resp => {
         if (resp.code === 0) {
           this.dataList = resp.data.list
           this.totalSize = resp.data.totalSize
@@ -174,27 +183,6 @@ export default {
           duration: 3000
         })
       })
-
-      getExamPapers(this.currentPage).then(resp => {
-        if (resp.code === 0) {
-          // this.dataList = resp.data.list
-          // this.totalSize = resp.data.totalSize
-        } else {
-          this.$notify({
-            title: '提示',
-            message: resp.msg,
-            type: 'warning',
-            duration: 3000
-          })
-        }
-      }).catch(error => {
-        this.$notify({
-          title: '提示',
-          message: error.message,
-          type: 'error',
-          duration: 3000
-        })
-      })
     },
     prepareExam(index, row) {
       row.password = 12345678
@@ -218,13 +206,16 @@ export default {
       }
     },
     startExam(paperId) {
-      const path = '/exam/paper/' + paperId
+      const path = '/exam/start/' + paperId
       console.log(path)
-      this.$router.push('/exam/paper/' + paperId)
+      this.$router.push('/exam/start/' + paperId)
     },
     search() {
       this.currentPage = 1
       this.getData(this.searchForm)
+    },
+    addExamPaper() {
+      this.$router.push('/exam/paper/add')
     }
   }
 }

+ 22 - 21
src/views/exam/ExamPaperAdd.vue

@@ -35,11 +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="序号"
-              width="50"
-            />
+            <el-table-column type="index" label="顺序"/>
             <el-table-column label="题目内容" align="center">
               <template slot-scope="scope">
                 {{ scope.row.content.substr(0, 20) }}
@@ -187,7 +183,7 @@
     <el-dialog title="添加试题" :visible.sync="showQuestionDialog" width="80%" center>
       <el-row>
         <el-select
-          v-model="queryInfo.questionBank"
+          v-model="queryInfo.subjectId"
           clearable
           placeholder="请选择科目"
           style="margin-left: 5px"
@@ -298,11 +294,11 @@ export default {
       dataList: [],
       // 查询题目的参数
       queryInfo: {
-        'subjectId': null,
-        'type': null,
-        'level': null,
-        'pageNumber': 1,
-        'pageSize': 10
+        subjectId: null,
+        type: null,
+        level: null,
+        pageNumber: 1,
+        pageSize: 10
       },
       // 所有题库信息
       allSubject: [],
@@ -369,7 +365,7 @@ export default {
     sumTotalScore() {
       if (this.makeModel === 1) {
         let score = 0
-        this.addExamQuestion2.forEach(item => {
+        this.addExamQuestion1.forEach(item => {
           score += parseInt(item.score)
         })
         return score
@@ -516,10 +512,10 @@ export default {
     // 自由组卷中选中的题目添加进去
     addQuToFree() {
       this.selectedTable.forEach(item => {
-        if (!this.addExamQuestion1.some(i2 => {
-          return i2.questionId === item.id
-        })) { // 不存在有当前题目
+        // 不存在有当前题目
+        if (!this.addExamQuestion1.some(i2 => { return i2.questionId === item.id })) {
           this.addExamQuestion1.push({
+            'pos': this.addExamQuestion1.length + 1,
             'questionId': item.questionId,
             'content': item.content,
             'type': item.type,
@@ -554,26 +550,31 @@ export default {
         exam.totalScore = this.sumTotalScore
         exam.status = 1
         // 权限id设置
-        exam.type = this.examAuthority
+        exam.examAuthority = this.examAuthority
         if (this.examAuthority === 2) { // 考试密码
           if (this.examPassword === '') { // 当前用户选择了需要密码权限,但是密码为空
             this.$message.error('当前权限为需要密码,但是密码为空')
             return false
           }
-          exam.password = this.examPassword
+          exam.examPassword = this.examPassword
         }
 
         if (this.makeModel === 1 && !this.addExamQuestion1.some(item => item.bankId === '')) {
-          // 题目id数组
+          var questions = []
           const questionIds = []
-          // 题目成绩数组
           const scores = []
           this.addExamQuestion1.forEach(item => {
+            questions.push({
+              pos: item.pos,
+              questionId: item.questionId,
+              score: item.score
+            })
             questionIds.push(item.questionId)
             scores.push(item.score)
           })
-          exam.questionIds = questionIds.join(',')
-          exam.scores = scores.join(',')
+          // exam.questionIds = questionIds.join(',')
+          // exam.scores = scores.join(',')
+          exam.questions = questions
           this.addExamPaper(exam)
         } else if (this.makeModel === 2) {
           const bankNames = []

+ 55 - 36
src/views/exam/ExamQuestion.vue

@@ -2,34 +2,34 @@
   <el-container>
     <el-header height="220">
       <el-row>
-        <el-select v-model="queryInfo.questionType" clearable placeholder="请选择试题类型" @change="typeChange">
-          <el-option
-            v-for="item in questionType"
-            :key="item.id"
-            :label="item.name"
-            :value="item.id"
-          />
-        </el-select>
         <el-select
-          v-model="queryInfo.questionBank"
+          v-model="queryInfo.subjectId"
           clearable
-          placeholder="请选择题库"
+          placeholder="请选择科目"
           style="margin-left: 5px"
-          @change="bankChange"
+          @change="subjectChange"
         >
           <el-option
             v-for="item in allSubject"
-            :key="item.id"
+            :key="item.key"
+            :label="item.value"
+            :value="item.key"
+          />
+        </el-select>
+        <el-select v-model="queryInfo.type" clearable placeholder="请选择试题类型" @change="typeChange">
+          <el-option
+            v-for="item in allType"
+            :key="item.key"
             :label="item.value"
-            :value="item.value"
+            :value="item.key"
           />
         </el-select>
         <el-input
           v-model="queryInfo.questionContent"
-          placeholder="试题内容"
+          placeholder="题内容"
           style="margin-left: 5px;width: 220px"
           prefix-icon="el-icon-search"
-          @blur="contentChange"
+          @blur="getQuestionInfo"
         />
       </el-row>
       <el-row style="margin-top: 10px">
@@ -429,7 +429,13 @@
 </template>
 
 <script>
-import { getExamSubjectKV, postExamQuestion, getExamQuestion, getExamQuestion1, deleteExamQuestion } from '@/api/exam'
+import {
+  getExamSubjectKV,
+  postExamQuestion,
+  getExamQuestion1,
+  deleteExamQuestion,
+  getExamQuestionPage, getExamQuestionType
+} from '@/api/exam'
 import { validFormAndInvoke } from '@/utils/util'
 
 export default {
@@ -446,12 +452,11 @@ export default {
       uploadImageUrl: '/',
       // 查询用户的参数
       queryInfo: {
-        // 试题类型下拉款所选的内容
-        'questionType': '',
-        'questionBank': '',
-        'questionContent': '',
-        'pageNo': 1,
-        'pageSize': 10
+        subjectId: null,
+        type: null,
+        level: null,
+        pageNumber: 1,
+        pageSize: 10
       },
       // 试题类型
       questionType: [
@@ -490,6 +495,7 @@ export default {
       ],
       // 题库信息
       allSubject: [],
+      allType: [],
       // 试题信息
       questionInfo: [],
       // 试题信息表格是否加载
@@ -658,7 +664,8 @@ export default {
   },
   created() {
     document.title = '题库管理'
-    this.getQuestionBankInfo()
+    this.getSubjects()
+    this.getQuestionTypes()
     this.getData(this.searchForm)
   },
   methods: {
@@ -672,9 +679,9 @@ export default {
         this.MathJax.MathQueue1(className)
       })
     },
-    getData(searchForm) {
+    getData() {
       this.dataList = []
-      getExamQuestion(this.currentPage).then(resp => {
+      getExamQuestionPage(this.queryInfo).then(resp => {
         if (resp.code === 0) {
           this.dataList = resp.data.list
           this.totalSize = resp.data.totalSize
@@ -695,8 +702,22 @@ export default {
         })
       })
     },
+    getQuestionTypes() {
+      getExamQuestionType().then((resp) => {
+        if (resp.code === 0) {
+          this.allType = resp.data
+        } else {
+          this.$notify({
+            title: 'Tips',
+            message: resp.message,
+            type: 'error',
+            duration: 2000
+          })
+        }
+      })
+    },
     // 获取所有的题库信息
-    getQuestionBankInfo() {
+    getSubjects() {
       getExamSubjectKV().then((resp) => {
         if (resp.code === 0) {
           this.allSubject = resp.data
@@ -705,12 +726,16 @@ export default {
     },
     // 试题类型变化
     typeChange(val) {
-      this.queryInfo.questionType = val
+      this.queryInfo.type = val
+      this.queryInfo.pageNumber = this.currentPage
+      this.queryInfo.pageSize = this.pageSize
       this.getQuestionInfo()
     },
     // 题库变化
-    bankChange(val) {
-      this.queryInfo.questionBank = val
+    subjectChange(val) {
+      this.queryInfo.subjectId = val
+      this.queryInfo.pageNumber = this.currentPage
+      this.queryInfo.pageSize = this.pageSize
       this.getQuestionInfo()
     },
     // 试题名字筛选
@@ -720,13 +745,7 @@ export default {
     },
     // 获取试题信息
     getQuestionInfo() {
-      getQuestion(this.queryInfo).then((resp) => {
-        if (resp.code === 0) {
-          this.questionInfo = resp.data.data
-          this.total = resp.data.total
-          this.loading = false
-        }
-      })
+      this.getData()
     },
     // 处理表格被选中
     handleTableSectionChange(val) {

+ 1 - 1
src/views/exam/ExamResult.vue

@@ -175,7 +175,7 @@ export default {
     },
     // 根据考试id查询考试信息
     getExamInfoById(examId) {
-      getExamInfoById({ 'examId': examId }).then((resp) => {
+      getExamInfoById(examId).then((resp) => {
         if (resp.code === 0) this.examInfo = resp.data
       })
     },