newEvacuationBigDataHome.vue 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672
  1. <template>
  2. <div class="newEvacuationBigDataHome" ref="maxBox">
  3. <newEvacuationBigDataSubPageKYDXNH v-if="versionField() === 'kuangYeDaXue_nanHu'"></newEvacuationBigDataSubPageKYDXNH>
  4. <newEvacuationBigDataSubPagePublic v-else></newEvacuationBigDataSubPagePublic>
  5. <div class="evacuation-out-button-position-box">
  6. <i class="el-icon-switch-button"></i>
  7. <p @click="goRoute">{{routeType?'退出全屏':'全屏'}}</p>
  8. </div>
  9. <div class="left-max-big-box">
  10. <div class="left-top-big-box">
  11. <div class="big-title-box">
  12. <img src="@/assets/ZDimages/bigData3_2/icon_znjc_tb.png">
  13. <p>智能监测</p>
  14. </div>
  15. <div class="left-top-for-big-box scrollbar-box">
  16. <div class="left-top-for-box" v-for="(item,index) in lotStaticList" :key="index">
  17. <p>{{item.sensorTotal}}</p>
  18. <p>{{item.sensorName}}</p>
  19. <img v-if="item.sensorType == 1" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_zcbg.png">
  20. <img v-if="item.sensorType == 2" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_hyjc.png">
  21. <img v-if="item.sensorType == 3" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_qtjc.png">
  22. <img v-if="item.sensorType == 4" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_wsd.png">
  23. <img v-if="item.sensorType == 5" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_wsd(1).png">
  24. <img v-if="item.sensorType == 6" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_fcjc.png">
  25. <img v-if="item.sensorType == 7" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_znjk.png">
  26. <img v-if="item.sensorType == 8" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_znmj.png">
  27. <img v-if="item.sensorType == 9" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_ytj.png">
  28. <img v-if="item.sensorType == 10" src="@/assets/ZDimages/bigData3_2/home/icon_dqkz.png">
  29. <img v-if="item.sensorType == 11" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_zntf.png">
  30. <img v-if="item.sensorType == 12" src="@/assets/ZDimages/bigData3_2/home/img_zdmh_znmh.png">
  31. <img src="@/assets/ZDimages/bigData3_2/home/icon_znjc_bg.png">
  32. </div>
  33. </div>
  34. <p class="hazardSum-p" v-if="lotStaticSum">总数:{{lotStaticSum}}</p>
  35. </div>
  36. <div class="left-bottom-big-box">
  37. <div class="big-title-box">
  38. <img src="@/assets/ZDimages/bigData3_2/icon_znjc_tb.png">
  39. <p>危险源</p>
  40. </div>
  41. <div id="eCharts"></div>
  42. <p class="hazardSum-p" v-if="hazardSum">总数:{{hazardSum}}</p>
  43. <p class="eCharts-null-p" v-if="!eChartsData.nameList[0]">暂无数据</p>
  44. </div>
  45. </div>
  46. <div class="center-max-big-box">
  47. <div class="top-button-box">
  48. <div class="top-button-left-select-box">
  49. <el-select v-model="buildingId" placeholder="请选择"
  50. :popper-append-to-body="false"
  51. @change="buildingChange"
  52. class="building-select-box">
  53. <el-option
  54. v-for="item in buildingOptions"
  55. :key="item.id"
  56. :label="item.name"
  57. :value="item.id">
  58. <div style="display: flex" v-if="item.planType">
  59. <img src="@/assets/ZDimages/bigData3_2/icon_lc_yc.png" style="margin:11px 10px 0 0;width:14px;height:12px;">
  60. <p style="margin-right:24px;">{{ item.name }}</p>
  61. </div>
  62. <div style="display: flex" v-else>
  63. <p style="margin:0 24px;">{{ item.name }}</p>
  64. </div>
  65. </el-option>
  66. </el-select>
  67. </div>
  68. <div class="top-button-right-num-box">
  69. </div>
  70. </div>
  71. <div id="container" ref="container" @mousedown="getMouseXY($event)">
  72. </div>
  73. <!--<div class="position-floor-user-box">-->
  74. <!--<img src="@/assets/ZDimages/bigData3_2/icon_zhpt_rs.png">-->
  75. <!--<p>实时人数:</p>-->
  76. <!--<p>{{userNum}}人</p>-->
  77. <!--</div>-->
  78. <div class="position-floor-button-box" v-if="mapList[0]">
  79. <p class="position-floor-for-button-p" :class="item.checkType?'check-button-box':''"
  80. @click="dataDispose(item.index)"
  81. v-for="(item,index) in maxMapButtonList" :key="index">
  82. {{item.indexName}}
  83. </p>
  84. </div>
  85. </div>
  86. <div class="right-max-big-box scrollbar-box">
  87. <p class="null-p" v-if="!monitorNumList[0]">暂无数据</p>
  88. <div class="monitor-max-for-box" v-for="(item,index) in monitorNumList" :key="index">
  89. <div class="monitor-title-box">
  90. <p>{{item.name}}</p>
  91. <i :class="index == monitorType?'el-icon-arrow-up':'el-icon-arrow-down'" @click="getMonitorUrl(index)"></i>
  92. </div>
  93. <div class="video-mx-big-box" v-show="index == monitorType"
  94. v-for="(videoItem,videoIndex) in item.hardwareList" :key="videoIndex">
  95. <video class="video-box" :id="videoItem" ref="videoRef" :poster="videoCover"
  96. autoplay controls muted width="366px" height="210px"></video>
  97. </div>
  98. </div>
  99. </div>
  100. </div>
  101. </template>
  102. <script>
  103. import mqtt from 'mqtt'
  104. import flvjs from 'flv.js'
  105. import { subjectInfo,startUrl } from "@/api/laboratory/subject";
  106. import { getBuildOrFloorList,exitHazardTotalByBuildId,getLotStatis,
  107. getBuildOrFloorDetailList,getBuildOrFloorInfo,selectTriggerInfo } from '@/api/evacuationBigData/index.js'
  108. import * as Three from 'three'
  109. import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  110. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
  111. import { mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils'
  112. import { SceneUtils } from 'three/examples/jsm/utils/SceneUtils.js'
  113. import newEvacuationBigDataSubPageKYDXNH from './differenceComponent/newEvacuationBigDataSubPageKYDXNH.vue'
  114. import newEvacuationBigDataSubPagePublic from './differenceComponent/newEvacuationBigDataSubPagePublic.vue'
  115. import { airbottleBluetoothGetBeaconNotice } from "@/api/gasBottleManage/index";
  116. export default {
  117. name: 'newEvacuationBigDataHome',
  118. components: {
  119. newEvacuationBigDataSubPageKYDXNH,
  120. newEvacuationBigDataSubPagePublic,
  121. },
  122. computed:{
  123. Obj(){
  124. return this.$store.state.settings.planData
  125. }
  126. },
  127. watch:{
  128. Obj(newVal,oldVal){
  129. //可以对数据执行相应的操作
  130. // console.log(newVal,oldVal)
  131. this.selectTriggerInfo();
  132. }
  133. },
  134. data() {
  135. return {
  136. videoCover:window.location.href.split('://')[0]+'://' + this.judgmentNetworkReturnAddress() + "/admin/" + localStorage.getItem('videoCover'),
  137. //当前路由状态
  138. routeType:false,
  139. containerType:false,
  140. buttonIndex:null,
  141. mapData:[{"x":1,"y":160,"w":797,"h":100,"type":"2","lightList":[{"type":"light","state":"4","w":40,"h":40,"x":520,"y":30,"relayType":2,"configName":"2","configStatus":"2","key":"light0","openType":false},{"type":"light","state":"3","w":40,"h":40,"x":266,"y":30,"relayType":2,"configName":"1","configStatus":"1","key":"light1","openType":false}],"key":"corridor0"},{"x":1,"y":1,"w":398,"h":159,"type":"1","doorList":[{"type":"door","toward":"bottom","w":34,"h":34,"x":193,"y":123}],"roomType":1,"roomNum":"1-1","roomName":null,"subId":160,"subName":"管理员测试实验室1","key":"lab0","id":486,"buildId":48,"floorId":49,"online":0,"loginAdmin":true,"planType":false},{"x":399,"y":1,"w":398,"h":159,"type":"1","doorList":[{"type":"door","toward":"bottom","w":34,"h":34,"x":181,"y":123}],"roomType":-99,"roomNum":"1-2","roomName":"其他房间","subId":-1,"subName":null,"key":"lab1","id":487,"buildId":48,"floorId":49,"online":null,"loginAdmin":false,"planType":false},{"x":1,"y":260,"w":301,"h":139,"type":"1","doorList":[{"type":"door","toward":"top","w":34,"h":34,"x":131,"y":2}],"roomType":-99,"roomNum":"1-3","roomName":"其他房间","subId":-1,"subName":null,"key":"lab2","id":488,"buildId":48,"floorId":49,"online":null,"loginAdmin":false,"planType":false},{"x":302,"y":260,"w":316,"h":139,"type":"1","doorList":[{"type":"door","toward":"top","w":34,"h":34,"x":153,"y":2}],"roomType":-99,"roomNum":"1-4","roomName":"其他房间","subId":-1,"subName":null,"key":"lab3","id":489,"buildId":48,"floorId":49,"online":null,"loginAdmin":false,"planType":false},{"x":618,"y":260,"w":181,"h":139,"type":"3","doorList":[{"type":"door","toward":"top","w":34,"h":34,"x":80,"y":2}],"key":"escape0","roomCheckType":false}],
  142. maxMapButtonList:[],
  143. maxMapList:[],
  144. mapList:[],
  145. // 地基数据
  146. foundation:{
  147. bgColor:'#999',
  148. bgOpacity:1,
  149. x:null,//镜头位置
  150. y:null,//镜头位置
  151. spacing:300,
  152. visualDistance:null,
  153. planColor:'#f15b6c'
  154. },
  155. //数据类型1.实验室
  156. roomData_1:{
  157. bgColor:'#2a5caa',
  158. bgOpacity:0.4,
  159. },
  160. //数据类型 2.走廊
  161. roomData_2:{
  162. bgColor:'#84bf96',
  163. bgOpacity:1,
  164. },
  165. //数据类型 3.逃生通道
  166. roomData_3:{
  167. bgColor:'#007d65',
  168. bgOpacity:0.4,
  169. },
  170. //dom
  171. container:null,
  172. //场景
  173. scene: null,
  174. camera:null,
  175. controls:null,
  176. renderer:null,
  177. //楼栋数据
  178. buildingId:null,
  179. buildingOptions:[],
  180. //楼栋下传感器数据
  181. lotStaticSum:null,
  182. lotStaticList:[],
  183. //楼栋下危险源数量
  184. hazardSum:null,
  185. //实时人数
  186. userNum:null,
  187. //eCharts
  188. eChartsData:{
  189. nameList: [],
  190. numList: [],
  191. maxNumList: [],
  192. },
  193. //mqtt
  194. //全局MQTT相关
  195. allClient:{},
  196. planTopic:"lab/newexit/line",//预案
  197. //楼栋MQTT相关
  198. buildingClient:{},
  199. userTopic:"lab/horn",//消息
  200. //气瓶MQTT相关
  201. gasBottleClient:{},
  202. gasBottleTopic:"air/blueTooth/gateway",//预案
  203. //摄像头数据
  204. monitorNumList:[],
  205. monitorType:null,
  206. videoList:[],
  207. videoPlayList:[],
  208. //动画数据
  209. animateData:null,
  210. }
  211. },
  212. created() {
  213. if(this.$route.path == '/newEvacuationBigData'){
  214. this.$set(this,'routeType',true);
  215. }else{
  216. this.$set(this,'routeType',false);
  217. }
  218. },
  219. mounted(){
  220. // this.offAllMQTT('on');
  221. //获取楼栋数据
  222. this.getBuilding();
  223. },
  224. methods: {
  225. //数据处理
  226. dataDispose(num){
  227. let self = this;
  228. if(this.maxMapList[num]){
  229. let list = [];
  230. let index = 0;
  231. if(num == self.maxMapList.length-1){
  232. index = 0
  233. }else if(num-2<=0 && num+2>=(self.maxMapList.length-1)){
  234. index = 0;
  235. }else if (num > (self.maxMapList.length-6) && (num-2) > 0){
  236. if(num + 2 > (self.maxMapList.length-1)){
  237. index = self.maxMapList.length-5;
  238. }else{
  239. index = num - 2;
  240. }
  241. }else{
  242. if(num - 2 > 0){
  243. index = num - 2;
  244. }else{
  245. index = 0;
  246. }
  247. }
  248. let pushNum = 0
  249. for (let i=0 ;i < self.maxMapList.length;i++){
  250. if(index == i && pushNum < 5){
  251. list.push(self.maxMapList[i])
  252. self.maxMapList[i].checkType = true;
  253. pushNum ++
  254. index ++
  255. }else{
  256. self.maxMapList[i].checkType = false;
  257. }
  258. }
  259. this.$set(this,'mapList',list);
  260. if(this.mapList[0]){
  261. let newList = [];
  262. for(let i=0;i<self.maxMapList.length;i++){
  263. let obj = JSON.parse(JSON.stringify(self.maxMapList[i]))
  264. obj.index = i;
  265. newList.unshift(obj);
  266. }
  267. this.$set(this,'maxMapButtonList',newList);
  268. this.$set(this,'buttonIndex',num);
  269. this.selectTriggerInfo();
  270. }
  271. }
  272. },
  273. //初始化
  274. initAdd(){
  275. let self = this;
  276. let maxWidth = 0;
  277. let maxHeight = 0;
  278. let minWidth = 0;
  279. let minHeight = 0;
  280. //数据初始化
  281. for(let i=0;i<self.mapList.length;i++){
  282. self.mapList[i].maxWidth = 0;
  283. self.mapList[i].maxHeight = 0;
  284. for(let o=0;o<self.mapList[i].relationalData.length;o++){
  285. if ((self.mapList[i].relationalData[o].x + self.mapList[i].relationalData[o].w) > self.mapList[i].maxWidth) {
  286. self.mapList[i].maxWidth = self.mapList[i].relationalData[o].x + self.mapList[i].relationalData[o].w
  287. }
  288. if ((self.mapList[i].relationalData[o].y + self.mapList[i].relationalData[o].h) > self.mapList[i].maxHeight) {
  289. self.mapList[i].maxHeight = self.mapList[i].relationalData[o].y + self.mapList[i].relationalData[o].h
  290. }
  291. }
  292. //找出最大高度
  293. if(self.mapList[i].maxHeight > maxHeight){
  294. maxHeight = self.mapList[i].maxHeight;
  295. }
  296. //找出最大宽度
  297. if(self.mapList[i].maxWidth > maxWidth){
  298. maxWidth = self.mapList[i].maxWidth;
  299. }
  300. //找出最小高度
  301. if(minHeight == 0){
  302. minHeight = self.mapList[i].maxHeight;
  303. }else if(self.mapList[i].maxHeight < minHeight){
  304. minHeight = self.mapList[i].maxHeight;
  305. }
  306. //找出最小宽度
  307. if(minWidth == 0){
  308. minWidth = self.mapList[i].maxWidth;
  309. }else if(self.mapList[i].maxWidth < minWidth){
  310. minWidth = self.mapList[i].maxWidth;
  311. }
  312. }
  313. this.$set(this.foundation,'x',maxHeight);
  314. this.$set(this.foundation,'y',maxWidth);
  315. //根据楼层宽度或高度来设定每层之间的间距
  316. // this.$set(this.foundation,'spacing',minWidth>minHeight?minHeight:minWidth);
  317. if(maxWidth>maxHeight){
  318. if(maxWidth>1120){
  319. maxWidth/1120
  320. }else{
  321. }
  322. }else{
  323. if(maxHeight>1120){
  324. }else{
  325. }
  326. }
  327. this.$set(this.foundation,'spacing',maxWidth>maxHeight?maxHeight*0.6:maxWidth*0.6);
  328. this.$set(this.foundation,'visualDistance',maxWidth>maxHeight?maxWidth:maxHeight);
  329. /*
  330. * 创建场景对象Scene
  331. */
  332. // this.scene = new Three.Scene()
  333. //创建层数据
  334. let maxList = [];
  335. for(let i=0;i<self.mapList.length;i++){
  336. /*
  337. * 创建楼层地基
  338. */
  339. let geometryList = [];
  340. let materialList = [];
  341. let geometry = new Three.BoxGeometry(self.mapList[i].maxWidth, 4, self.mapList[i].maxHeight);
  342. //位置偏移
  343. geometry.translate((self.mapList[i].maxWidth/2)-self.mapList[i].maxWidth/2,
  344. (i*self.foundation.spacing),
  345. (self.mapList[i].maxHeight/2)-self.mapList[i].maxHeight/2)
  346. //材质
  347. let material = new Three.MeshLambertMaterial()
  348. //透明度开启关闭
  349. material.transparent = true;
  350. //透明度
  351. material.opacity = self.foundation.bgOpacity;
  352. material.emissive.setStyle(self.foundation.bgColor);
  353. //添加
  354. geometryList.push(geometry)
  355. materialList.push(material)
  356. /*
  357. * 创建楼层房间
  358. */
  359. for(let o=0;o<self.mapList[i].relationalData.length;o++){
  360. let geometry = new Three.BoxGeometry(self.mapList[i].relationalData[o].w, self.mapList[i].relationalData[o].type == 2?4:1, self.mapList[i].relationalData[o].h);
  361. //位置偏移
  362. geometry.translate((self.mapList[i].relationalData[o].x+(self.mapList[i].relationalData[o].w/2))-self.mapList[i].maxWidth/2,
  363. ((i*self.foundation.spacing)+(self.mapList[i].relationalData[o].type == 2?4:20)),
  364. (self.mapList[i].relationalData[o].y+(self.mapList[i].relationalData[o].h/2))-self.mapList[i].maxHeight/2)
  365. //材质
  366. let material = new Three.MeshPhongMaterial()
  367. //区分房间类型 生成文字
  368. //透明度开启关闭
  369. material.transparent = true;
  370. //透明度
  371. material.opacity = self.mapList[i].relationalData[o].type == 1?self.roomData_1.bgOpacity:(self.mapList[i].relationalData[o].type == 2?self.roomData_2.bgOpacity:(self.mapList[i].relationalData[o].type == 3?self.roomData_3.bgOpacity:''))
  372. if(self.mapList[i].relationalData[o].planType){
  373. material.emissive.setStyle(self.foundation.planColor);
  374. }else{
  375. material.emissive.setStyle(self.mapList[i].relationalData[o].type == 1?self.roomData_1.bgColor:(self.mapList[i].relationalData[o].type == 2?self.roomData_2.bgColor:(self.mapList[i].relationalData[o].type == 3?self.roomData_3.bgColor:'')));
  376. }
  377. //添加
  378. geometryList.push(geometry)
  379. materialList.push(material)
  380. if(self.mapList[i].relationalData[o].type != 2){
  381. //生成墙体
  382. let qt_1 = new Three.BoxGeometry(self.mapList[i].relationalData[o].w, 20, 2);
  383. qt_1.translate((self.mapList[i].relationalData[o].x+(self.mapList[i].relationalData[o].w/2))-self.mapList[i].maxWidth/2,
  384. ((i*self.foundation.spacing)+10),
  385. self.mapList[i].relationalData[o].y-self.mapList[i].maxHeight/2)
  386. let cz_1 = new Three.MeshLambertMaterial()
  387. cz_1.opacity = 1
  388. if(self.mapList[i].relationalData[o].planType){
  389. cz_1.emissive.setStyle(self.foundation.planColor);
  390. }else{
  391. cz_1.emissive.setStyle(self.mapList[i].relationalData[o].type == 1?self.roomData_1.bgColor:(self.mapList[i].relationalData[o].type == 2?self.roomData_2.bgColor:(self.mapList[i].relationalData[o].type == 3?self.roomData_3.bgColor:'')));
  392. }
  393. geometryList.push(qt_1)
  394. materialList.push(cz_1)
  395. let qt_2 = new Three.BoxGeometry(self.mapList[i].relationalData[o].w, 20, 2);
  396. qt_2.translate(self.mapList[i].relationalData[o].x+(self.mapList[i].relationalData[o].w/2)-self.mapList[i].maxWidth/2,
  397. ((i*self.foundation.spacing)+10),
  398. self.mapList[i].relationalData[o].y+self.mapList[i].relationalData[o].h-self.mapList[i].maxHeight/2)
  399. let cz_2 = new Three.MeshLambertMaterial()
  400. cz_2.opacity = 1
  401. if(self.mapList[i].relationalData[o].planType){
  402. cz_2.emissive.setStyle(self.foundation.planColor);
  403. }else{
  404. cz_2.emissive.setStyle(self.mapList[i].relationalData[o].type == 1?self.roomData_1.bgColor:(self.mapList[i].relationalData[o].type == 2?self.roomData_2.bgColor:(self.mapList[i].relationalData[o].type == 3?self.roomData_3.bgColor:'')));
  405. }
  406. geometryList.push(qt_2)
  407. materialList.push(cz_2)
  408. let qt_3 = new Three.BoxGeometry(2, 20, self.mapList[i].relationalData[o].h);
  409. qt_3.translate(self.mapList[i].relationalData[o].x-self.mapList[i].maxWidth/2,
  410. ((i*self.foundation.spacing)+10),
  411. self.mapList[i].relationalData[o].y+(self.mapList[i].relationalData[o].h/2)-self.mapList[i].maxHeight/2)
  412. let cz_3 = new Three.MeshLambertMaterial()
  413. cz_3.opacity = 1
  414. if(self.mapList[i].relationalData[o].planType){
  415. cz_3.emissive.setStyle(self.foundation.planColor);
  416. }else{
  417. cz_3.emissive.setStyle(self.mapList[i].relationalData[o].type == 1?self.roomData_1.bgColor:(self.mapList[i].relationalData[o].type == 2?self.roomData_2.bgColor:(self.mapList[i].relationalData[o].type == 3?self.roomData_3.bgColor:'')));
  418. }
  419. geometryList.push(qt_3)
  420. materialList.push(cz_3)
  421. let qt_4 = new Three.BoxGeometry(2, 20, self.mapList[i].relationalData[o].h);
  422. qt_4.translate(self.mapList[i].relationalData[o].x+self.mapList[i].relationalData[o].w-self.mapList[i].maxWidth/2,
  423. ((i*self.foundation.spacing)+10),
  424. self.mapList[i].relationalData[o].y+(self.mapList[i].relationalData[o].h/2)-self.mapList[i].maxHeight/2)
  425. let cz_4 = new Three.MeshLambertMaterial()
  426. cz_4.opacity = 1
  427. if(self.mapList[i].relationalData[o].planType){
  428. cz_4.emissive.setStyle(self.foundation.planColor);
  429. }else{
  430. cz_4.emissive.setStyle(self.mapList[i].relationalData[o].type == 1?self.roomData_1.bgColor:(self.mapList[i].relationalData[o].type == 2?self.roomData_2.bgColor:(self.mapList[i].relationalData[o].type == 3?self.roomData_3.bgColor:'')));
  431. }
  432. geometryList.push(qt_4)
  433. materialList.push(cz_4)
  434. //生成文字图片
  435. let canvas = document.createElement("canvas");
  436. let ctx = canvas.getContext('2d')
  437. canvas.width = self.mapList[i].relationalData[o].w/2
  438. canvas.height = self.mapList[i].relationalData[o].h/2
  439. //制作矩形
  440. ctx.fillStyle = "gray";
  441. ctx.fillRect(0, 0, 0, 0)
  442. //设置文字
  443. ctx.fillStyle = "white";
  444. ctx.font = 'normal 14px "楷体"'
  445. ctx.fillText(self.mapList[i].relationalData[o].type==3?'紧急出口':(self.mapList[i].relationalData[o].roomName?self.mapList[i].relationalData[o].roomName:self.mapList[i].relationalData[o].subName),0, 20)
  446. //生成图片
  447. let url = canvas.toDataURL('image/png');
  448. let geometry1 = new Three.PlaneGeometry(self.mapList[i].relationalData[o].w/2, 60)
  449. geometry1.translate(self.mapList[i].relationalData[o].x+(self.mapList[i].relationalData[o].w/2)-self.mapList[i].maxWidth/2,
  450. ((i*self.foundation.spacing)+10),
  451. self.mapList[i].relationalData[o].y+(self.mapList[i].relationalData[o].h/2)-self.mapList[i].maxHeight/2)
  452. let material1 = new Three.MeshBasicMaterial({
  453. map: new Three.TextureLoader().load(url),
  454. side: Three.DoubleSide,
  455. opacity: 1,
  456. transparent: true, // 设为透明
  457. })
  458. geometryList.push(geometry1)
  459. materialList.push(material1)
  460. }
  461. }
  462. maxList.push({
  463. geometryList:geometryList,
  464. materialList:materialList,
  465. name:self.mapList[i].name,
  466. floorId:self.mapList[i].id,
  467. subNum:self.mapList[i].subNum,
  468. })
  469. // //合并数据
  470. // let merged = mergeBufferGeometries(geometryList, true)
  471. // let mergeMesh = new Three.Mesh(merged, materialList)
  472. // //给合并项增加名称
  473. // mergeMesh.name = self.mapList[i].name;
  474. // mergeMesh.floorId = self.mapList[i].id;
  475. // mergeMesh.subNum = self.mapList[i].subNum;
  476. // //插入合并数据
  477. // self.scene.add(mergeMesh);
  478. }
  479. //清除动画数据
  480. if(this.renderer){
  481. cancelAnimationFrame(this.animateData);
  482. this.scene.traverse((child) => {
  483. if (child.material) {
  484. for(let i=0;i<child.material.length;i++){
  485. child.material[i].dispose();
  486. }
  487. }
  488. if (child.geometry) {
  489. child.geometry.dispose();
  490. }
  491. child = null;
  492. });
  493. this.container.innerHTML = '';
  494. this.renderer.forceContextLoss();
  495. this.renderer.dispose();
  496. this.scene.clear();
  497. this.$set(this,'scene',null);
  498. this.$set(this,'camera',null);
  499. this.$set(this,'controls',null);
  500. this.$set(this.renderer,'domElement',null);
  501. this.$set(this,'renderer',null);
  502. this.$set(this,'animateData',null);
  503. this.$set(this,'container',null);
  504. }
  505. this.scene = new Three.Scene()
  506. for(let i=0;i<maxList.length;i++){
  507. //合并数据
  508. let merged = mergeBufferGeometries(maxList[i].geometryList, true)
  509. let mergeMesh = new Three.Mesh(merged, maxList[i].materialList)
  510. //给合并项增加名称
  511. mergeMesh.name = maxList[i].name;
  512. mergeMesh.floorId = maxList[i].floorId;
  513. mergeMesh.subNum = maxList[i].subNum;
  514. //插入合并数据
  515. self.scene.add(mergeMesh);
  516. }
  517. this.lens();
  518. },
  519. //镜头
  520. lens(){
  521. this.container = document.getElementById('container')
  522. /*
  523. * 创建相机对象
  524. */
  525. this.camera = new Three.PerspectiveCamera(75, this.container.clientWidth / this.container.clientHeight, 0.1, 3000)
  526. //根据楼层间距与显示层数设定相机距离
  527. this.camera.position.set(0,
  528. this.foundation.visualDistance+(this.foundation.spacing*this.maxMapButtonList.length)*0.2,
  529. this.foundation.visualDistance+(this.foundation.spacing*this.maxMapButtonList.length)*0.2)
  530. /*
  531. * 创建渲染器对象
  532. */
  533. this.renderer = new Three.WebGLRenderer({antialias: true})
  534. this.renderer.setClearColor(0xf4f4f4, 0)
  535. //设置渲染区域尺寸
  536. this.renderer.setSize(this.container.clientWidth, this.container.clientHeight)
  537. //设置背景颜色
  538. //body元素中插入canvas对象
  539. this.container.appendChild(this.renderer.domElement)
  540. //执行渲染操作 指定场景、相机作为参数
  541. this.renderer.render(this.scene, this.camera)
  542. //镜头控制器
  543. this.createControls();
  544. //执行渲染
  545. // this.render();
  546. },
  547. //渲染
  548. render() {
  549. this.renderer.render(this.scene,this.camera);//执行渲染操作
  550. },
  551. // 创建控件对象
  552. createControls() {
  553. this.controls = new OrbitControls(this.camera, this.renderer.domElement)
  554. this.controls.enablePan = false // 是否开启右键拖拽
  555. this.controls.maxPolarAngle = 1 // 上下翻转的最大角度
  556. this.controls.minPolarAngle = 1 // 上下翻转的最小角度
  557. this.controls.autoRotate = true // 是否自动旋转
  558. this.controls.enableZoom = true // 是否可以缩放 默认是true
  559. this.controls.dampingFactor = 0.5 // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
  560. // this.controls.addEventListener('change', this.render)
  561. this.animate();
  562. },
  563. //旋转动画
  564. animate() {
  565. let t0 = new Date()
  566. this.controls.update();
  567. let t1 = new Date(); //本次时间
  568. let t = t1 - t0; // 时间差
  569. this.camera.rotateY(0.0001 * t / 3); //物体的均匀从左到又平移可以用相机旋转Y轴来实现
  570. this.controls.target = new Three.Vector3(0,((this.foundation.visualDistance/40)*(this.maxMapButtonList.length*4)),0);
  571. this.renderer.render(this.scene, this.camera);
  572. this.animateData = requestAnimationFrame(this.animate);
  573. },
  574. // 点击事件
  575. getMouseXY(event){
  576. let self = this;
  577. let dom = document.getElementById('container');
  578. var mouse=new Three.Vector3();
  579. var raycaster=new Three.Raycaster();
  580. if(this.routeType){
  581. mouse.x = ((event.clientX - dom.offsetParent.offsetLeft) / dom.clientWidth) * 2 - 1;//因为布局原因获取父级的offsetLeft
  582. mouse.y = -((event.clientY - dom.offsetTop) / dom.clientHeight) * 2 + 1;
  583. }else{
  584. let borderLeft = Math.round(this.$refs.maxBox.getBoundingClientRect().left);
  585. let borderTop = Math.round(this.$refs.maxBox.getBoundingClientRect().top);
  586. let str = this.$refs.maxBox.style.transform + '';
  587. let index1=str.indexOf('(')
  588. let index2=str.indexOf(')')
  589. str = this.accMul(parseFloat(str.substring(index1+1,index2)),100)
  590. let x = event.clientX - borderLeft;
  591. x = x/str
  592. x = this.accMul(x,100)
  593. x = x - dom.offsetParent.offsetLeft
  594. let y = event.clientY - borderTop;
  595. y = y/str
  596. y = this.accMul(y,100)
  597. y = y - dom.offsetTop
  598. mouse.x = (x / dom.clientWidth) * 2 - 1
  599. mouse.y = -(y / dom.clientHeight) * 2 + 1;
  600. }
  601. raycaster.setFromCamera(mouse, this.camera);
  602. const intersects = raycaster.intersectObjects(this.scene.children);
  603. if(intersects[0]){
  604. if(intersects[0].object.subNum > 0){
  605. for(let i=0;i<self.mapList.length;i++){
  606. if(self.mapList[i].id == intersects[0].object.floorId){
  607. for(let o=0;o<self.mapList[i].relationalData.length;o++){
  608. if(self.mapList[i].relationalData[o].type == '1'){
  609. if(self.mapList[i].relationalData[o].roomType != '-99'){
  610. if(self.mapList[i].relationalData[o].planType){
  611. for(let x=0;x<self.mapList[i].buildFloorLayoutVoList.length;x++){
  612. if(self.mapList[i].buildFloorLayoutVoList[x].loginAdmin){
  613. if(self.mapList[i].buildFloorLayoutVoList[x].subId == self.mapList[i].relationalData[o].subId){
  614. if(self.$route.query.buildId){
  615. delete self.$route.query.buildId;
  616. }
  617. if(self.$route.query.subId){
  618. delete self.$route.query.subId;
  619. }
  620. if(self.$route.query.floorId){
  621. delete self.$route.query.floorId;
  622. }
  623. if(self.$route.query.groupId){
  624. delete self.$route.query.groupId;
  625. }
  626. let obj = {
  627. buildId:self.buildingId,
  628. floorId:self.mapList[i].id,
  629. subId:self.mapList[i].buildFloorLayoutVoList[x].subId,
  630. planType:true
  631. }
  632. self.$parent.goPage(2,obj);
  633. return
  634. }
  635. }
  636. }
  637. }
  638. }
  639. }
  640. }
  641. for(let o=0;o<self.mapList[i].buildFloorLayoutVoList.length;o++){
  642. if(self.mapList[i].buildFloorLayoutVoList[o].loginAdmin){
  643. if(self.$route.query.buildId){
  644. delete self.$route.query.buildId;
  645. }
  646. if(self.$route.query.subId){
  647. delete self.$route.query.subId;
  648. }
  649. if(self.$route.query.floorId){
  650. delete self.$route.query.floorId;
  651. }
  652. if(self.$route.query.groupId){
  653. delete self.$route.query.groupId;
  654. }
  655. let obj = {
  656. buildId:self.buildingId,
  657. floorId:self.mapList[i].id,
  658. subId:self.mapList[i].buildFloorLayoutVoList[o].subId,
  659. planType:false
  660. }
  661. self.$parent.goPage(2,obj);
  662. return
  663. }
  664. }
  665. }
  666. }
  667. }
  668. }
  669. },
  670. //获取楼栋数据
  671. getBuilding(){
  672. getBuildOrFloorList({type:2,parentId:''}).then(response => {
  673. if(response.data[0]){
  674. this.$set(this,'buildingOptions',response.data);
  675. this.$set(this,'buildingId',response.data[0].id);
  676. //获取楼层数据
  677. this.getFloor();
  678. //获取楼栋人数
  679. this.getBuildOrFloorInfo();
  680. //获取eCharts数据
  681. this.exitHazardTotalByBuildId();
  682. //获取楼栋传感器数据接口
  683. this.getLotStatis();
  684. //楼栋MQTT
  685. this.offBuildingMQTT('on');
  686. //气瓶MQTT
  687. this.offGasBottleMQTT('on');
  688. }
  689. })
  690. },
  691. //楼栋数据选择
  692. buildingChange(){
  693. this.$set(this,'monitorType',null);
  694. //获取楼层数据
  695. this.getFloor();
  696. //获取楼栋人数
  697. this.getBuildOrFloorInfo();
  698. //获取eCharts数据
  699. this.exitHazardTotalByBuildId();
  700. //获取楼栋传感器数据接口
  701. this.getLotStatis();
  702. //楼栋MQTT
  703. this.offBuildingMQTT('on');
  704. //气瓶MQTT
  705. this.offGasBottleMQTT('on');
  706. },
  707. //获取楼栋人数
  708. getBuildOrFloorInfo(){
  709. let obj = {
  710. type:2,
  711. id:this.buildingId
  712. }
  713. getBuildOrFloorInfo(obj).then(response => {
  714. this.$set(this,'userNum',response.data.online);
  715. })
  716. },
  717. //获取楼层数据
  718. getFloor(){
  719. getBuildOrFloorDetailList({parentId : this.buildingId}).then(response => {
  720. let list = [];
  721. let monitorList = [];
  722. for(let i=0;i<response.data.length;i++){
  723. let obj = {
  724. id:response.data[i].id,
  725. name:response.data[i].name,
  726. parentId:response.data[i].parentId,
  727. subNum:response.data[i].subNum,
  728. buildFloorLayoutVoList:response.data[i].buildFloorLayoutVoList,
  729. relationalData:JSON.parse(response.data[i].exitLineVertexList[0].layoutJoinData),
  730. checkType:false,
  731. indexName:i+1,
  732. }
  733. list.push(obj);
  734. //处理楼层摄像头
  735. if(response.data[i].sparseHardwareList[0]){
  736. let newObj = {
  737. name:response.data[i].name,
  738. type:i==0?true:false,
  739. hardwareList:[],
  740. urlList:[],
  741. }
  742. for(let o=0;o<response.data[i].sparseHardwareList.length;o++){
  743. newObj.hardwareList.push(response.data[i].sparseHardwareList[o].hardwareNum)
  744. }
  745. monitorList.push(newObj)
  746. }
  747. }
  748. this.$set(this,'maxMapList',list);
  749. //处理楼层摄像头
  750. this.$set(this,'monitorNumList',monitorList);
  751. if(monitorList[0]){
  752. this.getMonitorUrl(0);
  753. }
  754. //初始化
  755. this.dataDispose(0);
  756. })
  757. },
  758. //获取楼栋摄像头
  759. async getMonitorUrl(index){
  760. let self = this;
  761. if(index !== this.monitorType){
  762. this.videoOff()
  763. let obj = {
  764. page:"1",
  765. count:"100",
  766. deviceIds:this.monitorNumList[index].hardwareList+'',
  767. };
  768. const { data } = await startUrl(obj);
  769. if(data){
  770. let newData = data;
  771. let urlText = window.location.href;
  772. let videoList = [];
  773. if(urlText.indexOf(localStorage.getItem('ipIdentify')) != -1){
  774. for(let i=0;i<newData.length;i++){
  775. let obj = {
  776. divId:newData[i].deviceID,
  777. hasAudio:false,
  778. height:false,
  779. videoUrl:newData[i].ws_flv,
  780. }
  781. videoList.push(obj)
  782. }
  783. }else{
  784. for(let i=0;i<newData.length;i++){
  785. let text = localStorage.getItem('cameraUrl');
  786. let url = newData[i].ws_flv;
  787. url = url.split("rtp/");
  788. let newUrl = text+'rtp/'+url[1];
  789. let obj = {
  790. divId:newData[i].deviceID,
  791. hasAudio:false,
  792. height:false,
  793. videoUrl:newUrl,
  794. }
  795. videoList.push(obj)
  796. }
  797. }
  798. this.$set(this,'videoList',videoList);
  799. this.$set(this,'monitorType',index);
  800. setTimeout(function(){
  801. self.videoPlay();
  802. },300);
  803. }
  804. }
  805. },
  806. //播放视频流
  807. videoPlay(){
  808. let self = this;
  809. this.loading = false;
  810. let videoList = JSON.parse(JSON.stringify(this.videoList))
  811. for(let i=0;i<videoList.length;i++){
  812. let obj = {
  813. player :{},
  814. flvPlayer:{}
  815. };
  816. obj.player = document.getElementById(videoList[i].divId);
  817. obj.flvPlayer = flvjs.createPlayer(
  818. {
  819. // isLive: true, //=> 是否为直播流
  820. // hasAudio: false, //=> 是否开启声音
  821. type: 'flv', //媒体类型 flv 或 mp4
  822. url: videoList[i].videoUrl //视频流地址
  823. },
  824. {
  825. enableStashBuffer: true,//启用 IO 存储缓冲区。 如果您需要实时流播放(最小延迟),请设置为 false,但如果存在网络抖动,则可能会停止。
  826. stashInitialSize: 128,//IO 存储缓冲区初始大小。 默认值为 384KB。 指示合适的大小可以改善视频加载/搜索时间。
  827. isLive: true,//是否是直播
  828. lazyLoadRecoverDuration: 30,//指示以秒为单位的lazyLoad 恢复时间边界。
  829. autoCleanupSourceBuffer: true,//进行自动清理
  830. autoCleanupMaxBackwardDuration: 3 * 60,//3 * 60 当向后缓冲持续时间超过这个值(以秒为单位)时,对 SourceBuffer 进行自动清理
  831. autoCleanupMinBackwardDuration: 2 * 60,//2 * 60 指示在执行自动清理时为后向缓冲区保留的持续时间(以秒为单位)。
  832. }
  833. );
  834. self.videoPlayList.push(obj);
  835. }
  836. for(let i=0;i<self.videoPlayList.length;i++){
  837. self.videoPlayList[i].flvPlayer.attachMediaElement(self.videoPlayList[i].player);
  838. self.videoPlayList[i].flvPlayer.load(); //加载
  839. self.videoPlayList[i].flvPlayer.play(); //加载
  840. }
  841. },
  842. //断开视频流
  843. videoOff(){
  844. let self = this;
  845. if(self.videoPlayList[0]){
  846. for(let i=0;i<self.videoPlayList.length;i++){
  847. if(self.videoPlayList[i].flvPlayer){
  848. self.videoPlayList[i].flvPlayer.pause();
  849. self.videoPlayList[i].flvPlayer.unload();
  850. self.videoPlayList[i].flvPlayer.detachMediaElement();
  851. self.videoPlayList[i].flvPlayer.destroy();
  852. self.videoPlayList[i].flvPlayer = null;
  853. }
  854. }
  855. self.$set(self,'videoList',[]);
  856. self.$set(self,'videoPlayList',[]);
  857. }
  858. },
  859. //获取楼栋下传感器数据
  860. getLotStatis(){
  861. getLotStatis({buildId:this.buildingId}).then(response => {
  862. this.$set(this,'lotStaticList',response.data.lotStaticList);
  863. this.$set(this,'lotStaticSum',response.data.lotStaticSum);
  864. })
  865. },
  866. //获取eCharts数据
  867. exitHazardTotalByBuildId(){
  868. exitHazardTotalByBuildId({buildId:this.buildingId}).then(response => {
  869. if(response.data.hazardTotal[0]){
  870. this.$set(this,'hazardSum',response.data.hazardSum);
  871. let obj = {
  872. nameList: [],
  873. numList: [],
  874. maxNumList: [],
  875. }
  876. for(let i=0;i<response.data.hazardTotal.length;i++){
  877. obj.nameList.push(response.data.hazardTotal[i].name.length>6?response.data.hazardTotal[i].name.substring(0,6)+'..':response.data.hazardTotal[i].name)
  878. obj.numList.push(response.data.hazardTotal[i].percentage)
  879. obj.maxNumList.push(100)
  880. }
  881. this.$set(this,'eChartsData',obj);
  882. this.eChartsFunction(this.eChartsData);
  883. }else{
  884. this.$set(this,'hazardSum',0);
  885. let obj = {
  886. nameList: [],
  887. numList: [],
  888. maxNumList: [],
  889. }
  890. this.$set(this,'eChartsData',obj);
  891. this.eChartsFunction(this.eChartsData);
  892. }
  893. });
  894. },
  895. //eCharts表格
  896. eChartsFunction(obj){
  897. let self = this;
  898. // document.getElementById('eCharts').innerHTML = '';
  899. this.myChart = this.$echarts.init(document.getElementById('eCharts'));
  900. let option = {
  901. backgroundColor: 'rgba(0,0,0,0)',
  902. grid: {
  903. left: '10%',
  904. right: '10%',
  905. bottom: '10%',
  906. top: '10%',
  907. containLabel: true,
  908. },
  909. legend: [{
  910. show: false,
  911. }],
  912. xAxis: [
  913. {
  914. type: 'category',
  915. data: obj.nameList,
  916. axisLine: {
  917. lineStyle: {
  918. color: 'rgba(5, 80, 93, 1)',
  919. },
  920. },
  921. axisLabel: {
  922. fontSize: 12,
  923. // color: 'black',
  924. color: '#fff',
  925. fontFamily: 'DIN-Medium',
  926. padding: [3, 0, 0, 0]
  927. },
  928. axisTick: {
  929. show: false,
  930. },
  931. },
  932. {
  933. type: 'category',
  934. data: obj.nameList,
  935. show: false,
  936. },],
  937. yAxis: [{
  938. type: 'value',
  939. name: "",
  940. nameTextStyle: {
  941. fontSize: 14,
  942. fontFamily: 'Source Han Sans CN',
  943. fontWeight: '400',
  944. color: 'rgba(255, 255, 255, 1)',
  945. padding: [0, 75, -8, 0]
  946. },
  947. nameGap: 24,
  948. axisLine: {
  949. show: true,
  950. lineStyle: {
  951. color: 'rgba(5, 80, 93, 1)',
  952. }
  953. },
  954. axisTick: {
  955. show: false,
  956. },
  957. splitLine: {
  958. show: false,
  959. lineStyle: {
  960. color: 'rgba(5, 80, 93, 1)',
  961. type: "dashed",
  962. },
  963. },
  964. alignTicks: true,
  965. axisLabel: {
  966. fontSize: 12,
  967. color: 'rgba(255, 255, 255, 1)',
  968. fontFamily: 'DIN-Medium',
  969. padding: [0, 7, 0, 0]
  970. },
  971. splitArea: {
  972. show: false,
  973. },
  974. }],
  975. series: [
  976. {
  977. type: 'bar',
  978. label: {
  979. normal: {
  980. show: true,
  981. position: 'top',
  982. fontSize: 12,
  983. color: 'rgba(16, 213, 223, 1)',
  984. formatter: function (params) {
  985. return params.value + '%'
  986. },
  987. offset: [0, -10],
  988. },
  989. },
  990. tooltip: {
  991. show: false
  992. },
  993. barWidth: 14,
  994. itemStyle: {
  995. color: {
  996. type: 'linear',
  997. x: 0, x2: 0, y: 0, y2: 1,
  998. colorStops: [
  999. { offset: 0, color: '#00FCFC' },
  1000. { offset: 1, color: '#016FCC' }
  1001. ]
  1002. },
  1003. },
  1004. name: '',
  1005. data: obj.numList
  1006. },
  1007. {
  1008. // 分隔
  1009. type: 'pictorialBar',
  1010. itemStyle: {
  1011. normal: {
  1012. color: 'rgba(3, 72, 84, 0.5)',
  1013. },
  1014. },
  1015. symbolRepeat: 'fixed',//重复
  1016. symbolMargin: 2,//上下间隔
  1017. symbol: 'rect',//图形类型
  1018. symbolClip: true,//是否裁剪
  1019. symbolSize: [20, 2],//图形的大小,可以用数组分开表示宽和高
  1020. symbolPosition: 'center',//图形的定位位置
  1021. symbolOffset: [0, 2],//图形相对于原本位置的偏移
  1022. data: obj.numList,
  1023. z: 0,
  1024. zlevel: 1,
  1025. },
  1026. {
  1027. type: 'bar',
  1028. barWidth: 40,
  1029. xAxisIndex: 1,
  1030. itemStyle: {
  1031. color: 'rgba(0, 0, 0, 0)'
  1032. },
  1033. name: '',
  1034. data: obj.maxNumList
  1035. },
  1036. ],
  1037. }
  1038. this.myChart.setOption(option);
  1039. },
  1040. //查询预案发生
  1041. selectTriggerInfo(){
  1042. let self = this;
  1043. let newList = [];
  1044. selectTriggerInfo().then(responseOne => {
  1045. newList = newList.concat(responseOne.data);
  1046. airbottleBluetoothGetBeaconNotice().then(responseTow => {
  1047. newList = newList.concat(responseTow.data);
  1048. //********************处理数据********************
  1049. if(newList[0]){
  1050. //楼栋预案标记
  1051. for(let o=0;o<self.buildingOptions.length;o++){
  1052. let num = 0;
  1053. for(let i=0;i<newList.length;i++){
  1054. if(newList[i].buildId == self.buildingOptions[o].id){
  1055. num++
  1056. }
  1057. }
  1058. self.buildingOptions[o].planType = num != 0;
  1059. }
  1060. for(let i=0;i<newList.length;i++){
  1061. for(let o=0;o<self.mapList.length;o++){
  1062. for(let x=0;x<self.mapList[o].relationalData.length;x++){
  1063. if (self.mapList[o].relationalData[x].type == '1' && self.mapList[o].relationalData[x].roomType!='-99'){
  1064. if(newList[i].subId == self.mapList[o].relationalData[x].subId){
  1065. self.mapList[o].relationalData[x].planType = true;
  1066. //判断预案是否进入过
  1067. // for(let s=0;s<newList.length;s++){
  1068. // if(newList[s].riskAttribute != '1'&&newList[s].ifCheck != '1'){
  1069. // setTimeout(function (){
  1070. // if(self.$route.query.buildId){
  1071. // delete self.$route.query.buildId;
  1072. // }
  1073. // if(self.$route.query.subId){
  1074. // delete self.$route.query.subId;
  1075. // }
  1076. // if(self.$route.query.floorId){
  1077. // delete self.$route.query.floorId;
  1078. // }
  1079. // if(self.$route.query.groupId){
  1080. // delete self.$route.query.groupId;
  1081. // }
  1082. // let obj = {
  1083. // buildId:newList[s].buildId,
  1084. // floorId:newList[s].floorId,
  1085. // subId:newList[s].subId,
  1086. // groupId:newList[s].groupId,
  1087. // planType:true
  1088. // }
  1089. // self.$parent.goPage(2,obj);
  1090. // },5000)
  1091. // break
  1092. // }
  1093. // }
  1094. }else{
  1095. self.mapList[o].relationalData[x].planType = false;
  1096. }
  1097. }
  1098. }
  1099. }
  1100. }
  1101. this.$forceUpdate();
  1102. }else{
  1103. for(let o=0;o<self.mapList.length;o++){
  1104. for(let x=0;x<self.mapList[o].relationalData.length;x++){
  1105. if (self.mapList[o].relationalData[x].type == '1' && self.mapList[o].relationalData[x].roomType!='-99'){
  1106. self.mapList[o].relationalData[x].planType = false;
  1107. }
  1108. }
  1109. }
  1110. for(let o=0;o<self.buildingOptions.length;o++){
  1111. self.buildingOptions[o].planType = false;
  1112. }
  1113. this.$forceUpdate();
  1114. }
  1115. this.initAdd();
  1116. })
  1117. })
  1118. },
  1119. //全局-MQTT订阅
  1120. onAllMQTT(){
  1121. let self = this;
  1122. this.allClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
  1123. username: localStorage.getItem('mqttUser'),
  1124. password: localStorage.getItem('mqttPassword')
  1125. });
  1126. this.allClient.on("connect", e =>{
  1127. // console.log("连接成功");
  1128. this.allClient.subscribe(self.planTopic, (err) => {
  1129. if (!err) {
  1130. // console.log("预案-订阅成功:" + self.planTopic);
  1131. }
  1132. });
  1133. });
  1134. this.allClient.on("message", (topic, message) => {
  1135. if (message){
  1136. let data = JSON.parse(message)
  1137. if(data){
  1138. // console.log('data',data);
  1139. if(topic == self.planTopic){
  1140. //传感器状态
  1141. // console.log('预案-状态');
  1142. self.selectTriggerInfo();
  1143. }
  1144. }
  1145. }
  1146. });
  1147. },
  1148. //楼层-MQTT订阅
  1149. onBuildingMQTT(){
  1150. let self = this;
  1151. this.buildingClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
  1152. username: localStorage.getItem('mqttUser'),
  1153. password: localStorage.getItem('mqttPassword')
  1154. });
  1155. this.buildingClient.subscribe(self.userTopic+self.buildingId, (err) => {
  1156. if (!err) {
  1157. // console.log("实验室人数-订阅成功:" + self.userTopic+self.buildingId);
  1158. }
  1159. });
  1160. this.buildingClient.on("message", (topic, message) => {
  1161. if (message){
  1162. let data = JSON.parse(message)
  1163. if(data){
  1164. // console.log('data',data);
  1165. if(topic == (self.userTopic+self.buildingId)){
  1166. // console.log('实验室人数-状态');
  1167. //实验室人数
  1168. self.getBuildOrFloorInfo();
  1169. }
  1170. }
  1171. }
  1172. });
  1173. },
  1174. //气瓶-MQTT订阅
  1175. onGasBottleMQTT(){
  1176. let self = this;
  1177. this.gasBottleClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
  1178. username: localStorage.getItem('mqttUser'),
  1179. password: localStorage.getItem('mqttPassword')
  1180. });
  1181. this.gasBottleClient.on("connect", e =>{
  1182. // console.log("气瓶-连接成功");
  1183. this.gasBottleClient.subscribe(self.gasBottleTopic, (err) => {
  1184. if (!err) {
  1185. // console.log("气瓶-订阅成功:" + self.gasBottleTopic);
  1186. }
  1187. });
  1188. });
  1189. this.gasBottleClient.on("message", (topic, message) => {
  1190. if (message){
  1191. let data = JSON.parse(message)
  1192. if(data){
  1193. // console.log('data',data);
  1194. if(topic == (self.gasBottleTopic)){
  1195. //气瓶-预案触发
  1196. // console.log('气瓶-预案触发');
  1197. // this.$set(this,'sensorList',this.sensorIconMatching(data.data.functionStatuses));
  1198. this.selectTriggerInfo();
  1199. }
  1200. }
  1201. }
  1202. });
  1203. },
  1204. //取消订阅-全局-关闭MQTT连接
  1205. offAllMQTT(type){
  1206. // console.log('type',type)
  1207. let self = this;
  1208. //判断是否已有连接如果有责断开
  1209. if(this.allClient.unsubscribe){
  1210. this.allClient.unsubscribe(self.planTopic, error => {
  1211. if (error) {
  1212. console.log('预案-MQTT断开报错=>', error)
  1213. }
  1214. })
  1215. this.allClient.end();
  1216. this.$set(this,'allClient',{});
  1217. }
  1218. //判断传入参数如果存在 发起一次新的连接
  1219. if(type){
  1220. this.onAllMQTT();
  1221. }
  1222. },
  1223. //取消订阅-楼层-关闭MQTT连接
  1224. offBuildingMQTT(type){
  1225. let self = this;
  1226. //判断是否已有连接如果有责断开
  1227. if(this.buildingClient.unsubscribe){
  1228. this.buildingClient.unsubscribe(self.userTopic+self.buildingId, error => {
  1229. if (error) {
  1230. console.log('实验室人数-MQTT断开报错=>', error)
  1231. }
  1232. })
  1233. this.buildingClient.end();
  1234. this.$set(this,'buildingClient',{});
  1235. }
  1236. //判断传入参数如果存在 发起一次新的连接
  1237. if(type){
  1238. this.onBuildingMQTT();
  1239. }
  1240. },
  1241. //取消订阅气瓶-MQTT连接
  1242. offGasBottleMQTT(type){
  1243. let self = this;
  1244. //判断是否已有连接如果有责断开
  1245. if(this.gasBottleClient.unsubscribe){
  1246. this.gasBottleClient.unsubscribe(self.gasBottleTopic, error => {
  1247. if (error) {
  1248. console.log('气瓶-MQTT断开报错=>', error)
  1249. }
  1250. })
  1251. this.gasBottleClient.end();
  1252. this.$set(this,'gasBottleClient',{});
  1253. }
  1254. //判断传入参数如果存在 发起一次新的连接
  1255. if(type){
  1256. // console.log('===========>')
  1257. this.onGasBottleMQTT();
  1258. }
  1259. },
  1260. //跳转
  1261. goRoute(){
  1262. if(this.routeType){
  1263. this.$router.push({
  1264. path: "/emergencyManagement/newPerformEvacuation"
  1265. })
  1266. }else{
  1267. this.$router.push({
  1268. path: "/newEvacuationBigData"
  1269. })
  1270. }
  1271. },
  1272. accMul(arg1,arg2){
  1273. var m=0,s1=arg1.toString(),s2=arg2.toString();
  1274. try{m+=s1.split(".")[1].length}catch(e){}
  1275. try{m+=s2.split(".")[1].length}catch(e){}
  1276. return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
  1277. },
  1278. },
  1279. beforeDestroy() {
  1280. //清除定时器
  1281. let self = this;
  1282. self.videoOff();
  1283. // self.offAllMQTT();
  1284. self.offBuildingMQTT();
  1285. self.offGasBottleMQTT();
  1286. cancelAnimationFrame(self.animateData);
  1287. self.scene.traverse((child) => {
  1288. if (child.material) {
  1289. for(let i=0;i<child.material.length;i++){
  1290. child.material[i].dispose();
  1291. }
  1292. }
  1293. if (child.geometry) {
  1294. child.geometry.dispose();
  1295. }
  1296. child = null;
  1297. });
  1298. self.container.innerHTML = '';
  1299. self.renderer.forceContextLoss();
  1300. self.renderer.dispose();
  1301. self.scene.clear();
  1302. self.$set(self,'scene',null);
  1303. self.$set(self,'camera',null);
  1304. self.$set(self,'controls',null);
  1305. self.$set(self.renderer,'domElement',null);
  1306. self.$set(self,'renderer',null);
  1307. self.$set(self,'animateData',null);
  1308. self.$set(self,'container',null);
  1309. console.log("beforeDestroy");
  1310. },
  1311. }
  1312. </script>
  1313. <style scoped lang="scss">
  1314. .newEvacuationBigDataHome{
  1315. flex:1;
  1316. position: relative;
  1317. display: flex;
  1318. width:1920px;
  1319. height:1080px;
  1320. background: url("../assets/ZDimages/bigData3_2/img_bg.png") repeat;
  1321. background-size: 100% 100%;
  1322. p{
  1323. margin:0;
  1324. }
  1325. .evacuation-title-position-box{
  1326. position: absolute;
  1327. top:0;
  1328. height:92px;
  1329. left:41px;
  1330. width: 1837px;
  1331. background: url("../assets/ZDimages/bigData3_2/sy_db_bg.png");
  1332. background-size: 100% 100%;
  1333. text-align: center;
  1334. font-size:40px;
  1335. line-height:82px;
  1336. color:#24d1f9;
  1337. font-weight:900;
  1338. letter-spacing:10px
  1339. }
  1340. .evacuation-out-button-position-box{
  1341. display: flex;
  1342. position: absolute;
  1343. top:0;
  1344. right:0;
  1345. width:110px;
  1346. cursor: pointer;
  1347. i{
  1348. margin:0 10px;
  1349. line-height:40px;
  1350. color:#24D1F9;
  1351. font-size:18px;
  1352. }
  1353. p{
  1354. line-height:40px;
  1355. color:#24D1F9;
  1356. font-size:14px;
  1357. }
  1358. }
  1359. .left-max-big-box{
  1360. width:400px;
  1361. .left-top-big-box{
  1362. height:688px;
  1363. margin-top:71px;
  1364. position: relative;
  1365. .left-top-for-big-box{
  1366. .left-top-for-box{
  1367. display: inline-block;
  1368. width:78px;
  1369. height:118px;
  1370. position: relative;
  1371. margin:30px 0 0 43px;
  1372. p:nth-child(1){
  1373. line-height: 32px;
  1374. font-size:20px;
  1375. font-weight:700;
  1376. text-align: center;
  1377. color:#24d1f9;
  1378. }
  1379. p:nth-child(2){
  1380. line-height: 18px;
  1381. font-size:16px;
  1382. font-weight:500;
  1383. text-align: center;
  1384. color:#fff;
  1385. }
  1386. img:nth-child(3){
  1387. position: absolute;
  1388. bottom:14px;
  1389. left:19px;
  1390. width:40px;
  1391. height:40px;
  1392. }
  1393. img:nth-child(4){
  1394. position: absolute;
  1395. bottom:0;
  1396. left:0;
  1397. width:78px;
  1398. height:86px;
  1399. }
  1400. }
  1401. }
  1402. .hazardSum-p{
  1403. position: absolute;
  1404. top:26px;
  1405. right:60px;
  1406. color:#fff;
  1407. font-size:14px;
  1408. text-align: right;
  1409. }
  1410. }
  1411. .left-bottom-big-box{
  1412. height:321px;
  1413. position: relative;
  1414. #eCharts{
  1415. height:262px;
  1416. }
  1417. .eCharts-null-p{
  1418. position: absolute;
  1419. top:180px;
  1420. left:165px;
  1421. color:#fff;
  1422. font-size:14px;
  1423. }
  1424. .hazardSum-p{
  1425. position: absolute;
  1426. top:26px;
  1427. right:60px;
  1428. color:#fff;
  1429. font-size:14px;
  1430. text-align: right;
  1431. }
  1432. }
  1433. .big-title-box{
  1434. margin:0 0 0 29px;
  1435. width:181px;
  1436. height:59px;
  1437. background: url("../assets/ZDimages/bigData3_2/img_zjdp_bg.png");
  1438. background-size: 100%;
  1439. display: flex;
  1440. img{
  1441. width:18px;
  1442. height:18px;
  1443. margin:27px 16px 0 20px;
  1444. }
  1445. p{
  1446. margin-top:16px;
  1447. line-height:40px;
  1448. color:#fff;
  1449. font-size:16px;
  1450. }
  1451. }
  1452. }
  1453. .center-max-big-box{
  1454. flex:1;
  1455. display: flex;
  1456. flex-direction: column;
  1457. overflow: hidden;
  1458. position: relative;
  1459. .top-button-box{
  1460. height:226px;
  1461. position: relative;
  1462. .top-button-left-select-box{
  1463. position: absolute;
  1464. top:146px;
  1465. left:69px;
  1466. }
  1467. .top-button-right-num-box{
  1468. }
  1469. }
  1470. #container{
  1471. flex:1;
  1472. background: rgba(0,0,0,0)!important;
  1473. }
  1474. .position-floor-user-box{
  1475. position: absolute;
  1476. right:120px;
  1477. top:146px;
  1478. height:40px;
  1479. display: flex;
  1480. img{
  1481. width:26px;
  1482. height:24px;
  1483. margin:8px 16px 0 0;
  1484. }
  1485. p:nth-child(2){
  1486. font-size:16px;
  1487. color:#24D1F9;
  1488. line-height: 40px;
  1489. }
  1490. p:nth-child(3){
  1491. margin-left:10px;
  1492. font-size:20px;
  1493. color:#24D1F9;
  1494. line-height: 40px;
  1495. font-weight:900;
  1496. }
  1497. }
  1498. .position-floor-button-box{
  1499. position: absolute;
  1500. right:90px;
  1501. top:300px;
  1502. .position-floor-for-button-p:first-child{
  1503. border-top:2px solid #1e7790;
  1504. border-top-left-radius: 4px;
  1505. border-top-right-radius: 4px;
  1506. }
  1507. .position-floor-for-button-p:last-child{
  1508. border-bottom:2px solid #1e7790;
  1509. border-bottom-left-radius: 4px;
  1510. border-bottom-right-radius: 4px;
  1511. }
  1512. .check-button-box:first-child{
  1513. border-top:2px solid #24d1f9;
  1514. border-top-left-radius: 4px;
  1515. border-top-right-radius: 4px;
  1516. }
  1517. .check-button-box:last-child{
  1518. border-bottom:2px solid #24d1f9;
  1519. border-bottom-left-radius: 4px;
  1520. border-bottom-right-radius: 4px;
  1521. }
  1522. .position-floor-for-button-p{
  1523. width:38px;
  1524. height:36px;
  1525. text-align: center;
  1526. line-height:36px;
  1527. color:#1e7790;
  1528. border-left:2px solid #1e7790;
  1529. border-right:2px solid #1e7790;
  1530. border-bottom:1px solid #1e7790;
  1531. border-top:1px solid #1e7790;
  1532. font-size:12px;
  1533. cursor: pointer;
  1534. }
  1535. .check-button-box{
  1536. border-left:2px solid #24d1f9;
  1537. border-right:2px solid #24d1f9;
  1538. border-bottom:1px solid #24d1f9;
  1539. border-top:1px solid #24d1f9;
  1540. color:#fff;
  1541. box-shadow:0 0 6px 1px #24D1F9 inset;
  1542. }
  1543. }
  1544. }
  1545. .right-max-big-box{
  1546. width:400px;
  1547. margin-top:71px;
  1548. .null-p{
  1549. text-align: center;
  1550. line-height:500px;
  1551. color:#fff;
  1552. }
  1553. .monitor-max-for-box:nth-child(1){
  1554. .monitor-title-box{
  1555. border-top:none;
  1556. }
  1557. }
  1558. .monitor-max-for-box{
  1559. width:366px;
  1560. .monitor-title-box{
  1561. display: flex;
  1562. border-top:1px dashed #24D1F9;
  1563. border-bottom:1px dashed #24D1F9;
  1564. p{
  1565. color:#24D1F9;
  1566. font-size:16px;
  1567. line-height:54px;
  1568. flex:1;
  1569. margin-left:7px;
  1570. }
  1571. i{
  1572. color:#24D1F9;
  1573. font-size:18px;
  1574. line-height:54px;
  1575. text-align: center;
  1576. width:20px;
  1577. cursor: pointer;
  1578. margin-right:32px;
  1579. }
  1580. }
  1581. .video-mx-big-box:nth-child(2){
  1582. margin-top:20px;
  1583. }
  1584. .video-mx-big-box{
  1585. margin-bottom:20px;
  1586. }
  1587. }
  1588. }
  1589. }
  1590. </style>
  1591. <style lang="scss">
  1592. .newEvacuationBigDataHome{
  1593. .building-select-box{
  1594. .el-input__inner{
  1595. background:rgba(0,0,0,0);
  1596. border:1px solid #24D1F9;
  1597. box-shadow:0 0 5px 1px #24D1F9 inset;
  1598. color:#fff;
  1599. }
  1600. .el-input__inner:hover{
  1601. border:1px solid #24D1F9;
  1602. box-shadow:0 0 5px 1px #24D1F9 inset;
  1603. }
  1604. }
  1605. .floor-select-box{
  1606. width:100px;
  1607. .el-input__inner{
  1608. background:rgba(0,0,0,0);
  1609. border:1px solid #24D1F9;
  1610. box-shadow:0 0 5px 1px #24D1F9 inset;
  1611. color:#fff;
  1612. }
  1613. .el-input__inner:hover{
  1614. border:1px solid #24D1F9;
  1615. box-shadow:0 0 5px 1px #24D1F9 inset;
  1616. }
  1617. }
  1618. .el-select-dropdown{
  1619. background:#01294d;
  1620. border:1px solid #24D1F9;
  1621. .el-select-dropdown__item{
  1622. background: rgba(0,0,0,0);
  1623. color:#fff;
  1624. }
  1625. .el-select-dropdown__item:hover{
  1626. background: #24D1F9;
  1627. }
  1628. }
  1629. .popper__arrow{
  1630. top:-7px;
  1631. border-bottom-color:#24D1F9!important;
  1632. }
  1633. ::after{
  1634. border-bottom-color:#24D1F9!important;
  1635. }
  1636. ::placeholder{
  1637. color: #fff;
  1638. }
  1639. .scrollbar-box::-webkit-scrollbar{
  1640. width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
  1641. height: 4px;
  1642. }
  1643. .scrollbar-box::-webkit-scrollbar-thumb{
  1644. border-radius: 5px;
  1645. -webkit-box-shadow: inset 0 0 5px #116e8e;
  1646. background: #116e8e;
  1647. }
  1648. .scrollbar-box::-webkit-scrollbar-track{
  1649. -webkit-box-shadow: inset 0 0 5px rgba(255,255,255,0);
  1650. border-radius: 0;
  1651. background: rgba(255,255,255,0);
  1652. }
  1653. }
  1654. </style>