dedsudiyu 11 months ago
parent
commit
a2af025076
23 changed files with 1285 additions and 796 deletions
  1. 0 8
      src/api/chemicalManage/index.js
  2. 16 0
      src/api/commonality/permission.js
  3. 0 8
      src/api/iotDevice/index.js
  4. 235 0
      src/components/batchQrCodeDialog/batchQrCodeDialog.vue
  5. 10 2
      src/components/exportComponent/exportComponent.vue
  6. 43 15
      src/components/importComponent/importComponent.vue
  7. 12 12
      src/components/qrCodeDialog/index.vue
  8. 0 4
      src/views/chemicalManage/basicManagement/chemicalInfo/index.vue
  9. 2 3
      src/views/chemicalManage/basicManagement/chemicalsCabinetManage/addPage.vue
  10. 6 0
      src/views/chemicalManage/earlyWarningEvent/infoPage.vue
  11. 2 2
      src/views/emergencyManagement/planExecuteRecord/planExecuteRecordDetail.vue
  12. 84 12
      src/views/integratedManagement/laboratoryManagement/subject/index.vue
  13. 6 1
      src/views/integratedManagement/laboratoryManagement/subject/indexRightPage/hardwarePage.vue
  14. 10 1
      src/views/integratedManagement/laboratoryManagement/subject/indexRightPage/indexRightPage.vue
  15. 211 108
      src/views/integratedManagement/laboratoryManagement/subject/infoPage.vue
  16. 3 1
      src/views/systemManagement/notice/addPage.vue
  17. 2 2
      src/views/systemManagement/notice/index.vue
  18. 594 585
      src/views/integratedManagement/messageNotice/warningNotice/forewarningConfig.vue
  19. 0 4
      src/views/integratedManagement/personnelManage/researchGroupManage/index.vue
  20. 11 9
      src/views/integratedManagement/personnelManage/studentInfo/index.vue
  21. 12 10
      src/views/integratedManagement/personnelManage/teacherInfo/index.vue
  22. 1 2
      src/views/iotDevice/hardwareManagement/hardwareEquipment/index.vue
  23. 25 7
      src/views/iotDevice/intelligenceIot/iotHardware/batchAddPage.vue

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

@@ -226,14 +226,6 @@ export function chemicalStockGetStockByDoorId(query) {
     params: query
   })
 }
-//化学品柜-智能锁
-export function iotDeviceFindByType(data) {
-  return request({
-    url: '/iot/device/findByType',
-    method: 'post',
-    data: data
-  })
-}
 //化学品柜-删除
 export function chemicalCabinetDelete(data) {
   return request({

+ 16 - 0
src/api/commonality/permission.js

@@ -576,4 +576,20 @@ export function iotAlarmTemplateFindList(data) {
     data: data
   })
 }
+//硬件设备-根据类型查询物联设备
+export function iotDeviceFindByType(data) {
+  return request({
+    url: '/iot/device/findByType',
+    method: 'post',
+    data: data
+  })
+}
+//喇叭播放文字
+export function iotSpeakerPlayText(query) {
+  return request({
+    url: '/iot/speaker/playText',
+    method: 'get',
+    params: query
+  })
+}
 

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

@@ -770,14 +770,6 @@ export function iotHardwareTypeFindHardwareType(data) {
     data: data
   })
 }
