dedsudiyu 3 days ago
parent
commit
edd1334201
16 changed files with 638 additions and 578 deletions
  1. 40 0
      src/api/safetyEducationExaminationNew/index.js
  2. 104 192
      src/views/safetyEducationExaminationNew/components/examDetails.vue
  3. 1 1
      src/views/safetyEducationExaminationNew/components/examRecords.vue
  4. 1 1
      src/views/safetyEducationExaminationNew/components/historyOfIncorrectQuestions.vue
  5. 15 14
      src/views/safetyEducationExaminationNew/examManagement/examinationArrange/studentsTakingMakeUpExams.vue
  6. 10 26
      src/views/safetyEducationExaminationNew/examManagement/examinationResult/academicPerformance.vue
  7. 0 54
      src/views/safetyEducationExaminationNew/examManagement/examinationResult/learningProgress.vue
  8. 14 18
      src/views/safetyEducationExaminationNew/examManagement/examinationResult/viewGrades.vue
  9. 18 12
      src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/classHoursConfiguration.vue
  10. 177 172
      src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/gradingConfiguration.vue
  11. 1 1
      src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/index.vue
  12. 1 1
      src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/otherConfiguration.vue
  13. 5 3
      src/views/safetyEducationExaminationNew/publicConfiguration/certificateTemplate/addPage.vue
  14. 43 82
      src/views/safetyEducationExaminationNew/questionBankManagement/practiceSolvingProblems/index.vue
  15. 207 0
      src/views/safetyEducationExaminationNew/questionBankManagement/practiceSolvingProblems/practiceStatistics.vue
  16. 1 1
      src/views/safetyEducationExaminationNew/questionBankManagement/questionBankManagement/index.vue

+ 40 - 0
src/api/safetyEducationExaminationNew/index.js

@@ -465,5 +465,45 @@ export function systemUserGetRuleDataByParam(data) {
     data: data
   })
 }
+//查询考卷左侧数据
+export function examElExamAttemptReviewSidebar(data) {
+  return request({
+    url: '/exam/elExamAttempt/review-sidebar',
+    method: 'post',
+    data: data
+  })
+}
+//查询考卷右侧题目数据
+export function examElExamAttemptReviewQuestion(data) {
+  return request({
+    url: '/exam/elExamAttempt/review-question',
+    method: 'post',
+    data: data
+  })
+}
+//管理端刷题练习列表
+export function examElPracticeStatPage(data) {
+  return request({
+    url: '/exam/elPracticeStat/page',
+    method: 'post',
+    data: data
+  })
+}
+//管理端刷题练习-学习统计
+export function examElPracticeStatDetail(data) {
+  return request({
+    url: '/exam/elPracticeStat/detail',
+    method: 'post',
+    data: data
+  })
+}
+//分页查询考试奖励记录
+export function examElExamResultRewardPage(data) {
+  return request({
+    url: '/exam/elExamResult/reward-page',
+    method: 'post',
+    data: data
+  })
+}
 
 

+ 104 - 192
src/views/safetyEducationExaminationNew/components/examDetails.vue

@@ -3,38 +3,35 @@
   <div class="page-container examDetails-addPage">
     <!-- 左侧面板 -->
     <div class="left-panel">
-      <div class="exam-title">{{ examInfo.title }}</div>
-      <div class="exam-subtitle">总{{ examInfo.totalCount }}题 / 共{{ examInfo.totalScore }}分</div>
-
-      <div class="exam-name-box">{{ examInfo.name }}</div>
-
+      <div class="exam-title">{{ examInfo.examTypeName }}</div>
+      <div class="exam-subtitle">总{{ examInfo.questionCount }}题 / 共{{ examInfo.totalScore }}分</div>
+      <div class="exam-name-box">{{ examInfo.examName }}</div>
       <div class="exam-info-box">
         <div class="info-item"><span class="label">试卷总分:</span>{{ examInfo.totalScore }}分</div>
         <div class="info-item"><span class="label">及格分数:</span>{{ examInfo.passScore }}分</div>
-        <div class="info-item"><span class="label">我的得分:</span>{{ examInfo.myScore }}分</div>
-        <div class="info-item"><span class="label">考试用时:</span>{{ examInfo.duration }}</div>
+        <div class="info-item"><span class="label">我的得分:</span>{{ examInfo.earnedScore }}分</div>
+        <div class="info-item"><span class="label">考试用时:</span>{{ examInfo.durationText }}</div>
         <div class="info-item">
           <span class="label">考试结果:</span>
-          <span :class="examInfo.passed ? 'result-pass' : 'result-fail'">
-            {{ examInfo.passed ? '通过' : '无效' }}
+          <span :class="examInfo.passStatus == 1 ? 'result-pass' : 'result-fail'">
+            {{ examInfo.passStatus == 1?'通过':'无效' }}
           </span>
         </div>
       </div>
 
       <!-- 题目导航 -->
-      <div v-for="group in questionGroups" :key="group.type" class="question-group">
+      <div v-for="group in questionTypeGroups" :key="group.type" class="question-group">
         <div class="group-header">
-          <span class="group-title">{{ group.typeName }}</span>
-          <span class="group-count">{{ group.questions.length }}题 / 共{{ group.totalScore }}分</span>
+          <span class="group-title">{{ group.questionTypeName }}</span>
+          <span class="group-count">{{ group.questionCount }}题 / 共{{ group.totalScore }}分</span>
         </div>
         <div class="question-nums">
           <div
-            v-for="q in group.questions"
-            :key="q.index"
-            :class="['num-item', getNumClass(q), currentIndex === q.index ? 'num-active' : '']"
-            @click="selectQuestion(q.index)"
-          >
-            {{ q.index }}
+            v-for="(item,index) in group.questions"
+            :key="item.questionNo"
+            :class="['num-item', getNumClass(item), currentIndex === item.questionNo ? 'num-active' : '']"
+            @click="selectQuestion(item)">
+            {{ item.questionNo }}
           </div>
         </div>
       </div>
@@ -45,75 +42,40 @@
       <div class="question-card">
         <!-- 题目头部 -->
         <div class="question-header">
-          <div class="question-index-box">{{ currentQuestion.index }}</div>
-          <div class="question-type-score">{{ currentQuestion.typeName }}({{ currentQuestion.score }}分)</div>
+          <div class="question-index-box">{{ currentQuestion.questionNo }}</div>
+          <div class="question-type-score">{{ currentQuestion.questionTypeName }}({{ currentQuestion.questionScore }}分)</div>
           <div class="question-stars">
             <i
               v-for="s in 4"
               :key="s"
-              :class="['star-icon', s <= currentQuestion.starLevel ? 'star-active' : 'star-empty']"
+              :class="['star-icon', s <= currentQuestion.difficulty ? 'star-active' : 'star-empty']"
             >★</i>
           </div>
         </div>
-
         <!-- 题目内容(富文本) -->
-        <div class="question-content" v-html="currentQuestion.content"></div>
-
-        <!-- 单选题选项 -->
-        <div v-if="currentQuestion.type === 'single'" class="options-list">
-          <div
-            v-for="opt in currentQuestion.options"
-            :key="opt.key"
-            :class="['option-item', isSelectedOption(currentQuestion, opt.key) ? 'option-selected' : '']"
-          >
-            <span class="option-radio">
-              <i v-if="isSelectedOption(currentQuestion, opt.key)" class="el-icon-check radio-checked"></i>
-              <i v-else class="radio-empty"></i>
-            </span>
-            <span class="option-key">{{ opt.key }}</span>
-            <span class="option-text" v-html="opt.text"></span>
-          </div>
-        </div>
-
-        <!-- 多选题选项 -->
-        <div v-if="currentQuestion.type === 'multiple'" class="options-list">
-          <div
-            v-for="opt in currentQuestion.options"
-            :key="opt.key"
-            :class="['option-item', isSelectedOption(currentQuestion, opt.key) ? 'option-selected' : '']"
-          >
-            <span class="option-checkbox">
-              <el-checkbox :value="isSelectedOption(currentQuestion, opt.key)" disabled></el-checkbox>
-            </span>
-            <span class="option-key">{{ opt.key }}</span>
-            <span class="option-text" v-html="opt.text"></span>
-          </div>
-        </div>
-
-        <!-- 判断题选项 -->
-        <div v-if="currentQuestion.type === 'judge'" class="options-list">
-          <div
-            v-for="opt in judgeOptions"
-            :key="opt.key"
-            :class="['option-item', isSelectedOption(currentQuestion, opt.key) ? 'option-selected' : '']"
-          >
+        <div class="question-content" v-html="currentQuestion.questionContent"></div>
+        <!-- 单选题选项/多选题选项 -->
+        <div class="options-list">
+          <div v-for="(minItem,minIndex) in currentQuestion.options"
+               :key="minIndex" class="option-item"
+               :class="isValueInList(minItem.optionLabel,currentQuestion.correctAnswerTags)?'option-selected':''">
             <span class="option-radio">
