infoPage.vue 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193
  1. <template>
  2. <div class="infoPage" v-if="newData.id">
  3. <div :class="versionField() == 'xiBeiNongLinDaXue'?'left-max-box-flex':''" class="left-max-box scrollbar-box">
  4. <div :class="versionField() == 'xiBeiNongLinDaXue'?'top-max-box-flex':''" class="top-max-box" style="position: relative">
  5. <div class="all-title-box">
  6. <p></p>
  7. <p style="flex:1;">实验室安全信息牌</p>
  8. <div v-if="versionField() == 'xiBeiNongLinDaXue'" class="reset-button-one" style="margin-top:-5px;width:80px!important;height:30px!important;line-height:30px!important;" @click="backPage">返回</div>
  9. </div>
  10. <div class="left-top-title-box">
  11. <div class="left-box">
  12. <div class="lv-name-box">
  13. <p :style="'color:'+newData.fiedColor+';border:1px solid '+newData.fiedColor+';'">{{newData.levelName}}</p>
  14. <p>{{newData.name}}</p>
  15. </div>
  16. <div class="type-address-box">
  17. <p>{{newData.typeName}}</p>
  18. <p v-if="newData.subAddrr">{{newData.subAddrr.buildName}}{{newData.subAddrr.floorName}}</p>
  19. </div>
  20. </div>
  21. <div class="right-code-img" @click="clickCode">
  22. <vue-qr style="display: block;height:60px;width:60px;cursor:pointer;margin:0 10px 0 0;" :text="newData.qrCodeUrl" :size="300" @click="clickCode"></vue-qr>
  23. </div>
  24. </div>
  25. <div class="user-max-box">
  26. <div class="left-box">
  27. <p>责任人:<span>{{newData.adminName}}-{{newData.adminPhone}}</span></p>
  28. </div>
  29. <div class="right-box">
  30. <div>
  31. <p>安全责任人:<span v-for="(item,index) in newData.safeUserName" :key="index">{{newData.safeUserName[index]}}-{{newData.safeUserPhone[index]?newData.safeUserPhone[index]:'未填写'}}</span></p>
  32. </div>
  33. </div>
  34. </div>
  35. <div class="info-max-box">
  36. <div class="left-box">
  37. <div class="for-text-box">
  38. <p class="info-title">主要危险类别:{{!newData.hazardCategory?'未配置':''}}</p>
  39. <div class="for-box" v-for="(item,index1) in newData.hazardCategory" :key="index1">
  40. <p class="for-info-p" v-for="(minItem,index2) in hazardCategory" :key="index2" v-if="minItem.dictValue == item">● {{minItem.dictLabel}}</p>
  41. </div>
  42. </div>
  43. <div class="for-text-box">
  44. <p class="info-title">灭火要点:{{!newData.outfire?'未配置':''}}</p>
  45. <div class="for-box" v-for="(item,index1) in newData.outfire" :key="index1">
  46. <p class="for-info-p" v-for="(minItem,index2) in extinguishingKeyPoints" :key="index2" v-if="minItem.dictValue == item">● {{minItem.dictLabel}}</p>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="right-box">
  51. <div class="for-text-box">
  52. <p class="info-title">风险防控措施:{{!newData.riskMeasure?'未配置':''}}</p>
  53. <div class="for-box" v-for="(item,index1) in newData.riskMeasure" :key="index1">
  54. <p class="for-info-p" v-for="(minItem,index2) in riskMeasure" :key="index2" v-if="minItem.dictValue == item">● {{minItem.dictLabel}}</p>
  55. </div>
  56. </div>
  57. <div class="for-img-box">
  58. <p class="info-title" style="margin-bottom:7px;">安全警示标识:{{!newData.safeSigns?'未配置':''}}</p>
  59. <img src="@/assets/newImages/icon_aqxxp_jzxy.png" v-if="item == 'xiyan'" v-for="(item,index) in newData.safeSigns" :key="index">
  60. <img src="@/assets/newImages/icon_aqxxp_jzys.png" v-if="item == 'yinshi'" v-for="(item,index) in newData.safeSigns" :key="index">
  61. <img src="@/assets/newImages/icon_aqxxp_dxaq.png" v-if="item == 'anquan'" v-for="(item,index) in newData.safeSigns" :key="index">
  62. <img src="@/assets/newImages/icon_aqxxp_gzf.png" v-if="item == 'gongzuofu'" v-for="(item,index) in newData.safeSigns" :key="index">
  63. <img src="@/assets/newImages/icon_aqxxp_gbmc.png" v-if="item == 'menchuang'" v-for="(item,index) in newData.safeSigns" :key="index">
  64. <img src="@/assets/newImages/icon_aqxxp_gbsd.png" v-if="item == 'shuidian'" v-for="(item,index) in newData.safeSigns" :key="index">
  65. </div>
  66. </div>
  67. </div>
  68. </div>
  69. <div class="top-max-box">
  70. <div class="all-title-box" style="margin-top:20px;">
  71. <p></p>
  72. <p style="flex:1;">关联预案</p>
  73. </div>
  74. <div class="demo-max-box">
  75. <div class="demo-title-box">
  76. <p>预案名称</p>
  77. <p>启动次数</p>
  78. <p>最近启动时间</p>
  79. </div>
  80. <div class="demo-text-box" v-for="(item,index) in demoList" :key='index'>
  81. <p>{{item.name}}</p>
  82. <p>{{item.num}}</p>
  83. <p>{{item.time}}</p>
  84. </div>
  85. </div>
  86. </div>
  87. </div>
  88. <div class="right-max-box scrollbar-box" v-if="versionField() != 'xiBeiNongLinDaXue'">
  89. <div class="all-title-box" style="height:40px;">
  90. <p></p>
  91. <p>传感器监测</p>
  92. <p>{{newData.sensorFunctionStatusList[0]?'数据上报时间:'+newData.sensorFunctionStatusList[0].sendDate:''}}</p>
  93. <p class="reset-button-one" @click="backPage">返回</p>
  94. </div>
  95. <p class="sensor-box" v-for="(item,index) in newData.sensorFunctionStatusList" :key="index">{{item.funcName}}:<span>{{item.formatVal}}</span></p>
  96. <img class="null-data-img" src="@/assets/ZDimages/null-data.png" v-if="!newData.sensorFunctionStatusList[0]">
  97. <p class="null-p" v-if="!newData.sensorFunctionStatusList[0]" >暂无环境监测信息,请在更多操作-物联设备配置中进行添加</p>
  98. <div class="all-title-box" style="height:40px;margin-top:20px;">
  99. <p></p>
  100. <p>物联控制</p>
  101. </div>
  102. <div class="things-box" v-for="(item,index) in newData.labHardwareVOListTwo" :key="item.id" v-if="item.hardwareTypeEnum.enumName == 'SWITCH'">
  103. <div class="things-for-box">
  104. <p class="left-title">{{item.hardwareName}}</p>
  105. <el-switch
  106. v-if="item.state.code == 3||item.state.code == 4"
  107. class="switch"
  108. @click.native="changeIsNeedCaptcha(item)"
  109. v-model="item.state.code"
  110. :active-value="3"
  111. :inactive-value="4"
  112. active-text="开"
  113. inactive-text="关"
  114. disabled>
  115. </el-switch>
  116. <p class="switch-null-p" v-else>{{item.state.name}}</p>
  117. </div>
  118. </div>
  119. <div class="things-box" v-for="(item,index) in newData.labHardwareVOListTwo" :key="item.id" v-if="item.hardwareTypeEnum.enumName == 'AI_VENTILATION'">
  120. <div class="things-for-box">
  121. <p class="left-title">{{item.hardwareName}}</p>
  122. <el-switch
  123. v-if="item.state.code == 3||item.state.code == 4"
  124. class="switch"
  125. @click.native="changeIsNeedCaptcha(item)"
  126. v-model="item.state.code"
  127. :active-value="3"
  128. :inactive-value="4"
  129. active-text="开"
  130. inactive-text="关"
  131. disabled>
  132. </el-switch>
  133. <p class="switch-null-p" v-else>{{item.state.name}}</p>
  134. </div>
  135. </div>
  136. <div class="things-box" v-for="(item,index) in newData.labHardwareVOListTwo" :key="item.id" v-if="item.hardwareTypeEnum.enumName == 'ONE_MACHINE'">
  137. <div class="things-for-box">
  138. <p class="left-title">广播系统</p>
  139. <p class="right-button" @click="handleAdd">播放文字</p>
  140. </div>
  141. </div>
  142. <img class="null-data-img" src="@/assets/ZDimages/null-data.png" v-if="!newData.labHardwareVOListTwo[0]">
  143. <p class="null-p" v-if="!newData.labHardwareVOListTwo[0]" >暂无物联控制信息,请在更多操作-物联设备配置中进行添加</p>
  144. <div class="all-title-box" style="height:40px;margin-top:10px;">
  145. <p></p>
  146. <p>危险源信息</p>
  147. </div>
  148. <div class="source-box">
  149. <span v-for="(item,index) in newData.hazardList" :key="index">{{index==0?item.label:'、'+item.label}}</span>
  150. </div>
  151. <img class="null-data-img" src="@/assets/ZDimages/null-data.png" v-if="!newData.hazardList[0]">
  152. <p class="null-p" v-if="!newData.hazardList[0]" >暂无危险源信息,请在更多操作-关联配置中进行添加</p>
  153. <div class="all-title-box" style="height:40px;margin-top:20px;">
  154. <p></p>
  155. <p>视频监控</p>
  156. </div>
  157. <div class="video-max-box">
  158. <div class="video-min-box" v-for="(item,index) in newData.videoData" :key="item.id">
  159. <video :id="item.divId" ref="videoRef" autoplay controls muted width="380"></video>
  160. <p class="el-icon-full-screen position-p" @click="videoFullScreen(index)"></p>
  161. <!--画中画-->
  162. <p class="video-all-button-2 el-icon-data-board" @click="requestPictureInPicture(index)"></p>
  163. <!--历史记录-->
  164. <p class="video-all-button-3 el-icon-date" @click="lookDialog"></p>
  165. </div>
  166. </div>
  167. <img class="null-data-img" src="@/assets/ZDimages/null-data.png" v-if="!newData.videoData[0]">
  168. <p class="null-p" v-if="!newData.videoData[0]" >暂无视频监控信息,请在更多操作-物联设备配置中进行添加</p>
  169. <div class="all-title-box" style="height:30px;">
  170. <p></p>
  171. <p>检查项信息</p>
  172. </div>
  173. <div class="inspection-box">
  174. <div style="display: flex">
  175. <div>
  176. <p>穿戴检查项:</p>
  177. <p>
  178. <span v-for="(item,index) in newData.safeInfo.checkInData">{{index==0?item:'、'+item}}</span>
  179. <span v-if="!newData.safeInfo.checkInData">未设置</span>
  180. </p>
  181. </div>
  182. <div style="margin-left:30px;">
  183. <p>穿戴检查可跳过:</p>
  184. <p>{{newData.skipped == '1'?'是':(newData.skipped == '0'?'否':'')}}</p>
  185. </div>
  186. <div style="margin-left:30px;" v-if="newData.skipped == 1">
  187. <p>穿戴检查识别上限:</p>
  188. <p>{{newData.checkCount?newData.checkCount:'未设置'}}</p>
  189. </div>
  190. </div>
  191. <div style="display: flex">
  192. <div>
  193. <p>重复签到限制时间:</p>
  194. <p>
  195. <span>二十四小时</span>
  196. </p>
  197. </div>
  198. <div style="margin-left:30px;">
  199. <p>离开检查项:</p>
  200. <p>
  201. <span v-for="(item,index) in newData.safeInfo.checkOutData">{{index==0?item:'、'+item}}</span>
  202. <span v-if="!newData.safeInfo.checkOutData">未设置</span>
  203. </p>
  204. </div>
  205. </div>
  206. </div>
  207. </div>
  208. <!--展示实验室二维码-->
  209. <el-dialog title="实验室二维码" :visible.sync="codeType" width="500px" append-to-body>
  210. <vue-qr style="display: block;height:460px;width:460px;cursor:pointer;margin:0 auto;" :text="newData.qrCodeUrl" :size="200"></vue-qr>
  211. </el-dialog>
  212. <!--播放文字窗口-->
  213. <el-dialog title="广播系统" :visible.sync="open" width="500px" append-to-body>
  214. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  215. <el-form-item label="播放文字" prop="txt">
  216. <el-input v-model="form.txt" placeholder="请输入播放文字" />
  217. </el-form-item>
  218. <el-form-item label="播报方式" prop="type">
  219. <el-radio-group v-model="form.type">
  220. <el-radio :label="1">文字</el-radio>
  221. <el-radio :label="2">音频</el-radio>
  222. </el-radio-group>
  223. </el-form-item>
  224. </el-form>
  225. <div slot="footer" class="dialog-footer">
  226. <el-button @click="cancel">取 消</el-button>
  227. <el-button type="primary" @click="submitFormOne">确 定</el-button>
  228. </div>
  229. </el-dialog>
  230. <el-dialog title="历史视频" v-if="dialogType"
  231. @close="close"
  232. :visible.sync="dialogType" width="1000px"
  233. append-to-body class="look-video-dialog-box">
  234. <div>
  235. <el-date-picker
  236. style="margin-right:20px;"
  237. v-model="datePicker"
  238. type="date"
  239. placeholder="选择日期"
  240. format="yyyy 年 MM 月 dd 日">
  241. </el-date-picker>
  242. <el-time-select
  243. style="margin-right:20px;"
  244. placeholder="起始时间"
  245. v-model="startTime"
  246. :picker-options="{
  247. start: '00:00',
  248. step: '01:00',
  249. end: '23:00',
  250. }">
  251. </el-time-select>
  252. <el-time-select
  253. style="margin-right:20px;"
  254. placeholder="结束时间"
  255. v-model="endTime"
  256. :picker-options="{
  257. start: '00:00',
  258. step: '01:00',
  259. end: '23:00',
  260. minTime: startTime
  261. }">
  262. </el-time-select>
  263. <el-button type="primary" style="height:40px;" @click="videoButtonLock(1)">确定</el-button>
  264. <el-button style="height:40px;" @click="videoButtonLock(2)">重置</el-button>
  265. </div>
  266. <div class="dialog-video-max-box">
  267. <p class="dialog-position-p"></p>
  268. <div class="dialog-video-max-left-box">
  269. <video controls width="730"
  270. autoplay muted
  271. :poster="videoCover" v-if="dialogVideoType">
  272. <source :src="videoUrl"
  273. type="video/webm">
  274. <source :src="videoUrl"
  275. type="video/mp4">
  276. </video>
  277. <i v-if="!videoUrl" style="display: inline-block;width:730px;line-height:200px;text-align: center;font-size:16px;color:#999">请选择视频</i>
  278. <!--<video class="video-box" ref="dialogVideoRef" :poster="videoCover"-->
  279. <!--v-if="dialogVideoType"-->
  280. <!--:url="videoUrl"-->
  281. <!--autoplay controls muted width="366px" height="210px"></video>-->
  282. </div>
  283. <div class="dialog-video-max-right-box scrollbar-box">
  284. <p :class="videoUrl == item.url?'check-p':''"
  285. v-if="item.type"
  286. @click="videoClick(item)"
  287. v-for="(item,index) in videoDataList" :key="index">{{item.name}}</p>
  288. <i v-if="nullType">暂无数据</i>
  289. </div>
  290. </div>
  291. </el-dialog>
  292. </div>
  293. </template>
  294. <script>
  295. import flvjs from 'flv.js'
  296. import { hardWareControl } from "@/api/laboratory/hardware";
  297. import { subjectInfo,mangerVoice } from "@/api/laboratory/subject";
  298. import vueQr from 'vue-qr'
  299. export default {
  300. name: "infoPage",
  301. components: {
  302. vueQr
  303. },
  304. props:{
  305. newData:{},
  306. },
  307. data() {
  308. return {
  309. // newData:{},
  310. //主要危险类别
  311. hazardCategory:[],
  312. //风险防控措施
  313. riskMeasure:[],
  314. //灭火要点
  315. extinguishingKeyPoints:[],
  316. //实验室二维码展示开关
  317. codeType:false,
  318. //播放文字的实验室id
  319. open:false,
  320. form:{},
  321. rules:{
  322. txt:[
  323. {required: true, message: '请输入播放文字', trigger: 'blur'},
  324. { required: true, message: "请输入播放文字", validator: this.spaceJudgment, trigger: "blur" }
  325. ],
  326. type:[
  327. {required: true, message: '请选择播报方式', trigger: 'blur'}
  328. ],
  329. },
  330. videoList:[],
  331. safetyInfoList:[],
  332. demoList:[
  333. {
  334. name:"大气压预案",
  335. num:"三次",
  336. time:"2021年6月1日 12:00",
  337. },
  338. {
  339. name:"VOC预案",
  340. num:"三次",
  341. time:"2021年6月5日 10:00",
  342. },
  343. {
  344. name:"烟感预案",
  345. num:"三次",
  346. time:"2021年6月7日 15:00",
  347. },
  348. ],
  349. dialogType:false,
  350. datePicker:null,
  351. startTime:null,
  352. endTime:null,
  353. videoDataList:[
  354. {
  355. name:"2023-06-21/18:00",
  356. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-21/18-38-49.mp4",
  357. type:true,
  358. },
  359. {
  360. name:"2023-06-22/18:00",
  361. url: "http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-21/18-43-08.mp4",
  362. type:true,
  363. },
  364. {
  365. name:"2023-06-25/10:00",
  366. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-36-09.mp4",
  367. type:true,
  368. },
  369. {
  370. name:"2023-06-26/10:00",
  371. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-42-26.mp4",
  372. type:true,
  373. },
  374. {
  375. name:"2023-06-25/10:00",
  376. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-47-58.mp4",
  377. type:true,
  378. },
  379. {
  380. name:"2023-06-25/11:00",
  381. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-49-50.mp4",
  382. type:true,
  383. },
  384. {
  385. name:"2023-06-25/12:00",
  386. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-50-29.mp4",
  387. type:true,
  388. },
  389. {
  390. name:"2023-06-25/13:00",
  391. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-50-58.mp4",
  392. type:true,
  393. },
  394. {
  395. name:"2023-06-25/14:00",
  396. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-51-09.mp4",
  397. type:true,
  398. },
  399. {
  400. name:"2023-06-25/15:00",
  401. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-25/10-51-26.mp4",
  402. type:true,
  403. },
  404. {
  405. name:"2023-06-26/16:00",
  406. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-26/10-19-55.mp4",
  407. type:true,
  408. },
  409. {
  410. name:"2023-06-26/17:00",
  411. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-26/10-20-34.mp4",
  412. type:true,
  413. },
  414. {
  415. name:"2023-06-26/10:00",
  416. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-26/10-21-19.mp4",
  417. type:true,
  418. },
  419. {
  420. name:"2023-06-26/10:00",
  421. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-26/10-22-04.mp4",
  422. type:true,
  423. },
  424. {
  425. name:"2023-06-26/14:00",
  426. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-26/14-59-04.mp4",
  427. type:true,
  428. },
  429. {
  430. name:"2023-06-26/15:00",
  431. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-06-26/15-33-20.mp4",
  432. type:true,
  433. },
  434. {
  435. name:"2023-07-12/10:00",
  436. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-07-12/10-26-33.mp4",
  437. type:true,
  438. },
  439. {
  440. name:"2023-07-12/10:00",
  441. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-07-12/10-32-55.mp4",
  442. type:true,
  443. },
  444. {
  445. name:"2023-07-12/10:00",
  446. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-07-12/10-36-12.mp4",
  447. type:true,
  448. },
  449. {
  450. name:"2023-07-12/08:00",
  451. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-07-12/10-41-21.mp4",
  452. type:true,
  453. },
  454. {
  455. name:"2023-07-12/14:00",
  456. url:"http://lab-demo.sxitdlc.com/statics/record/app192168164/stream192168164/2023-07-12/14-19-44.mp4",
  457. type:true,
  458. },
  459. ],
  460. videoUrl:null,
  461. dialogVideoType:false,
  462. nullType:false,
  463. }
  464. },
  465. created() {
  466. //主要危险类别
  467. this.getDicts("sys_hazard_category").then(response => {
  468. this.hazardCategory = response.data;
  469. });
  470. //风险防控措施
  471. this.getDicts("sys_risk_measure").then(response => {
  472. this.riskMeasure = response.data;
  473. });
  474. //灭火要点
  475. this.getDicts("sys_extinguishing_key_points").then(response => {
  476. this.extinguishingKeyPoints = response.data;
  477. });
  478. },
  479. mounted(){
  480. let self = this;
  481. setTimeout(function(){
  482. self.videoFunction();
  483. },500);
  484. },
  485. methods:{
  486. close(){
  487. this.$set(this,'dialogType',false);
  488. this.$set(this,'datePicker',null);
  489. this.$set(this,'startTime',null);
  490. this.$set(this,'endTime',null);
  491. this.$set(this,'videoUrl',null);
  492. this.$set(this,'dialogVideoType',false);
  493. this.$set(this,'nullType',false);
  494. },
  495. videoButtonLock(type){
  496. let self = this;
  497. if(type == 2){
  498. this.$set(this,'datePicker',null);
  499. this.$set(this,'startTime',null);
  500. this.$set(this,'endTime',null);
  501. for(let i=0;i<self.videoDataList.length;i++){
  502. self.$set(self.videoDataList[i],'type',true);
  503. }
  504. }else{
  505. let time = this.datePicker?this.parseTime(this.datePicker, '{y}-{m}-{d}'):'';
  506. let time1 = this.startTime;
  507. let time2 = this.endTime;
  508. if(time||time1||time2){
  509. let num = 0;
  510. for(let i=0;i<self.videoDataList.length;i++){
  511. if(time&&time1&&time2){
  512. let x = parseInt(self.videoDataList[i].name.split('/')[1].split(':')[0])
  513. let a = parseInt(time1.split(':')[0])
  514. let b = parseInt(time2.split(':')[0])
  515. if(self.videoDataList[i].name.indexOf(time) != -1 && x >= a && x <= b){
  516. self.videoDataList[i].type = true;
  517. }else{
  518. num++
  519. self.videoDataList[i].type = false;
  520. }
  521. }else if(time&&time1){
  522. let x = parseInt(self.videoDataList[i].name.split('/')[1].split(':')[0])
  523. let a = parseInt(time1.split(':')[0])
  524. if(self.videoDataList[i].name.indexOf(time) != -1 && x >= a){
  525. self.videoDataList[i].type = true;
  526. }else{
  527. num++
  528. self.videoDataList[i].type = false;
  529. }
  530. }else if(time&&time2){
  531. let x = parseInt(self.videoDataList[i].name.split('/')[1].split(':')[0])
  532. let b = parseInt(time2.split(':')[0])
  533. if(self.videoDataList[i].name.indexOf(time1) != -1 && x <= b){
  534. self.videoDataList[i].type = true;
  535. }else{
  536. num++
  537. self.videoDataList[i].type = false;
  538. }
  539. }else if(time1&&time2){
  540. let x = parseInt(self.videoDataList[i].name.split('/')[1].split(':')[0])
  541. let a = parseInt(time1.split(':')[0])
  542. let b = parseInt(time2.split(':')[0])
  543. if(x >= a && x <= b){
  544. self.videoDataList[i].type = true;
  545. }else{
  546. num++
  547. self.videoDataList[i].type = false;
  548. }
  549. }else if(time1){
  550. let x = parseInt(self.videoDataList[i].name.split('/')[1].split(':')[0])
  551. let a = parseInt(time1.split(':')[0])
  552. if(x >= a){
  553. self.videoDataList[i].type = true;
  554. }else{
  555. num++
  556. self.videoDataList[i].type = false;
  557. }
  558. }else if(time2){
  559. let x = parseInt(self.videoDataList[i].name.split('/')[1].split(':')[0])
  560. let b = parseInt(time2.split(':')[0])
  561. if(x <= b){
  562. self.videoDataList[i].type = true;
  563. }else{
  564. num++
  565. self.videoDataList[i].type = false;
  566. }
  567. }else if(time){
  568. if(self.videoDataList[i].name.indexOf(time) != -1){
  569. self.videoDataList[i].type = true;
  570. }else{
  571. num++
  572. self.videoDataList[i].type = false;
  573. }
  574. }
  575. }
  576. if(num == self.videoDataList.length){
  577. this.$set(this,'nullType',true);
  578. }else{
  579. this.$set(this,'nullType',false);
  580. }
  581. }
  582. }
  583. },
  584. videoClick(item){
  585. let self = this;
  586. this.$set(this,'dialogVideoType',false);
  587. this.$set(this,'videoUrl',item.url);
  588. setTimeout(function(){
  589. self.$set(self,'dialogVideoType',true);
  590. },300);
  591. },
  592. requestPictureInPicture(index){
  593. this.$refs.videoRef[index].requestPictureInPicture();
  594. },
  595. lookDialog(){
  596. this.$set(this,'dialogType',!this.dialogType);
  597. this.$set(this,'videoUrl',null);
  598. },
  599. //视频方法
  600. videoFunction(){
  601. let self = this;
  602. self.videoList = [];
  603. for(let i=0;i<self.newData.videoData.length;i++){
  604. let obj = {
  605. player :{},
  606. flvPlayer:{}
  607. };
  608. obj.player = document.getElementById(self.newData.videoData[i].divId);
  609. obj.flvPlayer = flvjs.createPlayer(
  610. {
  611. // isLive: true, //=> 是否为直播流
  612. // hasAudio: false, //=> 是否开启声音
  613. type: self.newData.videoData[i].videoType, //媒体类型 flv 或 mp4
  614. url: self.newData.videoData[i].url //视频流地址
  615. },
  616. {
  617. enableStashBuffer: true,//启用 IO 存储缓冲区。 如果您需要实时流播放(最小延迟),请设置为 false,但如果存在网络抖动,则可能会停止。
  618. stashInitialSize: 128,//IO 存储缓冲区初始大小。 默认值为 384KB。 指示合适的大小可以改善视频加载/搜索时间。
  619. isLive: true,//是否是直播
  620. lazyLoadRecoverDuration: 30,//指示以秒为单位的lazyLoad 恢复时间边界。
  621. autoCleanupSourceBuffer: true,//进行自动清理
  622. autoCleanupMaxBackwardDuration: 3 * 60,//3 * 60 当向后缓冲持续时间超过这个值(以秒为单位)时,对 SourceBuffer 进行自动清理
  623. autoCleanupMinBackwardDuration: 2 * 60,//2 * 60 指示在执行自动清理时为后向缓冲区保留的持续时间(以秒为单位)。
  624. }
  625. );
  626. self.videoList.push(obj);
  627. console.log("i",i)
  628. }
  629. for(let i=0;i<self.videoList.length;i++){
  630. self.videoList[i].flvPlayer.attachMediaElement(self.videoList[i].player);
  631. self.videoList[i].flvPlayer.load(); //加载
  632. self.videoList[i].flvPlayer.play(); //加载
  633. }
  634. },
  635. //视屏全屏方法
  636. videoFullScreen(index){
  637. this.$refs.videoRef[index].webkitRequestFullScreen();
  638. },
  639. //数据中心视频关闭
  640. videoOff(){
  641. let self = this;
  642. if(self.videoList[0]){
  643. for(let i=0;i<self.videoList.length;i++){
  644. self.videoList[i].flvPlayer.pause();
  645. self.videoList[i].flvPlayer.unload();
  646. self.videoList[i].flvPlayer.detachMediaElement();
  647. self.videoList[i].flvPlayer.destroy();
  648. self.videoList[i].flvPlayer = null;
  649. }
  650. self.videoList = [];
  651. }
  652. },
  653. //播放文字
  654. handleAdd() {
  655. this.open = true;
  656. },
  657. // 取消按钮
  658. cancel() {
  659. this.form = {};
  660. this.open = false;
  661. },
  662. /*播放文字*/
  663. submitFormOne(){
  664. this.$refs["form"].validate(valid => {
  665. if (valid) {
  666. let id = this.newData.id;
  667. mangerVoice(this.form,id).then(response => {
  668. this.msgSuccess("播放成功");
  669. this.open = false;
  670. });
  671. }
  672. });
  673. },
  674. //展示实验室二维码
  675. clickCode(){
  676. this.codeType = true;
  677. },
  678. // 开启关闭验证
  679. async changeIsNeedCaptcha (row) {
  680. let self = this;
  681. console.log(row)
  682. if(row.state.code!=3 && row.state.code!=4){
  683. return
  684. }
  685. let text = row.state.code==3?'关闭':(row.state.code==4?'开启':'')
  686. this.$confirm(`是否`+text+`此设备`, "提示", {
  687. confirmButtonText: "确定",
  688. cancelButtonText: "取消",
  689. type: "warning"
  690. }).then(async () => {
  691. self.switchChange(row)
  692. }).catch(() => {
  693. })
  694. },
  695. //开关按钮
  696. switchChange(row){
  697. let switchData = {
  698. id:row.id,
  699. switchVal:row.state.code==3?'close':(row.state.code==4?'open':'')
  700. };
  701. hardWareControl(switchData).then(response => {
  702. console.log(response);
  703. if(response.code==200){
  704. row.state.code = row.state.code==3?4:(row.state.code==4?3:'')
  705. this.msgSuccess("操作成功")
  706. }
  707. });
  708. },
  709. //返回上一页
  710. backPage(){
  711. this.$parent.clickPage(1);
  712. },
  713. },
  714. beforeDestroy() {
  715. //清除定时器
  716. let self = this;
  717. self.videoOff();
  718. console.log("beforeDestroy");
  719. },
  720. }
  721. </script>
  722. <style lang="scss" scoped>
  723. .infoPage{
  724. flex:1;
  725. display: flex;
  726. overflow: hidden;
  727. /*padding:5px 20px 20px 10px!important;*/
  728. *{
  729. margin:0;
  730. }
  731. .null-data-img{
  732. width:137px;
  733. height:137px;
  734. display: block;
  735. margin:10px auto;
  736. }
  737. .all-title-box{
  738. display: flex;
  739. height:18px;
  740. p{
  741. line-height:18px;
  742. }
  743. p:nth-child(1){
  744. width:4px;
  745. height:18px;
  746. margin-right:12px;
  747. background: #0045af;
  748. }
  749. p:nth-child(2){
  750. font-size:18px;
  751. color:#0045af;
  752. margin-right:28px;
  753. font-weight:700;
  754. }
  755. p:nth-child(3){
  756. font-size:14px;
  757. color:#999;
  758. flex:1;
  759. }
  760. p:nth-child(4){
  761. line-height:40px!important;
  762. }
  763. }
  764. .null-p{
  765. line-height:50px;
  766. text-align: center;
  767. font-size:14px;
  768. color:#999;
  769. }
  770. .left-max-box-flex{
  771. flex:1;
  772. }
  773. .left-max-box{
  774. font-weight:500;
  775. width:735px;
  776. display: flex;
  777. flex-direction: column;
  778. .top-max-box-flex{
  779. flex:1;
  780. }
  781. .top-max-box{
  782. border-radius:10px!important;
  783. box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1) !important;
  784. padding:20px;
  785. margin:5px 10px 20px 10px;
  786. .left-top-title-box{
  787. margin-top:13px;
  788. height:74px;
  789. display: flex;
  790. border-bottom:1px dashed #999999;
  791. .left-box{
  792. flex:1;
  793. .lv-name-box{
  794. height:34px;
  795. display: flex;
  796. p:nth-child(1){
  797. height:22px;
  798. line-height:20px;
  799. margin:6px 15px 0 0;
  800. font-size:12px;
  801. text-align: center;
  802. padding:0 8px;
  803. border-radius:4px;
  804. }
  805. p:nth-child(2){
  806. font-size:16px;
  807. height:34px;
  808. line-height:34px;
  809. color:#333;
  810. }
  811. }
  812. .type-address-box{
  813. display: flex;
  814. p{
  815. font-size:14px;
  816. height:40px;
  817. line-height:40px;
  818. color:#999;
  819. }
  820. p:nth-child(1){
  821. margin-right:40px;
  822. }
  823. }
  824. }
  825. .right-code-img{
  826. width:60px;
  827. height:60px;
  828. margin:0 10px 0 0;
  829. cursor: pointer;
  830. }
  831. }
  832. .user-max-box{
  833. margin-top:10px;
  834. .left-box{
  835. flex:1;
  836. display: flex;
  837. p{
  838. line-height: 32px;
  839. font-size:14px;
  840. flex:1;
  841. color:#333;
  842. span{
  843. color:#999;
  844. }
  845. }
  846. }
  847. .right-box{
  848. flex:1;
  849. display: inline-block;
  850. div{
  851. display: flex;
  852. p{
  853. margin-right:20px;
  854. line-height: 32px;
  855. font-size:14px;
  856. color:#333;
  857. span{
  858. color:#999;
  859. margin-right:20px;
  860. }
  861. }
  862. }
  863. }
  864. }
  865. .info-max-title-p{
  866. line-height:20px;
  867. font-size:16px;
  868. color:#333;
  869. font-weight:700;
  870. border-top:1px dashed #999999;
  871. padding-top:20px;
  872. margin-top:10px;
  873. }
  874. .info-max-box{
  875. margin-top:7px;
  876. display: flex;
  877. flex-wrap: wrap;
  878. .for-text-box{
  879. width:320px;
  880. .info-title{
  881. font-size:14px;
  882. color:#333;
  883. line-height:40px;
  884. font-weight:700;
  885. }
  886. .for-box{
  887. overflow: hidden;
  888. .for-info-p{
  889. line-height:16px;
  890. font-size:14px;
  891. color:#999;
  892. margin:7px 0;
  893. overflow: hidden;
  894. }
  895. }
  896. }
  897. .for-img-box{
  898. width:320px;
  899. .info-title{
  900. font-size:14px;
  901. color:#333;
  902. line-height:40px;
  903. font-weight:700;
  904. }
  905. img{
  906. width:37px;
  907. height:50px;
  908. margin:0 14px 14px 0;
  909. }
  910. }
  911. }
  912. }
  913. .bottom-max-box{
  914. border-radius:10px!important;
  915. box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1) !important;
  916. padding:20px;
  917. margin:0 10px 20px 10px;
  918. .for-list-box{
  919. margin-top:22px;
  920. .title-box{
  921. background: #F5F5F5;
  922. height:50px;
  923. line-height:50px;
  924. display: flex;
  925. p{
  926. flex:1;
  927. font-size:16px;
  928. color:#333;
  929. font-weight:700;
  930. }
  931. p:nth-child(1){
  932. margin-left:50px;
  933. }
  934. }
  935. .list-box:nth-child(2){
  936. border:none;
  937. }
  938. .list-box{
  939. border-top:1px solid #E0E0E0;
  940. height:40px;
  941. line-height:40px;
  942. display: flex;
  943. p{
  944. flex:1;
  945. font-size:14px;
  946. color:#999;
  947. }
  948. p:nth-child(1){
  949. margin-left:50px;
  950. }
  951. }
  952. }
  953. }
  954. }
  955. .right-max-box{
  956. font-weight:500;
  957. width:845px;
  958. border-radius:10px!important;
  959. box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1) !important;
  960. margin:5px 20px 20px 10px;
  961. padding:20px;
  962. .sensor-box{
  963. display: inline-block;
  964. font-size:14px;
  965. color:#333;
  966. line-height:34px;
  967. width:220px;
  968. span{
  969. color:#999;
  970. }
  971. }
  972. .things-box{
  973. width:210px;
  974. height:30px;
  975. display: inline-block;
  976. margin-bottom:10px;
  977. .things-for-box{
  978. display: flex;
  979. .left-title{
  980. width: 110px;
  981. font-size:14px;
  982. color:#333;
  983. line-height:30px;
  984. margin-right:10px;
  985. display:block;
  986. overflow:hidden;
  987. text-overflow:ellipsis;
  988. white-space:nowrap;
  989. }
  990. .switch{
  991. }
  992. .switch-null-p{
  993. font-size:14px;
  994. color:#999;
  995. line-height:30px;
  996. }
  997. .right-button{
  998. cursor: pointer;
  999. line-height:30px;
  1000. border-radius:6px;
  1001. border:1px solid #0045af;
  1002. color:#0045af;
  1003. font-size:14px;
  1004. text-align: center;
  1005. width:100px;
  1006. }
  1007. }
  1008. }
  1009. .source-box{
  1010. span{
  1011. font-size:14px;
  1012. line-height:18px;
  1013. color:#333;
  1014. }
  1015. }
  1016. .video-max-box{
  1017. .video-min-box{
  1018. display: inline-block;
  1019. overflow: hidden;
  1020. width:380px;
  1021. margin-bottom:20px;
  1022. margin-right:20px;
  1023. position: relative;
  1024. .position-p{
  1025. width:30px;
  1026. height:30px;
  1027. text-align: center;
  1028. line-height:30px;
  1029. font-size:18px;
  1030. position: absolute;
  1031. top:0;
  1032. right:0;
  1033. color:#fff;
  1034. cursor: pointer;
  1035. }
  1036. .video-all-button-2{
  1037. width:30px;
  1038. height:30px;
  1039. text-align: center;
  1040. line-height:30px;
  1041. position: absolute;
  1042. top:0;
  1043. right:30px;
  1044. color:#fff;
  1045. cursor: pointer;
  1046. }
  1047. .video-all-button-3{
  1048. width:30px;
  1049. height:30px;
  1050. text-align: center;
  1051. line-height:30px;
  1052. position: absolute;
  1053. top:0;
  1054. right:60px;
  1055. color:#fff;
  1056. cursor: pointer;
  1057. }
  1058. }
  1059. /*.video-min-box:nth-child(2n+0){*/
  1060. /*margin-left:20px;*/
  1061. /*}*/
  1062. }
  1063. .inspection-box{
  1064. div{
  1065. display: flex;
  1066. p:nth-child(1){
  1067. line-height:16px;
  1068. font-size:14px;
  1069. margin:11px 0;
  1070. color:#999;
  1071. }
  1072. p:nth-child(2){
  1073. flex:1;
  1074. line-height:16px;
  1075. font-size:14px;
  1076. margin:11px 0;
  1077. color:#333;
  1078. span{
  1079. color:#333;
  1080. }
  1081. }
  1082. }
  1083. }
  1084. }
  1085. .demo-max-box{
  1086. padding:20px;
  1087. .demo-title-box{
  1088. display: flex;
  1089. p{
  1090. flex:1;
  1091. color:#666;
  1092. font-size:16px;
  1093. line-height:30px;
  1094. }
  1095. }
  1096. .demo-text-box{
  1097. display: flex;
  1098. p{
  1099. flex:1;
  1100. color:#333;
  1101. font-size:14px;
  1102. line-height:30px;
  1103. }
  1104. }
  1105. }
  1106. }
  1107. </style>
  1108. <style lang="scss">
  1109. .look-video-dialog-box{
  1110. // 画中画
  1111. video::-webkit-media-controls-enclosure {
  1112. display: none;
  1113. }
  1114. // 音频开关
  1115. video::-webkit-media-controls-mute-button {
  1116. display: none;
  1117. }
  1118. // 音频大小
  1119. video::-webkit-media-controls-volume-slider {
  1120. display: none;
  1121. }
  1122. //全屏按钮
  1123. video::-webkit-media-controls-fullscreen-button {
  1124. display: none;
  1125. }
  1126. //开始暂停按钮
  1127. video::-webkit-media-controls-play-button {
  1128. display: none;
  1129. }
  1130. // 时间显示
  1131. video::-webkit-media-controls-current-time-display {
  1132. display: none;
  1133. }
  1134. // 未知时间
  1135. video::-webkit-media-controls-toggle-closed-captions-button {
  1136. display: none;
  1137. }
  1138. //进度条
  1139. video::-webkit-media-controls-timeline {
  1140. display: none;
  1141. }
  1142. //未知进度条
  1143. video::-webkit-media-controls-time-remaining-display {
  1144. display: none;
  1145. }
  1146. video {
  1147. object-fit: fill; //视频全铺
  1148. pointer-events: none; //点击禁用
  1149. }
  1150. .dialog-video-max-box{
  1151. display: flex;
  1152. height:410px;
  1153. margin:20px 0;
  1154. position: relative;
  1155. .dialog-position-p{
  1156. position: absolute;
  1157. top: 0;
  1158. left:0;
  1159. width: 730px;
  1160. height:30px;
  1161. background-color: #ffffff;
  1162. z-index:999;
  1163. }
  1164. .dialog-video-max-left-box{
  1165. flex:1;
  1166. }
  1167. .dialog-video-max-right-box{
  1168. width:200px;
  1169. p{
  1170. line-height:30px;
  1171. }
  1172. p:hover{
  1173. background-color: #0183fa;
  1174. color:#fff;
  1175. cursor: pointer;
  1176. }
  1177. .check-p{
  1178. color:#0183fa;
  1179. }
  1180. }
  1181. }
  1182. }
  1183. </style>