5 Commits f9c4c9bb32 ... 327112f828

Auteur SHA1 Message Date
  dedsudiyu 327112f828 Merge branch 'master' into xbnl_20260904(应知应会区分学生/教职工) il y a 4 jours
  dedsudiyu bd87c9d199 zc il y a 4 jours
  dedsudiyu 443ae4d6f1 zc il y a 5 jours
  dedsudiyu 530ed9271b zc il y a 5 jours
  dedsudiyu 66b3eef883 zc il y a 5 jours

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

@@ -778,6 +778,14 @@ export function examElLabEduRelationAudit(data) {
     data: data
   })
 }
+//解除实验室绑定
+export function examElLabEduRelationUnbind(data) {
+  return request({
+    url: '/exam/elLabEduRelation/unbind',
+    method: 'post',
+    data: data
+  })
+}
 //实验室申请绑定
 export function examElLabEduRelationBind(data) {
   return request({

+ 202 - 0
src/views/safetyEducationExaminationNew/components/safetyCommitmentLetter.vue

@@ -0,0 +1,202 @@
+<template>
+  <div class="safetyCommitmentLetter-max-big-box">
+    <div class="max-img-box" ref="viewBox" v-if="showType">
+      <transition name="fade" mode="in-out">
+        <vue-office-docx
+          v-if="officeType === 'docx'&&!officeNullType"
+          :src="lookUrl"
+          :class="pdfType == 1?'':'vertical'"
+          @rendered="renderedHandler"
+          @error="errorHandler"
+        />
+        <vue-office-excel
+          v-if="officeType === 'excel'&&!officeNullType"
+          :src="lookUrl"
+          @rendered="renderedHandler"
+          @error="errorHandler"
+        />
+        <vue-office-pdf
+          v-if="officeType === 'pdf'&&!officeNullType"
+          :src="lookUrl"
+          :class="pdfType == 1?'':'vertical'"
+          @rendered="renderedHandler"
+          @error="errorHandler"/>
+      </transition>
+    </div>
+  </div>
+</template>
+
+<script>
+  //引入VueOfficeDocx组件
+  import VueOfficeDocx from '@vue-office/docx'
+  import '@vue-office/docx/lib/index.css'
+  //引入VueOfficeExcel组件
+  import VueOfficeExcel from '@vue-office/excel'
+  import '@vue-office/excel/lib/index.css'
+  //引入VueOfficePdf组件
+  import VueOfficePdf from '@vue-office/pdf'
+  export default {
+    name: 'safetyCommitmentLetter',
+    components: {
+      VueOfficeDocx,
+      VueOfficeExcel,
+      VueOfficePdf,
+    },
+    props: {
+      answerKeyPropsData: {}
+    },
+    data() {
+      return {
+        showType:false,
+        officeNullType:false,
+        //文档类型
+        officeType:null,
+        //文档名称
+        lookName:"",
+        //文档地址
+        lookUrl:"",
+        currentPage: 1,
+        totalPages: 1,
+        currentScale: 1.0, // 初始缩放比例
+        pdfType:1,
+        buttonState:false,
+      }
+    },
+    mounted() {
+      this.initialize('安全承诺书','http://192.168.1.88/statics/study/bigFile/2026/09/29/f2384978-355f-4dab-ba05-7738e8423a30.docx','docx');
+    },
+    methods: {
+      //初始化
+      initialize(name,url,type){
+        let self = this;
+        this.$set(this,'officeNullType',true);
+        this.$set(this,'showType',false);
+        this.$nextTick(()=>{
+          if(name&&url&&type){
+            this.$set(this,'officeType',type);
+            this.$set(this,'lookName',name);
+            this.$set(this,'lookUrl',url);
+            this.$set(this,'officeNullType',false);
+            this.$set(this,'pdfType',1);
+            this.$set(this,'showType',true);
+            if(type === 'docx'){
+              this._detectDocxOrientation(url);
+            }
+          }else{
+            this.msgError('文件参数异常')
+          }
+        })
+      },
+      // 解析 docx XML 自动判断纸张方向,设置 pdfType(1纵向 2横向)
+      async _detectDocxOrientation(url) {
+        try {
+          const res = await fetch(url);
+          const buf = await res.arrayBuffer();
+          const zip = await JSZip.loadAsync(buf);
+          const xmlStr = await zip.file('word/document.xml').async('string');
+          const orientMatch = xmlStr.match(/w:pgSz[^/]*?w:orient="([^"]+)"/);
+          if (orientMatch) {
+            this.$set(this, 'pdfType', orientMatch[1] === 'landscape' ? 2 : 1);
+            return;
+          }
+          // 无 orient 属性时比较 w:w 与 w:h
+          const sizeMatch = xmlStr.match(/w:pgSz[^/]*?w:w="(\d+)"[^/]*?w:h="(\d+)"/);
+          if (sizeMatch) {
+            this.$set(this, 'pdfType', parseInt(sizeMatch[1]) > parseInt(sizeMatch[2]) ? 2 : 1);
+          }
+        } catch (e) {
+          // 解析失败保持默认纵向
+        }
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .vertical{
+    ::v-deep .docx{
+      padding:0!important;
+    }
+  }
+  .safetyCommitmentLetter-max-big-box {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    .max-img-box{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      overflow: hidden;
+      position: relative;
+      overflow-y: scroll;
+      .office-null-text{
+        line-height:700px;
+        text-align: center;
+        color:#dedede;
+        font-size:16px;
+      }
+      .video-box{
+        width:1458px;
+        height:797px;
+      }
+      .rich-text-box {
+        padding:20px 100px;
+        flex:1;
+        background-color: #fff;
+        line-height: 1.6; /* 基础行高 */
+        word-break: break-word; /* 防止长单词或长链接撑破布局 */
+      }
+
+      /* 穿透样式,控制富文本内部的标签 */
+      .rich-text-box ::v-deep img {
+        max-width: 100% !important; /* 防止图片超出容器 */
+        height: auto !important;
+        display: block;
+        margin: 10px auto;
+      }
+
+      .rich-text-box ::v-deep table {
+        width: 100%;
+        border-collapse: collapse;
+      }
+
+      .rich-text-box ::v-deep p {
+        margin-bottom: 10px;
+      }
+    }
+
+    //滚动条样式
+    .max-img-box::-webkit-scrollbar{
+      width: 6px;     /*高宽分别对应横竖滚动条的尺寸*/
+      height: 6px;
+    }
+    .max-img-box::-webkit-scrollbar-thumb{
+      border-radius: 5px;
+      background: #D3D7D4;
+    }
+    .max-img-box::-webkit-scrollbar-track{
+      -webkit-box-shadow: inset 0 0 5px #FFFFFF;
+      border-radius: 0;
+      background: #FFFFFF;
+    }
+    //滚动条样式
+    ::v-deep .ofd-footer{
+      padding:10px 0;
+    }
+    ::v-deep .ofd-body::-webkit-scrollbar{
+      width: 6px;     /*高宽分别对应横竖滚动条的尺寸*/
+      height: 6px;
+    }
+    ::v-deep .ofd-body::-webkit-scrollbar-thumb{
+      border-radius: 5px;
+      background: #D3D7D4;
+    }
+    ::v-deep .ofd-body::-webkit-scrollbar-track{
+      -webkit-box-shadow: inset 0 0 5px #FFFFFF;
+      border-radius: 0;
+      background: #FFFFFF;
+    }
+  }
+</style>

+ 60 - 2
src/views/safetyEducationExaminationNew/examManagement/examinationArrange/addPage.vue

@@ -572,6 +572,28 @@
                     <span class="unit-text">个月</span>
                   </div>
                 </el-form-item>
+
+                <!--<el-form-item label="安全承诺书" prop="securityCommitmentEnabled">-->
+                  <!--<div class="switch-row">-->
+                    <!--<el-switch :disabled="showType" v-model="newData.securityCommitmentEnabled" :active-value="1" :inactive-value="0"-->
+                               <!--active-color="#0183FB" inactive-color="#AAAAAA"-->
+                    <!--/>-->
+                    <!--<p v-if="newData.securityCommitmentEnabled==1&&!showType" class="checkButton-p" style="margin-left:20px;"-->
+                       <!--@click="openSafetyCommitmentLetterDrawer"-->
+                    <!--&gt;选择模板</p>-->
+                  <!--</div>-->
+                  <!--<div class="mock-stat-bar" style="padding:0 20px;"-->
+                       <!--v-if="newData.securityCommitmentTemplateId&&newData.securityCommitmentEnabled == 1">-->
+                    <!--<span style="margin-right:20px;"><b>{{ newData.securityCommitmentTemplateName}}</b></span>-->
+                    <!--&lt;!&ndash;<i class="el-icon-close" @click="newData.certificateTemplateId = null;newData.certificateTemplateName = '';"></i>&ndash;&gt;-->
+                  <!--</div>-->
+                <!--</el-form-item>-->
+
+                <!--<el-form-item label="承诺书打印" v-if="newData.securityCommitmentEnabled == 1">-->
+                  <!--<el-switch :disabled="showType" v-model="newData.securityCommitmentPrintEnabled" :active-value="1" :inactive-value="0"-->
+                             <!--active-color="#0183FB" inactive-color="#AAAAAA"-->
+                  <!--/>-->
+                <!--</el-form-item>-->
               </div>
             </div>
           </el-form>
@@ -597,6 +619,8 @@
       <selectScope v-if="drawerType === 4&&drawer"></selectScope>
       <!--选择证书-->
       <selectCertificate v-if="drawerType === 6&&drawer"></selectCertificate>
+      <!--选择安全承诺书-->
+      <safetyCommitmentLetter v-if="drawerType === 7&&drawer"></safetyCommitmentLetter>
     </el-drawer>
   </div>
 </template>
@@ -609,6 +633,7 @@
   import selectUser from './selectUser.vue'
   import selectScope from './selectScope.vue'
   import selectCertificate from './selectCertificate.vue'
+  import safetyCommitmentLetter from './safetyCommitmentLetter.vue'
   import {
     examElExamAdd,examElExamEdit,examElExamDetail,examElKnowledgePointTreeList,examElDisciplineTypeList,
     examElExamTypeList, laboratoryLevelConfigGetLevelTitleList,examElConfigMasterInitMinHour
@@ -622,7 +647,8 @@
       selectCourse,
       selectUser,
       selectScope,
-      selectCertificate
+      selectCertificate,
+      safetyCommitmentLetter,
     },
     props: {
       propsData: {}
@@ -710,6 +736,13 @@
           callback()
         }
       }
+      const validateData9 = (rule, value, callback) => {
+        if (this.newData.securityCommitmentEnabled == 1 && !this.newData.securityCommitmentTemplateId) {
+          callback(new Error('请选择安全承诺书'))
+        } else {
+          callback()
+        }
+      }
       return {
         //日期选择范围限制
         pickerOptions: {
@@ -798,6 +831,10 @@
           certificatePrintEnabled: 0,
           certificateValidMonths: 0,
           certificateReviewMonths: 0,
+          securityCommitmentEnabled: 0,
+          securityCommitmentTemplateId: null,
+          securityCommitmentTemplateName: '',
+          securityCommitmentPrintEnabled: 0,
           mandatoryStudyHoursConfig:{
             freshmanNoLabHours:0,
             undergraduateHours:0,
@@ -874,6 +911,10 @@
             { required: true, message: '证书复审周期不能为0', trigger: 'change' },
             { validator: validateData8, trigger: 'blur' }
           ],
+          securityCommitmentEnabled: [
+            { required: true, message: '请选择安全承诺书', trigger: 'change' },
+            { validator: validateData9, trigger: 'blur' }
+          ],
         },
         //弹窗相关
         drawerTitle: '',
@@ -958,6 +999,10 @@
               certificatePrintEnabled: response.data.certificateEnabled==1?response.data.certificatePrintEnabled:0,
               certificateValidMonths: response.data.certificateEnabled==1?response.data.certificateValidMonths:0,
               certificateReviewMonths: response.data.certificateEnabled==1?response.data.certificateReviewMonths:0,
+              securityCommitmentEnabled: response.data.securityCommitmentEnabled,
+              securityCommitmentTemplateId: response.data.securityCommitmentEnabled==1?response.data.securityCommitmentTemplateId:null,
+              securityCommitmentTemplateName: response.data.securityCommitmentEnabled==1?response.data.securityCommitmentTemplateName:'',
+              securityCommitmentPrintEnabled: response.data.securityCommitmentEnabled==1?response.data.securityCommitmentPrintEnabled:0,
               mandatoryStudyHoursConfig: response.data.mandatoryStudyHoursConfig,
             };
             this.$set(this,'scopeList',response.data.ruleScopeItems?response.data.ruleScopeItems:[]);
@@ -982,7 +1027,7 @@
               { tab: 'basic', list: ['examTypeId','disciplineTypeId','riskLevelId','examName','attemptLimit','paperId','enableStatus','answerDuration','scopeType','examTimeRange'] },
               { tab: 'preExam', list: ['studyHoursRequirementEnabled','preCourseEnabled','mockEnabled','commitmentEnabled'] },
               // { tab: 'antiCheat', list: ['popupVerifyEnabled'] },
-              { tab: 'certificate', list: ['certificateEnabled','certificateValidMonths','certificateReviewMonths'] }
+              { tab: 'certificate', list: ['certificateEnabled','securityCommitmentEnabled','certificateValidMonths','certificateReviewMonths'] }
             ]
             const matchedTab = tabFieldMap.find(item => item.list.includes(firstErrorField))
             this.activeTab = matchedTab ? matchedTab.tab : 'basic'
@@ -1049,6 +1094,9 @@
           certificatePrintEnabled:this.newData.certificateEnabled == 1?this.newData.certificatePrintEnabled:0,
           certificateValidMonths:this.newData.certificateEnabled == 1?this.newData.certificateValidMonths:0,
           certificateReviewMonths:this.newData.certificateEnabled == 1?this.newData.certificateReviewMonths:0,
+          securityCommitmentEnabled:this.newData.securityCommitmentEnabled,
+          securityCommitmentTemplateId:this.newData.securityCommitmentEnabled == 1?this.newData.securityCommitmentTemplateId:'',
+          securityCommitmentPrintEnabled:this.newData.securityCommitmentEnabled == 1?this.newData.securityCommitmentPrintEnabled:0,
         };
         if(this.newData.id){
           obj.id = this.newData.id;
@@ -1106,6 +1154,12 @@
         this.$set(this, 'drawerType', 6)
         this.$set(this, 'drawer', true)
       },
+      openSafetyCommitmentLetterDrawer() {
+        // TODO: 打开选择安全承诺书模板弹窗
+        this.$set(this, 'drawerTitle', '选择安全承诺书')
+        this.$set(this, 'drawerType', 7)
+        this.$set(this, 'drawer', true)
+      },
       //弹窗关闭
       drawerOffButton(data) {
         if (this.drawerType == 1) {
@@ -1142,6 +1196,10 @@
           //选择证书
           this.$set(this.newData, 'certificateTemplateId', data.id)
           this.$set(this.newData, 'certificateTemplateName', data.name)
+        }else if(this.drawerType == 7){
+          //选则安全承诺书
+          this.$set(this.newData, 'securityCommitmentTemplateId', data.id)
+          this.$set(this.newData, 'securityCommitmentTemplateName', data.name)
         }
         this.$refs.drawer.closeDrawer()
       },

+ 182 - 0
src/views/safetyEducationExaminationNew/examManagement/examinationArrange/safetyCommitmentLetter.vue

@@ -0,0 +1,182 @@
+<!-- 选择证书 -->
+<template>
+  <div class="page-container safetyCommitmentLetter-addPage">
+    <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="shareStatus">
+          <el-select v-model="queryParams.shareStatus" placeholder="是否共享" style="width: 120px">
+            <el-option label="共享" value="1"/>
+            <el-option label="不共享" value="0"/>
+          </el-select>
+        </el-form-item>
+        <!--<el-form-item label="" prop="templateType">-->
+        <!--<el-select v-model="queryParams.templateType" placeholder="考试类型" style="width: 140px">-->
+        <!--<el-option-->
+        <!--v-for="dict in optionListA"-->
+        <!--:key="dict.id"-->
+        <!--:label="dict.examTypeName"-->
+        <!--:value="dict.id"-->
+        <!--/>-->
+        <!--</el-select>-->
+        <!--</el-form-item>-->
+        <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="searchValue">
+          <el-input
+            maxLength="30"
+            v-model="queryParams.searchValue"
+            placeholder="搜索名称"
+            style="width: 140px"
+          />
+        </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="templateName"  show-overflow-tooltip/>
+        <el-table-column label="适用考试类型" prop="examTypeName" width="200" show-overflow-tooltip/>
+        <el-table-column label="是否共享" prop="shareStatus" width="200" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span style="padding:2px 10px;border:1px solid rgb(1, 131, 251);border-radius:4px;color: rgb(1, 131, 251);background-color:rgba(1, 131, 251,0.2)" v-if="scope.row.shareStatus === 1">共享</span>
+            <span style="padding:2px 10px;border:1px solid rgb(245, 154, 35);border-radius:4px;color: rgb(245, 154, 35);background-color:rgba(245, 154, 35,0.2)" v-if="scope.row.shareStatus === 0">不共享</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="颁发单位" prop="deptName" width="200" show-overflow-tooltip/>
+        <el-table-column label="更新人" prop="updateName" 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="checkButton(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>
+</template>
+
+<script>
+  import { examElCertificateTemplatePage,examElExamTypeList,systemDeptCurrentDept, } from "@/api/safetyEducationExaminationNew/index";
+  export default {
+    name: 'safetyCommitmentLetter',
+    props: {
+      propsData: {}
+    },
+    data() {
+      return {
+        //下拉列表数据
+        optionListA:[],
+        optionListB:[],
+        //查询条件
+        queryParams:{
+          page:1,
+          pageSize:20,
+          shareStatus:null,
+          templateType :3,
+          deptId :null,
+          searchValue :'',
+        },
+        //列表数据
+        dataList:[],
+        //数据数量
+        total:0,
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+      this.getList();
+      this.examElExamTypeList();
+      this.systemDeptCurrentDept();
+    },
+    methods: {
+      // 提交按钮
+      checkButton(row) {
+        this.$parent.$parent.drawerOffButton({
+          id:row.id,
+          name:row.templateName,
+        })
+      },
+      //查询按钮
+      handleQuery(){
+        this.$set(this.queryParams,'page',1);
+        this.getList();
+      },
+      //重置按钮
+      resetQuery(){
+        this.$set(this,'queryParams',{
+          page:1,
+          pageSize:20,
+          shareStatus:null,
+          templateType :3,
+          deptId :null,
+          searchValue :'',
+        });
+        this.getList();
+      },
+      //获取数据列表
+      getList(){
+
+        let obj = JSON.parse(JSON.stringify(this.queryParams))
+        examElCertificateTemplatePage(obj).then(response => {
+
+          this.$set(this,'dataList',response.data.records);
+          this.$set(this,'total',response.data.total);
+        });
+      },
+      //查询全部考试类型
+      examElExamTypeList(){
+        examElExamTypeList({}).then(response => {
+          this.$set(this,'optionListA',response.data);
+        });
+      },
+      //学院列表
+      systemDeptCurrentDept(){
+        systemDeptCurrentDept({}).then(response => {
+          const list = response.data || [];
+          this.formatTreeData(list);
+          this.$set(this,'optionListB',list);
+        });
+      },
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .safetyCommitmentLetter-addPage {
+    flex:1;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+  }
+</style>

+ 1 - 1
src/views/safetyEducationExaminationNew/featurePage/mockExam/index.vue

@@ -10,7 +10,7 @@
       <div class="left-panel">
         <div class="exam-title">{{ examInfo.examTypeName }}</div>
         <div class="exam-subtitle">总{{ examInfo.questionCount }}题 / 共{{ examInfo.totalScore }}分</div>
-        <div class="exam-name-box scrollbar-box">{{ examInfo.examName }}</div>
+        <div class="exam-name-box">{{ examInfo.examName }}</div>
         <div class="question-group-max-box">
           <!-- 题目导航 -->
           <div v-for="(item,index) in questionTypeGroups" :key="index" class="question-group">

+ 1 - 1
src/views/safetyEducationExaminationNew/featurePage/startPracticing/index.vue

@@ -10,7 +10,7 @@
       <div class="left-panel">
         <div class="exam-title">刷题练习</div>
         <div class="exam-subtitle">总{{ examInfo.totalCount }}题</div>
-        <div class="exam-name-box scrollbar-box">{{ examInfo.knowledgePointName }}</div>
+        <div class="exam-name-box">{{ examInfo.knowledgePointName }}</div>
         <div class="question-group-max-box">
           <!-- 题目导航 -->
           <div v-for="(item,index) in questionTypeGroups" :key="index" class="question-group">

+ 1 - 1
src/views/safetyEducationExaminationNew/featurePage/startTheExam/index.vue

@@ -10,7 +10,7 @@
       <div class="left-panel">
         <div class="exam-title">{{ examInfo.examTypeName }}</div>
         <div class="exam-subtitle">总{{ examInfo.questionCount }}题 / 共{{ examInfo.totalScore }}分</div>
-        <div class="exam-name-box scrollbar-box">{{ examInfo.examName }}</div>
+        <div class="exam-name-box">{{ examInfo.examName }}</div>
         <p class="examKindType" v-if="examInfo.examKind== 2">补考</p>
         <div class="question-group-max-box">
           <!-- 题目导航 -->

+ 1 - 1
src/views/safetyEducationExaminationNew/featurePage/startTraining/index.vue

@@ -10,7 +10,7 @@
       <div class="left-panel">
         <div class="exam-title">刷题练习</div>
         <div class="exam-subtitle">总{{ examInfo.totalCount }}题</div>
-        <div class="exam-name-box scrollbar-box">{{ examInfo.knowledgePointName }}</div>
+        <div class="exam-name-box">{{ examInfo.knowledgePointName }}</div>
         <div class="question-group-max-box">
           <!-- 题目导航 -->
           <div v-for="(item,index) in questionTypeGroups" :key="index" class="question-group">

+ 42 - 4
src/views/safetyEducationExaminationNew/personnelApproval/index.vue

@@ -44,14 +44,21 @@
           <el-table-column prop="statusCode" label="状态" width="80" align="center" show-overflow-tooltip>
             <template slot-scope="scope">
             <span :class="scope.row.statusCode==0?'status-txt-a':(scope.row.statusCode==1?'status-txt-b':(scope.row.statusCode==2?'status-txt-c':''))">
-              {{ scope.row.statusCode==0?'待审批':(scope.row.statusCode==1?'已通过':(scope.row.statusCode==2?'已驳回':'')) }}
+              {{ scope.row.statusCode==0?'待审批':(scope.row.statusCode==1?'已通过':(scope.row.statusCode==2?'已驳回':(scope.row.statusCode==3?'已解绑':''))) }}
             </span>
             </template>
           </el-table-column>
           <el-table-column label="操作" min-width="130" align="left">
             <template slot-scope="scope">
-              <p class="button-color-a" v-if="scope.row.statusCode==0" @click="tableButton(1,scope.row)">通过</p>
-              <p class="button-color-b" v-if="scope.row.statusCode==0" @click="tableButton(2,scope.row)">驳回</p>
+              <div class="table-button-box">
+                <p class="table-button-null"></p>
+                <p class="button-color-a" v-if="scope.row.statusCode==0" @click="tableButton(1,scope.row)">通过</p>
+                <p class="button-color-b" v-if="scope.row.statusCode==0" @click="tableButton(2,scope.row)">驳回</p>
+                <p class="button-color-c" v-if="scope.row.statusCode==1"
+                   v-hasPermiRouter="['exam:personnelApproval:edit']"
+                   @click="tableButton(3,scope.row)">解绑</p>
+                <p class="table-button-null"></p>
+              </div>
             </template>
           </el-table-column>
         </el-table>
@@ -102,6 +109,7 @@
 <script>
   import {
     examElLabEduRelationAuditList,examElLabEduRelationAudit,
+    examElLabEduRelationUnbind,
   } from "@/api/safetyEducationExaminationNew/index";
   export default {
     name: 'LabBindingApply',
@@ -159,9 +167,19 @@
           }).then(() => {
             self.examElLabEduRelationAudit(1)
           }).catch(() => {});
-        } else {
+        } else if(val == 2) {
           //驳回
           this.$set(this,'dialogType',true);
+        } else if(val == 3) {
+          //解绑
+          this.$confirm('确认解除 '+row.userName+' 与 '+row.subName+'('+row.roomNum+')'+' 的绑定关系?', "提示", {
+            confirmButtonText: "确认",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(function() {
+          }).then(() => {
+            self.examElLabEduRelationUnbind(row.id)
+          }).catch(() => {});
         }
       },
       //提交按钮
@@ -185,6 +203,15 @@
           this.getList();
         })
       },
+      examElLabEduRelationUnbind(id){
+        let obj = {
+          relationId:id,
+        }
+        examElLabEduRelationUnbind(obj).then(response => {
+          this.msgSuccess(response.message)
+          this.getList();
+        })
+      },
       //关闭按钮
       dialogCancel(){
         this.$set(this,'dialogType',false);
@@ -293,6 +320,17 @@
       color: #fff;
       background-color: #E86452;
     }
+    .button-color-c{
+      width:60px;
+      cursor: pointer;
+      display: inline-block;
+      text-align: center;
+      line-height:24px;
+      border-radius:4px;
+      border: 1px solid #999;
+      color: #fff;
+      background-color: #999;
+    }
     .status-txt-a{
       color: #F59A48;
     }

+ 1 - 1
src/views/safetyEducationExaminationNew/publicConfiguration/certificateTemplate/addPage.vue

@@ -102,7 +102,7 @@
           Authorization: getToken(),
         },
         upData:[],