-              <i v-if="isSelectedOption(currentQuestion, opt.key)" class="el-icon-check radio-checked"></i>
+              <i v-if="isValueInList(minItem.optionLabel,currentQuestion.correctAnswerTags)" class="el-icon-check radio-checked"></i>
               <i v-else class="radio-empty"></i>
             </span>
-            <span class="option-key">{{ opt.key }}</span>
-            <span class="option-text">{{ opt.text }}</span>
+            <span class="option-key" v-if="currentQuestion.questionType == '1' || currentQuestion.questionType == '2'">{{ minItem.optionLabel }}</span>
+            <span class="option-text" v-html="minItem.optionContent"></span>
           </div>
         </div>
-
         <!-- 答题结果 -->
         <div class="answer-result-box">
           <div class="answer-status">
-            <span v-if="currentQuestion.isCorrect" class="status-correct">✅ 回答正确</span>
-            <span v-else class="status-wrong">❌ 回答错误</span>
+            <span v-if="currentQuestion.isCorrect == 1" class="status-correct">✅ 回答正确</span>
+            <span v-else-if="currentQuestion.isCorrect == 0" class="status-wrong">❌ 回答错误</span>
+            <span v-else class="status-wrong">❌ 未作答</span>
           </div>
           <div class="answer-detail">
-            <div class="answer-row"><span class="answer-label">回答选项:</span>{{ currentQuestion.userAnswer }}</div>
+            <div class="answer-row"><span class="answer-label">回答选项:</span>{{ arrayToString(currentQuestion.answerTags) }}</div>
             <div class="analysis-title">试题解析</div>
             <div class="analysis-content" v-html="currentQuestion.analysis"></div>
           </div>
@@ -124,119 +86,34 @@
 </template>
 
 <script>
