dedsudiyu 2 days ago
parent
commit
38089478a8

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

@@ -561,5 +561,37 @@ export function examElExamUserResultMyScoreListPage(data) {
     data: data
   })
 }
+//考试记录列表
+export function examElUserExamAttemptAttemptRecord(data) {
+  return request({
+    url: '/exam/elUserExamAttempt/attemptRecord',
+    method: 'post',
+    data: data
+  })
+}
+//考试类型下所有错题列表
+export function examElExamAttemptAnswerExamAnswer(data) {
+  return request({
+    url: '/exam/elExamAttemptAnswer/examAnswer',
+    method: 'post',
+    data: data
+  })
+}
+//单一考试下错题列表
+export function examElExamAttemptAnswerAttemptAnswer(data) {
+  return request({
+    url: '/exam/elExamAttemptAnswer/attemptAnswer',
+    method: 'post',
+    data: data
+  })
+}
+//我的证书列表
+export function examUserCertificateList(data) {
+  return request({
+    url: '/exam/user/certificate/list',
+    method: 'post',
+    data: data
+  })
+}
 
 

+ 1 - 5
src/components/fullScreenFileLook/fullScreenFileLook.vue

@@ -47,8 +47,7 @@
             v-if="officeType === 'pdf'&&!officeNullType"
             :src="lookUrl"
             @rendered="renderedHandler"
-            @error="errorHandler"
-          />
+            @error="errorHandler"/>
           <p v-if="officeNullType" class="office-null-text">加载失败...</p>
           <video v-if="officeType === 'video'" class="video-box" :src="lookUrl" controls></video>
           <div  v-if="officeType === 'text'" class="rich-text-box" v-html="lookUrl"></div>