-        optionList:[{value:'1',label:'考试证书'},{value:'2',label:'培训证书'},],
+        optionList:[{value:1,label:'考试证书'},{value:2,label:'培训证书'},{value:3,label:'安全承诺书'},],
         optionDeptList:[],
         newData:{
           templateName:'',

+ 2 - 2
src/views/safetyEducationExaminationNew/publicConfiguration/certificateTemplate/index.vue

@@ -61,7 +61,7 @@
           <el-table-column label="证书模板名称" prop="templateName"  show-overflow-tooltip/>
           <el-table-column label="证书类型" prop="templateType" width="200" show-overflow-tooltip>
             <template slot-scope="scope">
-              <span>{{scope.row.templateType==1?'考试证书':'培训证书'}}</span>
+              <span>{{scope.row.templateType==1?'考试证书':(scope.row.templateType==2?'培训证书':(scope.row.templateType==3?'安全承诺书':''))}}</span>
             </template>
           </el-table-column>
           <el-table-column label="是否共享" prop="shareStatus" width="120" show-overflow-tooltip>
@@ -127,7 +127,7 @@
         //页面状态
         pageType:1,
         //下拉列表数据
-        optionClassList:[{value:'1',label:'考试证书'},{value:'2',label:'培训证书'},],
+        optionClassList:[{value:1,label:'考试证书'},{value:2,label:'培训证书'},{value:3,label:'安全承诺书'},],
         optionList:[],
         queryParams:{
           page:1,

+ 28 - 1
src/views/safetyEducationExaminationNew/safetyTest/myGrades/index.vue

@@ -93,6 +93,24 @@
         <p class="dialog-footer-button-null"></p>
       </div>
     </el-dialog>
+    <el-dialog class="safetyCommitmentLetter-dialog"
+               :modal-append-to-body="false"
+               :close-on-click-modal="false" :close-on-press-escape="false"
+               title="安全承诺书"
+               :visible.sync="safetyCommitmentLetterDialogType"
+               v-if="safetyCommitmentLetterDialogType"
+               width="908px"
+               append-to-body>
+      <div style="height:600px;display: flex;flex-direction: column;overflow: hidden">
+        <safetyCommitmentLetter ref="dataStatisticsReport" :safetyCommitmentLetterPropsData="safetyCommitmentLetterPropsData"></safetyCommitmentLetter>
+      </div>
+      <div slot="footer" class="dialog-footer dialog-footer-box">
+        <p class="dialog-footer-button-null"></p>
+        <p class="dialog-footer-button-border" @click="safetyCommitmentLetterDialogButton(type)">下载</p>
+        <p class="dialog-footer-button-primary" @click="safetyCommitmentLetterDialogButton(type)">确认</p>
+        <p class="dialog-footer-button-null"></p>
+      </div>
+    </el-dialog>
   </div>
 </template>
 <script>
@@ -102,13 +120,15 @@
   import dataStatisticsReport from "./dataStatisticsReport.vue";
   import historyOfIncorrectQuestions from "@/views/safetyEducationExaminationNew/components/historyOfIncorrectQuestions.vue";
   import examRecords from "@/views/safetyEducationExaminationNew/components/examRecords.vue";
+  import safetyCommitmentLetter from "@/views/safetyEducationExaminationNew/components/safetyCommitmentLetter.vue";
   import { examElExamUserResultMyScoreListPage,examUserExamTypeSelectExamType,examElLabEduRelationGraduationReport, } from "@/api/safetyEducationExaminationNew/index";
   export default {
     name: 'index',
     components: {
       historyOfIncorrectQuestions,
       examRecords,
-      dataStatisticsReport
+      dataStatisticsReport,
+      safetyCommitmentLetter
     },
     data() {
       return {
@@ -136,6 +156,9 @@
         historyOfIncorrectQuestionsPropsData:{},
         dialogType:false,
         dataStatisticsReportPropsData:{},
+        //安全承诺书
+        safetyCommitmentLetterDialogType:false,
+        safetyCommitmentLetterPropsData:null,
       }
     },
     created() {
@@ -267,6 +290,10 @@
         m=Math.pow(10,Math.max(r1,r2))
         return ((arg1*m+arg2*m)/m).toFixed(0);
       },
+      //安全承诺书
+      safetyCommitmentLetterDialogButton(type){
+
+      },
     },
     beforeRouteLeave(to, from, next) {
       if (to.name === 'startTraining') {