home.vue 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. <template>
  2. <!--<div class="home" :class="pageType == 2 ? 'homeAlarm':''">-->
  3. <div class="home">
  4. <div class="home-left-box">
  5. <div class="scale-box-big">
  6. <div class="scale-box">
  7. <p class="time-p">{{timeData}}</p>
  8. <resourceAndEquipmentStatistics></resourceAndEquipmentStatistics>
  9. <overviewOfInstrumentCondition></overviewOfInstrumentCondition>
  10. <reservationUsageRankings></reservationUsageRankings>
  11. </div>
  12. </div>
  13. </div>
  14. <!--<div class="max-null-p"></div>-->
  15. <div class="home-center-box">
  16. <div class="scale-comprehensiveData">
  17. <div class="scale-box">
  18. <!--中间屏幕统计组件-->
  19. <comprehensiveData v-if="pageType == 1 && !deptVideoType"></comprehensiveData>
  20. </div>
  21. </div>
  22. <!--常规展示层-->
  23. <div class="center-max-box" v-if="pageType == 1 && !deptVideoType">
  24. <div class="center-left-box">
  25. <div class="scale-center-box">
  26. <div class="scale-box">
  27. <laboratoryData></laboratoryData>
  28. <secondaryCollegeUnitLaboratoryStatistics></secondaryCollegeUnitLaboratoryStatistics>
  29. <overdueServiceEquipmentStatistics></overdueServiceEquipmentStatistics>
  30. </div>
  31. </div>
  32. </div>
  33. <div class="center-center-box">
  34. <div class="scale-center-box">
  35. <div class="scale-box">
  36. </div>
  37. </div>
  38. </div>
  39. <div class="center-right-box">
  40. <div class="scale-center-box">
  41. <div class="scale-box">
  42. <statisticalAnalysisOfHazardSources></statisticalAnalysisOfHazardSources>
  43. <statisticalAnalysisOfHazardousChemicals></statisticalAnalysisOfHazardousChemicals>
  44. </div>
  45. </div>
  46. </div>
  47. </div>
  48. </div>
  49. <!--<div class="max-null-p"></div>-->
  50. <div class="home-right-box">
  51. <div class="scale-box-big">
  52. <div class="scale-box">
  53. <div class="button-box">
  54. <p class="null-p"></p>
  55. <div>
  56. <p></p>
  57. <p></p>
  58. </div>
  59. </div>
  60. <laboratoryAnimalCenterReservationStatistics></laboratoryAnimalCenterReservationStatistics>
  61. <resourceReservationStatistics></resourceReservationStatistics>
  62. <sensorsAndIotDevices></sensorsAndIotDevices>
  63. </div>
  64. </div>
  65. </div>
  66. <!--报警层-->
  67. <alarmComponents class="alarm-max-box" :alarmPropsData="alarmPropsData" v-if="pageType == 2"></alarmComponents>
  68. <!--logo-->
  69. <img class="logo-img" @click="demo()" src="@/assets/ZDimages/logo@1x.png">
  70. <!--title-->
  71. <p class="title-top-center-box" @click="demo2()">实验室安全智慧化管控中心</p>
  72. <!--背景视频-->
  73. <video
  74. ref="videoPlayer"
  75. class="back_mp4"
  76. autoplay
  77. muted
  78. loop
  79. playsinline
  80. >
  81. <source src="@/assets/video/max_back_4.webm" type="video/webm">
  82. 您的浏览器不支持视频标签.
  83. </video>
  84. <!--报警音频-->
  85. <audio class="waring_mp3" ref="audioPlayer" loop muted autoplay v-if="pageType == 2&&audioType">
  86. <source src="@/assets/video/waringVoice1.mp3" type="audio/mpeg">
  87. </audio>
  88. <!--左侧遮罩-->
  89. <div class="back-l-img"></div>
  90. <!--右侧遮罩-->
  91. <div class="back-r-img"></div>
  92. <!--地图层南校区-->
  93. <div class="map-max-big-box">
  94. <canvasMap ref="canvasMap" class="map-box"></canvasMap>
  95. </div>
  96. <!--左侧报警提示-->
  97. <div class="left-alarm-max-big-box" v-if="pageType == 2">
  98. <div>
  99. <p v-for="(item,index) in alarmTitle" :key="index">{{item}}</p>
  100. </div>
  101. </div>
  102. <!--右侧报警提示-->
  103. <div class="right-alarm-max-big-box" v-if="pageType == 2">
  104. <div>
  105. <p v-for="(item,index) in alarmTitle" :key="index">{{item}}</p>
  106. </div>
  107. </div>
  108. <!--视频监控退出-->
  109. <img class="position-button-0" v-if="deptVideoType" src="@/assets/ZDimages/icon_jksp_fh@1x.png" @click="goPage(1)">
  110. <!--静音按钮-->
  111. <img class="position-button-1" v-if="!audioType" src="@/assets/ZDimages/icon_yj_gbsy@1x.png" @click="audioButton">
  112. <!--未静音按钮-->
  113. <img class="position-button-2" v-if="audioType" src="@/assets/ZDimages/icon_yj_kqsy@1x.png" @click="audioButton">
  114. <!--全屏按钮-->
  115. <img class="position-button-3" v-if="fullType" src="@/assets/ZDimages/icon_yj_sf@1x.png" @click="fullButton">
  116. <!--未全屏按钮-->
  117. <img class="position-button-4" v-if="!fullType" src="@/assets/ZDimages/icon_yj_qp@1x.png" @click="fullButton">
  118. <div class="position-button-5" @click="goPage(1)">
  119. <img src="@/assets/ZDimages/icon_sy_spjk@1x.png">
  120. <p>实时监控</p>
  121. </div>
  122. <div class="position-button-6" @click="goPage(2)">
  123. <img src="@/assets/ZDimages/icon_sy_zcpt@1x.png">
  124. <p>三维模型</p>
  125. </div>
  126. <!--视频监控-->
  127. <div class="dept-video-max-box" v-if="pageType == 1 && deptVideoType">
  128. <div class="dept-video-box">
  129. <videoSurveillance></videoSurveillance>
  130. </div>
  131. </div>
  132. </div>
  133. </template>
  134. <script>
  135. import mqtt from 'mqtt'
  136. import { getToken,removeToken } from '@/utils/auth'
  137. import {
  138. laboratoryBigViewSelectTriggerInfo,
  139. } from "@/api/index";
  140. //左侧组件
  141. import resourceAndEquipmentStatistics from "@/views/leftMaxBox/resourceAndEquipmentStatistics/index.vue";
  142. import overviewOfInstrumentCondition from "@/views/leftMaxBox/overviewOfInstrumentCondition/index.vue";
  143. import reservationUsageRankings from "@/views/leftMaxBox/reservationUsageRankings/index.vue";
  144. //右侧组件
  145. import laboratoryAnimalCenterReservationStatistics from "@/views/rightMaxBox/laboratoryAnimalCenterReservationStatistics/index.vue";
  146. import resourceReservationStatistics from "@/views/rightMaxBox/resourceReservationStatistics/index.vue";
  147. import sensorsAndIotDevices from "@/views/rightMaxBox/sensorsAndIotDevices/index.vue";
  148. //中间组件
  149. import comprehensiveData from "@/views/cengterMaxBox/comprehensiveData/index.vue";
  150. import laboratoryData from "@/views/cengterMaxBox/laboratoryData/index.vue";
  151. import secondaryCollegeUnitLaboratoryStatistics from "@/views/cengterMaxBox/secondaryCollegeUnitLaboratoryStatistics/index.vue";
  152. import overdueServiceEquipmentStatistics from "@/views/cengterMaxBox/overdueServiceEquipmentStatistics/index.vue";
  153. import statisticalAnalysisOfHazardSources from "@/views/cengterMaxBox/statisticalAnalysisOfHazardSources/index.vue";
  154. import statisticalAnalysisOfHazardousChemicals from "@/views/cengterMaxBox/statisticalAnalysisOfHazardousChemicals/index.vue";
  155. import alarmComponents from "@/views/cengterMaxBox/alarmComponents/index.vue";
  156. import videoSurveillance from "@/views/cengterMaxBox/videoSurveillance/index.vue";
  157. //地图模型组件
  158. import canvasMap from "@/views/cengterMaxBox/canvasMap/index.vue";
  159. export default {
  160. name: 'home',
  161. components: {
  162. //左侧组件
  163. resourceAndEquipmentStatistics,
  164. overviewOfInstrumentCondition,
  165. reservationUsageRankings,
  166. //右侧组件
  167. laboratoryAnimalCenterReservationStatistics,
  168. resourceReservationStatistics,
  169. sensorsAndIotDevices,
  170. //中间组件
  171. comprehensiveData,
  172. laboratoryData,
  173. secondaryCollegeUnitLaboratoryStatistics,
  174. overdueServiceEquipmentStatistics,
  175. statisticalAnalysisOfHazardSources,
  176. statisticalAnalysisOfHazardousChemicals,
  177. alarmComponents,
  178. videoSurveillance,
  179. //地图模型组件
  180. canvasMap,
  181. },
  182. data () {
  183. return {
  184. rectangleLogo:localStorage.getItem('rectangleLogo'),
  185. // 时间
  186. timeData:null,
  187. // 定时器
  188. timer:null,
  189. //页面
  190. pageType:1,
  191. //全屏状态
  192. fullType:true,
  193. //播放报警音状态
  194. audioType:false,
  195. //预案MQTT
  196. planOpic:'lab/risk/plan/change',
  197. planClient:{},
  198. //预案数据
  199. alarmPropsData:{},
  200. //校区模型关系
  201. schoolModelList:[
  202. // {school:'B', name:'5号楼', buildId:'101093843117592833',buildIdList:[],},
  203. {school:'B', name:'6B教学楼', buildId:'101093843117592815',buildIdList:[],},
  204. {school:'B', name:'中心实验楼', buildId:'101093843117592829',buildIdList:[],},
  205. {school:'B', name:'信息工程学院教学楼', buildId:'101093843117592812',buildIdList:[],},
  206. {school:'B', name:'养虫楼', buildId:'101093843117592805',buildIdList:[],},
  207. {school:'B', name:'农业机械实验室平房', buildId:'101093843117592807',buildIdList:[],},
  208. {school:'B', name:'农药研究所', buildId:'101093843117592804',buildIdList:[],},
  209. {school:'B', name:'动物中心B座', buildId:'101093843117592785',buildIdList:[],},
  210. {school:'B', name:'动物中心实验楼A', buildId:'101093843117592765',buildIdList:[],},
  211. {school:'B', name:'动物中心实验楼B', buildId:'101093843117592764',buildIdList:[],},
  212. {school:'B', name:'动物科技学院楼', buildId:'101093843117592831',buildIdList:[],},
  213. {school:'B', name:'动科楼', buildId:'101093843117592832',buildIdList:[],},
  214. {school:'B', name:'北1号教学楼', buildId:'101093843117592802',buildIdList:[],},
  215. {school:'B', name:'北2号教学楼', buildId:'101093843117592813',buildIdList:[],},
  216. {school:'B', name:'北3号教学楼', buildId:'101093843117592782',buildIdList:[],},
  217. {school:'B', name:'北4号教学楼', buildId:'101093843117592781',buildIdList:[],},
  218. {school:'B', name:'北5号教学楼', buildId:'101093843117592783',buildIdList:['101093843117592783','101093843117592833'],},
  219. {school:'B', name:'北6号教学楼', buildId:'101093843117592814',buildIdList:[],},
  220. {school:'B', name:'北7号教学楼', buildId:'101093843117592816',buildIdList:[],},
  221. {school:'B', name:'危化品服务中心', buildId:'101093843117592826',buildIdList:[],},
  222. // {school:'B', name:'原农一站办公楼', buildId:'101093843117592811',buildIdList:[],},
  223. // {school:'B', name:'工程训练中心楼', buildId:'101093843117592808',buildIdList:[],},
  224. // {school:'B', name:'教学办公楼', buildId:'101093843117592806',buildIdList:[],},
  225. // {school:'B', name:'未知实验室 ',buildId:'1855791848753147906',buildIdList:[],},
  226. // {school:'B', name:'机械及液压实验室平房', buildId:'101093843117592810',buildIdList:[],},
  227. {school:'B', name:'机电锻铸车间', buildId:'101093843117592809',buildIdList:['101093843117592809','101093843117592811','101093843117592808','101093843117592806','1855791848753147906','101093843117592810'],},
  228. // {school:'B', name:'水利与建筑工程学院', buildId:'101093843117592788',buildIdList:[],},
  229. // {school:'B', name:'水利与建筑工程学院A', buildId:'101093843117592766',buildIdList:[],},
  230. // {school:'B', name:'水利与建筑工程学院B', buildId:'101093843117592768',buildIdList:[],},
  231. // {school:'B', name:'水利与建筑工程学院C', buildId:'101093843117592769',buildIdList:[],},
  232. // {school:'B', name:'水利与建筑工程学院D', buildId:'101093843117592767',buildIdList:[],},
  233. {school:'B', name:'水工厅', buildId:'1871736666456633346',buildIdList:['1871736666456633346','101093843117592788','101093843117592766','101093843117592768','101093843117592769','101093843117592767'],},
  234. {school:'B', name:'水工水力学实验大厅', buildId:'1871729400227606529',buildIdList:[],},
  235. {school:'B', name:'理科综合实验楼A', buildId:'101093843117592774',buildIdList:['101093843117592774','101093843117592779','101093843117592775','101093843117592776','101093843117592780'],},
  236. // {school:'B', name:'理科综合实验楼B', buildId:'101093843117592779',buildIdList:[],},
  237. // {school:'B', name:'理科综合实验楼C', buildId:'101093843117592775',buildIdList:[],},
  238. // {school:'B', name:'理科综合实验楼D', buildId:'101093843117592776',buildIdList:[],},
  239. // {school:'B', name:'理科综合实验楼E', buildId:'101093843117592780',buildIdList:[],},
  240. {school:'B', name:'老昆虫博物馆', buildId:'101093843117592786',buildIdList:[],},
  241. {school:'B', name:'食品楼', buildId:'101093843117592789',buildIdList:['101093843117592789','101093843117592771','101093843117592770','101093843117592772','101093843117592773'],},
  242. // {school:'B', name:'食品楼A', buildId:'101093843117592771',buildIdList:[],},
  243. // {school:'B', name:'食品楼B', buildId:'101093843117592770',buildIdList:[],},
  244. // {school:'B', name:'食品楼C', buildId:'101093843117592772',buildIdList:[],},
  245. // {school:'B', name:'食品楼D', buildId:'101093843117592773',buildIdList:[],},
  246. {school:'N', name:'农科楼(农学院)', buildId:'101084081109864872',buildIdList:['101084081109864872','101084081109864874','101084081109864873','101093843117592803'],},
  247. // {school:'N', name:'农科楼(园艺学院)', buildId:'101084081109864874',buildIdList:[],},
  248. // {school:'N', name:'农科楼(植物保护学院)', buildId:'101084081109864873',buildIdList:[],},
  249. // {school:'N', name:'农科楼(资源环境学院)', buildId:'101093843117592803',buildIdList:[],},
  250. {school:'N', name:'农科院子校教学楼(初中)', buildId:'101093843117592823',buildIdList:[],},
  251. {school:'N', name:'南2号教学楼', buildId:'101093843117592817',buildIdList:[],},
  252. {school:'N', name:'南3号教学楼', buildId:'101093843117592820',buildIdList:[],},
  253. {school:'N', name:'南校子校楼', buildId:'101093843117592800',buildIdList:[],},
  254. {school:'N', name:'南校水保楼', buildId:'101093843117592801',buildIdList:[],},
  255. {school:'N', name:'家畜生物学重点实验室楼', buildId:'101093843117592787',buildIdList:[],},
  256. {school:'N', name:'木艺坊', buildId:'101093843117592819',buildIdList:[],},
  257. {school:'N', name:'林学院实验楼', buildId:'101093843117592818',buildIdList:[],},
  258. {school:'N', name:'科研主楼', buildId:'101093843117592784',buildIdList:[],},
  259. {school:'N', name:'科研楼', buildId:'101093843117592822',buildIdList:[],},
  260. {school:'N', name:'经管园林楼(文科楼)A', buildId:'101093843117592777',buildIdList:[],},
  261. {school:'N', name:'经管园林楼(文科楼)C', buildId:'101093843117592778',buildIdList:[],},
  262. {school:'N', name:'草业与草原楼', buildId:'101093843117592825',buildIdList:[],},
  263. {school:'N', name:'进学院实验楼', buildId:'101093843117592821',buildIdList:[],},
  264. {school:'旱研院校区', name:'农一站科研楼', buildId:'101093843117592827',buildIdList:[],},
  265. {school:'旱研院校区', name:'农机一站平房', buildId:'101093843117592828',buildIdList:[],},
  266. {school:'校外', name:'农三站科研办公楼', buildId:'101093843117592790',buildIdList:[],},
  267. {school:'校外', name:'器材楼', buildId:'101093843117592792',buildIdList:[],},
  268. {school:'水保所校区', name:'人工降雨实验大厅', buildId:'101093843117592793',buildIdList:[],},
  269. {school:'水保所校区', name:'南校区农科楼', buildId:'101093843117592799',buildIdList:[],},
  270. {school:'水保所校区', name:'国家重点实验室西楼', buildId:'101093843117592798',buildIdList:[],},
  271. {school:'水保所校区', name:'水保所人工干旱环境气候室工程', buildId:'101093843117592795',buildIdList:[],},
  272. {school:'水保所校区', name:'水保所国家重点实验室楼', buildId:'101093843117592794',buildIdList:[],},
  273. {school:'水保所校区', name:'水保所科研大楼', buildId:'101093843117592797',buildIdList:[],},
  274. {school:'水保所校区', name:'水保所西区科研楼', buildId:'101093843117592796',buildIdList:[],},
  275. {school:'老附中校区', name:'附中实验楼', buildId:'101093843117592830',buildIdList:[],},
  276. {school:'老附中校区', name:'附中教学楼', buildId:'101093843117592791',buildIdList:[],},
  277. ],
  278. //最新报警文字
  279. alarmTitle:'',
  280. //视频监控页面状态
  281. deptVideoType:false,
  282. }
  283. },
  284. created(){
  285. // if(!getToken()){
  286. // this.$router.push({path:'/'});
  287. // }
  288. },
  289. mounted(){
  290. //时间
  291. this.timeFunction();
  292. //判断是否已有预警MQTT链接
  293. if(!this.planClient.unsubscribe){
  294. this.offPlanMQTT('on');
  295. }
  296. //查询是否有预案发生
  297. this.laboratoryBigViewSelectTriggerInfo();
  298. //全屏窗口变化
  299. window.onresize = () => {
  300. if(window.innerWidth == 11520 && window.innerHeight == 2160){
  301. this.$set(this,'fullType',true);
  302. }else if(window.innerWidth == 1920 && window.innerHeight == 1080){
  303. this.$set(this,'fullType',true);
  304. }else{
  305. this.$set(this,'fullType',false);
  306. }
  307. }
  308. },
  309. methods:{
  310. demo(){
  311. let list = [
  312. {
  313. eventId: "1888781767708901377",
  314. eventName: "温度1预案预警",
  315. subName: "test样品制备室1",
  316. riskPlanId: null,
  317. riskPlanName: "1温度预案",
  318. riskPlanLevel: 1,
  319. riskReason: "【实验室安全系统】test样品制备室1-公司温度传感器数值异常,请立即核实处理!",
  320. ifCheck: false,
  321. eventStartTime: "2025-02-10T10:47:20",
  322. riskAttribute: "0",
  323. triggerUploadData: "[{\"code\":\"wd\",\"deviceId\":1859497698701836289,\"deviceName\":\"公司温度传感器\",\"deviceNo\":\"123\",\"deviceValue\":20.7,\"lastOnlineTime\":\"2025-02-10T10:47:19.903\",\"online\":true,\"unit\":\"℃\"}]",
  324. deptId: null,
  325. deptName: "葡酒学院",
  326. deptShortName: null,
  327. schoolId: null,
  328. schoolName: "第零个",
  329. buildId: "101093843117592825",
  330. // buildId: "101084081109864872",
  331. buildName: "S科研主楼",
  332. floorId: "17263016944919323",
  333. floorName: "1层",
  334. roomNum: "1301B",
  335. subId: "1400700979543928834",
  336. infoId: "172731652135310",
  337. eventStartTimestamp: 1739155640,
  338. classLevelName: "Ⅰ级",
  339. classLevelColor: "#DE0000",
  340. classTypeNames: "生物类"
  341. },
  342. {
  343. eventId: "1888781767708901377",
  344. eventName: "温度2预案预警",
  345. subName: "test样品制备室1",
  346. riskPlanId: null,
  347. riskPlanName: "2温度预案",
  348. riskPlanLevel: 1,
  349. riskReason: "【实验室安全系统】test样品制备室1-公司温度传感器数值异常,请立即核实处理!",
  350. ifCheck: false,
  351. eventStartTime: "2025-02-10T10:47:20",
  352. riskAttribute: "0",
  353. triggerUploadData: "[{\"code\":\"wd\",\"deviceId\":1859497698701836289,\"deviceName\":\"公司温度传感器\",\"deviceNo\":\"123\",\"deviceValue\":20.7,\"lastOnlineTime\":\"2025-02-10T10:47:19.903\",\"online\":true,\"unit\":\"℃\"}]",
  354. deptId: null,
  355. deptName: "葡酒学院",
  356. deptShortName: null,
  357. schoolId: null,
  358. schoolName: "第一个",
  359. buildId: "101093843117592787",
  360. // buildId: "101093843117592833",
  361. buildName: "S科研主楼",
  362. floorId: "17263016944919323",
  363. floorName: "1层",
  364. roomNum: "1301B",
  365. subId: "1400700979543928834",
  366. infoId: "172731652135310",
  367. eventStartTimestamp: 1739155640,
  368. classLevelName: "Ⅰ级",
  369. classLevelColor: "#DE0000",
  370. classTypeNames: "生物类"
  371. },
  372. {
  373. eventId: "1888781767708901377",
  374. eventName: "温度3预案预警",
  375. subName: "test样品制备室1",
  376. riskPlanId: null,
  377. riskPlanName: "3温度预案",
  378. riskPlanLevel: 1,
  379. riskReason: "【实验室安全系统】test样品制备室1-公司温度传感器数值异常,请立即核实处理!",
  380. ifCheck: false,
  381. eventStartTime: "2025-02-10T10:47:20",
  382. riskAttribute: "0",
  383. triggerUploadData: "[{\"code\":\"wd\",\"deviceId\":1859497698701836289,\"deviceName\":\"公司温度传感器\",\"deviceNo\":\"123\",\"deviceValue\":20.7,\"lastOnlineTime\":\"2025-02-10T10:47:19.903\",\"online\":true,\"unit\":\"℃\"}]",
  384. deptId: null,
  385. deptName: "葡酒学院",
  386. deptShortName: null,
  387. schoolId: null,
  388. schoolName: "第二个",
  389. buildId: "101093843117592787",
  390. // buildId: "101093843117592833",
  391. buildName: "S科研主楼",
  392. floorId: "17263016944919323",
  393. floorName: "1层",
  394. roomNum: "1301B",
  395. subId: "1400700979543928834",
  396. infoId: "172731652135310",
  397. eventStartTimestamp: 1739155640,
  398. classLevelName: "Ⅰ级",
  399. classLevelColor: "#DE0000",
  400. classTypeNames: "生物类"
  401. },
  402. {
  403. eventId: "1888781767708901377",
  404. eventName: "温度4预案预警",
  405. subName: "22222222222222",
  406. riskPlanId: null,
  407. riskPlanName: "4温度预案",
  408. riskPlanLevel: 1,
  409. riskReason: "【实验室安全系统】test样品制备室1-公司温度传感器数值异常,请立即核实处理!",
  410. ifCheck: false,
  411. eventStartTime: "2025-02-10T10:47:20",
  412. riskAttribute: "0",
  413. triggerUploadData: "[{\"code\":\"wd\",\"deviceId\":1859497698701836289,\"deviceName\":\"公司温度传感器\",\"deviceNo\":\"123\",\"deviceValue\":20.7,\"lastOnlineTime\":\"2025-02-10T10:47:19.903\",\"online\":true,\"unit\":\"℃\"}]",
  414. deptId: null,
  415. deptName: "葡酒学院",
  416. deptShortName: null,
  417. schoolId: null,
  418. schoolName: "第三个",
  419. buildId: "101093843117592787",
  420. // buildId: "101093843117592833",
  421. buildName: "S科研主楼",
  422. floorId: "17263016944919323",
  423. floorName: "1层",
  424. roomNum: "1301B",
  425. subId: "1400700979543928834",
  426. infoId: "172731652135310",
  427. eventStartTimestamp: 1739155640,
  428. classLevelName: "Ⅰ级",
  429. classLevelColor: "#DE0000",
  430. classTypeNames: "生物类"
  431. },
  432. ]
  433. this.$refs['canvasMap'].alarmTrigger(list,list[list.length-1],'N');
  434. },
  435. demo2(){
  436. this.$refs['canvasMap'].alarmOff();
  437. },
  438. openBackManageUrl(){
  439. this.$confirm('确定注销并退出系统吗?', '提示', {
  440. confirmButtonText: '确定',
  441. cancelButtonText: '取消',
  442. type: 'warning'
  443. }).then(() => {
  444. removeToken();
  445. localStorage.removeItem('schoolToken');
  446. this.$router.push({path:'/'});
  447. }).catch(() => {});
  448. },
  449. goPage(type){
  450. //报警期间禁止操作
  451. if(this.pageType == 2){
  452. return
  453. }
  454. if (type == 1){
  455. this.$set(this,'deptVideoType',!this.deptVideoType);
  456. }else if(type == 2){
  457. window.open('https://zcsjpt-szls.nwafu.edu.cn/')
  458. }
  459. },
  460. //预案-MQTT连接
  461. offPlanMQTT(type){
  462. let self = this;
  463. if(self.planClient.unsubscribe){
  464. self.planClient.unsubscribe(self.planOpic, error => {
  465. if (error) {
  466. // console.log('mqtt关闭连接错误:', error)
  467. }
  468. })
  469. self.planClient.end();
  470. this.$set(this,'planClient',{});
  471. }
  472. //判断传入参数如果存在 发起一次新的连接
  473. if(type){
  474. this.planMQTT();
  475. }
  476. },
  477. //预案-MQTT订阅
  478. planMQTT(){
  479. let self = this;
  480. this.planClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
  481. username: localStorage.getItem('mqttUser'),
  482. password:localStorage.getItem('mqttPassword')
  483. });
  484. this.planClient.on("connect", e =>{
  485. this.planClient.subscribe(self.planOpic, (err) => {
  486. if (!err) {
  487. // console.log("预案-订阅成功:" + self.planOpic);
  488. }else{
  489. // console.log("预案-连接错误:" + err);
  490. }
  491. });
  492. });
  493. this.planClient.on("message", (topic, message) => {
  494. if (message){
  495. //获取预案数据
  496. this.laboratoryBigViewSelectTriggerInfo();
  497. }
  498. });
  499. },
  500. //查询当前正在发生的预案
  501. laboratoryBigViewSelectTriggerInfo(){
  502. let self = this;
  503. laboratoryBigViewSelectTriggerInfo().then(response => {
  504. if(response.data[0]){
  505. response.data.forEach((item)=>{
  506. item.triggerUploadData = JSON.parse(item.triggerUploadData);
  507. item.alarmText = item.riskPlanName.split('预案');
  508. item.alarmText = item.alarmText[0].split('预警');
  509. item.alarmText = item.alarmText[0]+'预警';
  510. //修正楼栋ID用于匹配本地数据
  511. self.schoolModelList.forEach((minItem)=>{
  512. if(minItem.buildIdList[0]){
  513. minItem.buildIdList.forEach((minItemMin)=>{
  514. if(item.buildId == minItemMin){
  515. item.buildId = minItem.buildId;
  516. }
  517. })
  518. }
  519. })
  520. })
  521. //报警提示title信息
  522. this.$set(this,'alarmTitle',response.data[response.data.length-1].alarmText);
  523. //报警窗口数据
  524. this.$set(this,'alarmPropsData',response.data[response.data.length-1]);
  525. //报警窗口开启
  526. this.$set(this,'pageType',2);
  527. //判断报警楼栋属于南北校区
  528. setTimeout(function(){
  529. self.schoolModelList.forEach((item)=>{
  530. if(item.buildId == response.data[response.data.length-1].buildId){
  531. self.$refs['canvasMap'].alarmTrigger(response.data,response.data[response.data.length-1],item.school);
  532. }
  533. })
  534. },500);
  535. //报警声音
  536. if(this.audioType){
  537. /* 报警音频播放 */
  538. const audio = this.$refs.audioPlayer;
  539. // 尝试静音自动播放
  540. audio.play().catch(() => {
  541. // 如果失败,延迟 2 秒再次尝试(趁浏览器未完全冻结)
  542. setTimeout(() => audio.play(), 2000);
  543. });
  544. // 延迟 3 秒后尝试取消静音(需浏览器允许)
  545. setTimeout(() => {
  546. audio.muted = false;
  547. }, 3000);
  548. }
  549. }else{
  550. //报警结束
  551. this.$set(this,'pageType',1);
  552. setTimeout(function(){
  553. self.$refs['canvasMap'].alarmOff();
  554. },500);
  555. }
  556. })
  557. },
  558. //时间定时器
  559. timeFunction(){
  560. let self = this;
  561. this.timer = window.setInterval(showTime, 1000);
  562. function showTime() {
  563. const date = new Date();
  564. let dayOfWeekName = '';
  565. let dayOfWeek = date.getDay();
  566. if (dayOfWeek === 0) {
  567. dayOfWeekName = "星期日"
  568. } else if (dayOfWeek === 1) {
  569. dayOfWeekName = "星期一";
  570. } else if (dayOfWeek === 2) {
  571. dayOfWeekName = "星期二";
  572. } else if (dayOfWeek === 3) {
  573. dayOfWeekName = "星期三";
  574. } else if (dayOfWeek === 4) {
  575. dayOfWeekName = "星期四";
  576. } else if (dayOfWeek === 5) {
  577. dayOfWeekName = "星期五";
  578. } else if (dayOfWeek === 6) {
  579. dayOfWeekName = "星期六";
  580. }
  581. const y = date.getFullYear().toString();
  582. const m = (date.getMonth() + 1).toString().padStart(2, '0');
  583. const d = date.getDate().toString().padStart(2, '0');
  584. const hours = date.getHours().toString().padStart(2, '0');
  585. const minutes = date.getMinutes().toString().padStart(2, '0');
  586. const seconds = date.getSeconds().toString().padStart(2, '0');
  587. self.$set(self,'timeData',y+'-'+m+'-'+d+' '+dayOfWeekName+' '+hours+':'+minutes+':'+seconds);
  588. }
  589. },
  590. //音频播放相关
  591. audioButton(){
  592. this.$set(this,'audioType',!this.audioType);
  593. if(this.pageType==2 && this.audioType){
  594. /* 报警音频播放 */
  595. const audio = this.$refs.audioPlayer;
  596. // 尝试静音自动播放
  597. audio.play().catch(() => {
  598. // 如果失败,延迟 2 秒再次尝试(趁浏览器未完全冻结)
  599. setTimeout(() => audio.play(), 2000);
  600. });
  601. // 延迟 3 秒后尝试取消静音(需浏览器允许)
  602. setTimeout(() => {
  603. audio.muted = false;
  604. }, 3000);
  605. }
  606. },
  607. //全屏按钮
  608. fullButton(){
  609. if (this.fullType){
  610. this.exitFullscreen();
  611. } else {
  612. this.fullScreen();
  613. }
  614. },
  615. //全屏
  616. fullScreen() {
  617. let element = document.documentElement;
  618. if (element.requestFullscreen) {
  619. element.requestFullscreen();
  620. } else if (element.msRequestFullscreen) {
  621. element.msRequestFullscreen();
  622. } else if (element.mozRequestFullScreen) {
  623. element.mozRequestFullScreen();
  624. } else if (element.webkitRequestFullscreen) {
  625. element.webkitRequestFullscreen();
  626. }
  627. },
  628. //退出全屏
  629. exitFullscreen() {
  630. if (document.exitFullscreen) {
  631. document.exitFullscreen();
  632. } else if (document.msExitFullscreen) {
  633. document.msExitFullscreen();
  634. } else if (document.mozCancelFullScreen) {
  635. document.mozCancelFullScreen();
  636. } else if (document.webkitExitFullscreen) {
  637. document.webkitExitFullscreen();
  638. }
  639. },
  640. },
  641. beforeDestroy() {
  642. let self = this;
  643. //清除定时器
  644. window.clearInterval(self.timer);
  645. //清除全屏窗口变化
  646. window.onresize = null
  647. // MQTT预警
  648. self.offPlanMQTT();
  649. },
  650. destroyed() {
  651. //清除定时器
  652. window.clearInterval(this.timer);
  653. //清除全屏窗口变化
  654. window.onresize = null
  655. }
  656. }
  657. </script>
  658. <style scoped lang="scss">
  659. .home{
  660. width: 11520px;
  661. height: 2160px;
  662. flex:1;
  663. display: flex;
  664. background-color: #01060C;
  665. position: relative;
  666. /*transform:scale(0.7714285);*/
  667. /*transform:scaleX(1.10769);*/
  668. /*transform-origin: 0 0;*/
  669. .home-left-box{
  670. z-index:20;
  671. /*width:2496px;*/
  672. .time-p{
  673. height:132px;
  674. line-height:132px;
  675. margin:0 0 46px 200px;
  676. color:#fff;
  677. font-size:34px;
  678. font-family: SOURCEHANSANSCN;
  679. }
  680. }
  681. .home-center-box{
  682. z-index:20;
  683. /*width:5408px;*/
  684. /*flex:1;*/
  685. position: relative;
  686. //地图层
  687. .map-box{
  688. position: absolute;
  689. top:0;
  690. left:0;
  691. z-index: 0;
  692. width:5408px;
  693. }
  694. //常规展示层
  695. .center-max-box{
  696. position: absolute;
  697. top:0;
  698. left:0;
  699. z-index: 1;
  700. /*width:5408px;*/
  701. width:5760px;
  702. display: flex;
  703. .center-left-box{
  704. width:1255px;
  705. margin-left:140px;
  706. }
  707. .center-center-box{
  708. flex:1;
  709. /*width: 2898px;*/
  710. }
  711. .center-right-box{
  712. /*width:1255px;*/
  713. width:1100px;
  714. }
  715. }
  716. }
  717. .home-right-box{
  718. z-index:20;
  719. /*width:2496px;*/
  720. .button-box{
  721. margin:0 200px 46px 0;
  722. display: flex;
  723. .null-p{
  724. flex:1;
  725. }
  726. div{
  727. display: flex;
  728. cursor: pointer;
  729. p{
  730. height:132px;
  731. line-height:132px;
  732. color:#fff;
  733. font-size:34px;
  734. }
  735. p:nth-child(1){
  736. margin-right:14px;
  737. }
  738. p:nth-child(2){
  739. font-family: SOURCEHANSANSCN;
  740. }
  741. }
  742. }
  743. }
  744. //报警层
  745. .alarm-max-box{
  746. position: absolute;
  747. top:0;
  748. left:0;
  749. z-index: 50;
  750. }
  751. .home-left-box{
  752. /*width: 2880px;*/
  753. width: 2760px;
  754. height:2160px;
  755. overflow: hidden;
  756. .scale-box-big{
  757. transform:scale(0.7714285);
  758. transform-origin: 0 0;
  759. .scale-box{
  760. transform:scaleX(1.4);
  761. transform-origin: 0 0;
  762. padding-left:210px;
  763. }
  764. }
  765. }
  766. .home-center-box{
  767. /*width:5760px;*/
  768. width:5927px;
  769. flex:1;
  770. height:2160px;
  771. display: flex;
  772. .scale-comprehensiveData{
  773. position: absolute;
  774. top:0;
  775. left:0;
  776. width:5760px;
  777. height:2160px;
  778. display: flex;
  779. transform:scale(0.7714285);
  780. transform-origin: 50% 0;
  781. .scale-box{
  782. flex:1;
  783. display: flex;
  784. transform:scaleX(1.4);
  785. transform-origin: 50% 0;
  786. }
  787. }
  788. .scale-center-box{
  789. height:2160px;
  790. flex:1;
  791. display: flex;
  792. transform:scale(0.7714285);
  793. transform-origin: 50% 0;
  794. .scale-box{
  795. flex:1;
  796. display: flex;
  797. flex-direction: column;
  798. transform:scaleX(1.4);
  799. transform-origin: 50% 0;
  800. }
  801. }
  802. }
  803. .home-right-box{
  804. /*width: 2880px;*/
  805. width: 2788px;
  806. height:2160px;
  807. .scale-box-big{
  808. transform:scale(0.7714285);
  809. transform-origin: 100% 0;
  810. .scale-box{
  811. transform:scaleX(1.4);
  812. transform-origin: 100% 0;
  813. padding-left:140px;
  814. }
  815. }
  816. }
  817. .back_mp4{
  818. z-index:40;
  819. position: absolute;
  820. top: 0;
  821. left: 0;
  822. /*width: 10400px;*/
  823. /*height: 2808px;*/
  824. width: 11520px;
  825. height: 2160px;
  826. /*background-color: transparent;*/
  827. /*transform:scaleX(1.10769);*/
  828. }
  829. .waring_mp3{
  830. z-index: -1000;
  831. width:1px;
  832. height:1px;
  833. overflow: hidden;
  834. }
  835. }
  836. //logo
  837. .logo-img{
  838. position:absolute;
  839. top:45px;
  840. left:4560px;
  841. z-index:50;
  842. width:559px;
  843. height:111px;
  844. display: inline-block;
  845. transform:scaleX(1.4);
  846. transform-origin: 50% 0;
  847. }
  848. //标题
  849. .title-top-center-box{
  850. transform:scaleX(1.4);
  851. transform-origin: 50% 0;
  852. position:absolute;
  853. top:40px;
  854. left:5590px;
  855. z-index:50;
  856. font-size:104px;
  857. line-height:104px;
  858. font-weight: 700;
  859. background: -webkit-linear-gradient(0deg, #41A4FF, #E8F5FF); /* Chrome, Safari */
  860. background: linear-gradient(0deg, #41A4FF, #E8F5FF); /* 标准语法 */
  861. -webkit-background-clip: text; /* Chrome, Safari */
  862. background-clip: text;
  863. -webkit-text-fill-color: transparent; /* Chrome, Safari */
  864. color: transparent; /* 其他浏览器 */
  865. }
  866. //中央区域左侧按钮
  867. .center-left-button-box{
  868. }
  869. //中央区域右侧按钮
  870. .center-right-button-box{
  871. }
  872. //左侧遮罩
  873. .back-l-img{
  874. z-index: 15;
  875. position: absolute;
  876. top:0;
  877. left:0;
  878. width: 4875px;
  879. height: 2160px;
  880. background: url("../assets/ZDimages/demo_l.png");
  881. background-size: 100% 100%;
  882. }
  883. //右侧遮罩
  884. .back-r-img{
  885. z-index: 15;
  886. position: absolute;
  887. top:0;
  888. right:0;
  889. width: 4875px;
  890. height: 2160px;
  891. background: url("../assets/ZDimages/demo_r.png");
  892. background-size: 100% 100%;
  893. }
  894. .map-max-big-box{
  895. z-index: 10;
  896. position: absolute;
  897. width:5927px;
  898. height: 2160px;
  899. top:300px;
  900. left:2760px;
  901. overflow: hidden;
  902. .map-box{
  903. transform:scaleX(1.4);
  904. transform-origin: 50% 0;
  905. }
  906. }
  907. .dept-video-max-box{
  908. z-index: 1000;
  909. position: absolute;
  910. width:5527px;
  911. height: 1700px;
  912. top:270px;
  913. left:2960px;
  914. overflow: hidden;
  915. .dept-video-box{
  916. transform:scaleX(1.4);
  917. transform-origin: 0 0;
  918. }
  919. }
  920. //报警提示边框
  921. .alarm-max-box{
  922. animation: slide 1s ease-in-out 1s infinite alternate;
  923. }
  924. @keyframes slide {
  925. 0% {
  926. box-shadow: inset 0 0 210px rgba(234, 1, 1, 1);
  927. }
  928. 50% {
  929. box-shadow: inset 0 0 210px rgba(234, 1, 1, 0.5);
  930. }
  931. 100% {
  932. box-shadow: inset 0 0 210px rgba(234, 1, 1, 0);
  933. }
  934. }
  935. .left-alarm-max-big-box{
  936. z-index:100;
  937. position: absolute;
  938. top:50%;
  939. left:650px;
  940. margin-top:-395px;
  941. width:1458px;
  942. height:679px;
  943. background: url("../assets/ZDimages/icon_yujing@1x.png");
  944. background-size: 100% 100%;
  945. animation: alarmSlide 1s ease-in-out 1s infinite alternate;
  946. div{
  947. margin:220px 0 0 425px;
  948. width:810px; padding: 0; /* 移除内边距以确保文字充分利用空间 */
  949. display: flex;
  950. p{
  951. flex:1;
  952. text-align: center;
  953. font-size:90px;
  954. height: 90px;
  955. line-height:90px;
  956. font-weight:700;
  957. font-family: SOURCEHANSANSCN;
  958. color:#FBFF00;
  959. text-shadow: 0 0 50px rgba(251,255,0,0.8);
  960. }
  961. }
  962. }
  963. .right-alarm-max-big-box{
  964. z-index:100;
  965. position: absolute;
  966. top:50%;
  967. right:665px;
  968. margin-top:-395px;
  969. width:1458px;
  970. height:679px;
  971. background: url("../assets/ZDimages/icon_yujing@1x.png");
  972. background-size: 100% 100%;
  973. animation: alarmSlide 1s ease-in-out 1s infinite alternate;
  974. div{
  975. margin:220px 0 0 425px;
  976. width:810px; padding: 0; /* 移除内边距以确保文字充分利用空间 */
  977. display: flex;
  978. p{
  979. flex:1;
  980. text-align: center;
  981. font-size:90px;
  982. height: 90px;
  983. line-height:90px;
  984. font-weight:700;
  985. font-family: SOURCEHANSANSCN;
  986. color:#FBFF00;
  987. text-shadow: 0 0 50px rgba(251,255,0,0.8);
  988. }
  989. }
  990. }
  991. @keyframes alarmSlide {
  992. 0% {
  993. opacity:1;
  994. }
  995. 25% {
  996. opacity:1;
  997. }
  998. 70% {
  999. opacity:1;
  1000. }
  1001. 85% {
  1002. opacity:0.5;
  1003. }
  1004. 100% {
  1005. opacity:0;
  1006. }
  1007. }
  1008. .position-button-0{
  1009. cursor: pointer;
  1010. width:60px;
  1011. height:60px;
  1012. position:absolute;
  1013. top:45px;
  1014. right:820px;
  1015. display: inline-block;
  1016. z-index:100;
  1017. transform:scaleX(1.4);
  1018. transform-origin: 50% 0;
  1019. }
  1020. .position-button-1{
  1021. cursor: pointer;
  1022. width:60px;
  1023. height:60px;
  1024. position:absolute;
  1025. top:45px;
  1026. right:700px;
  1027. display: inline-block;
  1028. z-index:100;
  1029. transform:scaleX(1.4);
  1030. transform-origin: 50% 0;
  1031. }
  1032. .position-button-2{
  1033. cursor: pointer;
  1034. width:60px;
  1035. height:60px;
  1036. position:absolute;
  1037. top:45px;
  1038. right:700px;
  1039. display: inline-block;
  1040. z-index:100;
  1041. transform:scaleX(1.4);
  1042. transform-origin: 50% 0;
  1043. }
  1044. .position-button-3{
  1045. cursor: pointer;
  1046. width:60px;
  1047. height:60px;
  1048. position:absolute;
  1049. top:45px;
  1050. right:580px;
  1051. display: inline-block;
  1052. z-index:100;
  1053. transform:scaleX(1.4);
  1054. transform-origin: 0 0;
  1055. }
  1056. .position-button-4{
  1057. cursor: pointer;
  1058. width:60px;
  1059. height:60px;
  1060. position:absolute;
  1061. top:45px;
  1062. right:580px;
  1063. display: inline-block;
  1064. z-index:100;
  1065. transform:scaleX(1.4);
  1066. transform-origin: 0 0;
  1067. }
  1068. .position-button-5{
  1069. cursor: pointer;
  1070. height:80px;
  1071. width:500px;
  1072. position:absolute;
  1073. bottom:25px;
  1074. left:5000px;
  1075. display: flex;
  1076. z-index:100;
  1077. transform:scaleX(1.4);
  1078. transform-origin: 0 0;
  1079. img{
  1080. width:80px;
  1081. height:80px;
  1082. margin-right:10px;
  1083. display: inline-block;
  1084. }
  1085. p{
  1086. height:80px;
  1087. line-height:80px;
  1088. font-size:40px;
  1089. font-family: SOURCEHANSANSCN;
  1090. font-weight: 700;
  1091. background: -webkit-linear-gradient(0deg, #0591F3, #F9F9F9); /* Chrome, Safari */
  1092. background: linear-gradient(0deg, #0591F3, #F9F9F9); /* 标准语法 */
  1093. -webkit-background-clip: text; /* Chrome, Safari */
  1094. background-clip: text;
  1095. -webkit-text-fill-color: transparent; /* Chrome, Safari */
  1096. color: transparent; /* 其他浏览器 */
  1097. }
  1098. }
  1099. .position-button-6{
  1100. cursor: pointer;
  1101. height:80px;
  1102. width:500px;
  1103. position:absolute;
  1104. bottom:25px;
  1105. left:6100px;
  1106. display: flex;
  1107. z-index:100;
  1108. transform:scaleX(1.4);
  1109. transform-origin: 0 0;
  1110. img{
  1111. width:80px;
  1112. height:80px;
  1113. margin-right:20px;
  1114. display: inline-block;
  1115. }
  1116. p{
  1117. height:80px;
  1118. line-height:80px;
  1119. font-size:40px;
  1120. font-family: SOURCEHANSANSCN;
  1121. font-weight: 700;
  1122. background: -webkit-linear-gradient(0deg, #0591F3, #F9F9F9); /* Chrome, Safari */
  1123. background: linear-gradient(0deg, #0591F3, #F9F9F9); /* 标准语法 */
  1124. -webkit-background-clip: text; /* Chrome, Safari */
  1125. background-clip: text;
  1126. -webkit-text-fill-color: transparent; /* Chrome, Safari */
  1127. color: transparent; /* 其他浏览器 */
  1128. }
  1129. }
  1130. </style>