-//硬件设备-新增-根据类型查询物联设备
-export function iotDeviceFindByType(data) {
-  return request({
-    url: '/iot/device/findByType',
-    method: 'post',
-    data: data
-  })
-}
 //硬件设备-硬件日志
 export function iotHardwareLogList(data) {
   return request({

+ 235 - 0
src/components/batchQrCodeDialog/batchQrCodeDialog.vue

@@ -0,0 +1,235 @@
+<!--  公共二维码dialog组件
+
+1.引入方式
+
+  <batchQrCodeDialog ref="batchQrCodeDialog" :batchQrCodeDialogData="batchQrCodeDialogData"></batchQrCodeDialog>
+
+  import batchQrCodeDialog from "@/components/batchQrCodeDialog/batchQrCodeDialog.vue";
+
+  components: {
+    batchQrCodeDialog
+  },
+
+2.必要参数
+
+  batchQrCodeDialogData:{},
+
+3.必要方法
+
+  //二维码组件开关
+  open(type,id,name){
+    if(this.checkSubList.length>0){
+      let list = [];
+      this.checkSubList.forEach((item)=>{
+        list.push({
+          code:item.subId,              //参数
+          name:item.subName             //名称
+        })
+      })
+      this.$set(this,'batchQrCodeDialogData',{
+        title:'二维码批量下载',                                       //弹窗名称(非必传)
+        type:'1',                                                     //二维码类型 用于区分二维码功能类型
+        codeList:list                                                 //二维码数据
+      });
+      this.$nextTick(function () {
+        this.$refs['batchQrCodeDialog'].initialize();
+      })
+    }else{
+      this.msgError('请勾选实验室')
+    }
+  },
+
+-->
+
+<template>
+  <div>
+    <!--添加/编辑弹窗-->
+    <el-dialog class="batch-qr-code-dialog" title=' '
+               :modal-append-to-body="false"
+               :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false"
+               :visible.sync="dialogType" v-if="dialogType" width="1210px">
+      <p class="title-p">{{batchQrCodeDialogData.title?batchQrCodeDialogData.title:'二维码'}}</p>
+      <div class="for-code-max-box scrollbar-box">
+        <div class="for-code-box" v-for="(item,index) in codeList" :key="item.code">
+          <vue-qr v-if="dialogType" :ref="'qr'+item.code" class="batch-qr-code-dialog-vue-qr" :text="item.parameter"
+                  :size="200"></vue-qr>
+          <canvas class="batch-qr-code-dialog-vue-qr-canvas" :id="item.code" :ref="'canvas'+item.code" width="300"
+                  :height="item.codeName?240:200"></canvas>
+        </div>
+      </div>
+      <div class="button-bottom-box">
+        <p class="null-p"></p>
+        <p class="out-p" @click="buttonClick(2)">取消</p>
+        <p class="batch-qr-code-dialog-button-p" @click="buttonClick(1)">批量下载</p>
+        <p class="null-p"></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import vueQr from 'vue-qr'
+
+  export default {
+    name: 'batchQrCodeDialog',
+    components: {
+      vueQr
+    },
+    props: {
+      batchQrCodeDialogData: {}
+    },
+    data() {
+      return {
+        dialogType: false,
+        vueQrCodeData: null,
+        vueQrImgType: false,
+        identification: localStorage.getItem('codeOnlineAdd'),            //二维码规则 服务器域名,需与微信后台开发配置内一致.
+        codeList: []
+      }
+    },
+    created() {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      //初始化
+      initialize() {
+        console.log('11')
+        let self = this
+        let list = []
+        this.batchQrCodeDialogData.codeList.forEach((item) => {
+          list.push({
+            code: item.code,
+            parameter: this.identification + '?code=' + item.code + '&type=' + this.batchQrCodeDialogData.type,
+            codeName: item.name
+          })
+        })
+        this.$set(this, 'codeList', list)
+        this.$set(this, 'dialogType', true)
+        this.$nextTick(function() {
+          // DOM 更新了
+          setTimeout(function() {
+            self.codeList.forEach((item) => {
+              //获取二维码数据
+              let imgbase64 = self.$refs['qr' + item.code][0].imgUrl
+              let img = new Image()
+              img.src = imgbase64
+              //获取canvas容器
+              let myCanvas = document.getElementById(item.code).getContext('2d')
+              //清空画布-设置背景白色
+              myCanvas.fillStyle = '#FFFFFF'
+              myCanvas.clearRect(0, 0, 300, 240)
+              myCanvas.fillRect(0, 0, 300, 240)
+              //绘制二维码
+              myCanvas.drawImage(img, 50, 0)
+              //设置水印
+              myCanvas.font = 'bold 14px \'Fira Sans\''
+              myCanvas.fillStyle = 'rgba(0,0,0,1)' //水印颜色
+              //绘制水印
+              myCanvas.fillText(item.codeName, (300 - (item.codeName.length * 14)) / 2, 215) //左下
+            })
+          }, 100)
+        })
+      },
+      buttonClick(type) {
+        if (type == 1) {
+          this.codeList.forEach((item) => {
+            let canvas = this.$refs['canvas'+item.code]
+            const base64Img = canvas.toDataURL('image/png')
+            console.log('base64Img',base64Img)
+            var a = document.createElement('a') // 生成一个a元素
+            var event = new MouseEvent('click') // 创建一个单击事件
+            a.download = this.batchQrCodeDialogData.codeName // 设置图片名称
+            a.href = base64Img // 将生成的URL设置为a.href属性
+            a.dispatchEvent(event)
+          })
+        } else {
+          this.$set(this, 'dialogType', false)
+        }
+      }
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .batch-qr-code-dialog {
+    z-index: 10000;
+    font-weight: 500;
+    .batch-qr-code-dialog-title-box {
+      display: flex;
+      p:nth-child(1) {
+        flex: 1;
+      }
+      p:nth-child(2) {
+        font-size: 18px;
+        width: 60px;
+        height: 60px;
+        text-align: center;
+        line-height: 60px;
+        color: #999;
+        cursor: pointer;
+      }
+    }
+    .title-p {
+      text-align: center;
+      margin-top: 40px;
+      font-size: 16px;
+      font-weight: 700;
+    }
+    .for-code-max-box {
+      max-height: 500px;
+      .for-code-box {
+        display: inline-block;
+        .batch-qr-code-dialog-vue-qr {
+          position: absolute;
+          z-index: -10;
+          opacity: 0;
+          display: block !important;
+          height: 200px;
+          width: 200px;
+          margin: 20px auto 27px;
+        }
+        .batch-qr-code-dialog-vue-qr-canvas {
+          display: block !important;
+        }
+      }
+    }
+    .button-bottom-box {
+      display: flex;
+      margin: 0 auto 30px;
+      .null-p {
+        flex: 1;
+      }
+      .out-p {
+        width: 100px;
+        height: 40px;
+        line-height: 40px;
+        color: #A9A9A9;
+        background: #fff;
+        border: 1px solid #A9A9A9;
+        border-radius: 4px;
+        text-align: center;
+        cursor: pointer;
+      }
+      .batch-qr-code-dialog-button-p {
+        margin-left: 20px;
+        width: 100px;
+        height: 40px;
+        line-height: 40px;
+        color: #fff;
+        background: #0045AF;
+        border-radius: 4px;
+        text-align: center;
+        cursor: pointer;
+      }
+    }
+    ::v-deep .el-dialog__header {
+      display: none;
+    }
+    ::v-deep .el-dialog__body {
+      padding: 0;
+    }
+  }
+</style>

+ 10 - 2
src/components/exportComponent/exportComponent.vue

@@ -17,9 +17,11 @@
   },
 
   exportConfig:{
-    api:'system/user/student/export',             //导出接口地址
-    ids:'',                                       //勾选导出,勾选的IDS
+    api:'system/user/student/export',              //导出接口地址
+    ids:'',                                        //勾选导出,勾选的IDS
     fileName:'导出文件名',                         //导出文件的命名
+    customKey:null,                                //自定义参数KEY(非必填)
+    customValue:null                               //自定义参数VALUE(非必填)
   },
 
 -->
@@ -67,6 +69,9 @@
             let obj = {
               ids :''
             }
+            if(self.exportConfig.customKey){
+              obj[self.exportConfig.customKey] = self.exportConfig.customValue
+            }
             self.download(self.exportConfig.api,obj, self.exportConfig.fileName+currentDate+'.xlsx')
             if(this.$parent.$refs['table-box']){
               this.$parent.$refs['table-box'].clearSelection();
@@ -87,6 +92,9 @@
               let obj = {
                 ids :ids
               }
+              if(self.exportConfig.customKey){
+                obj[self.exportConfig.customKey] = self.exportConfig.customValue
+              }
               self.download(self.exportConfig.api,obj, self.exportConfig.fileName+currentDate+'.xlsx')
               if(this.$parent.$refs['table-box']){
                 this.$parent.$refs['table-box'].clearSelection();

+ 43 - 15
src/components/importComponent/importComponent.vue

@@ -17,12 +17,12 @@
   importConfig:{
     upLoadApi:'/system/user/student/importData',                //上传接口地址
     downloadApi:'/system/user/student/importTemplate',          //下载模板接口地址
+    downloadCustomKey:null,                                     //下载模板自定义参数KEY(非必填)
+    downloadCustomValue:null,                                   //下载模板自定义参数VALUE(非必填)
     loseApi:'/system/user/student/importErrorData',             //失败报表接口地址
-    fileName:'导入模板-',                                   //下载模板命名
-  },
-  //必要方法-导入成功回调
-  submitSuccessful(){
-    this.getList();
+    loseCustomKey:null,                                         //失败报表自定义参数KEY(非必填)
+    loseCustomValue:null,                                       //失败报表自定义参数VALUE(非必填)
+    fileName:'导入模板-',                                       //下载模板命名
   },
 
 -->
@@ -85,7 +85,7 @@
     data () {
       return {
         loading:false,
-        uploadImgUrl: window.location.href.split('://')[0]+'://' + process.env.VUE_APP_BASE_API + this.importConfig.upLoadApi, // 上传地址
+        uploadImgUrl: window.location.href.split('://')[0]+'://' + this.judgmentNetworkReturnAddress() + this.importConfig.upLoadApi, // 上传地址
         headers: {
           Authorization: getToken(),
         },
@@ -99,6 +99,7 @@
           downFile:false,
           successNum:0,
           failureNum:0,
+          failCode:null,
           textName:"",
         },
         //导入状态展示
@@ -116,7 +117,13 @@
       importButton(item){
         if(item.command == 1){
           //  下载模板
-          this.downloadPost(this.importConfig.downloadApi,this.importConfig.fileName+`.xlsx`)
+          if (this.importConfig.downloadCustomKey){
+            let obj = {};
+            obj[this.importConfig.downloadCustomKey] = this.importConfig.downloadCustomValue
+            this.download(this.importConfig.downloadApi,obj,this.importConfig.fileName+`.xlsx`)
+          } else {
+            this.downloadPost(this.importConfig.downloadApi,this.importConfig.fileName+`.xlsx`)
+          }
         }else if(item.command == 2){
           //  导入数据
           this.importOpen = true;
@@ -124,20 +131,40 @@
       },
       //导入页面关闭
       importOpenOff(){
-        this.importOpen = false;
-        this.importType = false;
-        this.getImportData.downFile = false;
-        this.getImportData.successNum = 0;
-        this.getImportData.failureNum = 0;
-        this.getImportData.textName = "";
+        this.$set(this,'importOpen',false);
+        this.$set(this,'importType',false);
+        this.$set(this,'getImportData',{
+          downFile:false,
+          successNum:0,
+          failureNum:0,
+          failCode:null,
+          textName:"",
+        });
       },
       /** 下载模板操作 */
       importTemplate() {
-        this.downloadPost(this.importConfig.downloadApi,this.importConfig.fileName+`.xlsx`)
+        if (this.importConfig.downloadCustomKey){
+          let obj = {};
+          obj[this.importConfig.downloadCustomKey] = this.importConfig.downloadCustomValue
+          this.download(this.importConfig.downloadApi,obj,this.importConfig.fileName+`.xlsx`)
+        } else {
+          this.downloadPost(this.importConfig.downloadApi,this.importConfig.fileName+`.xlsx`)
+        }
       },
       /*下载失败列表*/
       failureExcel(){
-        this.downloadPost(this.importConfig.loseApi,`失败报表.xlsx`)
+        if(this.importConfig.loseCustomKey || this.getImportData.failCode){
+          let obj = {}
+          if(this.getImportData.failCode){
+            obj.failCode = this.getImportData.failCode;
+          }
+          if(this.importConfig.loseCustomKey){
+            obj[this.importConfig.loseCustomKey] = this.importConfig.loseCustomValue;
+          }
+          this.download(this.importConfig.loseApi,obj, '失败报表.xlsx')
+        }else{
+          this.downloadPost(this.importConfig.loseApi,`失败报表.xlsx`)
+        }
       },
       //****************************************导入功能**************************************
       handleAvatarSuccess(res, file) {
@@ -145,6 +172,7 @@
           this.getImportData.downFile = res.data.downFile
           this.getImportData.successNum = res.data.successNum
           this.getImportData.failureNum = res.data.failureNum
+          this.getImportData.failCode = res.data.failCode
           this.importType = true
           if (this.$parent.getList){
             this.$parent.getList();

+ 12 - 12
src/components/qrCodeDialog/index.vue

@@ -34,17 +34,17 @@
 <template>
   <div>
     <!--添加/编辑弹窗-->
-    <el-dialog class="trainingCourseAddDialog" title=' '
+    <el-dialog class="qrCodeDialog" title=' '
                :modal-append-to-body="false"
                :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false"
                :visible.sync="dialogType" v-if="dialogType" width="394px">
       <p class="title-p">{{qrCodeDialogData.title?qrCodeDialogData.title:'二维码'}}</p>
-      <vue-qr v-if="dialogType" ref="vueQr" class="trainingCourseAddDialog-vue-qr" :text="vueQrCodeData" :size="200"></vue-qr>
-      <canvas class="trainingCourseAddDialog-vue-qr-canvas" id="myCanvas" ref="myCanvas" width="300" :height="qrCodeDialogData.codeName?240:200"></canvas>
+      <vue-qr v-if="dialogType" ref="vueQr" class="qrCodeDialog-vue-qr" :text="vueQrCodeData" :size="200"></vue-qr>
+      <canvas class="qrCodeDialog-vue-qr-canvas" id="myCanvas" ref="myCanvas" width="300" :height="qrCodeDialogData.codeName?240:200"></canvas>
       <div class="button-bottom-box">
         <p class="null-p"></p>
         <p class="out-p" @click="buttonClick(2)">取消</p>
-        <p v-if="qrCodeDialogData.download" class="trainingCourseAddDialog-button-p" @click="buttonClick(1)">下载</p>
+        <p v-if="qrCodeDialogData.download" class="qrCodeDialog-button-p" @click="buttonClick(1)">下载</p>
         <p class="null-p"></p>
       </div>
     </el-dialog>
@@ -92,8 +92,8 @@
             let myCanvas = document.getElementById( "myCanvas" ).getContext( '2d' );
             //清空画布-设置背景白色
             myCanvas.fillStyle = "#FFFFFF";
-            myCanvas.clearRect(0, 0, 200, 240);
-            myCanvas.fillRect(0, 0, 200, 240);
+            myCanvas.clearRect(0, 0, 300, 240);
+            myCanvas.fillRect(0, 0, 300, 240);
             //绘制二维码
             myCanvas.drawImage( img, 50, 0 );
             if(self.qrCodeDialogData.codeName){
@@ -103,7 +103,7 @@
               //绘制水印
               myCanvas.fillText(self.qrCodeDialogData.codeName, (300-(self.qrCodeDialogData.codeName.length*14))/2, 215); //左下
             }
-          },50);
+          },100);
         })
       },
       buttonClick(type){
@@ -124,10 +124,10 @@
 </script>
 
 <style scoped lang="scss">
-  .trainingCourseAddDialog{
+  .qrCodeDialog{
     z-index: 10000;
     font-weight:500;
-    .trainingCourseAddDialog-title-box{
+    .qrCodeDialog-title-box{
       display: flex;
       p:nth-child(1){
         flex:1;
@@ -148,7 +148,7 @@
       font-size:16px;
       font-weight:700;
     }
-    .trainingCourseAddDialog-vue-qr{
+    .qrCodeDialog-vue-qr{
       position: absolute;
       z-index:-10;
       opacity: 0;
@@ -157,7 +157,7 @@
       width:200px;
       margin:20px auto 27px;
     }
-    .trainingCourseAddDialog-vue-qr-canvas{
+    .qrCodeDialog-vue-qr-canvas{
       display: block!important;
       margin:20px auto 27px;
     }
@@ -178,7 +178,7 @@
         text-align: center;
         cursor: pointer;
       }
-      .trainingCourseAddDialog-button-p{
+      .qrCodeDialog-button-p{
         margin-left:20px;
         width:100px;
         height:40px;

+ 0 - 4
src/views/chemicalManage/basicManagement/chemicalInfo/index.vue

@@ -172,10 +172,6 @@
           this.$set(this,'optionListA',response.data);
         });
       },
-      //导入成功
-      submitSuccessful(){
-        this.getList();
-      },
       //查询按钮
       handleQuery(){
         this.$set(this.queryParams,'page',1);

+ 2 - 3
src/views/chemicalManage/basicManagement/chemicalsCabinetManage/addPage.vue

@@ -172,13 +172,12 @@
 </template>
 
 <script>
-  import { getDeptDropList, systemUserSelect } from '@/api/commonality/permission'
+  import { getDeptDropList, systemUserSelect,iotDeviceFindByType } from '@/api/commonality/permission'
   import { laboratorySubRelInfoGetRelList } from '@/api/commonality/noPermission'
   import {
     chemicalCabinetAdd,
     chemicalCabinetUpdate,
-    chemicalStockGetStockByDoorId,
-    iotDeviceFindByType
+    chemicalStockGetStockByDoorId
   } from '@/api/chemicalManage'
   export default {
     name: 'addPage',

+ 6 - 0
src/views/chemicalManage/earlyWarningEvent/infoPage.vue

@@ -101,6 +101,12 @@
             <el-table-column label="纯度" prop="chemicalPurity" width="180"  show-overflow-tooltip/>
             <el-table-column label="规格" prop="normsNum"  width="180"  show-overflow-tooltip/>
             <el-table-column label="数量" prop="applyNum"  width="180" show-overflow-tooltip/>
+            <el-table-column label="已入库数量" prop="inStockNum"  width="180" show-overflow-tooltip/>
+            <el-table-column label="状态" prop="isStock"  width="180" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{scope.row.isStock?'已入库':'超期未入库'}}</span>
+              </template>
+            </el-table-column>
             <el-table-column label="归属人" prop="belongName" width="220"  show-overflow-tooltip/>
             <el-table-column label="学院" prop="deptName" width="220"  show-overflow-tooltip/>
             <el-table-column label="实验室" prop="subName" width="220"  show-overflow-tooltip/>

+ 2 - 2
src/views/emergencyManagement/planExecuteRecord/planExecuteRecordDetail.vue

@@ -79,7 +79,7 @@
                     +')'}}
                   </p>
                   <p v-if="(item.riskStatus==1||item.riskStatus==2)">
-                    传感器:<span v-for="(minItem,minIndex) in item.sensorJson">{{minIndex!=0?' ,':''}}{{minItem.sensorName}}:{{minItem.sensorValue}}</span>
+                    传感器:<span v-for="(minItem,minIndex) in item.sensorJson">{{minIndex!=0?' ,':''}}{{minItem.deviceName}}:{{minItem.deviceValue}}</span>
                   </p>
                   <p v-if="(item.riskStatus==1||item.riskStatus==2)">时间:{{parseTime(item.createTime)}}</p>
                 </div>
@@ -92,7 +92,7 @@
                     {{item.eventOperate}}
                   </p>
                   <p v-if="(item.riskStatus!=1&& item.riskStatus!=2)">
-                    传感器:<span v-for="(minItem,minIndex) in item.sensorJson">{{minIndex!=0?' ,':''}}{{minItem.sensorName}}:{{minItem.sensorValue}}</span>
+                    传感器:<span v-for="(minItem,minIndex) in item.sensorJson">{{minIndex!=0?' ,':''}}{{minItem.deviceName}}:{{minItem.deviceValue}}</span>
                   </p>
                   <p v-if="(item.riskStatus!=1&& item.riskStatus!=2)">
                     时间:{{parseTime(item.createTime)}}

+ 84 - 12
src/views/integratedManagement/laboratoryManagement/subject/index.vue

@@ -54,19 +54,26 @@
             </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-submit-common-style-button"
-               style="float: right;"
-               @click="clickPage(2)"
-               v-hasPermiRouter="['system:subject:add']"
-            >新增</p>
-            <el-form-item v-hasPermiRouter="['laboratory:subject:import']" style="float: right;margin-right:20px;">
+            <el-dropdown @command="commandButton" style="float: right;">
+              <p class="page-submit-common-style-button" style="width:105px;"
+              >操作<span class="el-icon-arrow-down" style="margin-left:10px;"></span></p>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="{command:1}" v-hasPermiRouter="['system:subject:add']">新增</el-dropdown-item>
+                <!--<el-dropdown-item :command="{command:2}">关联配置</el-dropdown-item>-->
+                <!--<el-dropdown-item :command="{command:3}">准入配置</el-dropdown-item>-->
+                <el-dropdown-item :command="{command:4}">下载二维码</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+            <el-form-item v-hasPermiRouter="['laboratory:subject:import']" style="float: right;">
               <import-component :importConfig="importConfig"></import-component>
             </el-form-item>
           </el-form>
         </div>
         <div class="page-content-box">
-          <el-table class="table-box" ref="multipleTable" border :data="dataList" highlight-current-row
+          <el-table class="table-box" ref="table-box" border :data="dataList" highlight-current-row
+                    @select-all="handleSelectionChange" @select="handleSelectionChange" :row-key="getRowKeys"
                     @current-change="handleCurrentChange">
+            <el-table-column type="selection" width="50" :reserve-selection="true" align="center"/>
             <el-table-column label="排序" align="left" prop="orderNum" width="75">
               <template slot-scope="scope">
                 <el-input maxlength="4" type="text" oninput="value=value.replace(/[^0-9.]/g,'')"
@@ -142,12 +149,15 @@
     <association-configuration v-if="pageType == 5" :subjectData="subjectData"></association-configuration>
     <!--详情-->
     <info-page v-if="pageType == 6" :subjectData="subjectData"></info-page>
+    <!--批量二维码-->
+    <batchQrCodeDialog ref="batchQrCodeDialog" :batchQrCodeDialogData="batchQrCodeDialogData"></batchQrCodeDialog>
   </div>
 </template>
 
 <script>
   /********************** V3 **********************/
   import importComponent from "@/components/importComponent/importComponent.vue";
+  import batchQrCodeDialog from "@/components/batchQrCodeDialog/batchQrCodeDialog.vue";
   import {
     getDeptDropList,
     systemBuildingGetTreeList,
@@ -174,10 +184,13 @@
       admissionConfiguration,
       associationConfiguration,
       infoPage,
-      indexRightPage
+      indexRightPage,
+      batchQrCodeDialog
     },
     data() {
       return {
+        //批量二维码
+        batchQrCodeDialogData:{},
         //导入数据
         importConfig:{
           upLoadApi:'/laboratory/subject/importSubData',                //上传接口地址
@@ -212,6 +225,8 @@
         typeList: [],
         //分级数据
         levelList: [],
+        //二维码勾选数据
+        checkSubList:'',
       }
     },
     created() {
@@ -229,6 +244,36 @@
       this.getList()
     },
     methods: {
+      //操作按钮
+      commandButton(item){
+        if(item.command == 1){
+          this.clickPage(2);
+        }else if(item.command == 2){
+
+        }else if(item.command == 3){
+
+        }else if(item.command == 4){
+          if(this.checkSubList.length>0){
+            let list = [];
+            this.checkSubList.forEach((item)=>{
+              list.push({
+                code:item.subId,
+                name:item.subName
+              })
+            })
+            this.$set(this,'batchQrCodeDialogData',{
+              title:'二维码批量下载',                                               //弹窗名称(非必传)
+              type:'1',                                                     //二维码类型 用于区分二维码功能类型
+              codeList:list
+            });
+            this.$nextTick(function () {
+              this.$refs['batchQrCodeDialog'].initialize();
+            })
+          }else{
+            this.msgError('请勾选实验室')
+          }
+        }
+      },
       // 页面切换
       clickPage(type, row) {
         if (this.pageType != type) {
@@ -345,6 +390,8 @@
       /** 搜索按钮操作 */
       handleQuery() {
         this.$set(this.queryParams,'page',1);
+        this.$set(this,'checkSubList','');
+        this.$refs['table-box'].clearSelection();
         this.getList()
       },
       /** 重置按钮操作 */
@@ -358,6 +405,8 @@
           typeId: '',
           levelId: ''
         })
+        this.$set(this,'checkSubList','');
+        this.$refs['table-box'].clearSelection();
         this.getList()
       },
       //选中实验室
@@ -370,7 +419,7 @@
           this.$set(this,'dataList',response.data.records);
           this.$set(this,'total',response.data.total);
           if (response.data.records[0]) {
-            this.$refs.multipleTable.setCurrentRow(response.data.records[0])
+            this.$refs['table-box'].setCurrentRow(response.data.records[0])
           }
         })
       },
@@ -428,9 +477,32 @@
         })
       },
       //****************************************导入功能**************************************
-      //必要方法-导入成功回调
-      submitSuccessful(){
-        this.resetQuery();
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        let self = this;
+        if(selection[40]){
+          this.$refs['table-box'].clearSelection();
+          this.$nextTick(()=>{
+            let ids = [];
+            for(let i=0;i<selection.length;i++){
+              if(i<40){
+                ids.push(selection[i]);
+                self.$refs['table-box'].toggleRowSelection(selection[i],true);
+              }
+            }
+            self.$set(self,'checkSubList',ids);
+          })
+          this.msgError('最多勾选40条')
+        }else{
+          this.$set(this,'checkSubList',selection.map(item => item));
+        }
+      },
+      /*===记录勾选数据===
+        需要再el-table 添加  :row-key="getRowKeys"
+        需要在selection 添加 :reserve-selection="true"
+      */
+      getRowKeys(row) {
+        return row.subId
       },
     },
   }

