newEvacuationBigDataHome.vue 58 KB

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