-  import { examElExamResultOverview, examElExamResultQuestionDetail } from '@/api/safetyEducationExaminationNew/index'
+  import {
+    examElExamAttemptReviewSidebar, examElExamAttemptReviewQuestion
+  } from '@/api/safetyEducationExaminationNew/index'
   export default {
     name: 'examDetails',
     props: {
-      propsData: {}
+      examDetailsPropsData: {}
     },
     data() {
       return {
-        // 当前选中的题目序号
+        newData:{},
         currentIndex: null,
-        // 左侧考试基本信息(来自 examElExamResultOverview 接口)
         examInfo: {
-          title: '新生入学考试',
-          name: '考试名称考试名称考试名称考试名称考试名称考试名称考试名称考试名称考试名称',
-          totalCount: 12,
-          totalScore: 100,
-          passScore: 90,
-          myScore: 70,
-          duration: '29分56秒',
-          passed: false
+          examTypeName: '',
+          examName: '',
+          questionCount: 0,
+          totalScore: 0,
+          passScore: 0,
+          earnedScore: 0,
+          durationText: '',
+          passStatus: null,
         },
-        judgeOptions: [
-          { key: 'A', text: '正确' },
-          { key: 'B', text: '错误' }
-        ],
-        // 左侧题目分组(来自 examElExamResultOverview 接口)
-        // status: 'correct' | 'wrong' | 'unanswered'
-        questionGroups: [
-          {
-            type: 'single', typeName: '单选题', totalScore: 60,
-            questions: [
-              { index: 1, status: 'correct', score: 10 },
-              { index: 2, status: 'wrong', score: 10 },
-              { index: 3, status: 'correct', score: 10 },
-              { index: 4, status: 'wrong', score: 10 },
-              { index: 5, status: 'unanswered', score: 10 },
-              { index: 6, status: 'correct', score: 10 }
-            ]
-          },
-          {
-            type: 'multiple', typeName: '多选题', totalScore: 30,
-            questions: [
-              { index: 7, status: 'wrong', score: 10 },
-              { index: 8, status: 'correct', score: 10 },
-              { index: 9, status: 'unanswered', score: 10 }
-            ]
-          },
-          {
-            type: 'judge', typeName: '判断题', totalScore: 10,
-            questions: [
-              { index: 10, status: 'correct', score: 10 },
-              { index: 11, status: 'wrong', score: 10 },
-              { index: 12, status: 'unanswered', score: 10 }
-            ]
-          }
-        ],
-        // 已加载的题目详情缓存,key 为题目序号
+        questionTypeGroups: [],
         questionCache: {},
-        // 当前题目详情(来自 examElExamResultQuestionDetail 接口)
         currentQuestion: null,
         // 右侧加载中状态
         questionLoading: false,
-        // 假数据:模拟 examElExamResultQuestionDetail 接口按序号返回
-        mockQuestions: {
-          1:  { index: 1,  type: 'single',   typeName: '单选题', score: 10, starLevel: 3, userAnswer: 'B', isCorrect: true,
-                content: '<p>第1题:题目内容题目内容题目内容题目内容题目内容题目内容题目内容题目内容题目内容</p>',
-                options: [{ key: 'A', text: '选项内容A选项内容A' }, { key: 'B', text: '选项内容B选项内容B' }, { key: 'C', text: '选项内容C选项内容C' }, { key: 'D', text: '选项内容D选项内容D' }],
-                analysis: '<p>本题考察...正确答案为B,因为...</p>' },
-          2:  { index: 2,  type: 'single',   typeName: '单选题', score: 10, starLevel: 2, userAnswer: 'A', isCorrect: false,
-                content: '<p>第2题:题目内容题目内容题目内容题目内容题目内容题目内容题目内容题目内容题目内容</p>',
-                options: [{ key: 'A', text: '选项内容A' }, { key: 'B', text: '选项内容B' }, { key: 'C', text: '选项内容C' }, { key: 'D', text: '选项内容D' }],
-                analysis: '<p>本题正确答案为C,因为...</p>' },
-          3:  { index: 3,  type: 'single',   typeName: '单选题', score: 10, starLevel: 1, userAnswer: 'C', isCorrect: true,
-                content: '<p>第3题:题目内容题目内容题目内容题目内容题目内容</p>',
-                options: [{ key: 'A', text: '选项A' }, { key: 'B', text: '选项B' }, { key: 'C', text: '选项C' }, { key: 'D', text: '选项D' }],
-                analysis: '<p>解析内容。</p>' },
-          4:  { index: 4,  type: 'single',   typeName: '单选题', score: 10, starLevel: 0, userAnswer: 'D', isCorrect: false,
-                content: '<p>第4题:题目内容题目内容题目内容</p>',
-                options: [{ key: 'A', text: '选项A' }, { key: 'B', text: '选项B' }, { key: 'C', text: '选项C' }, { key: 'D', text: '选项D' }],
-                analysis: '<p>解析内容。</p>' },
-          5:  { index: 5,  type: 'single',   typeName: '单选题', score: 10, starLevel: 0, userAnswer: '',  isCorrect: false,
-                content: '<p>第5题:题目内容题目内容题目内容</p>',
-                options: [{ key: 'A', text: '选项A' }, { key: 'B', text: '选项B' }, { key: 'C', text: '选项C' }, { key: 'D', text: '选项D' }],
-                analysis: '<p>解析内容。</p>' },
-          6:  { index: 6,  type: 'single',   typeName: '单选题', score: 10, starLevel: 0, userAnswer: 'B', isCorrect: true,
-                content: '<p>第6题:题目内容题目内容题目内容</p>',
-                options: [{ key: 'A', text: '选项A' }, { key: 'B', text: '选项B' }, { key: 'C', text: '选项C' }, { key: 'D', text: '选项D' }],
-                analysis: '<p>解析内容。</p>' },
-          7:  { index: 7,  type: 'multiple', typeName: '多选题', score: 10, starLevel: 2, userAnswer: 'A,B', isCorrect: false,
-                content: '<p>第7题:多选题题目内容多选题题目内容多选题题目内容多选题题目内容多选题题目内容</p>',
-                options: [{ key: 'A', text: '选项内容A' }, { key: 'B', text: '选项内容B' }, { key: 'C', text: '选项内容C' }, { key: 'D', text: '选项内容D' }],
-                analysis: '<p>正确答案为A、B、C,解析内容...</p>' },
-          8:  { index: 8,  type: 'multiple', typeName: '多选题', score: 10, starLevel: 0, userAnswer: 'A,C', isCorrect: true,
-                content: '<p>第8题:多选题题目内容多选题题目内容</p>',
-                options: [{ key: 'A', text: '选项A' }, { key: 'B', text: '选项B' }, { key: 'C', text: '选项C' }, { key: 'D', text: '选项D' }],
-                analysis: '<p>解析内容。</p>' },
-          9:  { index: 9,  type: 'multiple', typeName: '多选题', score: 10, starLevel: 0, userAnswer: '',  isCorrect: false,
-                content: '<p>第9题:多选题题目内容多选题题目内容</p>',
-                options: [{ key: 'A', text: '选项A' }, { key: 'B', text: '选项B' }, { key: 'C', text: '选项C' }, { key: 'D', text: '选项D' }],
-                analysis: '<p>解析内容。</p>' },
-          10: { index: 10, type: 'judge',    typeName: '判断题', score: 10, starLevel: 1, userAnswer: 'A', isCorrect: true,
-                content: '<p>第10题:以下说法正确的是:安全生产是企业第一责任。</p>',
-                options: [],
-                analysis: '<p>此说法正确,安全生产是企业的首要责任。</p>' },
-          11: { index: 11, type: 'judge',    typeName: '判断题', score: 10, starLevel: 0, userAnswer: 'B', isCorrect: false,
-                content: '<p>第11题:判断题题目内容判断题题目内容判断题题目内容</p>',
-                options: [],
-                analysis: '<p>解析内容。</p>' },
-          12: { index: 12, type: 'judge',    typeName: '判断题', score: 10, starLevel: 0, userAnswer: '',  isCorrect: false,
-                content: '<p>第12题:判断题题目内容判断题题目内容判断题题目内容</p>',
-                options: [],
-                analysis: '<p>解析内容。</p>' }
-        }
+        mockQuestions: {}
       }
     },
     computed: {},
@@ -246,27 +123,41 @@
     },
     methods: {
       initialize() {
-        // 默认选中第一题(假数据直接从 data 里读取,无需接口)
-        const firstGroup = this.questionGroups[0]
-        if (firstGroup && firstGroup.questions.length) {
-          this.$set(this, 'currentIndex', firstGroup.questions[0].index)
-          this.$set(this, 'currentQuestion', this.mockQuestions[firstGroup.questions[0].index] || null)
-        }
+        this.$set(this,'newData',this.examDetailsPropsData);
+        //左侧数据
+        examElExamAttemptReviewSidebar({attemptId:this.newData.attemptId}).then(response => {
+          this.$set(this,'examInfo',{
+            examTypeName: response.data.examTypeName?response.data.examTypeName:'',
+            examName: response.data.examName?response.data.examName:'',
+            questionCount: response.data.questionCount?response.data.questionCount:0,
+            totalScore: response.data.totalScore?response.data.totalScore:0,
+            passScore: response.data.passScore?response.data.passScore:0,
+            earnedScore: response.data.earnedScore?response.data.earnedScore:0,
+            durationText: response.data.durationText?response.data.durationText:'',
+            passStatus: response.data.passStatus?response.data.passStatus:null,
+          });
+          this.$set(this,'questionTypeGroups',response.data.questionTypeGroups);
+          // 默认选中第一题(假数据直接从 data 里读取,无需接口)
+          const firstGroup = this.questionTypeGroups[0]
+          if (firstGroup && firstGroup.questions.length) {
+            this.$set(this, 'currentIndex', firstGroup.questions[0].questionNo);
+            this.examElExamAttemptReviewQuestion(firstGroup.questions[0].snapshotQuestionId);
+          }
+        });
+      },
+      //右侧数据
+      examElExamAttemptReviewQuestion(id){
+        examElExamAttemptReviewQuestion({attemptId:this.newData.attemptId,snapshotQuestionId:id}).then(response => {
+          this.$set(this,'currentQuestion',response.data);
+        });
       },
       backPage() {
         this.$parent.tableButton(6)
       },
       // 点击左侧题号:切换当前题目,按需从接口加载详情
-      selectQuestion(index) {
-        this.$set(this, 'currentIndex', index)
-        if (this.questionCache[index]) {
-          this.$set(this, 'currentQuestion', this.questionCache[index])
-          return
-        }
-        // 假数据直接从 mockQuestions 取,对接真实接口时替换为下方注释的接口调用
-        const detail = this.mockQuestions[index] || null
-        this.$set(this.questionCache, index, detail)
-        this.$set(this, 'currentQuestion', detail)
+      selectQuestion(item) {
+        this.$set(this, 'currentIndex', item.questionNo);
+        this.examElExamAttemptReviewQuestion(item.snapshotQuestionId);
       },
       // 判断选项是否被选中
       isSelectedOption(q, key) {
@@ -274,12 +165,24 @@
         return q.userAnswer.split(',').includes(key)
       },
       // 根据左侧题目列表的 status 字段获取题号样式
-      // status: 'correct' → 绿色,'wrong' → 红色,'unanswered' → 灰色
-      getNumClass(q) {
-        if (q.status === 'correct') return 'num-correct'
-        if (q.status === 'wrong') return 'num-wrong'
+      // status: '1' → 绿色,'0' → 红色,'null' → 灰色
+      getNumClass(item) {
+        if (item.isCorrect === 1) return 'num-correct'
+        if (item.isCorrect === 0) return 'num-wrong'
         return 'num-unanswered'
-      }
+      },
+      //匹配用户选择
+      isValueInList(target, list) {
+        if (!Array.isArray(list)) return false;
+        return list.some(item => item === target);
+      },
+      //返回用户选择答案
+      arrayToString(list) {
+        // 防御性编程:如果传入的不是数组,返回空字符串防止报错
+        if (!Array.isArray(list)) return '';
+
+        return list.join(',');
+      },
     }
   }
 </script>
@@ -466,7 +369,6 @@
             padding: 10px 14px;
             cursor: default;
             transition: border-color 0.2s;
-
             &.option-selected {
               border-color: #1890ff;
               background: #e6f7ff;
@@ -544,7 +446,7 @@
 
             .analysis-content {
               font-size: 13px;
-              color: #fa8c16;
+              /*color: #fa8c16;*/
               line-height: 1.7;
             }
           }
@@ -553,3 +455,13 @@
     }
   }
 </style>
+<style lang="scss">
+  .viewGrades-addPage-drawer{
+    .el-drawer__body{
+      padding:0;
+    }
+    .el-drawer__header{
+      margin:0;
+    }
+  }
+</style>

+ 1 - 1
src/views/safetyEducationExaminationNew/components/examRecords.vue

@@ -77,7 +77,7 @@
     <historyOfIncorrectQuestions :propsData="propsData" v-if="pageType === 2"></historyOfIncorrectQuestions>
     <el-drawer
       size="100%"
-      custom-class="examinationArrange-addPage-drawer"
+      custom-class="examRecords-addPage-drawer"
       :append-to-body="true"
       :title="drawerTitle"
       ref="drawer"

