heyang 2 年之前
父节点
当前提交
5bb1995f26

+ 17 - 2
api/index.js

@@ -992,6 +992,14 @@ export const subject_class  = (data) => {
         data: data,
     })
 };
+//查询风扇
+export const listData  = (data) => {
+    return apiResquest({
+        url: `/system/dict/data/list`,
+        method: 'GET',
+        data: data,
+    })
+};
 
 //获取管理员工作台随手拍数量数据
 export const appReceivePhotoNote  = (data) => {
@@ -1055,7 +1063,7 @@ export const voice  = (id,data) => {
     })
 };
 
-//获取拍照检查配置
+//获取离开检查配置
 export const outSubjectPhoto  = (id,data) => {
     return apiResquestForm({
         url: `/base/app/lab/api/outSubjectPhoto`,
@@ -1064,7 +1072,7 @@ export const outSubjectPhoto  = (id,data) => {
     })
 };
 
-//获取拍照检查可选实验室列表
+//获取离开检查可选实验室列表
 export const outSubjectList  = () => {
     return apiResquestForm({
         url: `/base/app/lab/api/outSubjectList`,
@@ -1845,3 +1853,10 @@ export const controlSwitch = (data) => {
         method: 'post',
     })
 };
+// 查询实验室排风扇人工还是预案
+export const subjectTriggerModes = (data) => {
+    return apiResquest({
+        url: `/laboratory/control/newMsg/`+data,
+        method: 'GET',
+    })
+};

+ 2 - 2
api/request/config.js

@@ -1,14 +1,14 @@
 const config = {
 	//base_url: 'http://192.168.1.9:8080',//柴
 	// base_url: 'http://192.168.1.7:8080',//刘波
-	 //base_url: 'http://192.168.1.17:8080',//小飞
+	// base_url: 'http://192.168.1.17:8080',//小飞
 	// base_url: 'http://192.168.1.20:8080',//志伟
     // base_url: 'http://192.168.1.8:8080',//高升
 	// base_url: 'http://192.168.1.29:8080',//何成
     // base_url: 'http://192.168.1.43:9800',//43服务器
 	// base_url: 'https://demo.sxitdlc.com/xzgd/',
 
-	// base_url: 'https://lab.sxitdlc.com/labNhSystem/',//43服务器高升测试
+	 //base_url: 'https://lab.sxitdlc.com/labNhSystem/',//43服务器高升测试
 	//base_url: 'https://lab.sxitdlc.com/labAppTest/',//43服务器线上
     // base_url: 'https://lab.sxitdlc.com/appTest/',//88服务器线上
 	 base_url: 'https://lab.sxitdlc.com/labSystem/', //矿大地址

+ 1 - 1
component/topWarn.vue

@@ -2,7 +2,7 @@
 <template>
 	<view class="top-warn" v-if="pageType">
 		<view>{{text}}</view>
-		<view @click="buttonClick" v-if="whetherRoute">操作</view>
+		<view @click="buttonClick" v-if="whetherRoute">查看</view>
 	</view>
 </template>
 

+ 4 - 4
pages.json

@@ -56,9 +56,9 @@
 			}
 		},
 		{
-			"path": "pages/faceImage",//人脸图像
+			"path": "pages/faceImage",//身份验证
 			"style": {
-				"navigationBarTitleText": "人脸图像"
+				"navigationBarTitleText": "身份验证"
 			}
 		},
 		{
@@ -345,9 +345,9 @@
 					}
 				},
 				{
-					"path": "workbench/photoInspection",//拍照检查
+					"path": "workbench/photoInspection",//离开检查
 					"style": {
-						"navigationBarTitleText": "拍照检查"
+						"navigationBarTitleText": "离开检查"
 					}
 				},
 				{

+ 1 - 0
pages/avatar.vue

@@ -80,6 +80,7 @@
 				uni.navigateBack();
 			},
 			async uploadImg(tempFilePaths){
+				console.log(tempFilePaths)
 			    var self = this;
 			    uni.showLoading({
 			        title: '上传中',

+ 2 - 2
pages/faceImage.vue

@@ -1,4 +1,4 @@
-<!-- 人脸图像 -->
+<!-- 身份验证 -->
 <template>
     <view id="faceImage">
         <view class="max-box">
@@ -78,7 +78,7 @@
                             },2000);
                         }else{
                             uni.showToast({
-                                title: '您上传的人脸图像无法识别,请重新上传其他照片',
+                                title: '您上传的身份验证无法识别,请重新上传其他照片',
                                 icon:"none",
                                 mask:true,
                                 duration: 2000

+ 57 - 5
pages/login.vue

@@ -4,6 +4,12 @@
     <!-- <img class="login-max-big" src="@/images/img_bg_dl.png"> -->
     <img class="login-max-big" :src="loginBanner">
     <view class="login-box">
+	  <view class="tabTitle">
+	  	<view class="tabTitle_li" @tap="tabClick(index)"  :key="index" v-for="(item,index) in tabText">
+	  		<view :class="{on:curTab==index}" class="tabTitle_text">{{item}}</view>
+	  	    <view :class="{on:curTab==index}" class="tabTitle_across"></view>
+	  	</view>
+	  </view>
       <view class="input-max-box-one">
         <view class="input-box">
           <img src="@/images/img_log_in_account.png"/>
@@ -22,14 +28,12 @@
         <view>记住我</view>
       </view>
       <view class="button-box" @click="login">登录</view>
-      <view class="supplier" v-if="identityStatus==2">
+      <view class="supplier" v-if="curTab==1">
         <view class="supplier_l" @click="handleClick('forget')">忘记密码</view>
         <view class="supplier_r" @click="handleClick('register')">没有账号,<text>立即注册</text></view>
       </view>
-      <!-- 供应商 -->
-      <view class="switch_btn" @click="switchClick()">{{identityStatus==2?'师生登录':'供应商登录'}}<img  src="@/images/Version3.0/icon_ssdl_qh.png"/></view>
     </view>
-    <img class="top-back" src="@/images/img_sys_bg.png"/>
+    <!-- <img class="top-back" src="@/images/img_sys_bg.png"/> -->
   </view>
 </template>
 
@@ -46,6 +50,8 @@ export default {
       checkedType:false,
       loginBanner:uni.getStorageSync('loginBanner'),
       infoList:[],//模板消息Id
+	  tabText:['师生登录','供应商登录'],
+	  curTab:0,
     }
   },
 
@@ -68,6 +74,11 @@ export default {
 
   },
   methods: {
+	  //顶部tab点击
+	  tabClick(index) {
+	  	this.curTab = index;
+	
+	  },
     //获取openID
     async getOpenId(){
       let _this=this;
@@ -253,15 +264,56 @@ export default {
     z-index:0;
   }
   .login-box{
-    z-index:1;
+    z-index:3;
     position: absolute
     top:446rpx;
     left:46rpx;
     width:658rpx;
     height:700rpx;
     // background #fff
+	/* 切换按钮 */
+	.tabTitle{
+		display flex;
+		width:100%;
+		height: 100rpx;
+		position: absolute;
+		top: 50rpx;
+		justify-content: center;
+		>view:nth-of-type(1){
+			margin-right: 100rpx;
+		}
+		.tabTitle_li{
+			width:168rpx;
+			text-align center;
+			.tabTitle_text{
+				display: inline-block;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 90rpx;
+				&.on{
+					color:#0183FA;
+				}
+			}
+			.tabTitle_across{
+				width: 100rpx;
+				height: 4rpx;
+				background: #0183FA;
+				border-radius: 2rpx;
+				margin-left 30rpx;
+				display none;
+				&.on{
+					display block;
+				}
+			}
+	
+		}
+	}
     border-radius:20rpx;
     .input-max-box-one{
+		overflow: hidden;
+		margin-top:68rpx;
       .input-box{
         display flex
         width:600rpx;

+ 39 - 2
pages/manageWorkbench.vue

@@ -14,7 +14,7 @@
       </view>
       <view @click="goPage('photoInspection')">
         <img src="@/images/icon_dzt_pzjc.png">
-        <view>拍照检查</view>
+        <view>离开检查</view>
       </view>
       <view @click="goPage('accessQualification')">
         <img src="@/images/Version2.2/icon_sy_zrsq.png">
@@ -112,7 +112,7 @@
 <script>
 import $mqtt from '@/utils/mqtt.min.js';
 import { config } from '@/api/request/config.js'
-import { appReceivePhotoNote,getApprovalCount,subject_class,getSafeWarnList,laboratoryInfo,laboratoryList,getLoginUserInfo,outSubjectPhoto,gradingControl} from '@/api/index.js'
+import { appReceivePhotoNote,getApprovalCount,subject_class,getSafeWarnList,laboratoryInfo,laboratoryList,getLoginUserInfo,outSubjectPhoto,gradingControl,listData} from '@/api/index.js'
 import { tabBar } from '@/component/tabBar.vue'
 import { topWarn } from '@/component/topWarn.vue'
 export default {
@@ -146,6 +146,7 @@ export default {
       buttonArray:[],
       gradingCount:0,//分级管控未完成总数
       homepageBanner:uni.getStorageSync('homepageBanner'),
+	  fanList:[],//控制记录触发方式
     }
   },
   created() {
@@ -159,10 +160,24 @@ export default {
     this.getSafeWarnList();
     this.getLoginUserInfo();
     this.getGrading();
+	this.getListData();
     //监听报警信息
     getApp().watch(this.getSafeWarnList,'mqttAlarmData');
   },
   methods: {
+	  //查询控制记录触发方式
+	  async getListData() {
+		let _this = this;
+		let obj={
+		  pageNum:1,
+		  pageSize:20,
+		  dictType:'trigger_modes'
+		}
+		const {data} = await listData(obj)
+		if (data.code == 200) {
+		   this.fanList=data.rows
+		}
+	  },
     //暂无提示
     goCheckPage(){
       if(this.userInfo.isadmin){
@@ -231,6 +246,7 @@ export default {
     },
     //获取报警信息详情
     async laboratoryInfo(item){
+		let self=this;
       const {data} = await laboratoryInfo(item.subDiyVo.id);
       if(data.code == 200){
         let obj = data.data[0];
@@ -239,6 +255,16 @@ export default {
         obj.subTypeLable = item.subDiyVo.subTypeLable;
         obj.deptName = item.subDiyVo.deptName;
         obj.subAddrrStr = item.subDiyVo.subAddrrStr;
+		//循环判断如果是排风扇的话,启动的时候是人工还是预案还是定时
+		for(let i=0;i<obj.labHardwareVOList.length;i++){
+		 if(obj.labHardwareVOList[i].hardwareTypeEnum.hardwareTypeCode == '2'){
+		 	for(let b=0;b<self.fanList.length;b++){
+		 	  if(self.fanList[b].dictValue==obj.labHardwareVOList[i].triggerModes){
+		 		obj.labHardwareVOList[i].dictLabel=self.fanList[b].dictLabel
+		 	  }
+		 	}
+		 }
+		}
         uni.navigateTo({
           url: '/pages_manage/workbench/laboratory/laboratoryInfo?item='+encodeURIComponent(JSON.stringify(obj))+'&deptId='+obj.deptId
         });
@@ -246,6 +272,7 @@ export default {
     },
     //获取实验室详情
     async laboratoryInfoOne(item){
+		let self=this;
       const {data} = await laboratoryInfo(item.id);
       if(data.code == 200){
         let obj = data.data[0];
@@ -255,6 +282,16 @@ export default {
         obj.deptName = item.deptName;
         obj.subAddrrStr = item.subAddrrStr;
         obj.sensorFunctionList = item.sensorFunctionList;
+		//循环判断如果是排风扇的话,启动的时候是人工还是预案还是定时
+		for(let i=0;i<obj.labHardwareVOList.length;i++){
+		 if(obj.labHardwareVOList[i].hardwareTypeEnum.hardwareTypeCode == '2'){
+		 	for(let b=0;b<self.fanList.length;b++){
+		 	  if(self.fanList[b].dictValue==obj.labHardwareVOList[i].triggerModes){
+		 		obj.labHardwareVOList[i].dictLabel=self.fanList[b].dictLabel
+		 	  }
+		 	}
+		 }
+		}
         uni.navigateTo({
           url: '/pages_manage/workbench/laboratory/laboratoryInfo?item='+encodeURIComponent(JSON.stringify(obj))+'&deptId='+item.deptId
         });

+ 3 - 3
pages/mine.vue

@@ -78,7 +78,7 @@
         </view>
         <view class="button-max-box" @click="goPage('faceImage')">
           <img class="left-img" src="@/images/icon_001.png">
-          <view>人脸图像</view>
+          <view>身份验证</view>
           <view class="view-three-type" :class="!ifFaceFeature?'colorA':'marginType'">{{!ifFaceFeature?'去认证':'已认证'}}</view>
           <img class="right-img" src="@/images/icon_04.png">
         </view>
@@ -197,7 +197,7 @@ export default {
       if(data.code == 200){
         this.userData = data.data;
         this.userData.avatar=data.data.avatar;
-		
+
         this.userData.avatarUrl=config.base_url+data.data.avatar;
 		console.log(config.base_url)
 		console.log(this.userData.avatarUrl)
@@ -320,7 +320,7 @@ export default {
         uni.navigateTo({
           url: '/pages_student/mine/pointsRecord',
         });
-      }else if(type == 'faceImage'){//人脸图像
+      }else if(type == 'faceImage'){//身份验证
         uni.navigateTo({
           url: '/pages/faceImage',
         });

+ 2 - 2
pages/studentWorkbench.vue

@@ -21,7 +21,7 @@
       </view>
       <view @click="goPage('photoInspection')">
         <img src="@/images/icon_dzt_pzjc.png">
-        <view>拍照检查</view>
+        <view>离开检查</view>
       </view>
       <view @click="goPage('gas')">
         <img src="@/images/Version3.0/icon_sy_qpgl.png">
@@ -163,7 +163,7 @@ export default {
         uni.navigateTo({
           url: '/pages_student/workbench/meViolation',
         });
-      }else if(type == 'photoInspection'){//拍照检查
+      }else if(type == 'photoInspection'){//离开检查
         this.outSubjectPhoto();
       }else if(type == 'resultInquiry'){//成绩查询
         uni.navigateTo({

+ 45 - 7
pages_manage/emergencyEvacuationBig.vue

@@ -149,9 +149,10 @@
           </video>
         </view>
         <view class="bottom-button-box">
-          <view @click="shadeTypeClick()">语音广播</view>
-          <view @click="evacuationButton(1)" v-if="isEvacuate">执行疏散</view>
-          <view @click="evacuationButton(2)" v-if="!isEvacuate">结束疏散</view>
+          <view class="voice" @click="shadeTypeClick()">语音广播</view>
+          <view class="plan" v-if="planStatus"  @click="closePlan()">结束预案</view>
+          <view class="evacuate" @click="evacuationButton(1)" v-if="isEvacuate">执行疏散</view>
+          <view class="evacuate" @click="evacuationButton(2)" v-if="!isEvacuate">结束疏散</view>
         </view>
       </view>
       <!-- 语音广播-->
@@ -218,7 +219,8 @@ import {
   firedeviceStatus,
   firedeviceStatusTiming,
   firedeviceStart,
-  firedeviceCancel
+  firedeviceCancel,
+  closeRiskPlan
 } from '@/api/index.js'
 import {
   getBuildOrFloorList,
@@ -347,6 +349,8 @@ export default {
       fireCode:null,// //灭火设备code
       fireStartType:false, //灭火启动状态
       outfireData: {}, //一键灭火
+	  groupId:null,
+	  planStatus:false,
     }
   },
   onLoad(option) {
@@ -357,6 +361,7 @@ export default {
       this.$set(this,'floorId',obj.floorId);
       this.$set(this,'subId',obj.subId);
       this.$set(this.itemData,'subjectId',obj.subId);
+	  this.$set(this,'groupId',obj.groupId);
       this.$set(this,'pageType',2);
       this.confirmBtn();
 	  this.riskPlanId(obj.groupId);
@@ -417,6 +422,33 @@ export default {
       this.$set(this,'urlList',[]);
       this.treeselectByUser();
     },
+	//结束预案
+	closePlan(){
+		let self = this;
+		uni.showModal({
+			content: '传感器数据监测异常,确定要强制结束预案?关闭报警后,3分钟内系统不再触发预案报警,请核实确认后再执行此操作?',
+			cancelColor:"#999",
+			confirmColor:"#0183FA",
+			success: function (res) {
+				if (res.confirm) {
+					self.closeRiskPlan();
+				} else if (res.cancel) {
+				}
+			}
+		});
+	},
+	async closeRiskPlan(){
+		const {data} = await closeRiskPlan({id:this.groupId});
+		if(data.code == 200){
+			this.planStatus=false;
+			uni.showToast({
+				title: '操作成功',
+				icon:"none",
+				mask:true,
+				duration: 2000
+			});
+		}
+	},
     //全屏疏散页面
     goAllPage() {
       let obj = {
@@ -681,6 +713,10 @@ export default {
           for(let o=0;o<self.fjListArray.length;o++){
             for(let i=0;i<data.data.length;i++){
               if(data.data[i].subId == self.fjListArray[o].subId){
+				  console.log('预案')
+				  console.log(data.data[i])
+				self.planStatus=true;//如果有预案发生
+				self.$set(this,'groupId',data.data[i].groupId)
 				self.fjListArray[o].subName.replace('(预案发生)')
                 self.fjListArray[o].subName = '(预案发生) '+self.fjListArray[o].subName
               }
@@ -1994,13 +2030,15 @@ export default {
           font-size: 28rpx;
         }
 
-        view:nth-child(1) {
+        .voice {
           border-top-left-radius: 50rpx;
           border-bottom-left-radius: 50rpx;
           background: #FF9C00;
         }
-
-        view:nth-child(2) {
+		.plan{
+			background: #21A743;
+		}
+        .evacuate{
           border-top-right-radius: 50rpx;
           border-bottom-right-radius: 50rpx;
           background: #0183FA;

+ 487 - 45
pages_manage/workbench/laboratory/laboratoryInfo.vue

@@ -12,7 +12,7 @@
         <view>{{itemData.subAddrrStr}}</view>
       </view>
     </view>
-    <view class="sensor-max-box" v-if="itemData.sensorFunctionList[0]&&!saoCodeType">
+    <view class="sensor-max-box" v-if="itemData.sensorFunctionList.length >0&&!saoCodeType">
       <view class="title-max-box">
         <view class="left-view"></view>
         <view class="right-view">传感器</view>
@@ -69,16 +69,12 @@
         <view class="right-view">智能控制</view>
       </view>
       <view class="button-max-box">
-        <view class="button-box" v-if="itemData.videoNum>0">
-          <view>视频监控</view>
-          <view @click="goVideo()">查看</view>
+        <view class="button-box">
+          <view @click="goVideo()" v-if="itemData.videoNum>0">视频监控</view>
+          <view @click="shadeTypeClick()" v-if="trumpetList.length>0">语音广播</view>
         </view>
-<!--        <view class="button-box">
-          <view>语音播报</view>
-          <view @click="goWord()">播放文字</view>
-        </view> -->
         <view class="for-button-box" v-for="(minItem,minIndex) in itemData.labHardwareVOList" :key="minIndex" v-if="minItem.hardwareTypeEnum.enumName!='VIDEO_MONITOR' && minItem.hardwareTypeEnum.enumName!='RFID_RECOGNIZER'&& minItem.hardwareTypeEnum.enumName!='AI_TERMINAL'&& minItem.hardwareTypeEnum.enumName!='AI_DOORLOCK'&& minItem.hardwareTypeEnum.enumName!='AI_CABINETLOCK' && minItem.hardwareName!='一键灭火' && minItem.isPcfire != '1'">
-          <view class="for-button-p">{{minItem.hardwareName}}</view>
+          <view class="for-button-p">{{minItem.hardwareName}}<text v-if="minItem.state.code=='3'&& minItem.hardwareTypeEnum.hardwareTypeCode==2">({{minItem.dictLabel}})</text></view>
           <img v-if="minItem.state.code=='3' && minItem.pcType != 1" src="@/pages_manage/images/icon_10.png" @click="hardwareButton(minItem,'close')">
           <img v-if="minItem.state.code=='4' && minItem.pcType != 1" src="@/pages_manage/images/icon_11.png" @click="hardwareButton(minItem,'open')">
           <view class="for-button-p" v-if="minItem.state.code=='0' && minItem.pcType != 1">离线</view>
@@ -120,30 +116,17 @@
 			  <view>{{item.phone?item.phone:'未填写'}}</view>
 			</view>
         </view>
-        <view class="safety-max-box" v-if="itemData.hazardCategory[0]||itemData.riskMeasure[0]||itemData.outfire[0]">
-          <view class="max-for-box" v-if="itemData.hazardCategory[0]">
-            <view class="title-box">主要危险类别</view>
-            <view class="for-box" v-for="(item,index1) in itemData.hazardCategory" :key="index1">● {{item}}</view>
-          </view>
-          <view class="max-for-box" v-if="itemData.riskMeasure[0]">
-            <view class="title-box">风险防控措施</view>
-            <view class="for-box" v-for="(item,index1) in itemData.riskMeasure" :key="index1">● {{item}}</view>
-          </view>
-          <view class="max-for-box" v-if="itemData.outfire[0]">
-            <view class="title-box">灭火要点</view>
-            <view class="for-box" v-for="(item,index1) in itemData.outfire" :key="index1">● {{item}}</view>
+        <view class="safety-max-box" v-if="item.privateList.length>0 && item.classifyType==1" v-for="(item,index) in  itemData.classifyList">
+          <view class="max-for-box">
+            <view class="title-box">{{item.classifyName}}</view>
+            <view class="for-box" v-for="(item2,index2) in item.privateList" :key="index2">● {{item2.infoName}}</view>
           </view>
         </view>
-        <view class="img-bottom-box" v-if="itemData.safeSigns[0]||itemData.qrCode">
-          <view class="title-box">安全警示标识</view>
+        <view class="img-bottom-box" v-if="item.privateList.length>0 && item.classifyType==2" v-for="(item,index) in  itemData.classifyList">
+          <view class="title-box">{{item.classifyName}}</view>
           <view class="for-box">
-            <img class="img-ojb" src="@/pages_manage/images/icon_aqxxp_jzxy.png" v-if="item == 'xiyan'" v-for="(item,index) in itemData.safeSigns" :key="index">
-            <img class="img-ojb" src="@/pages_manage/images/icon_aqxxp_jzys.png" v-if="item == 'yinshi'" v-for="(item,index) in itemData.safeSigns" :key="index">
-            <img class="img-ojb" src="@/pages_manage/images/icon_aqxxp_dxaq.png" v-if="item == 'anquan'" v-for="(item,index) in itemData.safeSigns" :key="index">
-            <img class="img-ojb" src="@/pages_manage/images/icon_aqxxp_gzf.png" v-if="item == 'gongzuofu'" v-for="(item,index) in itemData.safeSigns" :key="index">
-            <img class="img-ojb" src="@/pages_manage/images/icon_aqxxp_gbmc.png" v-if="item == 'menchuang'" v-for="(item,index) in itemData.safeSigns" :key="index">
-            <img class="img-ojb" src="@/pages_manage/images/icon_aqxxp_gbsd.png" v-if="item == 'shuidian'" v-for="(item,index) in itemData.safeSigns" :key="index">
-            <img v-if="itemData.safeInfo.qrCode" class="code-img" :src="itemData.safeInfo.qrCode">
+			  <img class="img-ojb" :src="baseUrl+item2.infoContent" v-for="(item2,index2) in item.privateList" :key="index2">
+			  <img v-if="itemData.safeInfo.qrCodeUrl" class="code-img" :src="itemData.safeInfo.qrCodeUrl">
           </view>
         </view>
       </view>
@@ -157,6 +140,33 @@
 	    <view class="shade-outfire-n-b" @click="cancelOutfire()">放弃一键灭火</view>
 	  </view>
 	</view>
+	 <!-- 语音广播-->
+	  <view class="shade-max-big-box" v-if="broadcastType">
+		<view class="null-box" @click="shadeTypeClick()"></view>
+		<!-- 语音广播-执行疏散 -->
+		<view class="broadcast">
+		  <view class="broadcast_t">语音广播<label>选择喇叭位置</label></view>
+		  <!-- 按钮部分 -->
+		  <view class="trumpet-max-box">
+			<view @click="trumpetClick(index)" class="trumpet-for-box"
+				  :class="item.type?'trumpet-color-a':'trumpet-color-b'" v-for="(item,index) in trumpetList"
+				  :key="index">
+			  <img src="@/pages_manage/images/icon_sskz_zc.png" v-if="!item.type">
+			  <img src="@/pages_manage/images/icon_sskz_xz.png" v-if="item.type">
+			  {{item.name}}
+			</view>
+		  </view>
+		  <view class="broadcast_m">
+			<view class="broadcast_m_t" :class="liveType?'broadcast_m_t_back_a':'broadcast_m_t_back_b'"
+				  @longpress.stop="recordButton" @touchmove.stop="cancelButton" @touchend.stop="sendButton">
+
+			  {{liveType?'松开发送':'按住说话'}}
+			</view>
+			<view class="broadcast_m_b" v-if="!liveType">按住说话,录入广播内容</view>
+			<view class="broadcast_m_b" v-if="liveType">松开发送,向上滑动取消发送</view>
+		  </view>
+		</view>
+	  </view>
   </view>
 </template>
 
@@ -164,11 +174,14 @@
 import $mqtt from '@/utils/mqtt.min.js';
 import { config } from '@/api/request/config.js'
 import { mySubjectList,subject_class,listDepartments,mangerControl,getDicts,laboratoryInfo,
-		 firedeviceStatus,firedeviceStart,firedeviceCancel,controlSwitch} from '@/api/index.js'
+		 firedeviceStatus,firedeviceStart,firedeviceCancel,controlSwitch,getDeviceListBySub, textParseUrlIps,listData,subjectTriggerModes} from '@/api/index.js'
 export default {
   data() {
     return {
-      itemData:{},
+		baseUrl:config.base_url,
+      itemData:{
+		  sensorFunctionList:[],
+	  },
       //MQTT请求参数-传感器
       mtopic:"lab/function/data",
       //MQTT请求参数-设备
@@ -212,6 +225,17 @@ export default {
 	  fireStartType:false, //灭火启动状态
 	  outfireData: {}, //一键灭火
 	  subId:'',
+	  broadcastType: false,
+	  //喇叭数据
+	  trumpetList: [],
+	  //广播相关
+	  liveType: false,
+	  sendLock: true, //发送锁,当为true时上锁,false时解锁发送
+	  recorderManager: wx.getRecorderManager(),
+	  isEvacuate: true, //疏散按钮控制,当为true时候执行疏散
+	  //滑动记录
+	  startPoint: {},
+
     }
   },
   onLoad(option) {
@@ -290,6 +314,8 @@ export default {
       }
     }
 	this.firedeviceStatus();
+	this.getListData();
+	this.getDeviceListBySub();
 
   },
   onShow(){
@@ -306,6 +332,22 @@ export default {
 
   },
   methods: {
+	    shadeTypeClick() {
+	        this.broadcastType = !this.broadcastType
+	    },
+		//查询控制记录触发方式
+		async getListData() {
+		  let _this = this;
+		  let obj={
+		    pageNum:1,
+		    pageSize:20,
+		    dictType:'trigger_modes'
+		  }
+		  const {data} = await listData(obj)
+		  if (data.code == 200) {
+		     this.fanList=data.rows
+		  }
+		},
 	  //一键灭火-查询设备状态
 	  async firedeviceStatus() {
 	    let _this = this;
@@ -541,6 +583,16 @@ export default {
           this.itemData.safeInfo.subAdmin = newList;
         }
         this.infoMaxBoxType = true;
+		//循环判断如果是排风扇的话,启动的时候是人工还是预案还是定时
+		for(let i=0;i<self.itemData.labHardwareVOList.length;i++){
+		 if(self.itemData.labHardwareVOList[i].hardwareTypeEnum.hardwareTypeCode == '2'){
+		 	for(let b=0;b<self.fanList.length;b++){
+		 	  if(self.fanList[b].dictValue==self.itemData.labHardwareVOList[i].triggerModes){
+		 		self.itemData.labHardwareVOList[i].dictLabel=self.fanList[b].dictLabel
+		 	  }
+		 	}
+		 }
+		}
       }
     },
 	//一键灭火-传感器状态异常
@@ -571,8 +623,27 @@ export default {
 			}
 		}
 	},
+	//点击开关按钮开启的时候充电调用硬件状态
+	 async subjectTriggerModes(row){
+	  let self=this;
+	   const {data} = await subjectTriggerModes(row.id)
+	   console.log('data',data)
+		if(data.code==200){
+		  for(let b=0;b<self.fanList.length;b++){
+			  if(self.fanList[b].dictValue==data.data.triggerModes){
+				for(let i=0;i<self.itemData.labHardwareVOList.length;i++){
+				  if(row.id == self.itemData.labHardwareVOList[i].id){
+					this.$set(self.itemData.labHardwareVOList[i],'dictLabel',self.fanList[b].dictLabel);
+					this.$set(self.itemData.labHardwareVOList[i],'triggerModes',data.data.triggerModes);
+				  }
+				}
+			  }
+			}
+		}
+	},
     //监听传感器信息
     getMqttSensorData(val){
+		console.log('传感器',val)
       let self = this;
       if(val.subId){
         if(self.itemData.id == val.subId){
@@ -580,10 +651,11 @@ export default {
         }
       }
     },
+
     //监听设备信息
     getMqttDeviceData(val){
       let self = this;
-      // console.log('页面获取的-设备信息',val)
+       console.log('页面获取的-设备信息',val)
       for(let i=0;i<val.length;i++){
         for(let k=0;k<self.itemData.labHardwareVOList.length;k++){
           if(val[i].num == self.itemData.labHardwareVOList[k].id){
@@ -591,12 +663,17 @@ export default {
               self.itemData.labHardwareVOList[k].state.code = 4;
             }else if(val[i].hardwareOperate == 'OPEN'){
               self.itemData.labHardwareVOList[k].state.code = 3;
+              self.itemData.labHardwareVOList[k].state.code = 3;
             }else if(val[i].hardwareOperate == 'OFFLINE'){
               self.itemData.labHardwareVOList[k].state.code = 0;
             }else if(val[i].hardwareOperate == 'ONLINE'){
               self.itemData.labHardwareVOList[k].state.code = 2;
             }
+            if(self.itemData.labHardwareVOList[k].hardwareTypeEnum.hardwareTypeCode == '2' && self.itemData.labHardwareVOList[k].pcType == '0'){
+                self.subjectTriggerModes(self.itemData.labHardwareVOList[k])
+            }
           }
+
         }
       }
     },
@@ -786,6 +863,200 @@ export default {
         });
       }
     },
+	   //获取喇叭列表
+	    async getDeviceListBySub() {
+		  let _this=this;
+	      let obj = {
+	        subId: _this.subId,
+	        floorId: _this.itemData.subAddrr.floorId,
+	        page: 1,
+	        pageSize: 100,
+	      };
+	      const {
+	        data
+	      } = await getDeviceListBySub(obj)
+	      if (data.code == 200) {
+	        for (let i = 0; i < data.data.length; i++) {
+	          data.data[i].type = false;
+	        }
+	        this.$set(this, 'trumpetList', data.data)
+	      }
+	    },
+	//点击选择喇叭
+	    trumpetClick(index) {
+	      this.trumpetList[index].type = !this.trumpetList[index].type
+
+	    },
+	    //录制
+	    recordButton(e) {
+	      console.log("按下")
+	      let self = this;
+	      let num = 0;
+	      for (let i = 0; i < self.trumpetList.length; i++) {
+	        if (self.trumpetList[i].type) {
+	          num++
+	        }
+	      }
+	      if (num == 0) {
+	        uni.showToast({
+	          title: '请选择喇叭',
+	          icon: "none",
+	          mask: true,
+	          duration: 2000
+	        });
+	        return
+	      }
+	      this.liveType = true;
+	      console.log('录制', e)
+	      this.startPoint = e.touches[0]; //记录长按时开始点信息,后面用于计算上划取消时手指滑动的距离。
+	      const options = {
+	        duration: 10000,
+	        sampleRate: 16000,
+	        numberOfChannels: 1,
+	        encodeBitRate: 48000,
+	        format: 'mp3',
+	        frameSize: 50
+	      }
+	      this.recorderManager.start(options); //开始录音
+	      this.recorderManager.onStart(() => {
+	        console.log('recorder start')
+	      })
+	      this.recorderManager.onError((res) => {
+	        console.log(res);
+	      })
+	      wx.showToast({
+	        title: "正在录音,上划取消发送",
+	        icon: "none",
+	        duration: 60000 //先定义个60秒,后面可以手动调用wx.hideToast()隐藏
+	      });
+	      this.sendLock = false; //长按时是不上锁的。
+	    },
+	    //取消
+	    cancelButton(e) {
+	      console.log("移动")
+	      let self = this;
+	      let num = 0;
+	      for (let i = 0; i < self.trumpetList.length; i++) {
+	        if (self.trumpetList[i].type) {
+	          num++
+	        }
+	      }
+	      if (num == 0) {
+	        return
+	      }
+	      this.liveType = false;
+	      console.log('取消', e)
+	      let moveLenght = e.touches[e.touches.length - 1].clientY - this.startPoint.clientY; //移动距离
+	      if (Math.abs(moveLenght) > 50) {
+	        wx.showToast({
+	          title: "松开手指,取消发送",
+	          icon: "none",
+	          duration: 60000
+	        });
+	        this.sendLock = true; //触发了上滑取消发送,上锁
+	      } else {
+	        wx.showToast({
+	          title: "正在录音,上划取消发送",
+	          icon: "none",
+	          duration: 60000
+	        });
+	        this.sendLock = false; //上划距离不足,依然可以发送,不上锁
+	      }
+	    },
+	    //发送
+	    sendButton(e) {
+	      console.log("松开")
+	      let self = this;
+	      let num = 0;
+	      for (let i = 0; i < self.trumpetList.length; i++) {
+	        if (self.trumpetList[i].type) {
+
+	          num++
+	        }
+	      }
+	      if (num == 0) {
+	        return
+	      }
+	      this.liveType = false;
+	      console.log('发送', e)
+	      wx.hideToast(); //结束录音、隐藏Toast提示框
+	      this.recorderManager.stop(); //结束录音
+	      this.recorderManager.onStop((res) => {
+	        if (!this.sendLock) {
+	          console.log('1', this.recorderManager)
+	          this.uploadImg(res.tempFilePath);
+	        }
+	        console.log('停止录音', res.tempFilePath)
+	        console.log("sendLock", this.sendLock);
+	      })
+	    },
+	    //上传MP3
+	    async uploadImg(tempFilePaths) {
+	      var self = this;
+	      uni.uploadFile({
+	        url: config.base_url + '/base/file/upload', //仅为示例,非真实的接口地址
+	        header: {
+	          'Authorization': uni.getStorageSync('token')
+	        },
+	        filePath: tempFilePaths,
+	        name: 'file',
+	        formData: {
+	          'user': 'test'
+	        },
+	        success: (uploadFileRes) => {
+	          let res = JSON.parse(uploadFileRes.data);
+	          if (res.code == 200) {
+	            console.log("上传成功", res)
+	            self.textParseUrlIps(config.base_url + '/' + res.data.url);
+	          } else {
+	            uni.showToast({
+	              title: res.msg,
+	              icon: "none",
+	              mask: true,
+	              duration: 2000
+	            });
+	          }
+	        },
+	        fail: err => {
+	          uni.hideLoading()
+	        },
+	        complete: () => {}
+	      });
+	    },
+	    //发送语音
+	    async textParseUrlIps(text) {
+	      let self = this;
+	      let newList = [];
+	      for (let i = 0; i < self.trumpetList.length; i++) {
+	        if (self.trumpetList[i].type) {
+	          let obj = {
+	            sn: self.trumpetList[i].deviceSn,
+	            port: self.trumpetList[i].port,
+	            deviceIp: self.trumpetList[i].deviceIp,
+	            type: "",
+	            name: "",
+	            speed: "",
+	            params: {
+	              tid: "",
+	              vol: self.trumpetList[i].deviceVol,
+	              urls: []
+	            }
+	          };
+	          newList.push(obj);
+	        }
+	      }
+	      const {
+	        data
+	      } = await textParseUrlIps(newList, text)
+	      if (data.code == 200) {
+	        uni.showToast({
+	          title: '发送成功',
+	          icon: "none",
+	          mask: true,
+	          duration: 2000
+	        });
+	      }
+	    },
     goVideo(){
 		this.itemData.floorId = this.itemData.subAddrr.floorId;
       uni.navigateTo({
@@ -831,6 +1102,173 @@ export default {
   height:100%;
   display flex;
   flex-direction column;
+   /* 语音广播 */
+      .shade-max-big-box {
+        height: 100%;
+        width: 100%;
+        position: fixed;
+        display: flex;
+        flex-direction: column;
+        z-index: 10;
+        background: rgba(0, 0, 0, 0.2);
+
+        .null-box {
+          flex: 1;
+        }
+
+        /* 语音广播-执行疏散 */
+        .broadcast {
+          width: 100%;
+          // height: 532rpx;
+          background: #FFFFFF;
+          border-top-left-radius: 20rpx;
+          border-top-right-radius: 20rpx;
+          padding:22rpx 30rpx 30rpx;
+          box-sizing: border-box;
+          margin-top: 20rpx;
+
+          .broadcast_t {
+            font-size: 30rpx;
+            font-family: PingFang SC;
+            font-weight: 500;
+            color: #333333;
+            line-height: 30rpx;
+
+            >label {
+              font-size: 24rpx;
+              font-family: PingFang SC;
+              font-weight: 500;
+              color: #999999;
+              line-height: 30rpx;
+              margin-left: 16rpx;
+            }
+          }
+
+          .trumpet-max-box {
+            display: flex;
+            justify-content: flex-start;
+            margin-top: 22rpx;
+            flex-wrap: wrap;
+
+            .trumpet-for-box {
+              display: inline-block;
+               width: auto;
+              height: 60rpx;
+              line-height: 60rpx;
+              font-size: 24rpx;
+              text-align: center;
+              cursor: pointer;
+              overflow: hidden;
+              border: 1rpx solid #E0E0E0;
+              border-radius: 10rpx;
+              color: #E0E0E0;
+              display: flex;
+              justify-content: center;
+              margin-right: 20rpx;
+              margin-bottom: 10rpx;
+  			padding: 0 12rpx;
+  		  box-sizing: border-box;
+              >img {
+                width: 36rpx;
+                height: 34rpx;
+                margin: 12rpx 20rpx 0 25rpx;
+              }
+            }
+
+            .trumpet-color-a {
+              border: 1px solid #0183FA;
+              color: #0183FA;
+            }
+
+            .trumpet-color-b {
+              border: 1px solid #CCCCCC;
+              color: #999;
+            }
+          }
+
+          .broadcast_m {
+            width: 100%;
+
+            .broadcast_m_t {
+              width: 142rpx;
+              height: 142rpx;
+              margin: 30rpx 0 0 258rpx;
+              position: relative;
+              font-size: 24rpx;
+              font-family: PingFang SC;
+              font-weight: 500;
+              line-height: 170rpx;
+              text-align: center;
+
+              >img {
+                width: 142rpx;
+                height: 142rpx;
+                position: absolute;
+
+              }
+
+              >label {
+                width: 100%;
+                font-size: 24rpx;
+                font-family: PingFang SC;
+                font-weight: 500;
+                color: #0183FA;
+                line-height: 24rpx;
+                display: inline-block;
+                text-align: center;
+                position: absolute;
+                top: 76rpx;
+              }
+
+              /* 按下 */
+              .press_color {
+                color: #FFFFFF;
+              }
+
+              /* 松开 */
+              .slip_color {
+                color: #0183FA;
+              }
+            }
+
+            .broadcast_m_t_back_a {
+              background: url(@/images/icon_sskz_skfs.png);
+              background-size: 100%;
+              color: #FFFFFF;
+            }
+
+            .broadcast_m_t_back_b {
+              background: url(@/images/icon_sskz_azsh.png);
+              background-size: 100%;
+              color: #0183FA;
+            }
+
+            .broadcast_m_b {
+              font-size: 24rpx;
+              font-family: PingFang SC;
+              font-weight: 500;
+              color: #999999;
+              line-height: 24rpx;
+              text-align: center;
+              margin-top: 14rpx;
+            }
+          }
+
+          /* 疏散按钮 */
+          .evacuation-button-box {
+            width: 650rpx;
+            height: 100rpx;
+            background: #0183FA;
+            color: #fff;
+            text-align center;
+            line-height: 100rpx;
+            font-size: 28rpx;
+            margin: 88rpx auto 0;
+            border-radius: 20rpx;
+          }
+        }
+      }
+
   /* 一键灭火 */
   .outfire {
     width: 750rpx;
@@ -1112,21 +1550,21 @@ export default {
         display flex
         border-bottom:1rpx solid #e0e0e0;
         margin:0 20rpx;
+		view{
+			width:200rpx;
+			line-height:70rpx;
+			border: 2rpx solid #0183FA;
+			border-radius: 35rpx;
+			color: #0183FA;
+			font-size: 24rpx;
+			text-align center;
+			margin:30rpx 0 30rpx 0;
+		}
         view:nth-child(1){
-          flex:1;
-          line-height:90rpx;
-          color:#333333;
-          font-size:28rpx;
+         margin-right: 18rpx;
         }
         view:nth-child(2){
-          width:120rpx;
-          line-height:42rpx;
-          border:4rpx solid #0183FA;
-          border-radius:30rpx;
-          color: #0183FA;
-          font-size: 24rpx;
-          text-align center;
-          margin:20rpx 0 20rpx 0;
+
         }
       }
       .for-button-box:last-child{
@@ -1141,6 +1579,10 @@ export default {
           line-height:90rpx;
           color:#333333;
           font-size:28rpx;
+		  >text{
+			  font-size: 28rpx;
+			  color: #0183FA;
+		  }
         }
         img{
           height:50rpx;

+ 0 - 1
pages_manage/workbench/laboratory/monitor.vue

@@ -365,7 +365,6 @@ export default {
       const {data} = await GetStartList(obj);
       if(data.code == 200){
         let list = [];
-		debugger
         for(let i=0;i<data.data.length;i++){
           let text = uni.getStorageSync('cameraUrl');
           let url = data.data[i].hls;

+ 1 - 1
pages_manage/workbench/signature/signatureImg.vue

@@ -54,7 +54,7 @@
 				this.srcData = imagePath;
 				//小程序电子签名抠图生成图片
 				uni.uploadFile({
-				    url: config.base_url+'/app/sysuser/api/genSign', //仅为示例,非真实的接口地址
+				    url: config.base_url+'/base/app/sysuser/api/genSign', //仅为示例,非真实的接口地址
 				    header:{'Authorization':uni.getStorageSync('token')},
 				    filePath: imagePath,
 				    name: 'file',

+ 1 - 1
pages_student/mine/upStudentCard.vue

@@ -104,7 +104,7 @@
                     mask: true
                 });
                 uni.uploadFile({
-                    url: config.base_url+'/app/lab/api/commit/crad', //仅为示例,非真实的接口地址
+                    url: config.base_url+'/base/app/lab/api/commit/crad', //仅为示例,非真实的接口地址
                     header:{'Authorization':uni.getStorageSync('token')},
                     filePath: self.realImgUrl,
                     name: 'file',

+ 2 - 2
pages_student/workbench/safeAccess/accessApplication.vue

@@ -3,7 +3,7 @@
     <view id="accessApplication">
         <view class="button-max-box" @click="goFaceImage">
             <img src="@/pages_student/images/icon_001.png">
-            <view>人脸图像</view>
+            <view>身份验证</view>
             <view :class="!identifyType?'colorA':'marginType'">{{!identifyType?'去认证':'已认证'}}</view>
             <img v-if="!identifyType" src="@/pages_student/images/icon_04.png">
         </view>
@@ -42,7 +42,7 @@
                 let self = this;
                 if(!this.identifyType){
                     uni.showToast({
-                        title: '请先认证人脸图像',
+                        title: '请先认证身份验证',
                         icon:"none",
                         mask:true,
                         duration: 2000