+ 6 - 1
src/views/integratedManagement/laboratoryManagement/subject/indexRightPage/hardwarePage.vue

@@ -36,6 +36,7 @@
 </template>
 
 <script>
+  import { controlsRestrictVerify } from '@/utils/index'
   import mqtt from 'mqtt'
   import {
     iotHardwareFindByType,
@@ -64,13 +65,17 @@
       },
       //查询硬件数据
       iotHardwareFindByType(){
-        iotHardwareFindByType({subId:this.$parent.subId}).then(response => {
+        iotHardwareFindByType({subjectId:this.$parent.subId}).then(response => {
           this.$set(this,'hardwareList',response.data);
         })
       },
       // 开启关闭验证
       async changeIsNeedCaptcha (row) {
         let self = this;
+        if(!controlsRestrictVerify('subHardwareControl')){
+          this.msgError('没有相关操作权限,请联系管理员')
+          return
+        }
         let text = row.operatingState?'关闭':'开启';
         this.$confirm(`是否`+text+`此设备`, "提示", {
           confirmButtonText: "确定",

+ 10 - 1
src/views/integratedManagement/laboratoryManagement/subject/indexRightPage/indexRightPage.vue

@@ -37,6 +37,7 @@
 </template>
 
 <script>
+  import { controlsRestrictVerify } from '@/utils/index'
   import sensorPage from './sensorPage.vue'
   import hardwarePage from './hardwarePage.vue'
   import videoPage from './videoPage.vue'
@@ -87,24 +88,32 @@
       rightButtonClick(type) {
         let self = this
         if (this.rightButtonType != type) {
-          this.$set(this,'rightButtonType',type);
           if(type == 1){
+            this.$set(this,'rightButtonType',type);
             this.$nextTick(()=>{
               this.$refs.sensorPage.initialize();
             })
           }else if(type == 2){
+            this.$set(this,'rightButtonType',type);
             this.$nextTick(()=>{
               this.$refs.hardwarePage.initialize();
             })
           }else if(type == 3){
+            if(!controlsRestrictVerify('subVideo')){
+              this.msgError('没有相关操作权限,请联系管理员')
+              return
+            }
+            this.$set(this,'rightButtonType',type);
             this.$nextTick(()=>{
               this.$refs.videoPage.initialize();
             })
           }else if(type == 4){
+            this.$set(this,'rightButtonType',type);
             this.$nextTick(()=>{
               this.$refs.alarmPage.initialize();
             })
           }else if(type == 5){
+            this.$set(this,'rightButtonType',type);
             this.$nextTick(()=>{
               this.$refs.entrancePage.initialize();
             })

+ 211 - 108
src/views/integratedManagement/laboratoryManagement/subject/infoPage.vue

@@ -90,13 +90,12 @@
         <div class="all-title-box" style="height:40px;">
           <p></p>
           <p>传感器监测</p>
-          <p>数据上报时间:</p>
-          <!--<p>{{subjectData.sensorFunctionStatusList[0]?'数据上报时间:'+subjectData.sensorFunctionStatusList[0].sendDate:''}}</p>-->
+          <p v-if="lastOnlineTime">数据上报时间:{{parseTime(lastOnlineTime)}}</p>
+          <p></p>
           <p class="page-out-common-style-button" @click="backPage">返回</p>
         </div>
         <p class="sensor-box" v-for="(item,index) in sensorList" :key="index">{{item.deviceName}}:<span>{{item.deviceValue}}{{item.unit}}</span></p>
-        <img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data.png" v-if="!sensorList[0]">
-        <p class="null-p" v-if="!sensorList[0]" >暂无环境监测信息,请在更多操作-物联设备配置中进行添加</p>
+        <img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data-1.png" v-if="!sensorList[0]">
         <div class="all-title-box" style="height:40px;margin-top:20px;">
           <p></p>
           <p>物联控制</p>
@@ -118,31 +117,30 @@
             <p class="switch-null-p" v-else>离线</p>
           </div>
         </div>
-        <!--<div class="things-box" v-for="(item,index) in subjectData.labHardwareVOListTwo" :key="item.id" v-if="item.hardwareTypeEnum.enumName == 'AI_VENTILATION'">-->
-          <!--<div class="things-for-box">-->
-            <!--<p class="left-title">{{item.hardwareName}}</p>-->
-            <!--<el-switch-->
-              <!--v-if="item.state.code == 3||item.state.code == 4"-->
-              <!--class="switch"-->
-              <!--@click.native="changeIsNeedCaptcha(item)"-->
-              <!--v-model="item.state.code"-->
-              <!--:active-value="3"-->
-              <!--:inactive-value="4"-->
-              <!--active-text="开"-->
-              <!--inactive-text="关"-->
-              <!--disabled>-->
-            <!--</el-switch>-->
-            <!--<p class="switch-null-p" v-else>{{item.state.name}}</p>-->
-          <!--</div>-->
-        <!--</div>-->
-        <!--<div class="things-box" v-for="(item,index) in subjectData.labHardwareVOListTwo" :key="item.id" v-if="item.hardwareTypeEnum.enumName == 'ONE_MACHINE'">-->
-          <!--<div class="things-for-box">-->
-            <!--<p class="left-title">广播系统</p>-->
-            <!--<p class="right-button" @click="handleAdd">播放文字</p>-->
-          <!--</div>-->
-        <!--</div>-->
-        <!--<img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data.png" v-if="!subjectData.labHardwareVOListTwo[0]">-->
-        <!--<p class="null-p" v-if="!subjectData.labHardwareVOListTwo[0]" >暂无物联控制信息,请在更多操作-物联设备配置中进行添加</p>-->
+        <img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data-1.png" v-if="!hardwareList[0]">
+        <div class="all-title-box" style="height:40px;margin-top:20px;">
+          <p></p>
+          <p>视频监控</p>
+        </div>
+        <img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data-1.png" v-if="!videoList[0]">
+        <mpegts-video style="display: inline-block" :videoProps="item" v-for="(item,index) in videoList" :key="index"></mpegts-video>
+
+        <!--广播-->
+
+        <div class="all-title-box" style="height:40px;margin-top:10px;">
+        <p></p>
+        <p>语音广播</p>
+        </div>
+        <div class="things-box" v-for="(item,index) in loudspeakerList" :key="item.id">
+          <div class="things-for-box">
+            <p class="left-title">{{item.deviceName}}</p>
+            <p class="right-button" @click="handleAdd(item.deviceNo)">播放文字</p>
+          </div>
+        </div>
+        <img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data.png" v-if="!loudspeakerList[0]">
+
+        <!--危险源信息-->
+
         <!--<div class="all-title-box" style="height:40px;margin-top:10px;">-->
           <!--<p></p>-->
           <!--<p>危险源信息</p>-->
@@ -152,18 +150,9 @@
         <!--</div>-->
         <!--<img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data.png" v-if="!subjectData.hazardList[0]">-->
         <!--<p class="null-p" v-if="!subjectData.hazardList[0]" >暂无危险源信息,请在更多操作-关联配置中进行添加</p>-->
-        <!--<div class="all-title-box" style="height:40px;margin-top:20px;">-->
-          <!--<p></p>-->
-          <!--<p>视频监控</p>-->
-        <!--</div>-->
-        <!--<div class="video-max-box">-->
-          <!--<div class="video-min-box" v-for="(item,index) in subjectData.videoData" :key="item.id">-->
-            <!--<video :id="item.divId" ref="videoRef" autoplay controls  muted width="240" height="130px"></video>-->
-            <!--<p class="el-icon-full-screen position-p" @click="videoFullScreen(index)"></p>-->
-          <!--</div>-->
-        <!--</div>-->
-        <!--<img class="null-data-img" src="@/assets/ZDimages/basicsModules/null-data.png" v-if="!subjectData.videoData[0]">-->
-        <!--<p class="null-p" v-if="!subjectData.videoData[0]" >暂无视频监控信息,请在更多操作-物联设备配置中进行添加</p>-->
+
+        <!--检查项信息-->
+
         <!--<div class="all-title-box" style="height:30px;">-->
           <!--<p></p>-->
           <!--<p>检查项信息</p>-->
@@ -192,32 +181,21 @@
             <!--</p>-->
           <!--</div>-->
         <!--</div>-->
+
       </div>
-      <!--&lt;!&ndash;展示实验室二维码&ndash;&gt;-->
-      <!--<el-dialog title="实验室二维码" :visible.sync="codeType" width="500px" append-to-body>-->
-        <!--<vue-qr style="display: block;height:460px;width:460px;cursor:pointer;margin:0 auto;" :text="subjectData.qrCodeUrl" :size="200"></vue-qr>-->
-      <!--</el-dialog>-->
-      <!--&lt;!&ndash;播放文字窗口&ndash;&gt;-->
-      <!--<el-dialog title="广播系统" :visible.sync="open" width="500px" append-to-body>-->
-        <!--<el-form ref="form" :model="form" :rules="rules" label-width="80px">-->
-          <!--<el-form-item label="播放文字" prop="txt">-->
-            <!--<el-input v-model="form.txt" placeholder="请输入播放文字" />-->
-          <!--</el-form-item>-->
-          <!--<el-form-item label="播报方式" prop="type">-->
-            <!--<el-radio-group v-model="form.type">-->
-              <!--<el-radio :label="1">文字</el-radio>-->
-              <!--<el-radio :label="2">音频</el-radio>-->
-            <!--</el-radio-group>-->
-          <!--</el-form-item>-->
-        <!--</el-form>-->
-        <!--<div slot="footer" class="dialog-footer dialog-footer-box">-->
-          <!--<p class="dialog-footer-button-null"></p>-->
-          <!--<p class="dialog-footer-button-info" @click="cancel">取消</p>-->
-          <!--<p class="dialog-footer-button-primary" @click="submitFormOne">提交</p>-->
-          <!--<p class="dialog-footer-button-null"></p>-->
-        <!--</div>-->
-      <!--</el-dialog>-->
       <qr-code-dialog ref="qrCodeDialog" :qrCodeDialogData="qrCodeDialogData"></qr-code-dialog>
+      <!--播放文字窗口-->
+      <el-dialog title="语音广播" :visible.sync="open" width="500px" append-to-body>
+        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+          <el-form-item label="播放文字" prop="text">
+            <el-input v-model="form.text" placeholder="请输入播放文字" />
+          </el-form-item>
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button @click="cancel">取 消</el-button>
+          <el-button type="primary" @click="submitFormOne">确 定</el-button>
+        </div>
+      </el-dialog>
     </div>
 </template>
 
@@ -227,17 +205,22 @@
   import { subjectInfo,mangerVoice  } from "@/apiDemo/laboratory/subject";
   import vueQr from 'vue-qr'
   //                                  V3
+  import { controlsRestrictVerify } from '@/utils/index'
   import qrCodeDialog from "@/components/qrCodeDialog/index.vue"
+  import mpegtsVideo from '@/components/mpegtsVideo/mpegtsVideo.vue'
   import {
     iotSensorFindBySubId,
     iotHardwareFindByType,
-    iotHardwareOperatingHardware
+    iotHardwareOperatingHardware,
+    iotDeviceFindByType,
+    iotSpeakerPlayText
   } from '@/api/commonality/permission'
   export default {
       name: "infoPage",
       components: {
         vueQr,
-        qrCodeDialog
+        qrCodeDialog,
+        mpegtsVideo,
       },
       props:{
         subjectData:{},
@@ -260,7 +243,7 @@
           open:false,
           form:{},
           rules:{
-            txt:[
+            text:[
               {required: true, message: '请输入播放文字', trigger: 'blur'},
               { required: true, message: "请输入播放文字", validator: this.spaceJudgment, trigger: "blur" }
             ],
@@ -272,14 +255,39 @@
           sensorList:[],
           //硬件数据
           hardwareList:[],
+          //视频数据
+          videoList:[
+            {
+              id:1,        //(ID:非必传-默认随机生成)
+              width:490,    //(宽度:非必传-默认600)
+              height:280,   //(高度:非必传-默认338)
+              type:'flv',
+              url:"ws://192.168.1.43:8230/rtp/440102004920000000010064_34020000001320000064.flv"        //(视频地址:必传)
+            },
+            {
+              id:2,        //(ID:非必传-默认随机生成)
+              width:490,    //(宽度:非必传-默认600)
+              height:280,   //(高度:非必传-默认338)
+              type:'flv',
+              url:"ws://192.168.1.43:8230/rtp/440102004920000000010064_34020000001320000064.flv"        //(视频地址:必传)
+            },
+          ],
+          //喇叭数据
+          loudspeakerList:[],
+          //MQTT请求参数-传感器
+          sensorMtOpic:"iot/device/sensor/sub/",
+          sensorClient:{},
+          lastOnlineTime:'',
+          //MQTT请求参数-传感器
+          hardwareMtOpic:"iot/hardware/all/sub/",
+          hardwareClient:{},
         }
       },
       created() {
-        // 初始化
-        this.initialize();
       },
       mounted(){
-
+        // 初始化
+        this.initialize();
       },
       methods:{
         initialize(){
@@ -316,28 +324,38 @@
             this.$set(this,'sensorList',response.data);
           })
           //硬件查询
-          iotHardwareFindByType({subId:this.subjectData.subId}).then(response => {
+          iotHardwareFindByType({subjectId:this.subjectData.subId}).then(response => {
             this.$set(this,'hardwareList',response.data);
           })
+          iotDeviceFindByType({ subjectId:this.subjectData.subId, typeKeyList:['horn'] }).then(response => {
+            this.$set(this,'loudspeakerList',response.data);
+          })
         },
         //播放文字
-        handleAdd() {
-          this.open = true;
+        handleAdd(deviceNo) {
+          // if(!controlsRestrictVerify('subHardwareControl')){
+          //   this.msgError('没有相关操作权限,请联系管理员')
+          //   return
+          // }
+          this.$set(this,'form',{
+            deviceNo:deviceNo,
+            text:'',
+          });
+          this.$set(this,'open',true);
         },
         // 取消按钮
         cancel() {
-          this.form = {};
-          this.open = false;
+          this.$set(this,'form',{});
+          this.$set(this,'open',false);
         },
         /*播放文字*/
         submitFormOne(){
           this.$refs["form"].validate(valid => {
             if (valid) {
-              let id = this.subjectData.id;
-              mangerVoice(this.form,id).then(response => {
-                this.msgSuccess("播放成功");
-                this.open = false;
-              });
+              iotSpeakerPlayText(this.form).then(response => {
+                this.msgSuccess(response.message)
+                this.$set(this,'open',false);
+              })
             }
           });
         },
@@ -356,6 +374,10 @@
         // 开启关闭验证
         async changeIsNeedCaptcha (row) {
           let self = this;
+          if(!controlsRestrictVerify('subHardwareControl')){
+            this.msgError('没有相关操作权限,请联系管理员')
+            return
+          }
           let text = row.operatingState?'关闭':'开启';
           this.$confirm(`是否`+text+`此设备`, "提示", {
             confirmButtonText: "确定",
@@ -383,6 +405,113 @@
         backPage(){
           this.$parent.clickPage(1);
         },
+        //MQTT订阅
+        sensorMQTT(){
+          let self = this;
+          this.sensorClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
+            username: localStorage.getItem('mqttUser'),
+            password:localStorage.getItem('mqttPassword')
+          });
+          this.sensorClient.on("connect", e =>{
+            this.sensorClient.subscribe(this.sensorMtOpic+self.subjectData.subId, (err) => {
+              if (!err) {
+                // console.log("订阅成功:" + this.mtOpic+self.$parent.subId);
+              }else{
+                // console.log("连接错误:" + err);
+              }
+            });
+          });
+          this.sensorClient.on("message", (topic, message) => {
+            if (message){
+              let data = JSON.parse(message)
+              let list = JSON.parse(JSON.stringify(this.sensorList))
+              list.forEach((item)=>{
+                data.forEach((minItem)=>{
+                  if(item.deviceNo == minItem.deviceNo){
+                    item.deviceValue = minItem.deviceValue;
+                    item.online = minItem.online;
+                  }
+                })
+              })
+              if(data[0].lastOnlineTime){
+                this.$set(this,'lastOnlineTime',data[0].lastOnlineTime);
+              }else{
+                this.$set(this,'lastOnlineTime','');
+              }
+              this.$set(this,'sensorList',list);
+            }
+          });
+        },
+        //取消订阅关闭MQTT连接
+        sensorOffMQTT(type){
+          let self = this;
+          if(self.sensorClient.unsubscribe){
+            self.sensorClient.unsubscribe(self.hardwareMtOpic+self.subjectData.subId, error => {
+              if (error) {
+                // console.log('mqtt关闭连接错误:', error)
+              }
+            })
+            self.sensorClient.end();
+            this.$set(this,'sensorClient',{});
+          }
+          //判断传入参数如果存在 发起一次新的连接
+          if(type){
+            this.sensorMQTT();
+          }
+        },
+        //MQTT订阅
+        hardwareMQTT(){
+          let self = this;
+          this.hardwareClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
+            username: localStorage.getItem('mqttUser'),
+            password:localStorage.getItem('mqttPassword')
+          });
+          this.hardwareClient.on("connect", e =>{
+            this.hardwareClient.subscribe(this.mtOpic+self.$parent.subId, (err) => {
+              if (!err) {
+                // console.log("订阅成功:" + this.mtOpic+self.$parent.subId);
+              }else{
+                // console.log("连接错误:" + err);
+              }
+            });
+          });
+          this.hardwareClient.on("message", (topic, message) => {
+            if (message){
+              let data = JSON.parse(message)
+              let list = JSON.parse(JSON.stringify(this.hardwareList))
+              list.forEach((item)=>{
+                if(item.hardwareNo == data.hardwareNo){
+                  item.operatingState = data.operatingState;
+                  item.online = data.online;
+                }
+              })
+              this.$set(this,'hardwareList',list);
+            }
+          });
+        },
+        //取消订阅关闭MQTT连接
+        hardwareOffMQTT(type){
+          let self = this;
+          if(self.hardwareClient.unsubscribe){
+            self.hardwareClient.unsubscribe(self.mtOpic+self.$parent.subId, error => {
+              if (error) {
+                // console.log('mqtt关闭连接错误:', error)
+              }
+            })
+            self.hardwareClient.end();
+            this.$set(this,'hardwareClient',{});
+          }
+          //判断传入参数如果存在 发起一次新的连接
+          if(type){
+            this.hardwareMQTT();
+          }
+        },
+      },
+      beforeDestroy() {
+        //清除定时器
+        let self = this;
+        self.sensorOffMQTT();
+        self.hardwareOffMQTT();
       },
     }
 </script>
@@ -607,31 +736,6 @@
           color:#333;
         }
       }
-      .video-max-box{
-        .video-min-box{
-          display: inline-block;
-          overflow: hidden;
-          width:240px;
-          margin-bottom:20px;
-          height:130px;
-          position: relative;
-          .position-p{
-            width:30px;
-            height:30px;
-            text-align: center;
-            line-height:30px;
-            font-size:18px;
-            position: absolute;
-            top:0;
-            right:0;
-            color:#fff;
-            cursor: pointer;
-          }
-        }
-        .video-min-box:nth-child(2n+0){
-          margin-left:20px;
-        }
-      }
       .inspection-box{
         div{
           display: flex;
@@ -661,10 +765,9 @@
       color:#999;
     }
     .null-data-img{
-      width:137px;
-      height:137px;
       display: block;
       margin:10px auto;
+      width:150px;
     }
     .all-title-box{
       display: flex;

+ 3 - 1
src/views/systemManagement/notice/addPage.vue

@@ -65,7 +65,9 @@
 </template>
 
 <script>
-  import { systemNoticeGetSendType,systemNoticeAdd,systemNoticeDetail,systemNoticeUpdate,systemNoticeSendUserIds } from "@/api/systemManagement/index";
+  import { systemNoticeGetSendType,systemNoticeAdd,
+    systemNoticeDetail,systemNoticeUpdate,
+    systemNoticeSendUserIds } from "@/api/systemManagement/index";
   import { systemNoticeGetNoticeType,systemUserSelect } from "@/api/commonality/permission";
   export default {
     name: 'addPage',

+ 2 - 2
src/views/systemManagement/notice/index.vue

@@ -38,8 +38,8 @@
               <span v-for="item in typeList" v-if="item.code==scope.row.noticeType">{{item.name}}</span>
             </template>
           </el-table-column>
-          <el-table-column label="消息标题" align="left" prop="title" width="200" show-overflow-tooltip/>
-          <el-table-column label="消息内容" align="left" prop="content" show-overflow-tooltip/>
+          <el-table-column label="消息标题" align="left" prop="title" show-overflow-tooltip/>
+          <!--<el-table-column label="消息内容" align="left" prop="content" show-overflow-tooltip/>-->
           <el-table-column label="发送状态" align="left" prop="sendState" width="160" show-overflow-tooltip>
             <template slot-scope="scope">
               <span>{{scope.row.sendState == 0 ? '待发送' : (scope.row.sendState == 1 ? '已发送' : (scope.row.sendState == 2 ? '已撤回' : ''))}}</span>

File diff suppressed because it is too large
+ 594 - 585
src/views/integratedManagement/messageNotice/warningNotice/forewarningConfig.vue


+ 0 - 4
src/views/integratedManagement/personnelManage/researchGroupManage/index.vue

@@ -181,10 +181,6 @@
         });
         this.getList();
       },
-      //导入成功
-      submitSuccessful(){
-        this.getList();
-      },
       //获取数据列表
       getList(){
         this.$set(this,'loading',true);

+ 11 - 9
src/views/integratedManagement/personnelManage/studentInfo/index.vue

@@ -222,13 +222,19 @@ export default {
       importConfig:{
         upLoadApi:'/system/user/importStudent',                //上传接口地址
         downloadApi:'/system/user/importTemplate',          //下载模板接口地址
-        loseApi:'/system/user/student/importErrorData',             //失败报表接口地址
-        fileName:'导入模板-',                                   //下载模板命名
+        downloadCustomKey:'userType',                                      //下载模板自定义参数KEY(非必填)
+        downloadCustomValue:2,                                    //下载模板自定义参数VALUE(非必填)
+        loseApi:'/system/user/importErrorData',             //失败报表接口地址
+        loseCustomKey:'userType',                                          //失败报表自定义参数KEY(非必填)
+        loseCustomValue:2,                                        //失败报表自定义参数VALUE(非必填)
+        fileName:'导入模板-学生',                                       //下载模板命名
       },
       exportConfig:{
-        api:'/system/user/export',             //导出接口地址
-        ids:'',                                       //勾选导出,勾选的IDS
-        fileName:'学生信息',                         //导出文件的命名
+        api:'/system/user/export',              //导出接口地址
+        ids:'',                                        //勾选导出,勾选的IDS
+        fileName:'学生信息',                           //导出文件的命名
+        customKey:'userType',                                //自定义参数KEY(非必填)
+        customValue:2                               //自定义参数VALUE(非必填)
       },
       tableButtonType:this.hasPermiDom(['system:user:detail','system:user:edit','system:user:del','system:user:reset',]),
       tableDropdownType:this.hasPermiDom(['system:user:edit','system:user:del','system:user:reset',]),
@@ -376,10 +382,6 @@ export default {
     // this.getConfigKey("sys.user.initPassword").then(response => {});
   },
   methods: {
-    //必要方法-导入成功回调
-    submitSuccessful(){
-      this.getList();
-    },
     //批量绑卡页面跳转与数量检测
     bindingCard(){
       let self = this;

+ 12 - 10
src/views/integratedManagement/personnelManage/teacherInfo/index.vue

@@ -324,15 +324,21 @@
     data() {
       return {
         importConfig:{
-          upLoadApi:'/system/user/importStudent',                //上传接口地址
+          upLoadApi:'/system/user/importTeacher',                //上传接口地址
           downloadApi:'/system/user/importTemplate',          //下载模板接口地址
-          loseApi:'/system/user/student/importErrorData',             //失败报表接口地址
-          fileName:'导入模板-',                                   //下载模板命名
+          downloadCustomKey:'userType',                                      //下载模板自定义参数KEY(非必填)
+          downloadCustomValue:1,                                    //下载模板自定义参数VALUE(非必填)
+          loseApi:'/system/user/importErrorData',             //失败报表接口地址
+          loseCustomKey:'userType',                                          //失败报表自定义参数KEY(非必填)
+          loseCustomValue:1,                                        //失败报表自定义参数VALUE(非必填)
+          fileName:'导入模板-教职工',                                       //下载模板命名
         },
         exportConfig:{
-          api:'/system/user/export',             //导出接口地址
-          ids:'',                                       //勾选导出,勾选的IDS
-          fileName:'教职工信息',                         //导出文件的命名
+          api:'/system/user/export',              //导出接口地址
+          ids:'',                                        //勾选导出,勾选的IDS
+          fileName:'教职工信息',                           //导出文件的命名
+          customKey:'userType',                                //自定义参数KEY(非必填)
+          customValue:1                               //自定义参数VALUE(非必填)
         },
         /*============V3开始*/
         // 部门树选项
@@ -560,10 +566,6 @@
       this.getList();
     },
     methods: {
-      //必要方法-导入成功回调
-      submitSuccessful(){
-        this.getList();
-      },
       /*===========V3开始===========*/
       getDeptOrganizeStructure(){
         getDeptOrganizeStructure({deptName:this.inputDeptName}).then(response => {

+ 1 - 2
src/views/iotDevice/hardwareManagement/hardwareEquipment/index.vue

@@ -222,10 +222,9 @@
     iotHardwareList,
     iotHardwareDelete,
     iotHardwareTypeFindHardwareType,
-    iotDeviceFindByType,
     iotAttributeDetail
   } from '@/api/iotDevice/index'
-  import { systemBuildingGetTreeList, laboratorySubRelInfoGetListByFloor } from '@/api/commonality/permission'
+  import { systemBuildingGetTreeList, laboratorySubRelInfoGetListByFloor,iotDeviceFindByType } from '@/api/commonality/permission'
   import infoPage from "./infoPage.vue";
   export default {
     name: 'index',

+ 25 - 7
src/views/iotDevice/intelligenceIot/iotHardware/batchAddPage.vue

@@ -663,17 +663,35 @@
       //勾选数量限制
       dialogCheck (selection) {
         let self = this;
-        if(this.selectedData.selection[19]){
-          self.$refs.multipleTable.toggleRowSelection(selection[selection.length-1],false);
-          this.$set(this.selectedData,'selection',selection.map(item => item));
-          this.$set(this.selectedData,'userList',JSON.parse(JSON.stringify(selection)));
-          if(this.selectedData.selection[19]){
-            this.msgError('最多勾选20条数据');
-          }
+        if(selection[20]){
+          this.$refs['multipleTable'].clearSelection();
+          this.$nextTick(()=>{
+            let list = [];
+            for(let i=0;i<selection.length;i++){
+              if(i<20){
+                list.push(selection[i]);
+                self.$refs.multipleTable.toggleRowSelection(selection[i],true);
+              }
+            }
+            self.$set(self.selectedData,'selection',list);
+            self.$set(self.selectedData,'userList',JSON.parse(JSON.stringify(list)));
+          })
+          this.msgError('最多勾选20条数据')
         }else{
           this.$set(this.selectedData,'selection',selection.map(item => item));
           this.$set(this.selectedData,'userList',JSON.parse(JSON.stringify(selection)));
         }
+        // if(this.selectedData.selection[19]){
+        //   self.$refs.multipleTable.toggleRowSelection(selection[selection.length-1],false);
+        //   this.$set(this.selectedData,'selection',selection.map(item => item));
+        //   this.$set(this.selectedData,'userList',JSON.parse(JSON.stringify(selection)));
+        //   if(this.selectedData.selection[19]){
+        //     this.msgError('最多勾选20条数据');
+        //   }
+        // }else{
+        //   this.$set(this.selectedData,'selection',selection.map(item => item));
+        //   this.$set(this.selectedData,'userList',JSON.parse(JSON.stringify(selection)));
+        // }
       },
     },
   }