monitor.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. <!--监控中心-->
  2. <template>
  3. <div class="visual-con">
  4. <!--头部-->
  5. <vheader></vheader>
  6. <!--主体-->
  7. <div class="visual-body">
  8. <!-- 左侧 -->
  9. <div class="leftbar" :class="indentleft" ref="left">
  10. <div class="forthis">
  11. <div class="this-title">
  12. <span>态势感知</span>
  13. </div>
  14. <div class="i-list-con h-73">
  15. <div class="d-l-con-icon">
  16. <div class="icon-con w-33 m-btm-no" v-for="(item,index) in visuForestCloudMapDeviceBOList" v-on:click="selectDeviceType()"><!-- -->
  17. <div class="icon icon-dot"></div>
  18. <div class="icon-text">
  19. <h6>{{item.deviceCount}}</h6>
  20. <h5>{{item.deviceName}}</h5>
  21. </div>
  22. </div>
  23. </div>
  24. <div class="overflow-y" style="height: 33vh;">
  25. <el-collapse accordion>
  26. <el-collapse-item v-for="(item,index) in region" :key="index"><!-- deptId -->
  27. <template slot="title">
  28. <div class="d-l-con sj-collapse" v-on:click="selectCameraByDeptId(item.deptId)">
  29. <div class="d-l-l-text">
  30. <h4 class="collapse-title">{{item.deptName}}</h4>
  31. </div>
  32. <div class="d-l-l-count">{{item.deptCount}}</div>
  33. </div>
  34. </template>
  35. </el-collapse-item>
  36. </el-collapse>
  37. </div>
  38. <!-- 横向柱状 echart -->
  39. <div class="overflow-y" style="height: 33vh;">
  40. <div id="camera-chart" style="width: 100%;height:33vh;"></div>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. <!-- 地图 -->
  46. <supermap ref="supermap" style="width: 100%;height: 100vh;" :mapDiv="'forestMap'"
  47. :mapSite="{doubleClickZoom:false}"
  48. :codes="['9fa5']" :isSideBySide="false" @preview="preview"></supermap>
  49. </button>
  50. <!-- 右侧 -->
  51. <div class="rightbar" :class="indentright" ref="right">
  52. <div class="forthis">
  53. <div class="this-title">
  54. <span>列表</span>
  55. </div>
  56. <div class="i-list-con h-43">
  57. <span v-for="(item,index) in visuForestCloudCameraBOList" v-on:click="dropLocation(item.latitude,item.longitude)">
  58. <div class="d-l-con" @click="">
  59. <div class="d-l-l-text">
  60. <i class="iconfont sj-icon-jkzx icon-sxt"></i>
  61. <h4>{{item.cameraName}}</h4>
  62. </div>
  63. </div>
  64. </span>
  65. </div>
  66. </div>
  67. <div class="forthis">
  68. <div class="this-title">
  69. <span>重点区域</span>
  70. </div>
  71. <div class="i-list-con h-25">
  72. <div class="d-l-con" @click="">
  73. <div class="d-l-l-text">
  74. <i class="i-small"></i>
  75. <h4>三门林场东</h4>
  76. </div>
  77. </div>
  78. <div class="d-l-con" @click="">
  79. <div class="d-l-l-text">
  80. <i class="i-small"></i>
  81. <h4>四家林场西</h4>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. <vBottomMenu ref="bottomMenu"></vBottomMenu>
  88. <el-tooltip :content="indentText" placement="top" :disabled="indentdisabled">
  89. <div class="mascot" ref="mascot" :class="indentStyle" @click="indent"><img
  90. src="@/assets/images/mascot.png"/></div>
  91. </el-tooltip>
  92. </div>
  93. <eventLocation ref="eventLocation"></eventLocation>
  94. </div>
  95. </template>
  96. <script>
  97. import { selectDeviceType, selectCameraByDeptId } from '@/api/monitor'
  98. import supermap from '@/components/supermap' //超图
  99. import vheader from '@/components/v-header.vue' //一体化共用头部
  100. import vBottomMenu from '@/components/vBottomMenu.vue' //一体化公共底部菜单
  101. import eventLocation from '@/components/eventLocation.vue' //事件定位弹窗
  102. /** ----------------------------------摄像头预览开始------------------------------------- */
  103. import {getDahuaVideoServer} from "@/api/dahua/dahua";
  104. import DHWs from '@/dahua/lib/DHWs'
  105. /** ----------------------------------摄像头预览结束------------------------------------- */
  106. // import echarts from 'echarts'
  107. let echarts = require('echarts')
  108. export default {
  109. components: {
  110. supermap,
  111. vheader,
  112. vBottomMenu,
  113. eventLocation
  114. },
  115. created() {
  116. /** ----------------------------------摄像头预览开始------------------------------------- */
  117. const DHWsInstance = DHWs.getInstance();
  118. this.ws = DHWsInstance;
  119. console.log(this.ws);
  120. /** ----------------------------------摄像头预览结束------------------------------------- */
  121. /** ----------------------------------底部按钮公用组件开始------------------------------------- */
  122. window.showDialog=this.showDialog
  123. window.closeChild=this.closeChild
  124. window.choseLayerSwitching=this.choseLayerSwitching
  125. /** ----------------------------------底部按钮公用组件结束------------------------------------- */
  126. },
  127. mounted() {
  128. this.selectDeviceType()
  129. },
  130. data() {
  131. return {
  132. /** ----------------------------------摄像头预览开始------------------------------------- */
  133. activePanel: 'key1',
  134. isLogin: false,
  135. cameraParams: [],
  136. /** ----------------------------------摄像头预览结束------------------------------------- */
  137. visuForestCloudMapDeviceBOList: [],
  138. visuForestCloudCameraBOList: [],
  139. cameraMarkersList: [],
  140. sourceData:[],
  141. iframeBoo: true,
  142. open: false,
  143. iframeVue: null,
  144. activeName: 'info',
  145. radio: '1',
  146. region: [],
  147. //左右缩进
  148. indentStyle: '',
  149. indentleft: '',
  150. indentright: '',
  151. indentText: '收起左右栏',
  152. indentdisabled: false
  153. }
  154. },
  155. methods: {
  156. /** ----------------------------------底部按钮公用组件开始------------------------------------- */
  157. showDialog(click) {
  158. if (click == 'eventLocation') {
  159. this.$refs.eventLocation.showEventLocation()
  160. this.$refs.supermap.isEditableLayers = false
  161. this.$refs.bottomMenu.showChild = false
  162. } else if (click == 'editableLayers') {
  163. this.$refs.bottomMenu.showChild = false
  164. if (!this.$refs.supermap.isEditableLayers) {
  165. this.$refs.supermap.isEditableLayers = true
  166. } else {
  167. this.$refs.supermap.isEditableLayers = false
  168. }
  169. } else if (click == 'layerSwitching') {
  170. this.$refs.supermap.isEditableLayers = false
  171. if (!this.$refs.bottomMenu.showChild) {
  172. this.$refs.bottomMenu.showChild = true
  173. } else {
  174. this.$refs.bottomMenu.showChild = false
  175. }
  176. }
  177. },
  178. //点击关闭选择图层
  179. closeChild() {
  180. this.$refs.bottomMenu.showChild = false
  181. },
  182. //选择图层
  183. choseLayerSwitching(url) {
  184. this.$refs.supermap.layerSwitching(url, true);
  185. },
  186. /** ----------------------------------底部按钮公用组件结束------------------------------------- */
  187. cameraChat(){
  188. // 基于准备好的dom,初始化echarts实例
  189. let myChart = echarts.init(document.getElementById('camera-chart'))
  190. // 绘制图表
  191. const dfColor = ['#92E1FF', '#0097FB', '#30ECA6', '#FFC227', '#FF4848']
  192. myChart.setOption({
  193. dataset: {
  194. source: this.sourceData
  195. },
  196. tooltip: {
  197. trigger: 'item'
  198. },
  199. grid: {
  200. top: '5%',
  201. left: '2%',
  202. // right: "4%",
  203. bottom: '-15%',
  204. width: '75%',
  205. containLabel: true
  206. },
  207. xAxis: {
  208. show: false,
  209. type: 'value'
  210. },
  211. yAxis: {
  212. type: 'category', // 不设置类目轴,抽离的dataset数据展示不出来
  213. inverse: true,
  214. axisLabel: {
  215. show: true,
  216. textStyle: {
  217. color: '#5deaff',
  218. fontSize: '12'
  219. }
  220. },
  221. splitLine: {
  222. show: false
  223. },
  224. axisTick: {
  225. show: false
  226. },
  227. axisLine: {
  228. show: false
  229. }
  230. },
  231. series: [{
  232. type: 'bar',
  233. animationCurve: 'easeOutBack',
  234. barWidth: 5,
  235. label: {
  236. show: true,
  237. position: 'right',
  238. offset: [0, 0],
  239. color: '#88dfd5',
  240. // fontSize: "12",
  241. style: {
  242. fill: '#fff'
  243. }
  244. },
  245. backgroundBar: {
  246. show: true,
  247. style: {
  248. fill: 'rgba(97,152,255,0.20)'
  249. }
  250. },
  251. barStyle: {
  252. stroke: 'rgba(41,244,236,1)'
  253. },
  254. gradient: {
  255. color: ['rgba(41,244,236,1)', 'rgba(41,244,236,0)']
  256. },
  257. itemStyle: {
  258. label: {
  259. show: true
  260. },
  261. labelLine: {
  262. show: false
  263. },
  264. color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{
  265. offset: 0,
  266. color: 'rgba(41,244,236,0)'
  267. },
  268. {
  269. offset: 1,
  270. color: 'rgba(41,244,236,.5)'
  271. }
  272. ]),
  273. borderColor: '#a2f9f7',
  274. shadowBlur: 16,
  275. shadowColor: '#a2f9f7'
  276. }
  277. }]
  278. })
  279. },
  280. selectDeviceType() {
  281. //获取左侧动态感知设备
  282. let that = this
  283. selectDeviceType().then(res => {
  284. that.visuForestCloudMapDeviceBOList = res.data.visuForestCloudMapDeviceBOList
  285. that.region = res.data.visuForestCloudTodaySjfbBOList
  286. if (res.data.visuForestCloudTodaySjfbBOList!=null&&res.data.visuForestCloudTodaySjfbBOList.length>0){
  287. for (let i = 0; i < res.data.visuForestCloudTodaySjfbBOList.length; i++) {
  288. let aa=[];
  289. aa.push(res.data.visuForestCloudTodaySjfbBOList[i].deptName)
  290. aa.push(Number(res.data.visuForestCloudTodaySjfbBOList[i].deptCount))
  291. this.sourceData.push(aa);
  292. }
  293. }
  294. that.visuForestCloudCameraBOList = res.data.visuForestCloudCameraBOList
  295. this.cameraChat();
  296. if (res.data.visuForestCloudCameraBOList != null && res.data.visuForestCloudCameraBOList.length > 0) {
  297. for (let i = 0; i < res.data.visuForestCloudCameraBOList.length; i++) {
  298. let markersMap = {
  299. lng: 124.59,
  300. lat: 43.02,
  301. icon: 'camera',
  302. bindPopupHtml: '',
  303. click: 'preview',
  304. parameter: '',
  305. keepBindPopup: false,
  306. isAggregation: false
  307. }
  308. if (res.data.visuForestCloudCameraBOList.length > 50) {
  309. markersMap.isAggregation = true
  310. }
  311. if(res.data.visuForestCloudCameraBOList[i].channelCode!=null){
  312. markersMap.parameter = res.data.visuForestCloudCameraBOList[i].channelCode.split(',')
  313. }else{
  314. markersMap.parameter = [];
  315. }
  316. markersMap.lng = res.data.visuForestCloudCameraBOList[i].longitude
  317. markersMap.lat = res.data.visuForestCloudCameraBOList[i].latitude
  318. markersMap.bindPopupHtml = '<div class="map-tip">' +
  319. '<span>' +
  320. ' <div class="d-l-con">' +
  321. ' <div class="d-l-l-text">' +
  322. ' <h4>经纬度:' + res.data.visuForestCloudCameraBOList[i].longitude + ',' + res.data.visuForestCloudCameraBOList[i].latitude + '</h4>' +
  323. ' </div>' +
  324. ' </div>' +
  325. ' </span>' +
  326. '<span>' +
  327. ' <div class="d-l-con">' +
  328. ' <div class="d-l-l-text">' +
  329. ' <h4>摄像头名称:' + res.data.visuForestCloudCameraBOList[i].cameraName + '</h4>' +
  330. ' </div>' +
  331. ' </div>' +
  332. ' </span>' +
  333. '</div>'
  334. this.cameraMarkersList.push(markersMap)
  335. // cameraAccount: "1"
  336. // cameraCode: "1000010"
  337. // cameraFactory: "2"
  338. // cameraIp: "1"
  339. // cameraName: "2"
  340. // cameraPasword: "2"
  341. // cameraPort: 2
  342. // cameraRadius: 20
  343. // cameraRegion: "3"
  344. // dataDeptId: null
  345. // dataStatus: null
  346. // eventType: null
  347. // height: "11"
  348. // id: "0d165fc362514f79b12a899ea66295fd"
  349. // latitude: "49.325625"
  350. // longitude: "125.3333"
  351. }
  352. setTimeout(() => {
  353. that.$refs.supermap.clearM(true)
  354. that.$refs.supermap.clearM(false)
  355. that.$refs.supermap.setMarkers(this.cameraMarkersList)
  356. },1000)
  357. }
  358. })
  359. },
  360. dropLocation(lat,lng) {
  361. this.$refs.supermap.dropLocation(lat,lng)
  362. },
  363. selectCameraByDeptId(depId) {
  364. let that=this;
  365. that.cameraMarkersList=[];
  366. that.visuForestCloudCameraBOList =[];
  367. selectCameraByDeptId(depId).then(res => {
  368. //根据设备类型查看列表
  369. that.visuForestCloudCameraBOList = res.data
  370. if (res.data != null && res.data.length > 0) {
  371. for (let i = 0; i < res.data.length; i++) {
  372. let markersMap = {
  373. lng: 124.59,
  374. lat: 43.02,
  375. icon: 'camera',
  376. bindPopupHtml: '',
  377. click: 'preview',
  378. parameter: '',
  379. keepBindPopup: false,
  380. isAggregation: false
  381. }
  382. if (res.data.length > 50) {
  383. markersMap.isAggregation = true
  384. }
  385. if(res.data[i].channelCode!=null){
  386. markersMap.parameter = res.data[i].channelCode.split(',')
  387. }else{
  388. markersMap.parameter = []
  389. }
  390. markersMap.lng = res.data[i].longitude
  391. markersMap.lat = res.data[i].latitude
  392. markersMap.bindPopupHtml = '<div class="map-tip">' +
  393. '<span>' +
  394. ' <div class="d-l-con">' +
  395. ' <div class="d-l-l-text">' +
  396. ' <h4>经纬度:' + res.data[i].longitude + ',' + res.data[i].latitude + '</h4>' +
  397. ' </div>' +
  398. ' </div>' +
  399. ' </span>' +
  400. '<span>' +
  401. ' <div class="d-l-con">' +
  402. ' <div class="d-l-l-text">' +
  403. ' <h4>摄像头名称:' + res.data[i].cameraName + '</h4>' +
  404. ' </div>' +
  405. ' </div>' +
  406. ' </span>' +
  407. '</div>'
  408. this.cameraMarkersList.push(markersMap)
  409. // cameraAccount: "1"
  410. // cameraCode: "1000010"
  411. // cameraFactory: "2"
  412. // cameraIp: "1"
  413. // cameraName: "2"
  414. // cameraPasword: "2"
  415. // cameraPort: 2
  416. // cameraRadius: 20
  417. // cameraRegion: "3"
  418. // dataDeptId: null
  419. // dataStatus: null
  420. // eventType: null
  421. // height: "11"
  422. // id: "0d165fc362514f79b12a899ea66295fd"
  423. // latitude: "49.325625"
  424. // longitude: "125.3333"
  425. }
  426. setTimeout(() => {
  427. that.$refs.supermap.clearM(true)
  428. that.$refs.supermap.clearM(false)
  429. that.$refs.supermap.setMarkers(this.cameraMarkersList)
  430. },1000)
  431. }
  432. })
  433. },
  434. //吉祥物收起左右框
  435. indent() {
  436. let list = document.getElementsByClassName('el-tooltip__popper')
  437. list[list.length - 1].style.display = 'none'
  438. if (this.indentStyle == '') {
  439. this.indentStyle = 'indent-style'
  440. this.indentleft = 'indent-left'
  441. this.indentright = 'indent-right'
  442. this.indentText = '展开左右栏'
  443. } else if (this.indentText == '展开左右栏') {
  444. this.indentStyle = ''
  445. this.indentleft = ''
  446. this.indentright = ''
  447. this.indentText = '收起左右栏'
  448. }
  449. },
  450. /** ----------------------------------摄像头预览开始------------------------------------- */
  451. alertLogin: function () {
  452. this.$modal.msg("登录中....");
  453. },
  454. alertLoginSuccess: function () {
  455. this.$modal.msgSuccess("登录成功!");
  456. },
  457. alertLoginFailed: function () {
  458. this.$modal.msgError("登陆失败!");
  459. },
  460. alertReinstall: function () {
  461. this.$modal.msgWarning("请重新安装客户端");
  462. },
  463. /** 预览按钮操作 */
  464. preview(channelCode) {
  465. getDahuaVideoServer().then(newResponse => {
  466. this.ws.detectConnectQt().then(res => {
  467. if (res) { // 连接客户端成功
  468. this.alertLogin();
  469. this.ws.login({
  470. loginIp: newResponse.loginIp,
  471. loginPort: newResponse.loginPort,
  472. userName: newResponse.userName,
  473. userPwd: newResponse.userPwd,
  474. token: '',
  475. https: 1
  476. });
  477. this.ws.on('loginState', (res) => {
  478. this.isLogin = res;
  479. console.log('---res-----', res);
  480. if (res) {
  481. this.alertLoginSuccess()
  482. this.activePanel = 'key2'
  483. this.realTimeVideoDialog(channelCode);
  484. } else {
  485. this.alertLoginFailed();
  486. }
  487. });
  488. } else { // 连接客户端失败
  489. this.alertReinstall();
  490. }
  491. });
  492. });
  493. },
  494. realTimeVideoDialog(cameraParams) { // 调用弹窗实时播放接口
  495. if (!this.isLogin) {
  496. this.$Message.info('正在登陆客户端,请稍等......');
  497. return false;
  498. }
  499. this.ws.openVideo(cameraParams);
  500. },
  501. /** ----------------------------------摄像头预览结束------------------------------------- */
  502. }
  503. }
  504. </script>
  505. <style rel="stylesheet/scss" lang="scss" scoped>
  506. @import '@/assets/styles/base.scss';
  507. .header {
  508. width: 100%;
  509. background: #a7ec12;
  510. background: url(../assets/images/visual/v-header.png) repeat-x;
  511. height: 2.5rem;
  512. display: flex;
  513. align-items: center;
  514. z-index: 1000;
  515. position: absolute;
  516. top: 0;
  517. .title {
  518. display: flex;
  519. position: fixed;
  520. left: 50%;
  521. transform: translateX(-50%);
  522. h3 {
  523. display: flex;
  524. align-items: center;
  525. text-align: center;
  526. color: $white;
  527. font-size: 1.8rem;
  528. font-family: $fontFk;
  529. background: url(../assets/images/integrated/bigdata-header-nav-re2.png) repeat-x center;
  530. img {
  531. margin-right: .5rem;
  532. }
  533. }
  534. }
  535. .bignav {
  536. height: 40px;
  537. position: fixed;
  538. left: 50%;
  539. transform: translateX(-50%);
  540. top: 2.4rem;
  541. z-index: 1000;
  542. border-radius: 5px;
  543. display: flex;
  544. justify-content: cetner;
  545. align-items: center;
  546. .bignav-list {
  547. background: url(../assets/images/integrated/bigdata-header-nav-re2.png) repeat-x center;
  548. float: left;
  549. display: flex;
  550. justify-content: cetner;
  551. align-items: center;
  552. color: $white;
  553. height: 40px;
  554. font-size: 12px;
  555. padding: 0 23px;
  556. cursor: pointer;
  557. -webkit-transform: translateY(0);
  558. transform: translateY(0);
  559. transition: all 0.3s ease-in-out;
  560. }
  561. .router-link-active,
  562. .bignav-list:hover {
  563. filter: brightness(2.3);
  564. -webkit-transform: translateY(-1px);
  565. transform: translateY(-1px);
  566. color: $inBlueHover;
  567. border-bottom: 1px solid $inBlueHover;
  568. transition: all 0.3s ease-in-out;
  569. }
  570. }
  571. }
  572. </style>