+ 1 - 1
src/views/safetyEducationExaminationNew/components/historyOfIncorrectQuestions.vue

@@ -90,7 +90,7 @@
     </div>
     <el-drawer
       size="40%"
-      custom-class="examinationArrange-addPage-drawer"
+      custom-class="historyOfIncorrectQuestions-addPage-drawer"
       :append-to-body="true"
       :title="drawerTitle"
       ref="drawer"

+ 15 - 14
src/views/safetyEducationExaminationNew/examManagement/examinationArrange/studentsTakingMakeUpExams.vue

@@ -104,11 +104,9 @@
               style="width: 140px"
             />
           </el-form-item>
-          <el-form-item style="float: right;">
-            <export-component :exportConfig="exportConfig"></export-component>
-          </el-form-item>
           <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
           <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
+          <p class="page-add-common-style-button" style="float: right;" @click="exportButton()">导出</p>
         </el-form>
       </div>
       <div class="page-content-box">
@@ -154,7 +152,7 @@
     </div>
     <el-drawer
       size="100%"
-      custom-class="examinationArrange-addPage-drawer"
+      custom-class="studentsTakingMakeUpExams-addPage"
       :append-to-body="true"
       :title="drawerTitle"
       ref="drawer"
@@ -169,7 +167,6 @@
 </template>
 
 <script>
-  import exportComponent from '@/components/exportComponent/exportComponent.vue'
   import examDetails from '@/views/safetyEducationExaminationNew/components/examDetails.vue'
   import selectTestPaper from './selectTestPaper.vue'
   import {
@@ -181,7 +178,6 @@
   export default {
     name: 'addPage',
     components: {
-      exportComponent,
       selectTestPaper,
       examDetails
     },
@@ -235,14 +231,6 @@
         dataList: [],
         //数据数量
         total: 0,
-        exportConfig: {
-          api: 'system/user/student/export',              //导出接口地址
-          ids: '',                                        //勾选导出,勾选的IDS
-          fileName: '导出文件名',                         //导出文件的命名
-          customKey: null,                                //自定义参数KEY(非必填)
-          customValue: null,                               //自定义参数VALUE(非必填)
-          screenData: {}                                  //导出筛选数据(非必要-如有该参数组件会显示导出筛选数据按钮)
-        },
         //弹窗相关
         drawerTitle: '',
         drawerType: '',
@@ -260,6 +248,19 @@
       this.systemUserGetAcademicYear()
     },
     methods: {
+      //导出
+      exportButton(){
+        let self = this;
+        self.$confirm(`确认导出数据?`, "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(async () => {
+          let obj = JSON.parse(JSON.stringify(this.queryParams))
+          obj.examId = self.newData.parentExamId
+          self.download('/exam/elExam/makeup-candidates-export', {...obj}, '补考候选人.xlsx')
+        }).catch(() => {})
+      },
       //弹窗返回
       drawerReturnButton(){
         //选择试卷

+ 10 - 26
src/views/safetyEducationExaminationNew/examManagement/examinationResult/academicPerformance.vue

@@ -32,7 +32,7 @@
             maxLength="30"
             v-model="queryParams.searchValue"
             placeholder="姓名/学工号"
-            style="width: 140px"
+            style="width: 240px"
           />
         </el-form-item>
         <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
@@ -45,19 +45,13 @@
         <el-table-column label="姓名" prop="userName"  show-overflow-tooltip/>
         <el-table-column label="学工号" prop="account" width="140" show-overflow-tooltip/>
         <el-table-column label="学院单位" prop="deptName" width="240" show-overflow-tooltip/>
-        <el-table-column label="完成时间" prop="submitTime" width="200" show-overflow-tooltip>
+        <el-table-column label="完成时间" prop="completeTime" width="200" show-overflow-tooltip>
           <template slot-scope="scope">
-            <span>{{ parseTime(scope.row.submitTime,"{y}-{m}-{d} {h}:{i}") }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="学时" prop="durationText" width="200" show-overflow-tooltip/>
-        <el-table-column label="积分" prop="score" width="200" show-overflow-tooltip/>
-        <el-table-column label="是否完成" prop="resultStatus" width="200" show-overflow-tooltip>
-          <template slot-scope="scope">
-            <span v-if="scope.row.resultStatus == 0">已完成</span>
-            <span v-if="scope.row.resultStatus == 1">未完成</span>
+            <span>{{ parseTime(scope.row.completeTime,"{y}-{m}-{d} {h}:{i}") }}</span>
           </template>
         </el-table-column>
+        <el-table-column label="学时" prop="rewardCreditHours" width="200" show-overflow-tooltip/>
+        <el-table-column label="积分" prop="rewardPoints" width="200" show-overflow-tooltip/>
       </el-table>
       <pagination :page-sizes="[20, 30, 40, 50]"
                   v-show="total>0"
@@ -72,8 +66,7 @@
 
 <script>
   import {
-    systemUserGetCategories,systemUserGetAcademicYear,
-    examElExamResultScorePage,examElDisciplineTypeList,systemDeptCurrentDept,
+    examElExamResultRewardPage,systemDeptCurrentDept,
   } from "@/api/safetyEducationExaminationNew/index";
   export default {
     name: 'addPage',
@@ -117,15 +110,9 @@
           cancelButtonText: "取消",
           type: "warning"
         }).then(async () => {
-          let obj = JSON.parse(JSON.stringify(this.queryParams))
-          if(this.dateRange[0]){
-            obj.startTime = this.dateRange[0]+'T00:00:00'
-            obj.endTime = this.dateRange[1]+'T23:59:59'
-          }else{
-            obj.startTime = "";
-            obj.endTime = "";
-          }
-          self.download('/exam/elExamResult/score-export/', {...obj}, '学习情况-'+this.drawerPropsData.examName+'.xlsx')
+          let obj = JSON.parse(JSON.stringify(self.queryParams))
+          obj.examId = this.drawerPropsData.examId
+          self.download('/exam/elExamResult/reward-export', {...obj}, '学习情况-'+this.drawerPropsData.examName+'.xlsx')
         }).catch(() => {})
       },
       //查询按钮
@@ -149,12 +136,9 @@
       },
       //获取数据列表
       getList(){
-        console.log('drawerPropsData',this.drawerPropsData)
-
         let obj = JSON.parse(JSON.stringify(this.queryParams))
         obj.examId = this.drawerPropsData.examId
-        examElExamResultScorePage(obj).then(response => {
-
+        examElExamResultRewardPage(obj).then(response => {
           this.$set(this,'dataList',response.data.records);
           this.$set(this,'total',response.data.total);
         });

+ 0 - 54
src/views/safetyEducationExaminationNew/examManagement/examinationResult/learningProgress.vue

@@ -1,54 +0,0 @@
-<!-- 学习情况 -->
-<template>
-  <div class="page-container learningProgress-addPage">
-
-  </div>
-</template>
-
-<script>
-  //import { getDicts } from "@/api/commonality/noPermission";
-  //import { systemUserSelect } from "@/api/commonality/permission";
-  export default {
-    name: 'addPage',
-    props: {
-      propsData: {}
-    },
-    data() {
-      return {
-        newData: {}
-      }
-    },
-    created() {
-
-    },
-    mounted() {
-      this.initialize()
-    },
-    methods: {
-      // 初始化
-      initialize() {
-
-      },
-      // 返回按钮
-      backPage() {
-        this.$parent.tableButton(6)
-      },
-      // 提交按钮
-      submitForm() {
-
-      }
-    }
-  }
-</script>
-
-<style scoped lang="scss">
-  .learningProgress-addPage {
-    .content-box {
-      flex: 1;
-      display: flex;
-      flex-direction: column;
-      overflow: hidden;
-      padding: 20px;
-    }
-  }
-</style>

+ 14 - 18
src/views/safetyEducationExaminationNew/examManagement/examinationResult/viewGrades.vue

@@ -115,14 +115,13 @@
     </div>
     <el-drawer
       size="100%"
-      custom-class="examinationArrange-addPage-drawer"
+      custom-class="viewGrades-addPage-drawer"
       :append-to-body="true"
       :title="drawerTitle"
       ref="drawer"
       :visible.sync="drawer"
-      direction="rtl"
-    >
-      <examDetails v-if="drawer"></examDetails>
+      direction="rtl">
+      <examDetails v-if="drawer" :examDetailsPropsData="examDetailsPropsData"></examDetails>
     </el-drawer>
   </div>
 </template>
@@ -167,7 +166,8 @@
         //弹窗相关
         drawerTitle: '',
         drawerType: '',
-        drawer: false
+        drawer: false,
+        examDetailsPropsData:{},
       }
     },
     created() {
@@ -189,21 +189,20 @@
           cancelButtonText: "取消",
           type: "warning"
         }).then(async () => {
-          let obj = JSON.parse(JSON.stringify(this.queryParams))
-          if(this.dateRange[0]){
-            obj.startTime = this.dateRange[0]+'T00:00:00'
-            obj.endTime = this.dateRange[1]+'T23:59:59'
-          }else{
-            obj.startTime = "";
-            obj.endTime = "";
-          }
-          self.download('/exam/elExamResult/score-export', {...obj}, '查看成绩-'+this.drawerPropsData.examName+'.xlsx')
+          let obj = JSON.parse(JSON.stringify(self.queryParams))
+          obj.examId = self.drawerPropsData.examId
+          self.download('/exam/elExamResult/score-export', {...obj}, '查看成绩-'+self.drawerPropsData.examName+'.xlsx')
         }).catch(() => {})
       },