@@ -97,9 +96,6 @@
     methods: {
       //初始化
       initialize(name,url,type){
-        console.log('name',name)
-        console.log('url',url)
-        console.log('type',type)
         if(name&&url&&type){
           this.$set(this,'officeType',type);
           this.$set(this,'lookName',name);

+ 26 - 1
src/router/index.js

@@ -52,7 +52,32 @@ export const constantRoutes = [
         name: '403',
       },
     ]
-  }
+  },
+  {
+    path: '/learningCourse',//学习课程
+    component: (resolve) => require(['@/views/safetyEducationExaminationNew/featurePage/learningCourse/index.vue'], resolve),
+    hidden: true
+  },
+  {
+    path: '/learningMaterials',//学习课件
+    component: (resolve) => require(['@/views/safetyEducationExaminationNew/featurePage/learningMaterials/index.vue'], resolve),
+    hidden: true
+  },
+  {
+    path: '/startTheExam',//开始考试
+    component: (resolve) => require(['@/views/safetyEducationExaminationNew/featurePage/startTheExam/index.vue'], resolve),
+    hidden: true
+  },
+  {
+    path: '/mockExam',//模拟考试
+    component: (resolve) => require(['@/views/safetyEducationExaminationNew/featurePage/mockExam/index.vue'], resolve),
+    hidden: true
+  },
+  {
+    path: '/startPracticing',//开始练习
+    component: (resolve) => require(['@/views/safetyEducationExaminationNew/featurePage/startPracticing/index.vue'], resolve),
+    hidden: true
+  },
 ]
 
 export default new Router({

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

@@ -26,7 +26,7 @@
           <!-- 答案行 -->
           <div class="answer-row">
             <el-tag type="" class="tag-answer">答 案</el-tag>
-            <span class="answer-text">{{ questionData.answer.join('、') }}</span>
+            <span class="answer-text">{{ questionData.answer?questionData.answer.join('、'):'' }}</span>
           </div>
 
           <!-- 答案解析 -->

+ 36 - 31
src/views/safetyEducationExaminationNew/components/examRecords.vue

@@ -11,9 +11,9 @@
                  :inline="true" style="width:100%;">
           <div class="table-top-button-box">
             <div>
-              <p :class="shareStatus === ''?'check-table-button':''" @click="tableTypeButton('')">全部</p>
-              <p :class="shareStatus === 1?'check-table-button':''" @click="tableTypeButton(1)">通过</p>
-              <p :class="shareStatus === 2?'check-table-button':''" @click="tableTypeButton(2)">未通过</p>
+              <p :class="passStatus === ''?'check-table-button':''" @click="tableTypeButton('')">全部</p>
+              <p :class="passStatus === 1?'check-table-button':''" @click="tableTypeButton(1)">通过</p>
+              <p :class="passStatus === 0?'check-table-button':''" @click="tableTypeButton(0)">未通过</p>
             </div>
           </div>
           <el-form-item label="" prop="state">
@@ -35,18 +35,18 @@
       </div>
       <div class="page-content-box">
         <el-table class="table-box"  border :data="dataList">
-          <el-table-column label="考试时间" prop="createTime"  show-overflow-tooltip>
+          <el-table-column label="考试时间" prop="startTime"  show-overflow-tooltip>
             <template slot-scope="scope">
-              <span>{{ parseTime(scope.row.createTime,"{y}-{m}-{d} {h}:{i}") }}至{{ parseTime(scope.row.createTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+              <span>{{ parseTime(scope.row.startTime,"{y}-{m}-{d} {h}:{i}") }}</span>
             </template>
           </el-table-column>
-          <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="examDuration" width="200" show-overflow-tooltip/>
+          <el-table-column label="得分" prop="totalScore" width="200" show-overflow-tooltip/>
+          <el-table-column label="及格分" prop="passScore" width="200" show-overflow-tooltip/>
+          <el-table-column label="考试结果" prop="passStatus" width="200" show-overflow-tooltip>
             <template slot-scope="scope">
-              <span :class="scope.row.content?'colorA':(scope.row.content?'colorB':(scope.row.content?'colorC':''))">
-                {{scope.row.content?'通过':(scope.row.content?'未通过':(scope.row.content?'成绩无效':''))}}
+              <span :class="scope.row.passStatus == 1?'colorA':(scope.row.passStatus == 0?'colorB':(scope.row.passStatus ==2?'colorC':''))">
+                {{scope.row.passStatus == 1?'通过':(scope.row.passStatus == 0?'未通过':(scope.row.passStatus ==2?'成绩无效':''))}}
               </span>
             </template>
           </el-table-column>
@@ -74,7 +74,7 @@
         />
       </div>
     </div>
-    <historyOfIncorrectQuestions :propsData="propsData" v-if="pageType === 2"></historyOfIncorrectQuestions>
+    <historyOfIncorrectQuestions :historyOfIncorrectQuestionsPropsData="historyOfIncorrectQuestionsPropsData" v-if="pageType === 2"></historyOfIncorrectQuestions>
     <el-drawer
       size="100%"
       custom-class="examRecords-addPage-drawer"
@@ -82,9 +82,8 @@
       :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>
@@ -94,6 +93,7 @@
   //import { systemUserSelect } from "@/api/commonality/permission";
   import historyOfIncorrectQuestions from "@/views/safetyEducationExaminationNew/components/historyOfIncorrectQuestions.vue";
   import examDetails from '@/views/safetyEducationExaminationNew/components/examDetails.vue'
+  import { examElUserExamAttemptAttemptRecord, } from "@/api/safetyEducationExaminationNew/index";
   export default {
     name: 'addPage',
     components: {
@@ -107,7 +107,7 @@
       return {
         pageType:1,
         newData: {},
-        shareStatus:'',
+        passStatus:'',
         queryParams: {
           page: 1,
           pageSize: 20,
@@ -115,37 +115,31 @@
         //时间数据
         dateRange: [],
         //列表数据
-        dataList: [{}],
+        dataList: [],
         //数据数量
         total: 0,
         //弹窗相关
         drawerTitle: '',
         drawerType: '',
-        drawer: false
+        drawer: false,
+        examDetailsPropsData:{},
+        historyOfIncorrectQuestionsPropsData:{},
       }
     },
     created() {
 
     },
     mounted() {
-      this.initialize()
+      this.getList()
     },
     methods: {
-      // 初始化
-      initialize() {
-
-      },
       // 返回按钮
       backPage() {
         this.$parent.tableButton(6)
       },
-      // 提交按钮
-      submitForm() {
-
-      },
       tableTypeButton(val){
-        if(this.shareStatus != val){
-          this.$set(this,'shareStatus',val);
+        if(this.passStatus !== val){
+          this.$set(this,'passStatus',val);
           this.handleQuery();
         }
       },
@@ -166,6 +160,8 @@
       //获取数据列表
       getList() {
         let obj = JSON.parse(JSON.stringify(this.queryParams))
+        obj.examId = this.propsData.examId
+        obj.passStatus = this.passStatus
         if (this.dateRange[0]) {
           obj.startTime = this.dateRange[0] + 'T00:00:00'
           obj.endTime = this.dateRange[1] + 'T23:59:59'
@@ -173,7 +169,7 @@
           obj.startTime = ''
           obj.endTime = ''
         }
-        getListFunction(obj).then(response => {
+        examElUserExamAttemptAttemptRecord(obj).then(response => {
           this.$set(this, 'dataList', response.data.records)
           this.$set(this, 'total', response.data.total)
         })
@@ -186,10 +182,19 @@
           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
         } else if (type == 2) {
           // 历史错题
           this.$set(this, 'pageType', 2)
-          this.$set(this, 'propsData', {})
+          let obj = {
+            type:2,
+            attemptId:row.attemptId,
+          };
+          this.$set(this, 'historyOfIncorrectQuestionsPropsData', obj)
         } else if (type == 6) {
           //返回并刷新
           this.$set(this, 'pageType', 1)

+ 68 - 36
src/views/safetyEducationExaminationNew/components/historyOfIncorrectQuestions.vue

@@ -8,9 +8,9 @@
     <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-form-item label="" prop="knowledgePointId">
           <el-cascader
-            v-model="queryParams.queryParamsData1"
+            v-model="queryParams.knowledgePointId"
             :options="optionListA"
             :props="{
                 emitPath:false,
@@ -25,8 +25,8 @@
             placeholder="知识点"
           ></el-cascader>
         </el-form-item>
-        <el-form-item label="" prop="queryParamsData2">
-          <el-select v-model="queryParams.queryParamsData2" placeholder="题型" style="width: 200px">
+        <el-form-item label="" prop="questionType">
+          <el-select v-model="queryParams.questionType" placeholder="题型" style="width: 200px">
             <el-option
               v-for="dict in optionListB"
               :key="dict.value"
@@ -35,8 +35,8 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="" prop="queryParamsData3">
-          <el-select v-model="queryParams.queryParamsData3" placeholder="难度" style="width: 200px">
+        <el-form-item label="" prop="difficulty">
+          <el-select v-model="queryParams.difficulty" placeholder="难度" style="width: 200px">
             <el-option
               v-for="dict in optionListC"
               :key="dict.value"
@@ -45,10 +45,10 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="" prop="queryParamsData4">
+        <el-form-item label="" prop="searchValue">
           <el-input
             maxLength="30"
-            v-model="queryParams.queryParamsData4"
+            v-model="queryParams.searchValue"
             placeholder="搜索名称"
             style="width: 200px"
           />
@@ -63,11 +63,23 @@
     </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="questionContent"  show-overflow-tooltip/>
+          <!--<template slot-scope="scope">-->
+            <!--<span style="color:#0183fa;cursor: pointer;" @click="tableButton(2,scope.row)">{{ cleanRichText(scope.row.questionContent) }}</span>-->
+          <!--</template>-->
+        <!--</el-table-column>-->
+        <el-table-column label="题型" prop="content" width="200" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ scope.row.questionType == 1?'单选题':(scope.row.questionType == 2?'多选题':(scope.row.questionType == 3?'判断题':'')) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="难度" prop="content" width="200" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ scope.row.difficulty == 1?'简单':(scope.row.difficulty == 2?'一般':(scope.row.difficulty == 3?'较难':(scope.row.difficulty == 4?'极难':''))) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="做对次数" prop="correctCount" width="200" show-overflow-tooltip/>
+        <el-table-column label="做错次数" prop="errorCount" width="200" show-overflow-tooltip/>
         <el-table-column label="操作" width="200" show-overflow-tooltip>
           <template slot-scope="scope">
             <div class="table-button-box">
@@ -96,7 +108,7 @@
       ref="drawer"
       :visible.sync="drawer"
       direction="rtl">
-      <answerKey v-if="drawer"></answerKey>
+      <answerKey v-if="drawer" :answerKeyPropsData="answerKeyPropsData"></answerKey>
     </el-drawer>
   </div>
 </template>
@@ -106,13 +118,14 @@
   //import { systemUserSelect } from "@/api/commonality/permission";
   import { examElKnowledgePointTreeList, } from "@/api/safetyEducationExaminationNew/index";
   import answerKey from "@/views/safetyEducationExaminationNew/components/answerKey.vue";
+  import { examElExamAttemptAnswerExamAnswer,examElExamAttemptAnswerAttemptAnswer } from "@/api/safetyEducationExaminationNew/index";
   export default {
     name: 'addPage',
     components: {
       answerKey,
     },
     props: {
-      propsData: {}
+      historyOfIncorrectQuestionsPropsData: {}
     },
     data() {
       return {
@@ -123,33 +136,30 @@
         queryParams: {
           page: 1,
           pageSize: 20,
-          queryParamsData1: null,
-          queryParamsData2: null,
-          queryParamsData3: null,
-          queryParamsData4: '',
+          knowledgePointId: null,
+          questionType: null,
+          difficulty: null,
+          searchValue: '',
         },
         //列表数据
-        dataList:[{}],
+        dataList:[],
         //数据数量
         total:0,
         //弹窗相关
         drawerTitle: '',
         drawerType: '',
         drawer: false,
+        answerKeyPropsData:{},
       }
     },
     created() {
 
     },
     mounted() {
-      this.initialize()
+      this.getList();
       this.examElKnowledgePointTreeList();
     },
     methods: {
-      // 初始化
-      initialize() {
-
-      },
       // 返回按钮
       backPage() {
         this.$parent.tableButton(6)
@@ -158,7 +168,7 @@
       submitButton() {
 
       },
-      tableButton(type){
+      tableButton(type,row){
         if(type == '1'){
           //开始训练
         }else if(type == 2){
@@ -166,6 +176,9 @@
           this.$set(this, 'drawerTitle', '查看试题答案')
           this.$set(this, 'drawerType', 1)
           this.$set(this, 'drawer', true)
+          this.$set(this,'answerKeyPropsData',{
+            id:row.sourceQuestionId,
+          });
         }
       },
       //弹窗返回
@@ -182,22 +195,29 @@
         this.$set(this,'queryParams',{
           page:1,
           pageSize:20,
-          queryParamsData1: null,
-          queryParamsData2: null,
-          queryParamsData3: null,
-          queryParamsData4: '',
+          knowledgePointId: null,
+          questionType: null,
+          difficulty: null,
+          searchValue: '',
         });
         this.getList();
       },
       //获取数据列表
       getList(){
-
         let obj = JSON.parse(JSON.stringify(this.queryParams))
-        getListFunction(obj).then(response => {
-
-          this.$set(this,'dataList',response.data.records);
-          this.$set(this,'total',response.data.total);
-        });
+        if(this.historyOfIncorrectQuestionsPropsData.type == 1){
+          obj.examId = this.historyOfIncorrectQuestionsPropsData.examId;
+          examElExamAttemptAnswerExamAnswer(obj).then(response => {
+            this.$set(this,'dataList',response.data.records);
+            this.$set(this,'total',response.data.total);
+          });
+        }else if(this.historyOfIncorrectQuestionsPropsData.type == 2){
+          obj.attemptId = this.historyOfIncorrectQuestionsPropsData.attemptId;
+          examElExamAttemptAnswerAttemptAnswer(obj).then(response => {
+            this.$set(this,'dataList',response.data.records);
+            this.$set(this,'total',response.data.total);
+          });
+        }
       },
       examElKnowledgePointTreeList(){
         examElKnowledgePointTreeList({}).then(response => {
@@ -206,6 +226,18 @@
           this.$set(this, 'optionListA', list);
         });
       },
+      //清洗富文本
+      cleanRichText(htmlStr, maxLength = 50) {
+        if (!htmlStr) return '';
+        const tempDiv = document.createElement('div');
+        tempDiv.innerHTML = htmlStr;
+        let text = tempDiv.textContent || tempDiv.innerText || '';
+        text = text.replace(/\s+/g, ' ').trim();
+        if (maxLength && text.length > maxLength) {
+          return text.substring(0, maxLength) + '...';
+        }
+        return text;
+      },
     }
   }
 </script>

+ 57 - 0
src/views/safetyEducationExaminationNew/featurePage/learningCourse/index.vue

@@ -0,0 +1,57 @@
+<!-- 学习课程 -->
+<template>
+  <div class="learningCourse">
+    <div class="page-container-top-max-big-box">
+      <p class="top-1-p">开始学习</p>
+      <p class="top-2-p" @click="backPage()">返回</p>
+    </div>
+    <div class="content-box scrollbar-box">
+
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'index',
+    data() {
+      return {
+
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      /*
+      this.$router.push({
+        name: 'Detail',
+        params: {
+          id: 1,
+          title: '消息标题'
+        }
+      })
+      this.$route.params.title
+      */
+      //返回
+      backPage() {
+        this.$router.back()
+      },
+    }
+  }
+</script>
+<style scoped lang="scss">
+  .learningCourse {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    background:#FFFFFF;
+    border-radius:10px;
+    overflow: hidden;
+    padding:0;
+    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+    margin:10px;
+  }
+</style>

+ 47 - 0
src/views/safetyEducationExaminationNew/featurePage/learningMaterials/index.vue

@@ -0,0 +1,47 @@
+<!-- 学习课件 -->
+<template>
+  <div class="learningMaterials">
+    <div class="page-container-top-max-big-box">
+      <p class="top-1-p">开始学习</p>
+      <p class="top-2-p" @click="backPage()">返回</p>
+    </div>
+    <div class="content-box scrollbar-box">
+
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'index',
+    data() {
+      return {
+
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      //返回
+      backPage() {
+        this.$router.back()
+      },
+    }
+  }
+</script>
+<style scoped lang="scss">
+  .learningMaterials {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    background:#FFFFFF;
+    border-radius:10px;
+    overflow: hidden;
+    padding:0;
+    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+    margin:10px;
+  }
+</style>

+ 47 - 0
src/views/safetyEducationExaminationNew/featurePage/mockExam/index.vue

@@ -0,0 +1,47 @@
+<!-- 模拟考试 -->
+<template>
+  <div class="mockExam">
+    <div class="page-container-top-max-big-box">
+      <p class="top-1-p">模拟考试</p>
+      <p class="top-2-p" @click="backPage()">返回</p>
+    </div>
+    <div class="content-box scrollbar-box">
+
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'index',
+    data() {
+      return {
+
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      //返回
+      backPage() {
+        this.$router.back()
+      },
+    }
+  }
+</script>
+<style scoped lang="scss">
+  .mockExam {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    background:#FFFFFF;
+    border-radius:10px;
+    overflow: hidden;
+    padding:0;
+    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+    margin:10px;
+  }
+</style>

+ 47 - 0
src/views/safetyEducationExaminationNew/featurePage/startPracticing/index.vue

@@ -0,0 +1,47 @@
+<!-- 开始练习 -->
+<template>
+  <div class="app-container startPracticing">
+    <div class="page-container-top-max-big-box">
+      <p class="top-1-p">开始练习</p>
+      <p class="top-2-p" @click="backPage()">返回</p>
+    </div>
+    <div class="content-box scrollbar-box">
+
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'index',
+    data() {
+      return {
+
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      //返回
+      backPage() {
+        this.$router.back()
+      },
+    }
+  }
+</script>
+<style scoped lang="scss">
+  .startPracticing {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    background:#FFFFFF;
+    border-radius:10px;
+    overflow: hidden;
+    padding:0;
+    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+    margin:10px;
+  }
+</style>

+ 47 - 0
src/views/safetyEducationExaminationNew/featurePage/startTheExam/index.vue

@@ -0,0 +1,47 @@
+<!-- 开始考试 -->
+<template>
+  <div class="app-container startTheExam">
+    <div class="page-container-top-max-big-box">
+      <p class="top-1-p">开始考试</p>
+      <p class="top-2-p" @click="backPage()">返回</p>
+    </div>
+    <div class="content-box scrollbar-box">
+
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'index',
+    data() {
+      return {
+
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      //返回
+      backPage() {
+        this.$router.back()
+      },
+    }
+  }
+</script>
+<style scoped lang="scss">
+  .startTheExam {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    background:#FFFFFF;
+    border-radius:10px;
+    overflow: hidden;
+    padding:0;
+    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+    margin:10px;
+  }
+</style>

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

@@ -252,7 +252,6 @@
           this.$set(this, 'drawer', true)
           this.$set(this,'answerKeyPropsData',{
             id:row.id,
-            answer:false,
           });
         }else if(type == 3){
           //编辑

+ 134 - 0
src/views/safetyEducationExaminationNew/safetyTest/myCertificates/index.vue

@@ -0,0 +1,134 @@
+<!-- 我的证书 -->
+<template>
+  <div class="app-container myCertificates">
+    <div class="page-container myCertificatesPage" v-if="pageType === 1">
+      <p class="pageTitle">我的证书</p>
+      <div class="page-content-box">
+        <el-table class="table-box" border :data="dataList">
+          <el-table-column label="证书名称" prop="certificateName" show-overflow-tooltip/>
+          <el-table-column label="证书编号" prop="certificateNo" width="200" show-overflow-tooltip/>
+          <el-table-column label="获得方式" prop="obtainWay" width="200" show-overflow-tooltip/>
+          <el-table-column label="颁发单位" prop="issueDeptName" width="200" show-overflow-tooltip/>
+          <el-table-column label="获得时间" prop="issueTime" width="200" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.issueTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="到期时间" prop="expireTime" width="200" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.expireTime,"{y}-{m}-{d} {h}:{i}") }}</span>
+            </template>
+          </el-table-column>
+          <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(1,scope.row)"
+                >查看下载</p>
+                <p class="table-button-null"></p>
+              </div>
+            </template>
+          </el-table-column>
+        </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>
+    <fullScreenFileLook ref="fullScreenFileLook"></fullScreenFileLook>
+    <!--<add-page :propsData="propsData" v-if="pageType === 2"></add-page>-->
+  </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 { examUserCertificateList, } from "@/api/safetyEducationExaminationNew/index";
+  import fullScreenFileLook from "@/components/fullScreenFileLook/fullScreenFileLook.vue";
+  export default {
+    name: 'index',
+    components: {
+      fullScreenFileLook,
+    },
+    data() {
+      return {
+        tableButtonType: this.hasPermiDom(['demo:demo:detail', 'demo:demo:edit', 'demo:demo:del']),
+        //页面状态
+        pageType: 1,
+        //查询条件
+        queryParams: {
+          page: 1,
+          pageSize: 20,
+        },
+        //时间数据
+        dateRange: [],
+        //列表数据
+        dataList: [],
+        //数据数量
+        total: 0,
+        //组件传参
+        propsData: {}
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+      this.getList();
+    },
+    methods: {
+      //查询按钮
+      handleQuery() {
+        this.$set(this.queryParams, 'page', 1)
+        this.getList()
+      },
+      //重置按钮
+      resetQuery() {
+        this.$set(this, 'dateRange', [])
+        this.$set(this, 'queryParams', {
+          page: 1,
+          pageSize: 20,
+        })
+        this.getList()
+      },
+      //获取数据列表
+      getList() {
+        let obj = JSON.parse(JSON.stringify(this.queryParams))
+        examUserCertificateList(obj).then(response => {
+          this.$set(this, 'dataList', response.data.records)
+          this.$set(this, 'total', response.data.total)
+        })
+      },
+      //操作按钮
+      tableButton(type, row) {
+        let self = this
+        if (type == 1) {
+          //查看下载
+          this.$refs['fullScreenFileLook'].initialize(row.certificateName,row.certificatePath,'docx');
+        } else if (type == 6) {
+          //返回并刷新
+          this.$set(this, 'pageType', 1)
+          this.getList()
+        }
+      },
+    }
+  }
+</script>
+<style scoped lang="scss">
+  .myCertificates {
+    .myCertificatesPage {
+      .pageTitle{
+        height:60px;
+        line-height:60px;
+        padding:0 20px;
+        border-bottom:1px solid #dedede;
+      }
+    }
+  }
+</style>

+ 14 - 9
src/views/safetyEducationExaminationNew/safetyTest/myGrades/index.vue

@@ -14,8 +14,8 @@
           <div class="table-top-button-box">
             <div>
               <p :class="resultStatus === ''?'check-table-button':''" @click="tableTypeButton('')">全部</p>
-              <p :class="resultStatus === 1?'check-table-button':''" @click="tableTypeButton(1)">通过</p>
-              <p :class="resultStatus === 2?'check-table-button':''" @click="tableTypeButton(2)">未通过</p>
+              <p :class="resultStatus === 2?'check-table-button':''" @click="tableTypeButton(2)">通过</p>
+              <p :class="resultStatus === 3?'check-table-button':''" @click="tableTypeButton(3)">未通过</p>
             </div>
           </div>
           <el-form-item label="" prop="state">
@@ -48,8 +48,8 @@
               <p>获得积分:{{item.myScore}}</p>
               <p>考试结果:<span :class="item.resultStatus==2?'colorA':(item.resultStatus==3?'colorB':'')">{{item.resultStatus==1?'考试中':(item.resultStatus==2?'通过':(item.resultStatus==3?'未通过':(item.resultStatus==4?'缺考':'')))}}</span></p>
             </div>
-            <p class="position-p-1" v-if="item.resultStatus==2||item.resultStatus==3" @click="tableButton(1)">考试记录</p>
-            <p class="position-p-2" v-if="item.resultStatus==2" @click="tableButton(2)">历史错题</p>
+            <p class="position-p-1" v-if="item.resultStatus==2||item.resultStatus==3" @click="tableButton(1,item)">考试记录</p>
+            <p class="position-p-2" @click="tableButton(2,item)">历史错题</p>
           </div>
         </div>
         <pagination :page-sizes="[20, 30, 40, 50]"
@@ -63,7 +63,7 @@
       </div>
     </div>
     <examRecords :propsData="propsData" v-if="pageType === 2"></examRecords>
-    <historyOfIncorrectQuestions :propsData="propsData" v-if="pageType === 3"></historyOfIncorrectQuestions>
+    <historyOfIncorrectQuestions :historyOfIncorrectQuestionsPropsData="historyOfIncorrectQuestionsPropsData" v-if="pageType === 3"></historyOfIncorrectQuestions>
   </div>
 </template>
 <script>
@@ -131,7 +131,8 @@
         //数据数量
         total: 0,
         //组件传参
-        propsData: {}
+        propsData: {},
+        historyOfIncorrectQuestionsPropsData:{},
       }
     },
     created() {
@@ -191,11 +192,15 @@
         if (type == 1) {
           //考试记录
           this.$set(this, 'pageType', 2)
-          this.$set(this, 'propsData', {})
+          this.$set(this, 'propsData', row)
         } else if (type == 2) {
           //历史错题
           this.$set(this, 'pageType', 3)
-          this.$set(this, 'propsData', {})
+          let obj = {
+            type:1,
+            examId:row.examId,
+          };
+          this.$set(this, 'historyOfIncorrectQuestionsPropsData', obj)
         } else if (type == 6) {
           //返回并刷新
           this.$set(this, 'pageType', 1)
@@ -204,7 +209,7 @@
       },
       examUserExamTypeSelectExamType(){
         let self = this;
-        examUserExamTypeSelectExamType({examType:1}).then(response => {
+        examUserExamTypeSelectExamType({examType:3}).then(response => {
           let num = 0;
           for(let i=0;i<response.data.length;i++){
             num = self.accAdd(num,response.data[i].examTypeCount);

+ 386 - 185
src/views/safetyEducationExaminationNew/workbench/ResourceCard.vue

@@ -2,83 +2,70 @@
 <template>
   <div class="resource-card">
     <div class="card-title">实验室安全素养资源卡</div>
-
     <!-- 分类 Tab 横向滚动 -->
     <div class="tab-scroll-wrap">
       <div class="tab-bar">
-        <el-button
-          v-for="tab in resourceData.tabs"
-          :key="tab"
-          :type="resourceData.activeTab === tab ? 'primary' : 'default'"
-          size="mini"
-          round
-          @click="resourceData.activeTab = tab"
-        >{{ tab }}</el-button>
+        <p v-for="(item,index) in topList" :key="index"
+           :class="item.value == topIndex?'check-p':''"
+          @click="topButton(item.value)">{{ item.table }}</p>
       </div>
     </div>
 
     <div class="resource-body">
-      <!-- 左侧:知识学习 + 刷题练习 -->
-      <div class="left-panel">
-
-        <!-- 知识学习 -->
-        <div class="sub-block">
-          <div class="sub-header">
-            <span class="sub-title">知识学习</span>
-            <a class="more-link">查看更多</a>
+      <div class="left-max-big-box">
+        <!--知识学习-->
+        <div class="left-top-big-box">
+          <div class="big-title-box">
+            <p>知识学习</p>
+            <p>查看更多</p>
           </div>
-          <div v-for="item in resourceData.knowledgeList" :key="item.name + item.year" class="file-item">
-            <div class="file-icon-wrap">
-              <i class="el-icon-document file-icon"></i>
+          <div class="big-content-box scrollbar-box">
+            <p class="null-p" v-if="!leftTopList[0]">暂无数据</p>
+            <div class="for-big-box" v-for="(item,index) in leftTopList" :key="index">
+              <p>{{item.leftTopData1}}</p>
+              <p>{{item.leftTopData2}}分钟丨{{item.leftTopData3}}学时丨{{item.leftTopData4}}积分</p>
+              <p :class="item.leftTopData5==1?'colorA':''">{{item.leftTopData5==1?'学习中':'未学习'}}</p>
             </div>
-            <div class="file-info">
-              <div class="file-name">{{ item.name }}</div>
-              <div class="file-meta">{{ item.year }}|{{ item.term }}|{{ item.credit }}学分</div>
-            </div>
-            <el-button size="mini" type="primary" plain>学习</el-button>
           </div>
         </div>
-
-        <!-- 刷题练习 -->
-        <div class="sub-block">
-          <div class="sub-header">
-            <span class="sub-title">刷题练习</span>
-            <a class="more-link">查看更多</a>
+        <!--刷题练习-->
+        <div class="left-bottom-big-box">
+          <div class="big-title-box">
+            <p>刷题练习</p>
+            <p>查看更多</p>
           </div>
-          <div class="practice-item">
-            <div class="practice-top">
-              <a class="practice-date link">2026-09-01 9:30:33</a>
-              <div class="practice-more"><i class="el-icon-more"></i></div>
+          <div class="big-content-box scrollbar-box">
+            <p class="null-p" v-if="!leftBottomList[0]">暂无数据</p>
+            <div class="for-big-box" v-for="(item,index) in leftBottomList" :key="index">
+              <div class="for-flex-box">
+                <p class="el-icon-time"></p>
+                <p>{{item.leftBottomData1}}</p>
+              </div>
+              <p class="text-p">练习进度:{{item.leftBottomData2}}/{{item.leftBottomData3}}</p>
+              <p class="text-p">正确数:{{item.leftBottomData4}}丨错题数:{{item.leftBottomData5}}丨正确率:{{item.leftBottomData6}}%</p>
+              <el-progress
+                class="num-p" type="circle"
+                :stroke-width="4"
+                :width="60" :percentage="item.leftBottomData6">
+              </el-progress>
             </div>
-            <div class="practice-stats">
-              <span>练习题:<b>32/369</b></span>
-            </div>
-            <div class="practice-rates">
-              <span>答对率:<b>50%</b></span>
-              <span>正确数:<b>72%</b></span>
-              <span>错误数:<b>96%</b></span>
-            </div>
-            <div class="practice-time">2026-09-01 11:03:25</div>
           </div>
         </div>
-
       </div>
-
-      <!-- 右侧:视频课程学习 -->
-      <div class="right-panel">
-        <div class="sub-header">
-          <span class="sub-title">视频课程学习</span>
-          <a class="more-link">查看更多</a>
+      <!--视频资源学习-->
+      <div class="right-max-big-box">
+        <div class="big-title-box">
+          <p>视频资源学习</p>
+          <p>查看更多</p>
         </div>
-        <div class="video-grid">
-          <div v-for="item in resourceData.videoList" :key="item.name + item.idx" class="video-item">
-            <div class="video-thumb">
-              <div class="thumb-inner">视频缩略图</div>
-            </div>
-            <div class="video-footer">
-              <div class="video-name">{{ item.name }}</div>
-              <div class="video-meta">{{ item.year }}|{{ item.term }}|{{ item.credit }}学分</div>
-              <el-button size="mini" type="primary" plain>学习</el-button>
+        <div class="big-content-box-1 scrollbar-box">
+          <p class="null-p" v-if="!rightList[0]">暂无数据</p>
+          <div class="for-big-box" v-for="(item,index) in rightList" :key="index">
+            <img :src="item.rightData1">
+            <div class="text-box">
+              <p>{{item.rightData2}}</p>
+              <p>{{item.rightData3}}分钟丨{{item.rightData4}}学时丨{{item.rightData5}}积分</p>
+              <p :class="item.rightData6==1?'colorA':''">{{item.rightData6==1?'学习中':'未学习'}}</p>
             </div>
           </div>
         </div>
@@ -92,27 +79,138 @@ export default {
   name: 'ResourceCard',
   data() {
     return {
-      resourceData: {
-        activeTab: '总览',
-        tabs: ['总览', '生物类', '辐射类', '化学', '总览', '科目', '生物类', '辐射类', '化学', '科目'],
-        knowledgeList: [
-          { name: '课件资料名称.PDF', year: '2026年', term: '1学年', credit: '1' },
-          { name: '课件资料名称.PDF', year: '2026年', term: '1学年', credit: '1' },
-          { name: '课件资料名称.PDF', year: '2026年', term: '1学年', credit: '1' },
-          { name: '课件资料名称.PDF', year: '2026年', term: '1学年', credit: '1' },
-          { name: '课件资料名称.PDF', year: '2026年', term: '1学年', credit: '1' },
-        ],
-        videoList: [
-          { idx: 1, name: '视频课程名称', year: '2026年', term: '1学年', credit: '1' },
-          { idx: 2, name: '视频课程名称', year: '2026年', term: '1学年', credit: '1' },
-          { idx: 3, name: '视频课程名称', year: '2026年', term: '1学年', credit: '1' },
-          { idx: 4, name: '视频课程名称', year: '2026年', term: '1学年', credit: '1' },
-          { idx: 5, name: '视频课程名称', year: '2026年', term: '1学年', credit: '1' },
-          { idx: 6, name: '视频课程名称', year: '2026年', term: '1学年', credit: '1' },
-        ]
-      }
+      topList:[{value:'',table:'总览'},{value:'1',table:'生物类'},{value:'2',table:'辐射类'},{value:'3',table:'化学'}],
+      topIndex:'',
+      leftTopList:[
+        {
+          leftTopData1:'课件名称',
+          leftTopData2:'20',
+          leftTopData3:'1',
+          leftTopData4:'3',
+          leftTopData5:'1',
+        },
+        {
+          leftTopData1:'课件名称',
+          leftTopData2:'20',
+          leftTopData3:'1',
+          leftTopData4:'3',
+          leftTopData5:'2',
+        },
+        {
+          leftTopData1:'课件名称',
+          leftTopData2:'20',
+          leftTopData3:'1',
+          leftTopData4:'3',
+          leftTopData5:'1',
+        },
+        {
+          leftTopData1:'课件名称',
+          leftTopData2:'20',
+          leftTopData3:'1',
+          leftTopData4:'3',
+          leftTopData5:'1',
+        },
+      ],
+      leftBottomList:[
+        {
+          leftBottomData1:'2026-09-01 9:30:33',
+          leftBottomData2:'33',
+          leftBottomData3:'369',
+          leftBottomData4:'3',
+          leftBottomData5:'3',
+          leftBottomData6:'96',
+          leftBottomData7:'33',
+        },
+        {
+          leftBottomData1:'2026-09-01 9:30:33',
+          leftBottomData2:'33',
+          leftBottomData3:'369',
+          leftBottomData4:'3',
+          leftBottomData5:'3',
+          leftBottomData6:'96',
+          leftBottomData7:'33',
+        },
+        {
+          leftBottomData1:'2026-09-01 9:30:33',
+          leftBottomData2:'33',
+          leftBottomData3:'369',
+          leftBottomData4:'3',
+          leftBottomData5:'3',
+          leftBottomData6:'96',
+          leftBottomData7:'33',
+        },
+      ],
+      rightList:[
+        {
+          rightData1:'',
+          rightData2:'视频课件名称',
+          rightData3:'20',
+          rightData4:'1',
+          rightData5:'3',
+          rightData6:'1',
+        },
+        {
+          rightData1:'',
+          rightData2:'视频课件名称',
+          rightData3:'20',
+          rightData4:'1',
+          rightData5:'3',
+          rightData6:'2',
+        },
+        {
+          rightData1:'',
+          rightData2:'视频课件名称',
+          rightData3:'20',
+          rightData4:'1',
+          rightData5:'3',
+          rightData6:'1',
+        },
+        {
+          rightData1:'',
+          rightData2:'视频课件名称',
+          rightData3:'20',
+          rightData4:'1',
+          rightData5:'3',
+          rightData6:'1',
+        },
+        {
+          rightData1:'',
+          rightData2:'视频课件名称',
+          rightData3:'20',
+          rightData4:'1',
+          rightData5:'3',
+          rightData6:'2',
+        },
+        {
+          rightData1:'',
+          rightData2:'视频课件名称',
+          rightData3:'20',
+          rightData4:'1',
+          rightData5:'3',
+          rightData6:'1',
+        },
+      ],
     }
-  }
+  },
+  methods:{
+    topButton(val){
+      if(this.topIndex != val){
+        this.$set(this,'topIndex',val);
+        this.leftTopGetData();
+        this.leftBottomGetData();
+        this.rightGetData();
+      }
+    },
+    leftTopGetData(){
+
+    },
+    leftBottomGetData(){
+
+    },
+    rightGetData(){
+
+    },
+  },
 }
 </script>
 
@@ -120,21 +218,21 @@ export default {
 .resource-card {
   background: #fff;
   border-radius: 6px;
-  padding: 16px 20px;
   margin-bottom: 12px;
   box-shadow: 0 1px 4px rgba(0,0,0,0.06);
 
   .card-title {
-    font-size: 14px;
-    font-weight: 600;
+    font-size: 16px;
+    font-weight: 700;
+    line-height:20px;
     color: #333;
-    margin-bottom: 12px;
+    margin:20px 0 20px 20px;
   }
 
   .tab-scroll-wrap {
     overflow-x: auto;
-    margin-bottom: 16px;
     padding-bottom: 4px;
+    margin:20px 0 0 20px;
 
     &::-webkit-scrollbar { height: 4px; }
     &::-webkit-scrollbar-thumb { background: #ddd; border-radius: 2px; }
@@ -144,117 +242,220 @@ export default {
       gap: 6px;
       white-space: nowrap;
       width: max-content;
+      p{
+        height:40px;
+        line-height:40px;
+        border-radius:6px;
+        border:1px solid #666;
+        color:#666;
+        padding:0 20px;
+        min-width: 100px;
+        text-align: center;
+        cursor: pointer;
+      }
+      .check-p{
+        color:#fff;
+        background-color: #0183fa;
+        border: 1px solid #0183fa;
+      }
     }
   }
 
   .resource-body {
+    height:800px;
     display: flex;
-    gap: 20px;
-    align-items: flex-start;
-
-    .left-panel { flex: 0 0 45%; }
-    .right-panel { flex: 1; }
-  }
-
-  .sub-block { margin-bottom: 20px; }
-
-  .sub-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 10px;
-
-    .sub-title { font-size: 14px; font-weight: 600; color: #333; }
-    .more-link { font-size: 12px; color: #409eff; cursor: pointer; }
-  }
-
-  .file-item {
-    display: flex;
-    align-items: center;
-    gap: 10px;
-    padding: 8px 0;
-    border-bottom: 1px solid #f5f5f5;
-
-    .file-icon-wrap {
-      width: 32px;
-      height: 32px;
-      background: #fff3e0;
-      border-radius: 4px;
+    .left-max-big-box{
+      flex:1;
       display: flex;
-      align-items: center;
-      justify-content: center;
-      flex-shrink: 0;
-      .file-icon { font-size: 18px; color: #e6a23c; }
-    }
-
-    .file-info {
-      flex: 1;
-      min-width: 0;
-      .file-name { font-size: 13px; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-      .file-meta { font-size: 12px; color: #999; margin-top: 2px; }
+      flex-direction: column;
+      overflow: hidden;
+      padding:20px 0 20px 20px;
+      .left-top-big-box{
+        height:400px;
+        display: flex;
+        flex-direction: column;
+        overflow: hidden;
+        border-radius:10px;
+        box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
+        margin-bottom:20px;
+        margin-right:20px;
+        padding-bottom:20px;
+        .for-big-box{
+          margin:12px 14px 0 20px;
+          background-color: rgba(1, 131, 250, 0.1);
+          border-radius:6px;
+          padding:18px 20px;
+          position: relative;
+          cursor: pointer;
+          p:nth-child(1){
+            font-size:16px;
+            font-weight:700;
+            color:#0183fa;
+            line-height: 24px;
+          }
+          p:nth-child(2){
+            font-size:14px;
+            color:#333;
+            line-height: 24px;
+          }
+          p:nth-child(3){
+            position: absolute;
+            bottom:20px;
+            right:20px;
+            font-size:14px;
+            border-radius:4px;
+            line-height: 24px;
+            width: 60px;
+            text-align: center;
+            background-color: #999;
+            color:#fff;
+          }
+          .colorA{
+            background-color: #0183fa!important;
+            color:#fff!important;
+          }
+        }
+      }
+      .left-bottom-big-box{
+        height:400px;
+        display: flex;
+        flex-direction: column;
+        overflow: hidden;
+        border-radius:10px;
+        margin-right:20px;
+        box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
+        padding-bottom:20px;
+        .for-big-box{
+          margin:12px 14px 0 20px;
+          background-color: rgba(1, 131, 250, 0.1);
+          border-radius:6px;
+          padding:16px 20px;
+          position: relative;
+          .for-flex-box{
+            display: flex;
+            color:#0183fa;
+            p{
+              font-weight:700;
+            }
+            p:nth-child(1){
+              font-size:18px;
+              line-height:40px;
+              margin-right:5px;
+            }
+            p:nth-child(2){
+              font-size:14px;
+              line-height:40px;
+            }
+          }
+          .text-p{
+            line-height:30px;
+            font-size:14px;
+            color:#666;
+            font-weight:700;
+          }
+          .num-p{
+            position: absolute;
+            right:40px;
+            top:35px;
+          }
+          .num-p ::v-deep .el-progress__text {
+            margin-left:0!important;
+            font-size:12px!important;
+          }
+          .num-p ::v-deep svg path:first-child {
+            stroke: #cccccc !important; /* 修改为红色 */
+          }
+        }
+      }
     }
-  }
-
-  .practice-item {
-    border: 1px solid #eee;
-    border-radius: 6px;
-    padding: 12px;
-
-    .practice-top {
+    .right-max-big-box{
+      flex:1;
       display: flex;
-      justify-content: space-between;
-      align-items: center;
-      margin-bottom: 8px;
-      .link { color: #409eff; font-size: 13px; cursor: pointer; }
-      .practice-more { color: #ccc; cursor: pointer; font-size: 16px; }
-    }
-
-    .practice-stats {
-      font-size: 13px;
-      color: #555;
-      margin-bottom: 6px;
-      b { color: #333; }
+      flex-direction: column;
+      overflow: hidden;
+      width:740px;
+      border-radius:10px;
+      box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
+      margin:20px 20px 20px 0;
+      .big-content-box-1{
+        flex:1;
+        .for-big-box{
+          margin:12px 0 0 20px;
+          display: inline-block;
+          width:346px;
+          border-radius:6px;
+          overflow: hidden;
+          position: relative;
+          img{
+            width:346px;
+            height:180px;
+            display: block;
+            overflow: hidden;
+            margin: 0;
+            padding: 0;
+          }
+          .text-box{
+            background-color: rgba(1, 131, 250, 0.1);
+            p:nth-child(1){
+              margin:0 20px;
+              line-height:40px;
+              color:#0183fa;
+              font-size:16px;
+              font-weight:700;
+            }
+            p:nth-child(2){
+              margin:0 20px;
+              line-height:20px;
+              color:#333;
+              font-size:14px;
+              padding-bottom:10px;
+            }
+            p:nth-child(3){
+              position: absolute;
+              bottom:10px;
+              right:10px;
+              background-color: #999;
+              color:#fff;
+              font-size:14px;
+              border-radius:4px;
+              line-height: 24px;
+              width: 60px;
+              text-align: center;
+            }
+            .colorA{
+              background-color: #0183fa!important;
+              color:#fff!important;
+            }
+          }
+        }
+      }
     }
-
-    .practice-rates {
+    .big-title-box{
       display: flex;
-      gap: 16px;
-      font-size: 12px;
-      color: #666;
-      margin-bottom: 6px;
-      b { color: #409eff; }
-    }
-
-    .practice-time {
-      font-size: 12px;
-      color: #999;
-      text-align: right;
-    }
-  }
-
-  .video-grid {
-    display: grid;
-    grid-template-columns: repeat(2, 1fr);
-    gap: 12px;
-
-    .video-item {
-      border: 1px solid #eee;
-      border-radius: 6px;
-      overflow: hidden;
-
-      .video-thumb {
-        height: 72px;
-        background: #f0f2f5;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        .thumb-inner { color: #ccc; font-size: 12px; }
+      height:60px;
+      padding:0 20px;
+      p{
+        line-height:60px;
+        font-size:16px;
+        font-weight: 700;
       }
-
-      .video-footer {
-        padding: 8px 10px;
-        .video-name { font-size: 13px; color: #333; margin-bottom: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-        .video-meta { font-size: 12px; color: #999; margin-bottom: 6px; }
+      p:nth-child(1){
+        flex:1;
+      }
+      p:nth-child(2){
+        cursor: pointer;
+        color:#0183fa;
+      }
+    }
+    .big-content-box{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      .null-p{
+        text-align: center;
+        line-height:200px;
+        color:#999;
+        font-size:14px;
       }
     }
   }

+ 246 - 51
src/views/safetyEducationExaminationNew/workbench/TaskCard.vue

@@ -6,27 +6,73 @@
     </div>
     <div class="card-max-big-box">
       <div class="year-card-box for-max-big-box">
-        <div class="top-title-box">
-          <p>{{yearData.yearMinData1}}</p>
-          <p>{{yearData.yearMinData2}}</p>
-          <p>毕业报告</p>
+        <div class="year-card-top-title-box">
+          <p>学年数据统计</p>
+          <p>按学年统计历年考试通过情况与成绩</p>
+          <p v-if="yearType">毕业报告</p>
         </div>
-        <div class="bottom-content-box">
-          <div class="bottom-big-box-1">
-            <p></p>
-            <p></p>
+        <div class="bottom-content-box scrollbar-box">
+          <div class="bottom-big-box-1" v-for="(item,index) in yearMinList">
+            <p>{{item.yearMinListData1}}</p>
+            <p>{{item.yearMinListData2==1?'进行中':(item.yearMinListData2==2?'通过丨'+item.yearMinListData3:(item.yearMinListData2==3?'未通过':''))}}</p>
           </div>
         </div>
       </div>
       <div class="study-card-box for-max-big-box">
-
-
+        <div class="year-card-top-title-box">
+          <p>学习任务</p>
+          <p>待完成的学习任务</p>
+        </div>
+        <div class="bottom-content-box scrollbar-box">
+          <div class="bottom-big-box-2" v-for="(item,index) in studyMinList">
+            <p>{{item.studyMinListData1}}</p>
+            <p >{{item.studyMinListData2}}丨{{item.studyMinListData2==1?'待完成':(item.studyMinListData3==2?'进行中':(item.studyMinListData3==3?'已完成':''))}}</p>
+          </div>
+        </div>
       </div>
       <div class="examination-card-box for-max-big-box">
-
+        <div class="year-card-top-title-box">
+          <p>模拟考试</p>
+          <p>待完成的考前模拟练习</p>
+        </div>
+        <div class="bottom-content-box scrollbar-box">
+          <div class="bottom-big-box-3" v-for="(item,index) in examinationMinList">
+            <p>{{item.examinationMinListData1}}</p>
+            <p >最高成绩 {{item.examinationMinListData2}}</p>
+          </div>
+        </div>
       </div>
       <div class="for-max-big-box" v-for="(item,index) in dataList" :key="index">
-
+        <div class="year-card-top-title-box">
+          <p>{{item.minListName}}</p>
+          <p>满足前置条件后可参加考试</p>
+        </div>
+        <div class="bottom-content-box scrollbar-box">
+          <div class="bottom-big-box-4" v-if="item.minListType1 == 0">
+            <p>学时要求</p>
+            <p class="colorA">开始学习</p>
+          </div>
+          <div class="bottom-big-box-4" v-if="item.minListType2 == 0">
+            <p>考前学习</p>
+            <p class="colorA">开始学习</p>
+          </div>
+          <div class="bottom-big-box-4" v-if="item.minListType3 == 0">
+            <p>模拟考试</p>
+            <p class="colorC" v-if="item.minListType1 == 0||item.minListType2 == 0">待完成学习任务后解锁</p>
+            <p class="colorA" v-if="item.minListType1 == 1&&item.minListType2 == 1">开始考试</p>
+          </div>
+          <div class="bottom-big-box-4">
+            <p>考试状态</p>
+            <p class="colorC" v-if="item.minListType3 == 0">待通过模拟考试后解锁</p>
+            <p class="colorA" v-if="item.minListType3 == 1 && item.minListType4 == 0">开始考试</p>
+            <p class="colorB" v-if="item.minListType4 == 2">考试未通过</p>
+          </div>
+          <div class="bottom-big-box-4" v-if="item.minListType4 == 2">
+            <p>参加补考</p>
+            <p class="colorA" v-if="item.minListType5 == 0">开始考试</p>
+            <p class="colorB" v-if="item.minListType5 == 2">考试未通过</p>
+          </div>
+        </div>
       </div>
     </div>
   </div>
@@ -38,36 +84,107 @@ export default {
   data() {
     return {
       //学年数据
-      yearData:{
-        yearMinData1:'学年数据统计',
-        yearMinData2:'按学年统计历年考试通过情况与成绩',
-        yearMinList:[
-          {
-            yearMinListData1:'2025-2026',
-            yearMinListData2:'1',
-            yearMinListData3:'99',
-          },
-          {
-            yearMinListData1:'2025-2026',
-            yearMinListData2:'1',
-            yearMinListData3:'99',
-          },
-          {
-            yearMinListData1:'2025-2026',
-            yearMinListData2:'1',
-            yearMinListData3:'99',
-          },
-        ],
-      },
-      studyData:{
-
-      },
-      examinationData:{
-
-      },
+      yearType:true,
+      yearMinList:[
+        {
+          yearMinListData1:'2025-2026',
+          yearMinListData2:'1',
+          yearMinListData3:'99',
+        },
+        {
+          yearMinListData1:'2025-2026',
+          yearMinListData2:'2',
+          yearMinListData3:'99',
+        },
+        {
+          yearMinListData1:'2025-2026',
+          yearMinListData2:'3',
+          yearMinListData3:'99',
+        },
+      ],
+      studyMinList:[
+        {
+          studyMinListData1:'课程任务名称',
+          studyMinListData2:'来源单位',
+          studyMinListData3:'1',
+        },
+        {
+          studyMinListData1:'课程任务名称',
+          studyMinListData2:'来源单位',
+          studyMinListData3:'2',
+        },
+        {
+          studyMinListData1:'课程任务名称',
+          studyMinListData2:'来源单位',
+          studyMinListData3:'3',
+        },
+      ],
+      examinationMinList:[
+        {
+          examinationMinListData1:'试卷名称',
+          examinationMinListData2:'40',
+        },
+        {
+          examinationMinListData1:'试卷名称2',
+          examinationMinListData2:'60',
+        },
+      ],
       dataList:[
         {
-
+          minListName:'常规考试',
+          minListType1:0,
+          minListType2:0,
+          minListType3:0,
+          minListType4:0,
+          minListType5:0,
+        },
+        {
+          minListName:'常规考试',
+          minListType1:0,
+          minListType2:1,
+          minListType3:1,
+          minListType4:0,
+          minListType5:0,
+        },
+        {
+          minListName:'常规考试',
+          minListType1:1,
+          minListType2:0,
+          minListType3:0,
+          minListType4:0,
+          minListType5:0,
+        },
+        {
+          minListName:'常规考试',
+          minListType1:1,
+          minListType2:1,
+          minListType3:0,
+          minListType4:0,
+          minListType5:0,
+        },
+        {
+          minListName:'常规考试',
+          minListType1:1,
+          minListType2:1,
+          minListType3:1,
+          minListType4:0,
+          minListType5:0,
+        },
+        {
+          minListName:'常规考试',
+          minListType1:1,
+          minListType2:1,
+          minListType3:1,
+          minListType4:2,
+          minListType5:0,
+        },
+        {
+          minListName:'常规考试',
+          minListType1:1,
+          minListType2:1,
+          minListType3:1,
+          minListType4:2,
+          minListType5:2,
         },
       ],
     }
@@ -84,6 +201,7 @@ export default {
   box-shadow: 0 1px 4px rgba(0,0,0,0.06);
   .top-title-box{
     display: flex;
+    flex-direction: column;
     padding-left:20px;
     p{
       flex:1;
@@ -94,9 +212,10 @@ export default {
       font-weight:700;
     }
     p:nth-child(2){
-      text-align: right;
       font-size:14px;
-      font-weight:700;
+    }
+    p:nth-child(3){
+      font-size:14px;
     }
   }
   .card-max-big-box{
@@ -113,47 +232,123 @@ export default {
     .for-max-big-box{
       display: inline-block;
       width:360px;
-      height:290px;
+      height:240px;
       margin: 0 0 20px 20px;
       border-radius:6px;
       border:1px solid #dedede;
       box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
-      padding:20px 20px 0 20px;
       overflow: hidden;
-      .top-title-box{
+      .year-card-top-title-box{
+        padding:20px 20px 0 20px;
         position: relative;
+        height:64px;
         p:nth-child(1){
-          font-size:14px;
+          font-size:15px;
           font-weight:700;
+          line-height:20px;
         }
         p:nth-child(2){
           font-size:14px;
+          line-height:20px;
+          margin-top:4px;
 
         }
         p:nth-child(3){
+          cursor: pointer;
           font-size:14px;
           line-height:30px;
           background-color: #0183fa;
           color:#fff;
           border-radius:6px;
           position: absolute;
-          top:0;
-          right:0;
+          top:10px;
+          right:10px;
           padding:0 10px;
         }
       }
       .bottom-content-box{
+        height:168px;
+        margin-top:6px;
+        padding:8px 14px 0 20px;
         .bottom-big-box-1{
-
+          display: flex;
+          background-color: rgba(1, 131, 250, 0.1);
+          border-radius:6px;
+          padding:12px 14px;
+          margin-bottom:12px;
+          height:68px;
+          p{
+            font-size:14px;
+            line-height:44px;
+          }
+          p:nth-child(1){
+            flex:1;
+            font-size:15px;
+            font-weight:700;
+          }
+          p:nth-child(2){
+            width:80px;
+            text-align: center;
+          }
         }
         .bottom-big-box-2{
-
+          background-color: rgba(1, 131, 250, 0.1);
+          border-radius:6px;
+          padding:12px 14px;
+          margin-bottom:12px;
+          height:68px;
+          p{
+            font-size:14px;
+            line-height:22px;
+          }
+          p:nth-child(1){
+            font-size:15px;
+            font-weight:700;
+          }
         }
         .bottom-big-box-3{
-
+          background-color: rgba(1, 131, 250, 0.1);
+          border-radius:6px;
+          padding:12px 14px;
+          margin-bottom:12px;
+          height:68px;
+          p{
+            font-size:14px;
+            line-height:22px;
+          }
+          p:nth-child(1){
+            font-size:15px;
+            font-weight:700;
+          }
         }
         .bottom-big-box-4{
+          background-color: rgba(1, 131, 250, 0.1);
+          border-radius:6px;
+          padding:12px 14px;
+          margin-bottom:12px;
+          height:68px;
+          display: flex;
+          p{
+            font-size:14px;
+            line-height:44px;
+          }
+          p:nth-child(1){
 
+          }
+          p:nth-child(2){
+            flex: 1;
+            text-align: right;
+          }
+          .colorA{
+            color:#0183fa;
+            cursor: pointer;
+          }
+          .colorB{
+            color:#D9001B;
+          }
+          .colorC{
+            color:#999;
+          }
         }
       }
     }