-      lockExam(){
+      lockExam(row){
         this.$set(this, 'drawerTitle', '试卷详情')
         this.$set(this, 'drawerType', 2)
         this.$set(this, 'drawer', true)
+        let obj = {
+          attemptId:row.attemptId,
+          showType:true,
+        }
+        this.$set(this,'examDetailsPropsData',obj);//attemptId
       },
       //查询按钮
       handleQuery(){
@@ -226,12 +225,9 @@
       },
       //获取数据列表
       getList(){
-        console.log('drawerPropsData',this.drawerPropsData)
-
         let obj = JSON.parse(JSON.stringify(this.queryParams))
         obj.examId = this.drawerPropsData.examId
         examElExamResultScorePage(obj).then(response => {
-
           this.$set(this,'dataList',response.data.records);
           this.$set(this,'total',response.data.total);
         });

+ 18 - 12
src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/classHoursConfiguration.vue

@@ -8,7 +8,7 @@
           <el-form-item label="" label-width="0">
             <div class="form-min-box">
               <p class="form-min-left-p">1</p>
-              <p class="form-min-p">分钟</p>
+              <p class="form-min-p">学时</p>
             </div>
           </el-form-item>
           <p class="form-text-p" style="margin:0 18px;">=</p>
@@ -21,12 +21,12 @@
                                 :step="0.1" :precision="1" step-strictly
                                 v-model="newData.studyHours">
               </el-input-number>
-              <p class="form-min-p">学时</p>
+              <p class="form-min-p">分钟</p>
             </div>
           </el-form-item>
           <div class="form-help-box">
             <p class="el-icon-question"></p>
-            <p>学习要求时长</p>
+            <p>课件资料的要求时长与所获学时的计算公式</p>
           </div>
         </div>
         <div class="form-big-box">
@@ -40,10 +40,13 @@
                                 :step="0.1" :precision="1" step-strictly
                                 v-model="newData.repeatGetStudyDay">
               </el-input-number>
-              <p class="form-min-p">学时</p>
             </div>
           </el-form-item>
           <p class="form-text-p" style="margin:0 0 0 20px;">天,不可再获得学时</p>
+          <div class="form-help-box">
+            <p class="el-icon-question"></p>
+            <p>课件资料的要求时长与所获学时的计算公式</p>
+          </div>
         </div>
         <p class="border-top"></p>
         <p class="title-p">积分计算</p>
@@ -69,7 +72,7 @@
           </el-form-item>
           <div class="form-help-box">
             <p class="el-icon-question"></p>
-            <p>学习要求时长</p>
+            <p>课件资料的要求时长与所获积分的计算公式</p>
           </div>
         </div>
         <div class="form-big-box">
@@ -94,7 +97,7 @@
           </el-form-item>
           <div class="form-help-box">
             <p class="el-icon-question"></p>
-            <p>考试通过得分</p>
+            <p>考试通过后取的考试数与所获积分的计算公式</p>
           </div>
         </div>
         <div class="form-big-box">
@@ -119,24 +122,27 @@
           </el-form-item>
           <div class="form-help-box">
             <p class="el-icon-question"></p>
-            <p>刷题练习正确非重复数量</p>
+            <p>刷题练习正确题目数量与所获积分的计算公式</p>
           </div>
         </div>
         <div class="form-big-box">
           <p class="form-text-p" style="margin:0 20px 0 0;">重复学习同一课件超过</p>
-          <el-form-item label="" prop="repeatGetPointDat" label-width="0">
+          <el-form-item label="" prop="repeatGetPointDay" label-width="0">
             <div class="form-min-box">
               <el-input-number  class="form-input-number"
                                 style="width:160px"
                                 :min="0"
                                 :max="9999"
                                 :step="1" :precision="0" step-strictly
-                                v-model="newData.repeatGetPointDat">
+                                v-model="newData.repeatGetPointDay">
               </el-input-number>
-              <p class="form-min-p">学时</p>
             </div>
           </el-form-item>
           <p class="form-text-p" style="margin:0 0 0 20px;">天,不可再获得学时</p>
+          <div class="form-help-box">
+            <p class="el-icon-question"></p>
+            <p>超过设置的时间周期后,学员重复学习该课件将不会再获得积分奖励</p>
+          </div>
         </div>
       </el-form>
     </div>
@@ -161,7 +167,7 @@
           studuHoursPoint:0,
           examScorePoint:0,
           practisePoint:0,
-          repeatGetPointDat:0,
+          repeatGetPointDay:0,
         },
         rules:{},
       }
@@ -174,7 +180,7 @@
     },
     methods:{
       initialize(){
-        examElConfigValueMap({configType:2}).then(response => {
+        examElConfigValueMap({configType:5}).then(response => {
           this.$set(this,'newData',response.data);
         });
       },

+ 177 - 172
src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/gradingConfiguration.vue

@@ -1,130 +1,126 @@
 <!--分级要求配置-->
 <template>
   <div class="page-container basicConfiguration-gradingConfiguration">
+    <div class="top-button-box">
+      <p :class="checkIndex == 1 ?'check-p':''" @click="checkButton(1)">Ⅰ级</p>
+      <p :class="checkIndex == 2 ?'check-p':''" @click="checkButton(2)">Ⅱ级</p>
+      <p :class="checkIndex == 3 ?'check-p':''" @click="checkButton(3)">Ⅲ级</p>
+      <p :class="checkIndex == 4 ?'check-p':''" @click="checkButton(4)">Ⅳ级</p>
+    </div>
     <div class="content-box scrollbar-box">
-      <el-form class="add-form-box" :model="newData" ref="form"
-               :rules="rules">
-        <el-form-item label="学时计算" prop="gradeStudyHour" label-width="112px">
-          <div class="form-min-box">
-            <el-input-number  class="form-input-number"
-                              style="width:100px"
-                              :min="0"
-                              :max="9999"
-                              :step="1" :precision="0" step-strictly
-                              v-model="newData.gradeStudyHour"
-                              :controls="false">
-            </el-input-number>
-            <p class="form-min-p">分钟</p>
-            <span class="form-min-span">注:9月 1日至次年的8月31日为一学年</span>
-          </div>
-        </el-form-item>
-        <p class="title-1-p">Ⅰ级分级</p>
-        <div class="form-flex-box">
-          <el-form-item label="第一学年完成不少于" prop="levelOneInitMinHour" label-width="182px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelOneInitMinHour">
+      <el-form class="add-form-box" :model="newData" ref="form" :rules="rules" label-width="0">
+        <div class="title-box">
+          <p>用户类别</p>
+          <p>第一学年学时要求</p>
+          <p>后续学年学时要求</p>
+        </div>
+        <div class="input-box">
+          <p class="input-title-p">本科生</p>
+          <div class="input-min-box">
+            <el-form-item label="" prop="underInitMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.underInitMinHour">
               </el-input-number>
-              <p class="form-min-p">学时,</p>
-            </div>
-          </el-form-item>
-          <el-form-item label="后续每学年完成不少于" prop="levelOneFollowMinHour" label-width="170px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelOneFollowMinHour">
+            </el-form-item>
+          </div>
+          <div class="input-min-box">
+            <el-form-item label="" prop="underFollowMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.underFollowMinHour">
               </el-input-number>
-              <p class="form-min-p">学时学习</p>
-            </div>
-          </el-form-item>
+            </el-form-item>
+          </div>
         </div>
-        <p class="title-2-p">Ⅱ级分级</p>
-        <div class="form-flex-box">
-          <el-form-item label="第一学年完成不少于" prop="leveltwoInitMinHour" label-width="182px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.leveltwoInitMinHour">
+        <div class="input-box">
+          <p class="input-title-p">硕士研究生</p>
+          <div class="input-min-box">
+            <el-form-item label="" prop="masterInitMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.masterInitMinHour">
               </el-input-number>
-              <p class="form-min-p">学时,</p>
-            </div>
-          </el-form-item>
-          <el-form-item label="后续每学年完成不少于" prop="levelTwoFollowMinHour" label-width="170px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelTwoFollowMinHour">
+            </el-form-item>
+          </div>
+          <div class="input-min-box">
+            <el-form-item label="" prop="masterFollowMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.masterFollowMinHour">
               </el-input-number>
-              <p class="form-min-p">学时学习</p>
-            </div>
-          </el-form-item>
+            </el-form-item>
+          </div>
         </div>
-        <p class="title-3-p">Ⅲ级分级</p>
-        <div class="form-flex-box">
-          <el-form-item label="第一学年完成不少于" prop="levelThreeInitMinHour" label-width="182px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelThreeInitMinHour">
+        <div class="input-box">
+          <p class="input-title-p">博士生</p>
+          <div class="input-min-box">
+            <el-form-item label="" prop="phdInitMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.phdInitMinHour">
               </el-input-number>
-              <p class="form-min-p">学时,</p>
-            </div>
-          </el-form-item>
-          <el-form-item label="后续每学年完成不少于" prop="levelThreeFollowMinHour" label-width="170px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelThreeFollowMinHour">
+            </el-form-item>
+          </div>
+          <div class="input-min-box">
+            <el-form-item label="" prop="phdFollowMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.phdFollowMinHour">
               </el-input-number>
-              <p class="form-min-p">学时学习</p>
-            </div>
-          </el-form-item>
+            </el-form-item>
+          </div>
         </div>
-        <p class="title-4-p">Ⅳ级分级</p>
-        <div class="form-flex-box">
-          <el-form-item label="第一学年完成不少于" prop="levelFourInitMinHour" label-width="182px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelFourInitMinHour">
+        <div class="input-box">
+          <p class="input-title-p">教职工</p>
+          <div class="input-min-box">
+            <el-form-item label="" prop="facInitMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.facInitMinHour">
               </el-input-number>
-              <p class="form-min-p">学时,</p>
-            </div>
-          </el-form-item>
-          <el-form-item label="后续每学年完成不少于" prop="levelFourFollowMinHour" label-width="170px">
-            <div class="form-min-box-2">
-              <el-input-number  class="form-input-number"
-                                style="width:260px"
-                                :min="0"
-                                :max="9999"
-                                :step="0.1" :precision="1" step-strictly
-                                v-model="newData.levelFourFollowMinHour">
+            </el-form-item>
+          </div>
+          <div class="input-min-box">
+            <el-form-item label="" prop="facFollowMinHour">
+              <el-input-number
+                class="form-input-number"
+                style="width:160px"
+                :min="0"
+                :max="9999"
+                :step="0.1" :precision="1" step-strictly
+                v-model="newData.facFollowMinHour">
               </el-input-number>
-              <p class="form-min-p">学时学习</p>
-            </div>
-          </el-form-item>
+            </el-form-item>
+          </div>
         </div>
       </el-form>
     </div>
@@ -143,16 +139,16 @@
     },
     data(){
       return{
+        checkIndex:1,
         newData:{
-          gradeStudyHour:0,
-          levelOneInitMinHour:0,
-          levelOneFollowMinHour:0,
-          leveltwoInitMinHour:0,
-          levelTwoFollowMinHour:0,
-          levelThreeInitMinHour:0,
-          levelThreeFollowMinHour:0,
-          levelFourInitMinHour:0,
-          levelFourFollowMinHour:0,
+          underInitMinHour:0,
+          underFollowMinHour:0,
+          masterInitMinHour:0,
+          masterFollowMinHour:0,
+          phdInitMinHour:0,
+          phdFollowMinHour:0,
+          facInitMinHour:0,
+          facFollowMinHour:0,
         },
         rules:{
           // gradeStudyHour: [
@@ -201,8 +197,15 @@
 
     },
     methods:{
+      //切换按钮
+      checkButton(val){
+        if(this.checkIndex != val){
+          this.$set(this,'checkIndex',val);
+          this.initialize();
+        }
+      },
       initialize(){
-        examElConfigValueMap({configType:1}).then(response => {
+        examElConfigValueMap({configType:this.checkIndex}).then(response => {
           this.$set(this,'newData',response.data);
         });
       },
@@ -230,7 +233,7 @@
             }).then(function() {
             }).then(() => {
               const list = Object.entries(self.newData).map(([key, value]) => ({
-                configType: 1,
+                configType: self.checkIndex,
                 configCode: key,
                 configValue: value // 确保 configValue 是字符串类型
               }));
@@ -248,66 +251,68 @@
 
 <style scoped lang="scss">
   .basicConfiguration-gradingConfiguration{
+    overflow: hidden;
+    .top-button-box{
+      display: flex;
+      margin:30px 0 0 40px;
+      p{
+        text-align: center;
+        width:100px;
+        height:40px;
+        line-height:40px;
+        font-size:14px;
+        color:#999;
+        border:1px solid #999;
+        border-radius:4px;
+        margin:0 20px 0 0;
+        cursor: pointer;
+      }
+      .check-p{
+        color:#fff;
+        background-color: #0183fa;
+        border:1px solid #0183fa;
+      }
+    }
     .content-box{
       flex:1;
       display: flex;
       padding:20px;
-      .form-min-box{
+      .title-box{
+        width:1000px;
         display: flex;
-        .form-input-number ::v-deep .el-input__inner {
-          border-top-right-radius: 0;
-          border-bottom-right-radius:0;
+        padding:0 20px;
+        border-bottom:1px solid #dedede;
+        margin-left:20px;
+        p{
+          height:80px;
+          line-height:80px;
         }
-        .form-min-p{
-          background-color: #DCDFE6;
-          padding:0 20px;
-          border-top-right-radius: 4px;
-          border-bottom-right-radius: 4px;
-          line-height: 40px;
+        p:nth-child(1){
+          flex:1;
         }
-        .form-min-span{
-          margin-left:20px;
-          color: #999;
-          line-height: 40px;
+        p:nth-child(2){
+          width:200px;
         }
-      }
-      .form-min-box-2{
-        display: flex;
-        .form-min-p{
-          line-height: 40px;
-          margin-left:15px;
+        p:nth-child(3){
+          width:200px;
         }
       }
-      .form-flex-box{
+      .input-box{
+        width:1000px;
         display: flex;
-      }
-      .title-1-p{
-        font-size:18px;
-        line-height:40px;
-        margin-left:40px;
-        color:#FE0000;
-        margin-bottom:20px;
-      }
-      .title-2-p{
-        font-size:18px;
-        line-height:40px;
-        margin-left:40px;
-        color:#FCA401;
-        margin-bottom:20px;
-      }
-      .title-3-p{
-        font-size:18px;
-        line-height:40px;
-        margin-left:40px;
-        color:#FBDE01;
-        margin-bottom:20px;
-      }
-      .title-4-p{
-        font-size:18px;
-        line-height:40px;
-        margin-left:40px;
-        color:#0141FF;
-        margin-bottom:20px;
+        border-bottom:1px solid #dedede;
+        padding:0 20px;
+        margin-left:20px;
+        .input-title-p{
+          flex:1;
+          height:80px;
+          line-height:80px;
+        }
+        .input-min-box{
+          width:200px;
+          height:40px;
+          margin-top:20px;
+        }
       }
     }
   }

+ 1 - 1
src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/index.vue

@@ -1,7 +1,7 @@
 <!-- 基础配置 -->
 <template>
   <div class="basicConfiguration">
-    <div class="page-container-top-max-big-box">
+    <div class="page-container-top-max-big-box-shadow">
       <p class="top-1-p">基础配置</p>
       <p class="top-2-p" @click="resetButton()">重置</p>
       <p class="top-3-p" @click="submitButton()">保存</p>

+ 1 - 1
src/views/safetyEducationExaminationNew/publicConfiguration/basicConfiguration/otherConfiguration.vue

@@ -49,7 +49,7 @@
     },
     methods:{
       initialize(){
-        examElConfigValueMap({configType:3}).then(response => {
+        examElConfigValueMap({configType:6}).then(response => {
           this.$set(this,'newData',response.data);
         });
       },

+ 5 - 3
src/views/safetyEducationExaminationNew/publicConfiguration/certificateTemplate/addPage.vue

@@ -124,9 +124,11 @@
           ],
         },
         textList:[
-          {value:'{{name}}',name:'名称'},
-          {value:'{{name}}',name:'名称'},
-          {value:'{{name}}',name:'名称'},
+          {value:'{{cnName}}',name:'学院名称'},
+          {value:'{{userName}}',name:'用户姓名'},
+          {value:'{{account}}',name:'学工号'},
+          {value:'{{today}}',name:'发证日期'},
+          {value:'{{certNo}}',name:'证书编号'},
         ],
       }
     },

+ 43 - 82
src/views/safetyEducationExaminationNew/questionBankManagement/practiceSolvingProblems/index.vue

@@ -5,29 +5,26 @@
       <div class="page-form-title-box">
         <el-form :model="queryParams" class="form-box" ref="queryForm"
                  :inline="true" style="width:100%;">
-          <el-form-item label="" prop="queryParamsData1">
-            <el-select v-model="queryParams.queryParamsData1" multiple placeholder="学年" style="width: 200px">
-              <el-option
-                v-for="dict in optionListA"
-                :key="dict.value"
-                :label="dict.label"
-                :value="dict.value"
-              />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="" prop="queryParamsData2">
-            <el-select v-model="queryParams.queryParamsData2" placeholder="学院单位" style="width: 200px">
-              <el-option
-                v-for="dict in optionListB"
-                :key="dict.deptId"
-                :label="dict.deptName"
-                :value="dict.deptId"
-              />
-            </el-select>
+          <el-form-item label="" prop="deptId">
+            <el-cascader
+              style="width: 180px"
+              v-model="queryParams.deptId"
+              :options="optionListB"
+              :props="{
+                    emitPath:false,
+                    checkStrictly: true,
+                    value: 'deptId',
+                    label: 'deptName',
+                    children: 'child',
+                  }"
+              :show-all-levels="false"
+              filterable
+              placeholder="学院单位"
+            ></el-cascader>
           </el-form-item>
-          <el-form-item label="" prop="queryParamsData3">
+          <el-form-item label="" prop="knowledgePointId">
             <el-cascader
-              v-model="queryParams.queryParamsData3"
+              v-model="queryParams.knowledgePointId"
               :options="optionListC"
               :props="{
                 emitPath:false,
@@ -61,19 +58,18 @@
       </div>
       <div class="page-content-box">
         <el-table class="table-box"  border :data="dataList">
-          <el-table-column label="知识点" prop="name"  show-overflow-tooltip/>
-          <el-table-column label="试题总数" prop="content" width="200" show-overflow-tooltip/>
-          <el-table-column label="练习人数" prop="content" width="200" show-overflow-tooltip/>
-          <el-table-column label="答题总数" prop="content" width="200" show-overflow-tooltip/>
-          <el-table-column label="答对题数" prop="content" width="200" show-overflow-tooltip/>
-          <el-table-column label="整体正确率%" prop="content" width="200" show-overflow-tooltip/>
-          <el-table-column label="操作" width="200" show-overflow-tooltip v-if="tableButtonType">
+          <el-table-column label="知识点" prop="knowledgePointName"  show-overflow-tooltip/>
+          <el-table-column label="试题总数" prop="totalQuestionCount" width="200" show-overflow-tooltip/>
+          <el-table-column label="练习人数" prop="practiceUserCount" width="200" show-overflow-tooltip/>
+          <el-table-column label="答题总数" prop="totalAnswerCount" width="200" show-overflow-tooltip/>
+          <el-table-column label="答对题数" prop="correctAnswerCount" width="200" show-overflow-tooltip/>
+          <el-table-column label="整体正确率%" prop="correctRate" width="200" show-overflow-tooltip/>
+          <el-table-column label="操作" width="200" show-overflow-tooltip>
             <template slot-scope="scope">
               <div class="table-button-box">
                 <p class="table-button-null"></p>
                 <p class="table-button-p"
                    @click="tableButton(2,scope.row)"
-                   v-hasPermiRouter="['demo:demo:detail']"
                 >练习统计</p>
                 <p class="table-button-null"></p>
               </div>
@@ -89,27 +85,29 @@
         />
       </div>
     </div>
-    <!--<add-page :propsData="propsData" v-if="pageType === 2"></add-page>-->
+    <practiceStatistics :propsData="propsData" v-if="pageType === 2"></practiceStatistics>
   </div>
 </template>
 <script>
   //import { getDicts } from "@/api/commonality/noPermission";
   //import { systemUserSelect } from "@/api/commonality/permission";
   //import { getInfo } from "@/api/basicsModules/index";
-  //import addPage from "./addPage.vue";
-  import { examElKnowledgePointTreeList,systemDeptCurrentDept, } from "@/api/safetyEducationExaminationNew/index";
+  import practiceStatistics from "./practiceStatistics.vue";
+  import {
+    examElPracticeStatPage,
+    examElKnowledgePointTreeList,systemDeptCurrentDept,
+  } from "@/api/safetyEducationExaminationNew/index";
   export default {
     name: 'index',
-    //components: {
-    //  addPage
-    //},
+    components: {
+      practiceStatistics
+    },
     data () {
       return {
         tableButtonType:this.hasPermiDom(['demo:demo:detail','demo:demo:edit','demo:demo:del',]),
         //页面状态
         pageType:1,
         //下拉列表数据
-        optionListA:[],
         optionListB:[],
         optionListC:[],
         //查询条件
@@ -117,7 +115,7 @@
           page:1,
           pageSize:20,
           queryParamsData1:"",
-          queryParamsData2 :null,
+          deptId :null,
         },
         //时间数据
         dateRange:[],
@@ -135,7 +133,7 @@
     mounted () {
       this.systemDeptCurrentDept();
       this.examElKnowledgePointTreeList();
-      //this.getList();
+      this.getList();
     },
     methods: {
       //查询按钮
@@ -150,13 +148,12 @@
           page:1,
           pageSize:20,
           queryParamsData1:"",
-          queryParamsData2 :null,
+          deptId :null,
         });
         this.getList();
       },
       //获取数据列表
       getList(){
-
         let obj = JSON.parse(JSON.stringify(this.queryParams))
         if(this.dateRange[0]){
           obj.startTime = this.dateRange[0]+'T00:00:00'
@@ -165,8 +162,7 @@
           obj.startTime = "";
           obj.endTime = "";
         }
-        getListFunction(obj).then(response => {
-
+        examElPracticeStatPage(obj).then(response => {
           this.$set(this,'dataList',response.data.records);
           this.$set(this,'total',response.data.total);
         });
@@ -174,49 +170,11 @@
       //操作按钮
       tableButton(type,row){
         let self = this;
-        if(type == 1){
-          //新增
-          this.$set(this,'pageType',2);
-          this.$set(this,'propsData',{});
-        }else if(type == 2){
+        if(type == 2){
           //详情
           this.$set(this,'pageType',2);
           let obj = JSON.parse(JSON.stringify(row))
-          obj.showType = true;
-          this.$set(this,'propsData',obj);
-        }else if(type == 3){
-          //编辑
-          this.$set(this,'pageType',2);
-          let obj = JSON.parse(JSON.stringify(row))
-          obj.showType = false;
           this.$set(this,'propsData',obj);
-        }else if(type == 4){
-          //删除
-          this.$confirm('是否确认删除?', "警告", {
-            confirmButtonText: "确定",
-            cancelButtonText: "取消",
-            type: "warning"
-          }).then(function() {
-          }).then(() => {
-            deleteFunction({id:row.id}).then(response => {
-              self.msgSuccess(response.message)
-              self.getList();
-            });
-          }).catch(() => {});
-        }else if(type == 5){
-          //启用&停用
-          let text = row.state  ? "停用" : "启用";
-          this.$confirm('是否确认' + text + '?', "警告", {
-            confirmButtonText: "确定",
-            cancelButtonText: "取消",
-            type: "warning"
-          }).then(function() {
-          }).then(() => {
-            stateFunction({id:row.id,state:!row.state,}).then(response => {
-              self.msgSuccess(response.message)
-              self.getList();
-            });
-          }).catch(() => {});
         }else if(type == 6){
           //返回并刷新
           this.$set(this,'pageType',1);
@@ -226,9 +184,12 @@
       //学院列表
       systemDeptCurrentDept(){
         systemDeptCurrentDept({}).then(response => {
-          this.$set(this,'optionListB',response.data);
+          const list = response.data || [];
+          this.formatTreeData(list);
+          this.$set(this,'optionListB',list);
         });
       },
+      //知识点
       examElKnowledgePointTreeList(){
         examElKnowledgePointTreeList({}).then(response => {
           const list = response.data || [];

+ 207 - 0
src/views/safetyEducationExaminationNew/questionBankManagement/practiceSolvingProblems/practiceStatistics.vue

@@ -0,0 +1,207 @@
+<!-- 练习统计 -->
+<template>
+  <div class="page-container practiceStatistics-addPage">
+    <div class="page-container-top-max-big-box-shadow">
+      <p class="top-1-p">练习统计</p>
+      <p class="top-2-p" @click="backPage()">返回</p>
+    </div>
+    <div class="content-box">
+      <div class="page-form-title-box">
+        <el-form :model="queryParams" class="form-box" ref="queryForm"
+                 :inline="true" style="width:100%;">
+          <el-form-item label="" prop="deptId">
+            <el-cascader
+              style="width: 180px"
+              v-model="queryParams.deptId"
+              :options="optionListB"
+              :props="{
+                    emitPath:false,
+                    checkStrictly: true,
+                    value: 'deptId',
+                    label: 'deptName',
+                    children: 'child',
+                  }"
+              :show-all-levels="false"
+              filterable
+              placeholder="学院单位"
+            ></el-cascader>
+          </el-form-item>
+          <el-form-item label="" prop="userType">
+            <el-select v-model="queryParams.userType" placeholder="用户类别" style="width: 200px">
+              <el-option
+                v-for="dict in optionListC"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="" prop="keyword">
+            <el-input
+              maxLength="30"
+              v-model="queryParams.keyword"
+              placeholder="姓名/学工号"
+              style="width: 200px"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="state">
+            <el-date-picker
+              :clearable="false"
+              v-model="dateRange"
+              size="small"
+              style="width: 240px"
+              value-format="yyyy-MM-dd"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+            ></el-date-picker>
+          </el-form-item>
+          <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
+          <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
+        </el-form>
+      </div>
+      <div class="page-content-box">
+        <el-table class="table-box"  border :data="dataList">
+          <el-table-column label="姓名" prop="userName"  show-overflow-tooltip/>
+          <el-table-column label="学工号" prop="account" width="200" show-overflow-tooltip/>
+          <el-table-column label="学院单位" prop="deptName" width="200" show-overflow-tooltip/>
+          <el-table-column label="练习时间" prop="lastPracticeTime" width="200" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.lastPracticeTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="刷题总数" prop="totalAnswerCount" width="200" show-overflow-tooltip/>
+          <el-table-column label="答对题数" prop="correctAnswerCount" width="200" show-overflow-tooltip/>
+          <el-table-column label="整体正确率%" prop="correctRate" width="200" show-overflow-tooltip/>
+          <el-table-column label="积分" prop="points" width="200" show-overflow-tooltip/>
+        </el-table>
+        <pagination :page-sizes="[20, 30, 40, 50]"
+                    v-show="total>0"
+                    :total="total"
+                    :page.sync="queryParams.page"
+                    :limit.sync="queryParams.pageSize"
+                    @pagination="getList"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  //import { getDicts } from "@/api/commonality/noPermission";
+  //import { systemUserSelect } from "@/api/commonality/permission";
+  import {
+    examElPracticeStatDetail,
+    systemUserGetCategories,systemDeptCurrentDept,
+  } from "@/api/safetyEducationExaminationNew/index";
+  export default {
+    name: 'addPage',
+    props: {
+      propsData: {}
+    },
+    data() {
+      return {
+        //下拉列表数据
+        optionListB:[],
+        optionListC:[],
+        //查询条件
+        queryParams:{
+          page:1,
+          pageSize:20,
+          deptId :null,
+          userType:null,
+          keyword:'',
+        },
+        //时间数据
+        dateRange:[],
+        //列表数据
+        dataList:[],
+        //数据数量
+        total:0,
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+      this.getList()
+      this.systemDeptCurrentDept()
+      this.systemUserGetCategories()
+    },
+    methods: {
+      // 返回按钮
+      backPage() {
+        this.$parent.tableButton(6)
+      },
+      //查询按钮
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      //重置按钮
+      resetQuery(){
+        this.$set(this,'dateRange',[])
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          deptId :null,
+          userType:null,
+          keyword:'',
+        });
+        this.getList();
+      },
+      //获取数据列表
+      getList(){
+        let obj = JSON.parse(JSON.stringify(this.queryParams))
+        obj.knowledgePointId = this.propsData.knowledgePointId
+        if(this.dateRange[0]){
+          obj.startTime = this.dateRange[0]+'T00:00:00'
+          obj.endTime = this.dateRange[1]+'T23:59:59'
+        }else{
+          obj.startTime = "";
+          obj.endTime = "";
+        }
+        examElPracticeStatDetail(obj).then(response => {
+          this.$set(this,'dataList',response.data.records);
+          this.$set(this,'total',response.data.total);
+        });
+      },
+      //用户类别
+      systemUserGetCategories(){
+        systemUserGetCategories({}).then(response => {
+          this.$set(this,'optionListC',response.data);
+        });
+      },
+      //学院列表
+      systemDeptCurrentDept(){
+        systemDeptCurrentDept({}).then(response => {
+          const list = response.data || [];
+          this.formatTreeData(list);
+          this.$set(this,'optionListB',list);
+        });
+      },
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .practiceStatistics-addPage {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    .page-container-top-max-big-box-shadow{
+      margin:0;
+      box-shadow:none;
+      border-bottom:1px solid #dedede;
+      border-radius:0;
+    }
+    .content-box {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      overflow: hidden;
+    }
+  }
+</style>

+ 1 - 1
src/views/safetyEducationExaminationNew/questionBankManagement/questionBankManagement/index.vue

@@ -122,7 +122,7 @@
     <add-page :propsData="propsData" v-if="pageType === 2"></add-page>
     <el-drawer
       size="40%"
-      custom-class="examinationArrange-addPage-drawer"
+      custom-class="questionBankManagement-drawer"
       :append-to-body="true"
       :title="drawerTitle"
       ref="drawer"