Bladeren bron

融合大华视频插件

limeng 7 maanden geleden
bovenliggende
commit
0cbf84b102
76 gewijzigde bestanden met toevoegingen van 157857 en 3 verwijderingen
  1. 16 0
      zhsq_qk-ui/src/api/dahua/dahua.js
  2. BIN
      zhsq_qk-ui/src/assets/images/cameraType/not-online.png
  3. BIN
      zhsq_qk-ui/src/assets/images/cameraType/not-video.png
  4. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-left.png
  5. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-left2.png
  6. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-re.png
  7. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-re2.png
  8. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-right.png
  9. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-right2.png
  10. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-header-right-bg.png
  11. BIN
      zhsq_qk-ui/src/assets/images/integrated/bigdata-tit-icon.png
  12. BIN
      zhsq_qk-ui/src/assets/images/integrated/btm-light.png
  13. BIN
      zhsq_qk-ui/src/assets/images/integrated/btm-menu.png
  14. BIN
      zhsq_qk-ui/src/assets/images/integrated/btm-menu2.png
  15. BIN
      zhsq_qk-ui/src/assets/images/integrated/btn-bg-r.png
  16. BIN
      zhsq_qk-ui/src/assets/images/integrated/btn-bg.png
  17. BIN
      zhsq_qk-ui/src/assets/images/integrated/btn-six.png
  18. BIN
      zhsq_qk-ui/src/assets/images/integrated/event-img-sub.png
  19. BIN
      zhsq_qk-ui/src/assets/images/integrated/header.png
  20. BIN
      zhsq_qk-ui/src/assets/images/integrated/integrated-bg.jpg
  21. BIN
      zhsq_qk-ui/src/assets/images/integrated/integrated-bg2.jpg
  22. BIN
      zhsq_qk-ui/src/assets/images/integrated/light.png
  23. BIN
      zhsq_qk-ui/src/assets/images/integrated/logo-big.png
  24. BIN
      zhsq_qk-ui/src/assets/images/integrated/logo-small.png
  25. BIN
      zhsq_qk-ui/src/assets/images/integrated/map-bg.png
  26. BIN
      zhsq_qk-ui/src/assets/images/integrated/state-bg.png
  27. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/baoxue-18.png
  28. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/baoyu-11.png
  29. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/dabaoyu-12.png
  30. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/daxue-17.png
  31. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/dayu-10.png
  32. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/dongyu-20.png
  33. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/duoyun-2.png
  34. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/fuchen-30.png
  35. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/leizhenyu-5.png
  36. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/leizhenyubingbao-6.png
  37. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/qiangshachenbao-32.png
  38. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/qing-1.png
  39. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/shachenbao-21.png
  40. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/tedabaoyu-13.png
  41. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/wu-19.png
  42. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/xiaoxue-15.png
  43. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/xiaoyu-8.png
  44. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/yangsha-31.png
  45. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/yin-3.png
  46. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/yin.png
  47. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/yujiaxue-7.png
  48. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/zhenxue-14.png
  49. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/zhenyu-4.png
  50. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/zhongxue-16.png
  51. BIN
      zhsq_qk-ui/src/assets/images/integrated/weather/zhongyu-9.png
  52. 3383 0
      zhsq_qk-ui/src/assets/styles/base.scss
  53. 910 0
      zhsq_qk-ui/src/components/TVWall.vue
  54. 17 0
      zhsq_qk-ui/src/dahua/TVWalllib/.eslintrc
  55. 7675 0
      zhsq_qk-ui/src/dahua/TVWalllib/DHWs.js
  56. 1 0
      zhsq_qk-ui/src/dahua/TVWalllib/DHWs.js.map
  57. 82 0
      zhsq_qk-ui/src/dahua/TVWalllib/demo.css
  58. 147 0
      zhsq_qk-ui/src/dahua/TVWalllib/detect-element-resize.js
  59. 1 0
      zhsq_qk-ui/src/dahua/TVWalllib/iview.css
  60. 45435 0
      zhsq_qk-ui/src/dahua/TVWalllib/iview.js
  61. 10872 0
      zhsq_qk-ui/src/dahua/TVWalllib/jquery.js
  62. 533 0
      zhsq_qk-ui/src/dahua/TVWalllib/main.ts
  63. 1 0
      zhsq_qk-ui/src/dahua/TVWalllib/version.txt
  64. 11965 0
      zhsq_qk-ui/src/dahua/TVWalllib/vue.js
  65. 17 0
      zhsq_qk-ui/src/dahua/lib/.eslintrc
  66. 7661 0
      zhsq_qk-ui/src/dahua/lib/DHWs.js
  67. 1 0
      zhsq_qk-ui/src/dahua/lib/DHWs.js.map
  68. 82 0
      zhsq_qk-ui/src/dahua/lib/demo.css
  69. 147 0
      zhsq_qk-ui/src/dahua/lib/detect-element-resize.js
  70. 1 0
      zhsq_qk-ui/src/dahua/lib/iview.css
  71. 45435 0
      zhsq_qk-ui/src/dahua/lib/iview.js
  72. 10872 0
      zhsq_qk-ui/src/dahua/lib/jquery.js
  73. 533 0
      zhsq_qk-ui/src/dahua/lib/main.ts
  74. 1 0
      zhsq_qk-ui/src/dahua/lib/version.txt
  75. 11965 0
      zhsq_qk-ui/src/dahua/lib/vue.js
  76. 104 3
      zhsq_qk-ui/src/views/fusion/index.vue

+ 16 - 0
zhsq_qk-ui/src/api/dahua/dahua.js

@@ -0,0 +1,16 @@
+import request from '@/utils/request'
+
+// 查询摄像头列表
+export function getDahuaVideoServer() {
+  return request({
+    url: '/center-monitor/DahuaController/getDahuaVideoServer',
+    method: 'get',
+  })
+}
+// 查询电视墙
+export function getTVWallList() {
+  return request({
+    url: '/center-monitor/TVWallController/init',
+    method: 'get',
+  })
+}

BIN
zhsq_qk-ui/src/assets/images/cameraType/not-online.png


BIN
zhsq_qk-ui/src/assets/images/cameraType/not-video.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-left.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-left2.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-re.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-re2.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-right.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-nav-right2.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-header-right-bg.png


BIN
zhsq_qk-ui/src/assets/images/integrated/bigdata-tit-icon.png


BIN
zhsq_qk-ui/src/assets/images/integrated/btm-light.png


BIN
zhsq_qk-ui/src/assets/images/integrated/btm-menu.png


BIN
zhsq_qk-ui/src/assets/images/integrated/btm-menu2.png


BIN
zhsq_qk-ui/src/assets/images/integrated/btn-bg-r.png


BIN
zhsq_qk-ui/src/assets/images/integrated/btn-bg.png


BIN
zhsq_qk-ui/src/assets/images/integrated/btn-six.png


BIN
zhsq_qk-ui/src/assets/images/integrated/event-img-sub.png


BIN
zhsq_qk-ui/src/assets/images/integrated/header.png


BIN
zhsq_qk-ui/src/assets/images/integrated/integrated-bg.jpg


BIN
zhsq_qk-ui/src/assets/images/integrated/integrated-bg2.jpg


BIN
zhsq_qk-ui/src/assets/images/integrated/light.png


BIN
zhsq_qk-ui/src/assets/images/integrated/logo-big.png


BIN
zhsq_qk-ui/src/assets/images/integrated/logo-small.png


BIN
zhsq_qk-ui/src/assets/images/integrated/map-bg.png


BIN
zhsq_qk-ui/src/assets/images/integrated/state-bg.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/baoxue-18.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/baoyu-11.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/dabaoyu-12.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/daxue-17.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/dayu-10.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/dongyu-20.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/duoyun-2.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/fuchen-30.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/leizhenyu-5.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/leizhenyubingbao-6.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/qiangshachenbao-32.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/qing-1.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/shachenbao-21.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/tedabaoyu-13.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/wu-19.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/xiaoxue-15.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/xiaoyu-8.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/yangsha-31.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/yin-3.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/yin.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/yujiaxue-7.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/zhenxue-14.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/zhenyu-4.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/zhongxue-16.png


BIN
zhsq_qk-ui/src/assets/images/integrated/weather/zhongyu-9.png


File diff suppressed because it is too large
+ 3383 - 0
zhsq_qk-ui/src/assets/styles/base.scss


+ 910 - 0
zhsq_qk-ui/src/components/TVWall.vue

@@ -0,0 +1,910 @@
+<template>
+  <div class="TVcontainer" style="position: relative;">
+    <el-dialog :title="title" :visible.sync="TVWallVisible" v-if="TVWallVisible" customClass="TVWallCustomWidth"
+               @close="cancelEventLocationShow()" :width="this.detailInfo != null ? '1500px !important' : '1200px !important'">
+      <div style="display: flex;">
+        <img src="@/assets/images/cameraType/not-video.png" class="dom2" v-if="cameraVisible" alt="">
+        <div id="dom1" class="dom1" v-else></div>
+        <div class="leader-info-container" v-if="this.detailInfo!=null">
+          <div class="leader-info-list-con" :style="this.detailInfo.length < 12 ? 'height:100% !important' : '' ">
+            <div v-for="(item,index) in detailInfo" :key="index">
+              <el-descriptions class="margin-top" title="" :column="1" :size="size" direction="horizontal" border >
+                <el-descriptions-item >
+                  <template slot="label">
+                    {{ index }}
+                  </template>
+                  {{ item != null ? item : '无' }}
+                </el-descriptions-item>
+              </el-descriptions>
+            </div>
+          </div>
+        </div>
+      </div>
+
+    </el-dialog>
+
+  </div>
+
+</template>
+
+<script>
+/** ----------------------------------摄像头预览开始------------------------------------- */
+import { getDahuaVideoServer, getTVWallList } from '@/api/dahua/dahua'
+import DHWs from '@/dahua/lib/DHWs'
+
+/** ----------------------------------摄像头预览结束------------------------------------- */
+export default {
+  dicts: ['event_source'],
+  components: {},
+  props:['detailInfo','cameraList'],
+  data() {
+    return {
+      title:this.detailInfo != null ? "车路云监控服务" : "车路云监控服务",
+      tvListJson: [
+        {
+        'switchTab': '1',
+        'treeLabels': [
+          {
+            'labelCode': '123456',
+            'labelName': '视频场景',
+            'parentLabelCode': null
+          },
+          {
+            'labelCode': '5a81d1bd499b4940a21fc63ca51f4dfa',
+            'labelName': '标签2',
+            'parentLabelCode': 123456
+          },
+          {
+            'labelCode': 'd941adbbd3e64dac92cc448dec5293cd',
+            'labelName': '标签1',
+            'parentLabelCode': 123456
+          }
+        ],
+        'labelChannels': [{
+          'channelDates': [{
+            'channelCode': '6044981090191552',
+            'channelName': '复兴大桥中段-交通事故',
+            'channelSn': null,
+            'cameraType': 0,
+            'online': 1
+          },
+            {
+              'channelCode': 'ZgVzqsjwA1DTF561VGHK5E',
+              'channelName': '北京7青羊东二路77号2通道1',
+              'channelSn': null,
+              'cameraType': 1,
+              'online': 1
+            }
+          ],
+          'labelCode': 'd941adbbd3e64dac92cc448dec5293cd'
+        },
+          {
+            'channelDates': [{
+              'channelCode': 'ZgVzqsjwA1DTF561VGHKK7',
+              'channelName': '北京7青羊东二路77号2通道2',
+              'channelSn': null,
+              'cameraType': 2,
+              'online': 0
+            }],
+            'labelCode': '5a81d1bd499b4940a21fc63ca51f4dfa'
+          }
+        ]
+      },
+        {
+          'switchTab': '2',
+          'labelChannels': [{
+            'channelDates': [{
+              'channelCode': 'ZgVzqsjwA1DTF561VGHK5E',
+              'channelName': '北京7青羊东二路77号2通道1',
+              'channelSn': null,
+              'cameraType': 1,
+              'online': 1
+            },
+              {
+                'channelCode': 'ZgVzqsjwA1DTF561VGHKK7',
+                'channelName': '北京7青羊东二路77号2通道2',
+                'channelSn': null,
+                'cameraType': 2,
+                'online': 0
+              }
+            ]
+          }]
+        }
+      ],
+      TVWallVisible: false,
+      size: '',
+      activeName: 'tv',
+      channelId: ['ZgVzqsjwA1DTF561VHG69F'],
+      /** ----------------------------------摄像头预览开始------------------------------------- */
+      showModal: true,
+      activePanel: 'key1',
+      isLogin: false,
+      loginType: '1',
+      token: '',
+      ctrlType: 'playerWin',
+      https: 1,
+      httpsList: [
+        {
+          value: 0,
+          label: 0
+        },
+        {
+          value: 1,
+          label: 1
+        }
+      ],
+      ctrlTypeList: [{
+        value: 'playerWin',
+        label: '播放控件'
+      }, {
+        value: 'realMonitorUI',
+        label: '带设备树实时预览控件'
+      }, {
+        value: 'playbackUI',
+        label: '带设备树视频回放控件'
+      }, {
+        value: 'TVWallUI',
+        label: '视频上墙'
+      }],
+      ctrlList: [
+        {
+          value: 'ctrl1',
+          label: '控件1'
+        },
+        {
+          value: 'ctrl2',
+          label: '控件2'
+        },
+        {
+          value: 'ctrl3',
+          label: '控件3'
+        }
+      ],
+      splitList: [
+        {
+          value: 1,
+          label: '1 * 1'
+        },
+        {
+          value: 4,
+          label: '2 * 2'
+        },
+        {
+          value: 9,
+          label: '3 * 3'
+        }
+      ],
+      displayModeList: [
+        {
+          value: 1,
+          label: '播放器预览模式'
+        },
+        {
+          value: 2,
+          label: '播放器回放模式'
+        }
+      ],
+      mixedVideoDisplayModeList: [
+        {
+          value: 1,
+          label: '播放实时视频'
+        },
+        {
+          value: 2,
+          label: '播放回放视频'
+        }
+      ],
+      ctrl: 'ctrl1',
+      splitNum: 1,
+      displayMode: 1,
+      displayTimeRange: [],
+      modalDisplayTimeRange: [],
+      mixedVideoTime: null,
+      recordPath: 'C:\\DSS LightWeight\\DSS LightWeight Client\\Record\\',
+      downloadName: '',
+      downTimeRange: [],
+      downloadFormat: 0,
+      downloadFormatList: [{
+        value: 0,
+        label: 'dav'
+      },
+        {
+          value: 1,
+          label: 'avi'
+        }, {
+          value: 2,
+          label: 'mp4'
+        }],
+      downloadSource: 3,
+      downloadSourceList: [
+        {
+          value: 3,
+          label: '中心录像'
+        }, {
+          value: 2,
+          label: '设备录像'
+        }],
+      showDownloadStreamType: false,
+      downloadStreamType: 1,
+      downloadStreamTypeList: [{
+        value: 1,
+        label: '主码流'
+      },
+        {
+          value: 2,
+          label: '辅码流'
+        },
+        {
+          value: 3,
+          label: '三码流'
+        }],
+      downloadIsShow: true,
+      downloadIsShowList: [{
+        value: true,
+        label: '是'
+      },
+        {
+          value: false,
+          label: '否'
+        }],
+      crtPosX: 0,
+      crtPosY: 0,
+      crtWidth: 1150,
+      crtHeight: 700,
+      domId: 'dom1',
+      mixedVideoDisplayMode: 2,
+      isShowTipe: true,
+      /** ----------------------------------摄像头预览结束------------------------------------- */
+      cameraList:[],
+      initCount: 0,
+      pubKey: '',
+      oWebControl: null,
+      cameraVisible:false,
+    }
+  },
+  created() {
+    const DHWsInstance = DHWs.getInstance()
+    this.ws = DHWsInstance
+  },
+  methods: {
+    cancelEventLocationShow() {
+      // this.activeName = 'tv'
+      this.TVWallVisible = false
+      this.destroy()
+
+      if (this.oWebControl != null) {
+        this.oWebControl.JS_HideWnd()   // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
+        this.oWebControl.JS_Disconnect().then(function() {  // 断开与插件服务连接成功
+          },
+          function() {  // 断开与插件服务连接失败
+          })
+      }
+    },
+    //火点联动电视墙调用
+    showTVWall1(longitude,latitude,tvListJson) {
+      /** ----------------------------------大华摄像头预览开始------------------------------------- */
+      this.ws.addEventListener('connectStateChange', data => {
+        if (data) {
+          console.log('连接成功')
+        } else {
+          console.log('连接失败,下载客户端')
+          this.alertReinstall()
+        }
+      })
+        this.ws.detectConnectQt().then(res => {
+          if (res) { // 连接客户端成功
+            this.alertLogin()
+            this.ws.login({
+              // loginIp: '116.142.80.11',
+              loginIp: '192.168.100.100',
+              loginPort: 7902,
+              userName: 'system',
+              userPwd: 'Admin@123',
+              token: '',
+              https: 1
+            })
+            this.ws.on('loginState',  (res) => {
+              this.isLogin = res
+              console.log('---res-----', res)
+              if (res) {
+                this.alertLoginSuccess()
+                this.activePanel = 'key2'
+                console.log(tvListJson)
+                const array=[]
+                const array1=[]
+                if (tvListJson!=null)
+                {
+                  tvListJson[0].treeLabels.forEach((item,index)=>
+                  {
+                    if (index!=0)
+                    {
+                      const param =Object.assign({})
+                      param.channelId=item.labelCode
+                      array.push(param)
+                      array1.push(item.labelCode)
+                    }
+
+                  })
+                }
+                this.create1(longitude,latitude,tvListJson,array,array1)
+                // await nextTick();
+                // var obj=JSON.parse(tvListJson)
+              } else {
+                this.alertLoginFailed()
+              }
+            })
+          } else { // 连接客户端失败
+            this.alertReinstall()
+          }
+        })
+      /** ----------------------------------大华摄像头预览结束------------------------------------- */
+      this.TVWallVisible = true
+    },
+    realTimeVideoDialog(cameraParams) {
+      // 调用弹窗实时播放接口
+      if (!this.isLogin) {
+        this.$Message.info("正在登陆客户端,请稍等......");
+        return false;
+      }
+      this.ws.openVideo(cameraParams);
+    },
+    create1(longitude,latitude,tvListJson,array,array1) { // 调用创建控件接口
+      let _this = this
+      const params = [
+        {
+          'ctrlType': 'realMonitorUI',
+          'ctrlCode': 'ctrl1',
+          'ctrlProperty': {
+            'displayMode': 1,
+            'splitNum': 4,
+            'channelList': [
+              {
+                'channelId': ''
+              }
+            ]
+          },
+          'visible': true,
+          'domId': 'dom1'
+        }
+      ]
+      if(array1 != undefined && array1 != null ){
+        params[0].ctrlProperty.splitNum = (array1.length == 1 ? 1 : 4)
+      }
+      this.setPos()
+      this.customizeTree(tvListJson);
+      // if(array1.length == 1){
+      //   _this.realTimeVideoDialog(array1);
+      // }else{
+        _this.ws.createCtrl(params);
+        _this.playRealMonitorVideo(array)
+      // }
+      // setTimeout(() => {
+      //   _this.rotation(longitude,latitude,array1)
+      // }, 5000)
+
+    },
+    playRealMonitorVideo(array) { // 自定义设备树自动播放指定通道编码视频
+      const config = this.ws.config
+      const { loginIp, userCode } = config
+      this.ws.postMessage('playRealMonitorVideo', {
+        loginIp,
+        userCode,
+        params: {
+          ctrlCode: "ctrl1",
+          array: array
+        }
+      })
+
+    },
+    rotation(lng,lat,list){
+      console.log('--------------detailInfo',this.detailInfo)
+      console.log('--------------detailInfo',Object.entries(this.detailInfo))
+      console.log(list)
+      rotation(lng,lat,list).then(res => {
+      })
+    },
+    showTVWall(tvListJson,bfArray) {
+      selectConfigKey("DssVersion").then(res => {
+        if(this.ws.getLocalDssVersion()!=res.data){
+          this.$modal.confirm('系统检测到新客户端版本,请更新后使用', '系统提示', {
+              confirmButtonText: '确定',
+              cancelButtonText: '取消',
+              type: 'warning'
+            }
+          ).then(() => {
+            selectConfigKey('video_plugin_url').then(response => {
+              window.open(response.data);
+            })
+          }).catch(() => {
+            return
+          });
+          return
+        }else{
+
+          if(tvListJson){
+            this.preview(tvListJson,bfArray);
+            this.TVWallVisible = true;
+            return;
+          }
+          // let that=this;
+          /** ----------------------------------大华摄像头预览开始------------------------------------- */
+          this.ws.addEventListener('connectStateChange', data => {
+            if (data) {
+              console.log('连接成功')
+            } else {
+              console.log('连接失败,下载客户端')
+              this.alertReinstall()
+            }
+          })
+          this.preview()
+          /** ----------------------------------大华摄像头预览结束------------------------------------- */
+          /** ----------------------------------海康摄像头预览开始------------------------------------- */
+          // tvCameraList().then(response => {
+          //   this.cameraList=response.data
+          // })
+          // that.initPlugin()
+          // setTimeout(function() {
+          //   that.playhk();
+          // }, 5000)
+          // /** ----------------------------------海康摄像头预览结束------------------------------------- */
+          this.TVWallVisible = true
+        }
+      })
+
+    },
+    /** ----------------------------------大华摄像头预览开始------------------------------------- */
+    alertLogin: function() {
+      this.$modal.msg('登录中....')
+    },
+    alertLoginSuccess: function() {
+      this.$modal.msgSuccess('登录成功!')
+    },
+    alertLoginFailed: function() {
+      this.$modal.msgError('登陆失败!')
+    },
+    alertReinstall: function() {
+      this.$modal.msgWarning('请重新安装客户端')
+    },
+    /** 预览按钮操作 */
+    preview(tvListJson,bfArray) {
+      getTVWallList().then(newres => {
+        getDahuaVideoServer().then(newResponse => {
+          this.ws.detectConnectQt().then(res => {
+            if (res) { // 连接客户端成功
+              this.alertLogin()
+              this.ws.login({
+                // loginIp: newResponse.loginIp,
+                // loginPort: newResponse.loginPort,
+                // userName: newResponse.userName,
+                // userPwd: newResponse.userPwd,
+                loginIp: '192.168.100.100',
+                loginPort: 8314,
+                userName: 'system',
+                userPwd: 'Admin@123',
+                token: '',
+                https: 1
+              })
+              this.ws.on('loginState', (res) => {
+                this.isLogin = res
+                console.log('---res-----', res)
+                if (res) {
+                  this.alertLoginSuccess()
+                  this.activePanel = 'key2'
+                  this.create(tvListJson?tvListJson:newres.data,bfArray)
+                } else {
+                  this.alertLoginFailed()
+                }
+              })
+            } else { // 连接客户端失败
+              this.alertReinstall()
+            }
+          })
+        })
+      })
+    },
+
+    create(tvListJson,bfArray) { // 调用创建控件接口
+      // debugger
+      let _this = this
+      const params = [
+        {
+          'ctrlType': 'realMonitorUI',
+          'ctrlCode': 'ctrl1',
+          'ctrlProperty': {
+            'displayMode': 1,
+            'splitNum': 4,
+            'channelList': [
+              {
+                'channelId': ''
+              }
+            ]
+          },
+          'visible': true,
+          'domId': 'dom1'
+        }
+      ]
+      if (bfArray != undefined && bfArray != null) {
+        params[0].ctrlProperty.splitNum = (bfArray.length == 1 ? 1 : 4)
+      }
+      this.setPos()
+      this.customizeTree(tvListJson);
+      let length = tvListJson[0].treeLabels.length > 4 ? 5 : tvListJson[0].treeLabels.length;
+      bfArray = [];
+      for (let i = 1; i < length; i++) {
+        bfArray.push({"channelId": tvListJson[0].treeLabels[i].labelCode})
+      }
+      // if(bfArray.length == 1){
+      //   _this.realTimeVideoDialog([tvListJson[0].treeLabels[1].labelCode]);
+      // }else{
+        _this.ws.createCtrl(params);
+        _this.playRealMonitorVideo(bfArray)
+      // }
+    },
+    setPos() {
+      let target = document.getElementById(this.domId)
+      console.log(target, 'target')
+      target.style.right = `${this.crtPosX}px`
+      target.style.top = `${this.crtPosY}px`
+      target.style.width = `${this.crtWidth}px`
+      target.style.height = `${this.crtHeight}px`
+      if (document.createEvent) {
+        var event = document.createEvent('HTMLEvents')
+        event.initEvent('resize', true, true)
+        window.dispatchEvent(event)
+      } else if (document.createEventObject) {
+        window.fireEvent('onresize')
+      }
+    },
+    destroy() { // 调用销毁控件接口
+      if (!this.isLogin) {
+        this.$modal.msgWarning('正在登陆客户端,请稍等......')
+        return false
+      }
+      const ctrls = this.ws.ctrls.map(i => {
+        if (i.ctrlCode === this.ctrl) {
+          return i.ctrlCode
+        }
+      })
+      this.ws.destroyCtrl(ctrls)
+    },
+    customizeTree(tvListJson) { // 调用控件接口树
+      const config = this.ws.config
+      const { loginIp, userCode } = config
+      this.ws.postMessage('customizeTree', {
+        loginIp,
+        userCode,
+        params: {
+          array: tvListJson
+        }
+      })
+    },
+    /** ----------------------------------大华摄像头预览结束------------------------------------- */
+    /** ----------------------------------海康摄像头预览开始------------------------------------- */
+    // 创建播放实例
+    initPlugin() {
+      let that=this
+      that.oWebControl = new WebControl({
+        szPluginContainer: 'playWnd',                       // 指定容器id
+        iServicePortStart: 15900,                           // 指定起止端口号,建议使用该值
+        iServicePortEnd: 15909,
+        szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11',   // 用于IE10使用ActiveX的clsid
+        cbConnectSuccess: function() {                     // 创建WebControl实例成功
+          that.oWebControl.JS_StartService('window', {         // WebControl实例创建成功后需要启动服务
+            dllPath: './VideoPluginConnect.dll'         // 值"./VideoPluginConnect.dll"写死
+          }).then(function() {                           // 启动插件服务成功
+            that.oWebControl.JS_SetWindowControlCallback({   // 设置消息回调
+              cbIntegrationCallBack: cbIntegrationCallBack
+            })
+
+            that.oWebControl.JS_CreateWnd('playWnd', 850, 615).then(function() { //JS_CreateWnd创建视频播放窗口,宽高可设定
+              that.init()  // 创建播放实例成功后初始化
+            })
+          }, function() { // 启动插件服务失败
+          })
+        },
+        cbConnectError: function() { // 创建WebControl实例失败
+          that.oWebControl = null
+          $('#playWnd').html('插件未启动,正在尝试启动,请稍候...<a href="./hk/VideoWebPlugin.exe">点击下载插件</a>')
+          WebControl.JS_WakeUp('VideoWebPlugin://') // 程序未启动时执行error函数,采用wakeup来启动程序
+          initCount++
+          if (initCount < 3) {
+            setTimeout(function() {
+              that.initPlugin()
+            }, 3000)
+          } else {
+            $('#playWnd').html('插件启动失败,请检查插件是否安装!<a href="./hk/VideoWebPlugin.exe">点击下载插件</a>')
+          }
+        },
+        cbConnectClose: function(bNormalClose) {
+          // 异常断开:bNormalClose = false
+          // JS_Disconnect正常断开:bNormalClose = true
+          console.log('cbConnectClose')
+          that.oWebControl = null
+        }
+      })
+    },
+    //初始化
+    init() {
+      let that=this
+      this.getPubKey(function() {
+        ////////////////////////////////// 请自行修改以下变量值	////////////////////////////////////
+        var appkey = '24699060'                           //综合安防管理平台提供的appkey,必填
+        var secret = that.setEncrypt('tt1pMbsrlwGZUWucdAPw')   //综合安防管理平台提供的secret,必填
+        var ip = '36.49.108.22'                           //综合安防管理平台IP地址,必填
+        var playMode = 0                                  //初始播放模式:0-预览,1-回放
+        var port = 1443                                    //综合安防管理平台端口,若启用HTTPS协议,默认443
+        var snapDir = 'D:\\SnapDir'                       //抓图存储路径
+        var videoDir = 'D:\\VideoDir'                     //紧急录像或录像剪辑存储路径
+        var layout = '3x3'                                //playMode指定模式的布局
+        var enableHTTPS = 1                               //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1
+        var encryptedFields = 'secret'					   //加密字段,默认加密领域为secret
+        var showToolbar = 1                               //是否显示工具栏,0-不显示,非0-显示
+        var showSmart = 1                                 //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
+        var buttonIDs = '0,16,256,257,258,259,260,512,513,514,515,516,517,768,769'  //自定义工具条按钮
+        ////////////////////////////////// 请自行修改以上变量值	////////////////////////////////////
+
+        that.oWebControl.JS_RequestInterface({
+          funcName: 'init',
+          argument: JSON.stringify({
+            appkey: appkey,                            //API网关提供的appkey
+            secret: secret,                            //API网关提供的secret
+            ip: ip,                                    //API网关IP地址
+            playMode: playMode,                        //播放模式(决定显示预览还是回放界面)
+            port: port,                                //端口
+            snapDir: snapDir,                          //抓图存储路径
+            videoDir: videoDir,                        //紧急录像或录像剪辑存储路径
+            layout: layout,                            //布局
+            enableHTTPS: enableHTTPS,                  //是否启用HTTPS协议
+            encryptedFields: encryptedFields,          //加密字段
+            showToolbar: showToolbar,                  //是否显示工具栏
+            showSmart: showSmart,                      //是否显示智能信息
+            buttonIDs: buttonIDs                       //自定义工具条按钮
+          })
+        }).then(function(oData) {
+          that.oWebControl.JS_Resize(850, 615)  // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
+        })
+      })
+    },
+    //获取公钥
+    getPubKey(callback) {
+      let that=this
+      that.oWebControl.JS_RequestInterface({
+        funcName: 'getRSAPubKey',
+        argument: JSON.stringify({
+          keyLength: 1024
+        })
+      }).then(function(oData) {
+        console.log(oData)
+        if (oData.responseMsg.data) {
+          that.pubKey = oData.responseMsg.data
+          callback()
+        }125
+      })
+    },
+//RSA加密
+    setEncrypt(value) {
+      var encrypt = new JSEncrypt()
+      encrypt.setPublicKey(this.pubKey)
+      return encrypt.encrypt(value)
+    },
+    //播放海康摄像头
+    playhk(channelCode){
+      var cameraIndexCode = channelCode     //获取输入的监控点编号值,必填
+      var streamMode = 0                                     //主子码流标识:0-主码流,1-子码流
+      var transMode = 1                                      //传输协议:0-UDP,1-TCP
+      var gpuMode = 0                                        //是否启用GPU硬解,0-不启用,1-启用
+      var wndId = -1                                         //播放窗口序号(在2x2以上布局下可指定播放窗口)
+
+      cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, '')
+      cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, '')
+
+      this.oWebControl.JS_RequestInterface({
+        funcName: 'startPreview',
+        argument: JSON.stringify({
+          cameraIndexCode: cameraIndexCode,                //监控点编号
+          streamMode: streamMode,                         //主子码流标识
+          transMode: transMode,                           //传输协议
+          gpuMode: gpuMode,                               //是否开启GPU硬解
+          wndId: wndId                                     //可指定播放窗口
+        })
+      })
+    }
+    /** ----------------------------------海康摄像头预览结束------------------------------------- */
+  },
+  watch:{
+    detailInfo:{
+      handler(val,oldval){
+        this.$nextTick(() => {
+          this.detailInfo = val;
+        })
+      }
+    },
+    cameraList:{
+      handler(val,oldval){
+        this.$nextTick(() => {
+          setTimeout(() => {
+            console.log(this.cameraList)
+            this.cameraList.length > 0 ? this.cameraVisible = false : this.cameraVisible = true
+          },800)
+        })
+      }
+    }
+  }
+}
+
+// 推送消息
+function cbIntegrationCallBack(oData) {
+  console.log(JSON.stringify(oData.responseMsg))
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+@import '@/assets/styles/base.scss';
+
+.TVcontainer{
+  width: 100%;
+  height: 100%;
+}
+.detailLabel{
+  background-color: #bfc;
+}
+.event-info-con {
+  width: 100%;
+  display: flex;
+
+  .e-left {
+    width: 32%;
+  }
+
+  .e-center {
+    width: 30%;
+    margin-left: 1%;
+
+    .img-company {
+      width: 100%;
+      height: 18.3vh;
+
+      img {
+      }
+    }
+  }
+
+  .e-right {
+    margin-left: 1%;
+    width: 45%;
+  }
+
+  .e-location-left {
+    width: 28%;
+    margin-top: 1rem;
+  }
+
+  .e-location-right {
+    width: 71%;
+    margin-top: 1.3rem;
+    margin-left: 1rem;
+  }
+}
+
+.el-dialog:not(.is-fullscreen) {
+  margin-top: 5.5vh !important;
+}
+
+.bottom-menu-normal {
+  max-width: 90%;
+  padding: 0 3rem;
+  position: absolute;
+  left: 50%;
+  transform: translateX(-50%);
+  bottom: 0;
+  z-index: 100000;
+  border-radius: 5px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: url(../assets/images/integrated/btm-menu.png) center no-repeat;
+  background-size: cover;
+  overflow: hidden;
+
+  .btm-m-con {
+    position: relative;
+    color: $inBlue;
+    font-size: .5rem;
+    padding: 1rem 1.5rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+    transition: all 0.2s ease-in-out;
+    cursor: pointer;
+    white-space: nowrap;
+
+    i {
+      font-size: 1rem;
+      color: $inBlue;
+      text-shadow: 0 0 10px rgba($color: $inBlue, $alpha: .6);
+      margin-right: 0.2rem;
+    }
+  }
+
+  .btm-m-con:hover {
+    text-shadow: 0 0 20px rgba($color: $inBlueHover, $alpha: 1.0);
+    filter: brightness(2.3);
+    -webkit-transform: translateX(0.2rem);
+    transform: translateX(0.2rem);
+    transition: all 0.2s ease-in-out;
+
+    i {
+      color: $inBlueHover;
+      text-shadow: 0 0 20px rgba($color: $inBlueHover, $alpha: 1.0);
+    }
+  }
+
+  .m-l-none {
+    .el-input__inner {
+      margin-left: 0 !important;
+    }
+  }
+
+}
+
+/*海康*/
+html, body {
+  padding: 0;
+  margin: 0;
+}
+
+.playWnd {
+  margin: -13px 0 0 255px;
+  width: 850px; /*播放容器的宽和高设定*/
+  height: 615px;
+  border: 1px solid red;
+}
+
+.operate {
+  margin-top: 24px;
+}
+
+.operate::after {
+  content: '';
+  display: block;
+  clear: both;
+}
+
+.module {
+  float: left;
+  width: 340px;
+  /*min-height: 320px;*/
+  margin-left: 16px;
+  padding: 16px 8px;
+  box-sizing: border-box;
+  border: 1px solid #e5e5e5;
+}
+
+.module .item {
+  margin-bottom: 4px;
+}
+
+.module input[type="text"] {
+  box-sizing: border-box;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0;
+  width: 150px;
+  min-height: 20px;
+}
+
+.module .btn {
+  min-width: 80px;
+  min-height: 24px;
+  margin-top: 100px;
+  margin-left: 80px;
+}
+
+.dom2{
+  min-width: 907px;
+  height: 650px;
+  width: 1086px;
+}
+</style>

+ 17 - 0
zhsq_qk-ui/src/dahua/TVWalllib/.eslintrc

@@ -0,0 +1,17 @@
+{
+    "env": {
+        "browser": true,
+        "commonjs": true,
+        "es6": true,
+        "node": true
+    },
+    "parserOptions": {
+        "ecmaFeatures": {
+            "jsx": false
+        },
+        "sourceType": "module"
+    },
+    "rules": {
+        // "semi": ["error","never"]
+    }
+}

File diff suppressed because it is too large
+ 7675 - 0
zhsq_qk-ui/src/dahua/TVWalllib/DHWs.js


File diff suppressed because it is too large
+ 1 - 0
zhsq_qk-ui/src/dahua/TVWalllib/DHWs.js.map


+ 82 - 0
zhsq_qk-ui/src/dahua/TVWalllib/demo.css

@@ -0,0 +1,82 @@
+#dom1, #dom2, #dom3, #dom4 {
+    width: 700px;
+    height: 400px;
+    position:absolute;
+}
+#dom1{
+    right:0;
+}
+#dom2{
+    /* right:0;
+    top: 400px; */
+}
+#dom3{
+    /* right:0;
+    top: 800px; */
+}
+
+#dom4{
+    left:1000px;
+}
+
+.maskVideo{
+    background-color: aquamarine;
+    position: fixed;
+}
+.center{
+    margin: 0 auto;
+    width: 1350px;
+}
+#app{
+    padding: 16px 10px;
+}
+#demo .ivu-form-item-label {
+    padding-right: 20px;
+}
+#demo #loginInfo .ivu-input {
+    width: 220px;
+}
+.ivu-input-wrapper {
+    margin-right: 10px;
+}
+.ivu-select {
+    margin-right: 10px;
+}
+#demo .ivu-input-wrapper {
+    width: 68px;
+}
+#demo .ivu-input {
+    width: 100%;
+}
+
+#demo .ivu-date-picker-rel .ivu-input-wrapper  {
+    width: 360px;
+}
+.ivu-btn + .ivu-btn {
+    margin-left: 20px;
+}
+.ivu-form-item .ivu-form-item {
+    margin-bottom: 6px;
+}
+#loginModule {
+    width: 560px;
+    margin: 10px auto;
+    padding: 16px;
+    border: 1px dashed #ccc;
+}
+#ctrlModule{
+    width: 850px;
+    float: left;
+    padding: 10px;
+    border: 1px dashed #ccc;
+}
+#popModule{
+    float: right;
+    width: 482px;
+    height: 372px;
+    padding: 10px;
+    border: 1px dashed #ccc;
+}
+#ctrlModule .ivu-form-item {
+    margin-bottom: 16px;
+}

+ 147 - 0
zhsq_qk-ui/src/dahua/TVWalllib/detect-element-resize.js

@@ -0,0 +1,147 @@
+/**
+* Detect Element Resize
+*
+* https://github.com/sdecima/javascript-detect-element-resize
+* Sebastian Decima
+*
+* version: 0.5.3
+**/
+
+(function () {
+	var attachEvent = document.attachEvent,
+		stylesCreated = false;
+	
+	if (!attachEvent) {
+		var requestFrame = (function(){
+			var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
+								function(fn){ return window.setTimeout(fn, 20); };
+			return function(fn){ return raf(fn); };
+		})();
+		
+		var cancelFrame = (function(){
+			var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
+								   window.clearTimeout;
+		  return function(id){ return cancel(id); };
+		})();
+
+		function resetTriggers(element){
+			var triggers = element.__resizeTriggers__,
+				expand = triggers.firstElementChild,
+				contract = triggers.lastElementChild,
+				expandChild = expand.firstElementChild;
+			contract.scrollLeft = contract.scrollWidth;
+			contract.scrollTop = contract.scrollHeight;
+			expandChild.style.width = expand.offsetWidth + 1 + 'px';
+			expandChild.style.height = expand.offsetHeight + 1 + 'px';
+			expand.scrollLeft = expand.scrollWidth;
+			expand.scrollTop = expand.scrollHeight;
+		};
+
+		function checkTriggers(element){
+			return element.offsetWidth != element.__resizeLast__.width ||
+						 element.offsetHeight != element.__resizeLast__.height;
+		}
+		
+		function scrollListener(e){
+			var element = this;
+			resetTriggers(this);
+			if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
+			this.__resizeRAF__ = requestFrame(function(){
+				if (checkTriggers(element)) {
+					element.__resizeLast__.width = element.offsetWidth;
+					element.__resizeLast__.height = element.offsetHeight;
+					element.__resizeListeners__.forEach(function(fn){
+						fn.call(element, e);
+					});
+				}
+			});
+		};
+		
+		/* Detect CSS Animations support to detect element display/re-attach */
+		var animation = false,
+			animationstring = 'animation',
+			keyframeprefix = '',
+			animationstartevent = 'animationstart',
+			domPrefixes = 'Webkit Moz O ms'.split(' '),
+			startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
+			pfx  = '';
+		{
+			var elm = document.createElement('fakeelement');
+			if( elm.style.animationName !== undefined ) { animation = true; }    
+			
+			if( animation === false ) {
+				for( var i = 0; i < domPrefixes.length; i++ ) {
+					if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
+						pfx = domPrefixes[ i ];
+						animationstring = pfx + 'Animation';
+						keyframeprefix = '-' + pfx.toLowerCase() + '-';
+						animationstartevent = startEvents[ i ];
+						animation = true;
+						break;
+					}
+				}
+			}
+		}
+		
+		var animationName = 'resizeanim';
+		var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
+		var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
+	}
+	
+	function createStyles() {
+		if (!stylesCreated) {
+			//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
+			var css = (animationKeyframes ? animationKeyframes : '') +
+					'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
+					'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
+				head = document.head || document.getElementsByTagName('head')[0],
+				style = document.createElement('style');
+			
+			style.type = 'text/css';
+			if (style.styleSheet) {
+				style.styleSheet.cssText = css;
+			} else {
+				style.appendChild(document.createTextNode(css));
+			}
+
+			head.appendChild(style);
+			stylesCreated = true;
+		}
+	}
+	
+	window.addResizeListener = function(element, fn){
+		if (attachEvent) element.attachEvent('onresize', fn);
+		else {
+			if (!element.__resizeTriggers__) {
+				if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
+				createStyles();
+				element.__resizeLast__ = {};
+				element.__resizeListeners__ = [];
+				(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
+				element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
+																						'<div class="contract-trigger"></div>';
+				element.appendChild(element.__resizeTriggers__);
+				resetTriggers(element);
+				element.addEventListener('scroll', scrollListener, true);
+				
+				/* Listen for a css animation to detect element display/re-attach */
+				animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
+					if(e.animationName == animationName)
+						resetTriggers(element);
+				});
+			}
+			element.__resizeListeners__.push(fn);
+		}
+	};
+	
+	window.removeResizeListener = function(element, fn){
+		if (attachEvent) element.detachEvent('onresize', fn);
+		else {
+			element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
+			if (!element.__resizeListeners__.length) {
+					element.removeEventListener('scroll', scrollListener);
+					element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
+			}
+		}
+	}
+})();

File diff suppressed because it is too large
+ 1 - 0
zhsq_qk-ui/src/dahua/TVWalllib/iview.css


File diff suppressed because it is too large
+ 45435 - 0
zhsq_qk-ui/src/dahua/TVWalllib/iview.js


File diff suppressed because it is too large
+ 10872 - 0
zhsq_qk-ui/src/dahua/TVWalllib/jquery.js


+ 533 - 0
zhsq_qk-ui/src/dahua/TVWalllib/main.ts

@@ -0,0 +1,533 @@
+// 与客户端交互方法列表
+import wsPlugins from './plugins/index';
+// const ReWebSocket = require('reconnecting-websocket');
+// websocket重连
+import ReWebSocket from '../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs';
+// const Bowser = require('bowser');
+// 浏览器信息获取
+import Bowser from "../node_modules/bowser/es5";
+const browser = Bowser.getParser(window.navigator.userAgent);
+
+interface callbacks {
+	// 连接客户端状态
+	connectResult: any,
+	// 登录客户端状态
+	loginResult: any
+}
+
+
+export default class Ws {
+	[x: string]: any;
+	// 连接地址
+	static url: string = '';
+	// 传入的配置项(方法)
+	static opts: Object = {};
+	// 密码加密公钥
+	static publicKey = '';
+	// 是否连接客户端
+	private isConnectSuccessQt: Boolean = false;
+	// 是否登录客户端
+	private isLoginSuccess: Boolean = false;
+	// 唯一实例
+	private static _instance: any = null;
+	// 当前连接的webSocket
+	webSocket: any;
+	// 最大重连数
+	reConnectCount: number = 3;
+	// 连接失败次数
+	connectFailCount: number = 0;
+	// 重连完成标识
+	connectEnd: Boolean = false;
+	// 登录完成标识
+	loginEnd: Boolean = false;
+	// 最大重登数
+	reLoginCount: number = 1;
+	// 连接失败次数
+	loginFailCount: number = 0;
+	// 当前websocket登录配置
+	config: Object = {};
+	// 登陆IP
+	loginIp: string;
+	// 登陆端口
+	loginPort: string;
+	// 登录用户名
+	userName: string;
+	// 登录密码,密码与token二选一
+	userPwd: string;
+	// 登录token,密码与token二选一
+	token: string;
+	// 用户标识符
+	userCode: Number = 0;
+	// 回调函数
+	private callback: callbacks;
+	// 创建的控件ID列表
+	ids: Array<String> = [];
+	// 创建的控件列表
+	ctrls: Array<String> = [];
+	// 心跳
+	heartBeatTimer: any = null;
+	// 监听的方法表
+	listerns: any;
+	constructor({
+		url= 'ws://localhost:1234',
+		publicKey= 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbEpPpxpLJft4W9YZj8bRh2bYYZshBEsKOlxgyn11rlEyTasjBSZRV9aj33tvQ2T55izH0fWl+dL/dLZChawFrlGDcH8JuWge2xYMgII9mggcYa0UiQ7pLXJ9ivXZ/cOY3HzrRQdR7dGTSNn3Z0Ctbns6mLgvlA2r3qMNs/8wHBwIDAQAB',
+		reConnectCount = 3,
+		reLoginCount = 1,
+		loginIp= location.hostname,
+		loginPort= location.port,
+		userName = '',
+		userPwd = '',
+		token = '',
+		callback = {
+			connectResult: null,
+			loginResult: null
+		}
+	} : {
+		url: string,
+		publicKey: string,
+		reConnectCount: number,
+		reLoginCount: number,
+		loginIp: string,
+		loginPort: string,
+		userName: string,
+		userPwd: string,
+		token: string
+		callback: callbacks,
+	}) {
+		// if (/https/.test(location.protocol)) {
+		// 	url = `wss:${url}`;
+		// } else {
+		// 	url = `ws:${url}`;
+		// }
+		// url = `ws://localhost:1234`;
+
+		this.url = url;
+		this.userCode = new Date().valueOf();
+		this.webSocket = null;
+		this.reConnectCount = reConnectCount;
+		this.reLoginCount = reLoginCount;
+		this.publicKey = publicKey;
+		this.loginIp = loginIp;
+		this.loginPort = loginPort;
+		this.userName = userName;
+		this.userPwd = userPwd;
+		this.token = token;
+		this.callback = callback;
+		
+		this.connectFailCount = this.connectFailCount;
+
+		// 基础操作所需功能或属性
+		this.ids = [];
+		this.ctrls = [];
+
+		// 是否连接客户端
+		this.isConnectSuccessQt = false;
+		// 是否登陆客户端
+		this.isLoginSuccess = false;
+		this.heartBeatTimer = null;
+
+		// 初始化配置参数
+		this.initConfig();
+
+		// 连接客户端
+		this.connectQt();
+
+		// 获取与客户端交互方法列表
+		const plugins = [];
+		Object.keys(wsPlugins).forEach(item => {
+			if(hasKey(wsPlugins, item)){
+				plugins.push(wsPlugins[item]);
+			}
+		});
+		// 与客户端通讯功能注册
+		usePlugin(plugins);
+
+		// 用户注册监听事件表
+		this.listerns = new Map();
+
+		// 传入登录配置,则登录
+		if(this.userName) {
+			this.detectConnectQt().then((res: Boolean) => {
+				if(res) {
+					// 登陆客户端
+					this.loginClient();
+					// 心跳保活
+					this._heartbeat();
+				}
+			});
+		}
+	}
+	/**
+	 * @description 获得实例对象
+	 */
+	public static getInstance(options: any):Ws {
+		if(!this._instance) {
+			this._instance = new Ws(options);
+		}
+		return this._instance;
+	}
+	/**
+	 * @description 用户注册监听事件
+	 * @params {String} eventType 事件名称
+	 * @params {any} callback 回调函数
+	 */
+	on(eventType: String, callback: any) {
+		this.listerns.set(eventType, callback);
+	}
+	/**
+	 * @description 用户取消监听事件
+	 * @params {String} eventType 事件名称
+	 */
+	off(eventType: string) {
+		delete this.listerns[eventType];
+	}
+	/**
+	 * @description 发送消息给客户端
+	 * @params {String} method 事件名称
+	 * @params {Object} data 传输消息的数据内容
+	 */
+	emit(method: any, data: { method: any; }) {
+		const { webSocket } = this;
+		data.method = method;
+		// 不需要判断登录和连接的方法过滤
+		let filterList = ['heartbeat', 'login', 'logout', 'browserInfo'];
+		if(filterList.includes(method)) {
+			webSocket.send(JSON.stringify(data));
+			return;
+		}
+		return new Promise((resolve, reject) => {
+			this.detectConnectQt().then(con => {
+				if(con) {
+					this.detectLoginClient().then(login => {
+						if(login) {
+							webSocket.send(JSON.stringify(data));
+							resolve(true);
+						} else {
+							// 登录失败
+							reject(2);
+						}
+					})
+				} else {
+					// 连接失败
+					reject(1);
+				}
+			})
+		})
+	}
+	/*
+	* 初始化配置
+	*/
+	initConfig() {
+		this.config = {
+			userName: this.userName,
+			userCode: this.userCode,
+			loginPort: this.loginPort,
+			loginIp: this.loginIp,
+			userPwd: this.userPwd,
+			token: this.token,
+		};
+		// 浏览器信息
+		const browserInfo = {
+			name: '',
+			version: '',
+			platform: ''
+		};
+		browserInfo.name = browser.getBrowserName().toLowerCase();
+		browserInfo.version = browser.getBrowser().version.toLowerCase();
+		browserInfo.platform =
+			browser._ua.indexOf('Win64') >= 0 || browser._ua.indexOf('Wow64') >= 0
+				? 'win64'
+				: 'win32';
+		this.config['browser'] = browserInfo;
+	}
+	/**
+	 * @description 连接客户端
+	 */
+	connectQt() {
+		this.connectEnd = false;
+		// 连接客户端
+		this.webSocket = new ReWebSocket(this.url, '', {
+			maxRetries: this.reConnectCount
+		});
+		this.addEvents();
+	}
+	/**
+	 * @description 检测连接客户端状态
+	 */
+	detectConnectQt() {
+		let _this = this;
+		return new Promise((resolve, reject) => {
+			if(!this.connectEnd) { // 连接中
+				let _interval = setInterval(() => {
+					if(_this.connectEnd) {
+						clearInterval(_interval);
+						resolve(_this.isConnectSuccessQt);
+					}
+				}, 50)
+			} else {
+				resolve(_this.isConnectSuccessQt);
+			}
+		})
+	}
+	/**
+	 * @description 检测登录客户端状态
+	 */
+	detectLoginClient() {
+		let _this = this;
+		return new Promise((resolve, reject) => {
+			if(!this.loginEnd) { // 连接中
+				let _interval = setInterval(() => {
+					if(_this.loginEnd) {
+						clearInterval(_interval);
+						resolve(_this.isLoginSuccess);
+					}
+				}, 50)
+			} else {
+				resolve(_this.isLoginSuccess);
+			}
+		})
+	}
+	/**
+	 * @description 登录客户端
+	 * @params {Object} config 登录相关配置
+	 */
+	login(config: Object) {
+		this.loginEnd = false;
+		Object.assign(this.config, config);
+		// 未连接客户端
+		if(!this.isOpen()) {
+			// 连接失败
+			return false
+		} else {
+			// 若已登录,先注销
+			if (this.isLoginSuccess) {
+				this.logout();
+			}
+			// 登陆客户端
+			this.loginClient();
+			// 心跳保活
+			this._heartbeat();
+		}
+	}
+	/**
+	 * @description 连接客户端完成后登陆
+	 */
+	// loginAfterConnectEnd() {
+	// 	// 未连接客户端
+	// 	if(!this.isOpen()) {
+	// 		// 连接失败
+	// 		return false
+	// 	} else {
+	// 		// 若已登录,先注销
+	// 		if (this.isLoginSuccess) {
+	// 			this.logout();
+	// 		}
+	// 		// 登陆客户端
+	// 		this.loginClient();
+	// 		// 心跳保活
+	// 		this._heartbeat();
+	// 	}
+	// }
+	/**
+	 * @description 登出客户端
+	 */
+	logout() {
+		// 退出客户端
+		this.logoutClient();
+		this.isLoginSuccess = false;
+		if (typeof this.callback.loginResult === 'function') {
+			this.callback.loginResult.call(this, this.isLoginSuccess);
+		}
+	}
+	/**
+	 * @description 添加websocket/window监听事件
+	 */
+	addEvents() {
+		const webSocket = this.webSocket;
+		webSocket.addEventListener('open', () => this.onOpen());
+		webSocket.addEventListener('message', (e: any) => this.onMessage(e));
+		webSocket.addEventListener('error', () => this.onError());
+		window.addEventListener('resize', () => this.reLocatedPosition());
+		window.addEventListener('scroll', () => this.reLocatedPosition());
+	}
+	/**
+	 * @description 移除websocket/window监听事件
+	 */
+	removeEvents() {
+		const webSocket = this.webSocket;
+		webSocket.removeEventListener('open', this.onOpen);
+		webSocket.removeEventListener('message', this.onMessage);
+		webSocket.removeEventListener('error', this.onError);
+		webSocket.removeEventListener('resize', this.reLocatedPosition);
+		webSocket.removeEventListener('scroll', this.reLocatedPosition);
+	}
+	/**
+	 * @description 连接客户端成功事件
+	 */
+	onOpen() {
+		this.isConnectSuccessQt = true;
+		this.connectEnd = true;
+		if (typeof this.callback.connectResult === 'function') {
+			this.callback.connectResult.call(this, this.isConnectSuccessQt);
+		}
+	}
+	/**
+	 * @description 接收客户端消息
+	 * @params {Object} event 接收客户端的消息数据
+	 */
+	onMessage(event: { data: string; }) {
+		try {
+			const data = JSON.parse(event.data);
+			const { method } = data;
+			const callback = this.listerns.get(method);
+			if (method === 'loginState') {
+				this.loginFailCount ++;
+				if(this.loginFailCount < this.reLoginCount + 1) { // 登录未到最大次数
+					if(data.params.loginResult === 0) { // 登录成功
+						this.isLoginSuccess = data.params.loginResult === 0;
+						if (typeof this.callback.loginResult === 'function') {
+							this.callback.loginResult.call(this, this.isLoginSuccess);
+						}
+					} else { // 登录失败
+						this.loginClient();
+					}
+				} else { // 登录达到最大次数
+					this.loginEnd = true;
+					this.isLoginSuccess = data.params.loginResult === 0;
+					if (typeof this.callback.loginResult === 'function') {
+						this.callback.loginResult.call(this, this.isLoginSuccess);
+					}
+				}
+			}
+			if (callback) {
+				if (method === 'loginState') {
+					callback(this.isLoginSuccess);
+				} else if (method === 'createCtrlResult') {
+					callback(data.params.array);
+				} else {
+					callback(data);
+				}
+			}
+		} catch (e) {
+			// console.error('error', e);
+		}
+	}
+	/**
+	 * @description 客户端发生错误事件
+	 */
+	onError() {
+		this.isConnectSuccessQt = false;
+		clearTimeout(this.heartbeatTimer);
+		this.connectFailCount ++;
+		if(this.connectFailCount === this.reConnectCount + 1) {
+			this.connectEnd = true;
+			if (typeof this.callback.connectResult === 'function') {
+				this.callback.connectResult.call(this, this.isConnectSuccessQt);
+			}
+		}
+	}
+	/**
+	 * @description 判断是否成功连接客户端
+	 */
+	isOpen() {
+		if (!this.webSocket) return false;
+		return this.webSocket.readyState === 1;
+	}
+	/**
+	 * @description 心跳事件
+	 */
+	_heartbeat() {
+		this.heartbeat();
+		clearTimeout(this.heartbeatTimer);
+		this.heartbeatTimer = setTimeout(() => {
+			this._heartbeat();
+		}, 10000);
+	}
+	/**
+	 * @description 获取当前浏览器缩放和滚动条信息
+	 */
+	getScrollInfo() {
+		let ratio = detectZoom();
+		let scrollX = window.pageXOffset;
+		let scrollY = window.pageYOffset;
+		var hasscrollbary = hasScrollbarY();
+		var hasscrollbarx = hasScrollbarX();
+		var scrollbarWidth = getScrollbarWidth();
+		let scrollXH = hasscrollbarx ? scrollbarWidth : 0;
+		let scrollYW = hasscrollbary ? scrollbarWidth : 0;
+		return { ratio, scrollX, scrollY, scrollXH, scrollYW };
+	}
+}
+
+function promisify(func: Function) {
+	return new	Promise((resolve, reject) => {
+		func('1', (data) => resolve(data))
+	})
+}
+
+/**
+ * @description 判断对象是否含有某属性
+ * @params {Object} obj 对象
+ * @params {String} key 属性key
+ */
+function hasKey<O>(obj: O, key: keyof any): key is keyof O {
+	return key in obj
+}
+
+/**
+ * @description 与客户端通讯功能注册
+ * @params {Array} plugins 功能列表
+ */
+function usePlugin(plugins: any[]) {
+	plugins.forEach((plugin) => {
+		Object.getOwnPropertyNames(plugin).forEach(prop => {
+			Ws.prototype[prop] = plugin[prop];
+		});
+	});
+}
+
+function detectZoom() {
+	var ratio = 0,
+		screen = window.screen,
+		ua = navigator.userAgent.toLowerCase();
+
+	if (window.devicePixelRatio !== undefined) {
+		ratio = window.devicePixelRatio;
+	} else if (~ua.indexOf('msie')) {
+		if (screen['deviceXDPI'] && screen['logicalXDPI']) {
+			ratio = screen['deviceXDPI'] / screen['logicalXDPI'];
+		}
+	} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
+		ratio = window.outerWidth / window.innerWidth;
+	}
+
+	if (ratio) {
+		ratio = Math.round(ratio * 100);
+	}
+	return ratio;
+}
+
+function hasScrollbarY() {
+	return (
+		document.body.scrollHeight >
+		(window.innerHeight || document.documentElement.clientHeight)
+	);
+}
+
+function hasScrollbarX() {
+	return (
+		document.body.scrollWidth >
+		(window.innerWidth || document.documentElement.clientWidth)
+	);
+}
+
+function getScrollbarWidth() {
+	var scrollDiv = document.createElement('div');
+	scrollDiv.style.cssText =
+		'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
+	document.body.appendChild(scrollDiv);
+	var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+	document.body.removeChild(scrollDiv);
+
+	return scrollbarWidth;
+}

+ 1 - 0
zhsq_qk-ui/src/dahua/TVWalllib/version.txt

@@ -0,0 +1 @@
+version = '1.0.35'

File diff suppressed because it is too large
+ 11965 - 0
zhsq_qk-ui/src/dahua/TVWalllib/vue.js


+ 17 - 0
zhsq_qk-ui/src/dahua/lib/.eslintrc

@@ -0,0 +1,17 @@
+{
+    "env": {
+        "browser": true,
+        "commonjs": true,
+        "es6": true,
+        "node": true
+    },
+    "parserOptions": {
+        "ecmaFeatures": {
+            "jsx": false
+        },
+        "sourceType": "module"
+    },
+    "rules": {
+        // "semi": ["error","never"]
+    }
+}

File diff suppressed because it is too large
+ 7661 - 0
zhsq_qk-ui/src/dahua/lib/DHWs.js


File diff suppressed because it is too large
+ 1 - 0
zhsq_qk-ui/src/dahua/lib/DHWs.js.map


+ 82 - 0
zhsq_qk-ui/src/dahua/lib/demo.css

@@ -0,0 +1,82 @@
+#dom1, #dom2, #dom3, #dom4 {
+    width: 700px;
+    height: 400px;
+    position:absolute;
+}
+#dom1{
+    right:0;
+}
+#dom2{
+    /* right:0;
+    top: 400px; */
+}
+#dom3{
+    /* right:0;
+    top: 800px; */
+}
+
+#dom4{
+    left:1000px;
+}
+
+.maskVideo{
+    background-color: aquamarine;
+    position: fixed;
+}
+.center{
+    margin: 0 auto;
+    width: 1350px;
+}
+#app{
+    padding: 16px 10px;
+}
+#demo .ivu-form-item-label {
+    padding-right: 20px;
+}
+#demo #loginInfo .ivu-input {
+    width: 220px;
+}
+.ivu-input-wrapper {
+    margin-right: 10px;
+}
+.ivu-select {
+    margin-right: 10px;
+}
+#demo .ivu-input-wrapper {
+    width: 68px;
+}
+#demo .ivu-input {
+    width: 100%;
+}
+
+#demo .ivu-date-picker-rel .ivu-input-wrapper  {
+    width: 360px;
+}
+.ivu-btn + .ivu-btn {
+    margin-left: 20px;
+}
+.ivu-form-item .ivu-form-item {
+    margin-bottom: 6px;
+}
+#loginModule {
+    width: 560px;
+    margin: 10px auto;
+    padding: 16px;
+    border: 1px dashed #ccc;
+}
+#ctrlModule{
+    width: 850px;
+    float: left;
+    padding: 10px;
+    border: 1px dashed #ccc;
+}
+#popModule{
+    float: right;
+    width: 482px;
+    height: 372px;
+    padding: 10px;
+    border: 1px dashed #ccc;
+}
+#ctrlModule .ivu-form-item {
+    margin-bottom: 16px;
+}

+ 147 - 0
zhsq_qk-ui/src/dahua/lib/detect-element-resize.js

@@ -0,0 +1,147 @@
+/**
+* Detect Element Resize
+*
+* https://github.com/sdecima/javascript-detect-element-resize
+* Sebastian Decima
+*
+* version: 0.5.3
+**/
+
+(function () {
+	var attachEvent = document.attachEvent,
+		stylesCreated = false;
+	
+	if (!attachEvent) {
+		var requestFrame = (function(){
+			var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
+								function(fn){ return window.setTimeout(fn, 20); };
+			return function(fn){ return raf(fn); };
+		})();
+		
+		var cancelFrame = (function(){
+			var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
+								   window.clearTimeout;
+		  return function(id){ return cancel(id); };
+		})();
+
+		function resetTriggers(element){
+			var triggers = element.__resizeTriggers__,
+				expand = triggers.firstElementChild,
+				contract = triggers.lastElementChild,
+				expandChild = expand.firstElementChild;
+			contract.scrollLeft = contract.scrollWidth;
+			contract.scrollTop = contract.scrollHeight;
+			expandChild.style.width = expand.offsetWidth + 1 + 'px';
+			expandChild.style.height = expand.offsetHeight + 1 + 'px';
+			expand.scrollLeft = expand.scrollWidth;
+			expand.scrollTop = expand.scrollHeight;
+		};
+
+		function checkTriggers(element){
+			return element.offsetWidth != element.__resizeLast__.width ||
+						 element.offsetHeight != element.__resizeLast__.height;
+		}
+		
+		function scrollListener(e){
+			var element = this;
+			resetTriggers(this);
+			if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
+			this.__resizeRAF__ = requestFrame(function(){
+				if (checkTriggers(element)) {
+					element.__resizeLast__.width = element.offsetWidth;
+					element.__resizeLast__.height = element.offsetHeight;
+					element.__resizeListeners__.forEach(function(fn){
+						fn.call(element, e);
+					});
+				}
+			});
+		};
+		
+		/* Detect CSS Animations support to detect element display/re-attach */
+		var animation = false,
+			animationstring = 'animation',
+			keyframeprefix = '',
+			animationstartevent = 'animationstart',
+			domPrefixes = 'Webkit Moz O ms'.split(' '),
+			startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
+			pfx  = '';
+		{
+			var elm = document.createElement('fakeelement');
+			if( elm.style.animationName !== undefined ) { animation = true; }    
+			
+			if( animation === false ) {
+				for( var i = 0; i < domPrefixes.length; i++ ) {
+					if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
+						pfx = domPrefixes[ i ];
+						animationstring = pfx + 'Animation';
+						keyframeprefix = '-' + pfx.toLowerCase() + '-';
+						animationstartevent = startEvents[ i ];
+						animation = true;
+						break;
+					}
+				}
+			}
+		}
+		
+		var animationName = 'resizeanim';
+		var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
+		var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
+	}
+	
+	function createStyles() {
+		if (!stylesCreated) {
+			//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
+			var css = (animationKeyframes ? animationKeyframes : '') +
+					'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
+					'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
+				head = document.head || document.getElementsByTagName('head')[0],
+				style = document.createElement('style');
+			
+			style.type = 'text/css';
+			if (style.styleSheet) {
+				style.styleSheet.cssText = css;
+			} else {
+				style.appendChild(document.createTextNode(css));
+			}
+
+			head.appendChild(style);
+			stylesCreated = true;
+		}
+	}
+	
+	window.addResizeListener = function(element, fn){
+		if (attachEvent) element.attachEvent('onresize', fn);
+		else {
+			if (!element.__resizeTriggers__) {
+				if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
+				createStyles();
+				element.__resizeLast__ = {};
+				element.__resizeListeners__ = [];
+				(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
+				element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
+																						'<div class="contract-trigger"></div>';
+				element.appendChild(element.__resizeTriggers__);
+				resetTriggers(element);
+				element.addEventListener('scroll', scrollListener, true);
+				
+				/* Listen for a css animation to detect element display/re-attach */
+				animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
+					if(e.animationName == animationName)
+						resetTriggers(element);
+				});
+			}
+			element.__resizeListeners__.push(fn);
+		}
+	};
+	
+	window.removeResizeListener = function(element, fn){
+		if (attachEvent) element.detachEvent('onresize', fn);
+		else {
+			element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
+			if (!element.__resizeListeners__.length) {
+					element.removeEventListener('scroll', scrollListener);
+					element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
+			}
+		}
+	}
+})();

File diff suppressed because it is too large
+ 1 - 0
zhsq_qk-ui/src/dahua/lib/iview.css


File diff suppressed because it is too large
+ 45435 - 0
zhsq_qk-ui/src/dahua/lib/iview.js


File diff suppressed because it is too large
+ 10872 - 0
zhsq_qk-ui/src/dahua/lib/jquery.js


+ 533 - 0
zhsq_qk-ui/src/dahua/lib/main.ts

@@ -0,0 +1,533 @@
+// 与客户端交互方法列表
+import wsPlugins from './plugins/index';
+// const ReWebSocket = require('reconnecting-websocket');
+// websocket重连
+import ReWebSocket from '../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs';
+// const Bowser = require('bowser');
+// 浏览器信息获取
+import Bowser from "../node_modules/bowser/es5";
+const browser = Bowser.getParser(window.navigator.userAgent);
+
+interface callbacks {
+	// 连接客户端状态
+	connectResult: any,
+	// 登录客户端状态
+	loginResult: any
+}
+
+
+export default class Ws {
+	[x: string]: any;
+	// 连接地址
+	static url: string = '';
+	// 传入的配置项(方法)
+	static opts: Object = {};
+	// 密码加密公钥
+	static publicKey = '';
+	// 是否连接客户端
+	private isConnectSuccessQt: Boolean = false;
+	// 是否登录客户端
+	private isLoginSuccess: Boolean = false;
+	// 唯一实例
+	private static _instance: any = null;
+	// 当前连接的webSocket
+	webSocket: any;
+	// 最大重连数
+	reConnectCount: number = 3;
+	// 连接失败次数
+	connectFailCount: number = 0;
+	// 重连完成标识
+	connectEnd: Boolean = false;
+	// 登录完成标识
+	loginEnd: Boolean = false;
+	// 最大重登数
+	reLoginCount: number = 1;
+	// 连接失败次数
+	loginFailCount: number = 0;
+	// 当前websocket登录配置
+	config: Object = {};
+	// 登陆IP
+	loginIp: string;
+	// 登陆端口
+	loginPort: string;
+	// 登录用户名
+	userName: string;
+	// 登录密码,密码与token二选一
+	userPwd: string;
+	// 登录token,密码与token二选一
+	token: string;
+	// 用户标识符
+	userCode: Number = 0;
+	// 回调函数
+	private callback: callbacks;
+	// 创建的控件ID列表
+	ids: Array<String> = [];
+	// 创建的控件列表
+	ctrls: Array<String> = [];
+	// 心跳
+	heartBeatTimer: any = null;
+	// 监听的方法表
+	listerns: any;
+	constructor({
+		url= 'ws://localhost:1234',
+		publicKey= 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbEpPpxpLJft4W9YZj8bRh2bYYZshBEsKOlxgyn11rlEyTasjBSZRV9aj33tvQ2T55izH0fWl+dL/dLZChawFrlGDcH8JuWge2xYMgII9mggcYa0UiQ7pLXJ9ivXZ/cOY3HzrRQdR7dGTSNn3Z0Ctbns6mLgvlA2r3qMNs/8wHBwIDAQAB',
+		reConnectCount = 3,
+		reLoginCount = 1,
+		loginIp= location.hostname,
+		loginPort= location.port,
+		userName = '',
+		userPwd = '',
+		token = '',
+		callback = {
+			connectResult: null,
+			loginResult: null
+		}
+	} : {
+		url: string,
+		publicKey: string,
+		reConnectCount: number,
+		reLoginCount: number,
+		loginIp: string,
+		loginPort: string,
+		userName: string,
+		userPwd: string,
+		token: string
+		callback: callbacks,
+	}) {
+		// if (/https/.test(location.protocol)) {
+		// 	url = `wss:${url}`;
+		// } else {
+		// 	url = `ws:${url}`;
+		// }
+		// url = `ws://localhost:1234`;
+
+		this.url = url;
+		this.userCode = new Date().valueOf();
+		this.webSocket = null;
+		this.reConnectCount = reConnectCount;
+		this.reLoginCount = reLoginCount;
+		this.publicKey = publicKey;
+		this.loginIp = loginIp;
+		this.loginPort = loginPort;
+		this.userName = userName;
+		this.userPwd = userPwd;
+		this.token = token;
+		this.callback = callback;
+		
+		this.connectFailCount = this.connectFailCount;
+
+		// 基础操作所需功能或属性
+		this.ids = [];
+		this.ctrls = [];
+
+		// 是否连接客户端
+		this.isConnectSuccessQt = false;
+		// 是否登陆客户端
+		this.isLoginSuccess = false;
+		this.heartBeatTimer = null;
+
+		// 初始化配置参数
+		this.initConfig();
+
+		// 连接客户端
+		this.connectQt();
+
+		// 获取与客户端交互方法列表
+		const plugins = [];
+		Object.keys(wsPlugins).forEach(item => {
+			if(hasKey(wsPlugins, item)){
+				plugins.push(wsPlugins[item]);
+			}
+		});
+		// 与客户端通讯功能注册
+		usePlugin(plugins);
+
+		// 用户注册监听事件表
+		this.listerns = new Map();
+
+		// 传入登录配置,则登录
+		if(this.userName) {
+			this.detectConnectQt().then((res: Boolean) => {
+				if(res) {
+					// 登陆客户端
+					this.loginClient();
+					// 心跳保活
+					this._heartbeat();
+				}
+			});
+		}
+	}
+	/**
+	 * @description 获得实例对象
+	 */
+	public static getInstance(options: any):Ws {
+		if(!this._instance) {
+			this._instance = new Ws(options);
+		}
+		return this._instance;
+	}
+	/**
+	 * @description 用户注册监听事件
+	 * @params {String} eventType 事件名称
+	 * @params {any} callback 回调函数
+	 */
+	on(eventType: String, callback: any) {
+		this.listerns.set(eventType, callback);
+	}
+	/**
+	 * @description 用户取消监听事件
+	 * @params {String} eventType 事件名称
+	 */
+	off(eventType: string) {
+		delete this.listerns[eventType];
+	}
+	/**
+	 * @description 发送消息给客户端
+	 * @params {String} method 事件名称
+	 * @params {Object} data 传输消息的数据内容
+	 */
+	emit(method: any, data: { method: any; }) {
+		const { webSocket } = this;
+		data.method = method;
+		// 不需要判断登录和连接的方法过滤
+		let filterList = ['heartbeat', 'login', 'logout', 'browserInfo'];
+		if(filterList.includes(method)) {
+			webSocket.send(JSON.stringify(data));
+			return;
+		}
+		return new Promise((resolve, reject) => {
+			this.detectConnectQt().then(con => {
+				if(con) {
+					this.detectLoginClient().then(login => {
+						if(login) {
+							webSocket.send(JSON.stringify(data));
+							resolve(true);
+						} else {
+							// 登录失败
+							reject(2);
+						}
+					})
+				} else {
+					// 连接失败
+					reject(1);
+				}
+			})
+		})
+	}
+	/*
+	* 初始化配置
+	*/
+	initConfig() {
+		this.config = {
+			userName: this.userName,
+			userCode: this.userCode,
+			loginPort: this.loginPort,
+			loginIp: this.loginIp,
+			userPwd: this.userPwd,
+			token: this.token,
+		};
+		// 浏览器信息
+		const browserInfo = {
+			name: '',
+			version: '',
+			platform: ''
+		};
+		browserInfo.name = browser.getBrowserName().toLowerCase();
+		browserInfo.version = browser.getBrowser().version.toLowerCase();
+		browserInfo.platform =
+			browser._ua.indexOf('Win64') >= 0 || browser._ua.indexOf('Wow64') >= 0
+				? 'win64'
+				: 'win32';
+		this.config['browser'] = browserInfo;
+	}
+	/**
+	 * @description 连接客户端
+	 */
+	connectQt() {
+		this.connectEnd = false;
+		// 连接客户端
+		this.webSocket = new ReWebSocket(this.url, '', {
+			maxRetries: this.reConnectCount
+		});
+		this.addEvents();
+	}
+	/**
+	 * @description 检测连接客户端状态
+	 */
+	detectConnectQt() {
+		let _this = this;
+		return new Promise((resolve, reject) => {
+			if(!this.connectEnd) { // 连接中
+				let _interval = setInterval(() => {
+					if(_this.connectEnd) {
+						clearInterval(_interval);
+						resolve(_this.isConnectSuccessQt);
+					}
+				}, 50)
+			} else {
+				resolve(_this.isConnectSuccessQt);
+			}
+		})
+	}
+	/**
+	 * @description 检测登录客户端状态
+	 */
+	detectLoginClient() {
+		let _this = this;
+		return new Promise((resolve, reject) => {
+			if(!this.loginEnd) { // 连接中
+				let _interval = setInterval(() => {
+					if(_this.loginEnd) {
+						clearInterval(_interval);
+						resolve(_this.isLoginSuccess);
+					}
+				}, 50)
+			} else {
+				resolve(_this.isLoginSuccess);
+			}
+		})
+	}
+	/**
+	 * @description 登录客户端
+	 * @params {Object} config 登录相关配置
+	 */
+	login(config: Object) {
+		this.loginEnd = false;
+		Object.assign(this.config, config);
+		// 未连接客户端
+		if(!this.isOpen()) {
+			// 连接失败
+			return false
+		} else {
+			// 若已登录,先注销
+			if (this.isLoginSuccess) {
+				this.logout();
+			}
+			// 登陆客户端
+			this.loginClient();
+			// 心跳保活
+			this._heartbeat();
+		}
+	}
+	/**
+	 * @description 连接客户端完成后登陆
+	 */
+	// loginAfterConnectEnd() {
+	// 	// 未连接客户端
+	// 	if(!this.isOpen()) {
+	// 		// 连接失败
+	// 		return false
+	// 	} else {
+	// 		// 若已登录,先注销
+	// 		if (this.isLoginSuccess) {
+	// 			this.logout();
+	// 		}
+	// 		// 登陆客户端
+	// 		this.loginClient();
+	// 		// 心跳保活
+	// 		this._heartbeat();
+	// 	}
+	// }
+	/**
+	 * @description 登出客户端
+	 */
+	logout() {
+		// 退出客户端
+		this.logoutClient();
+		this.isLoginSuccess = false;
+		if (typeof this.callback.loginResult === 'function') {
+			this.callback.loginResult.call(this, this.isLoginSuccess);
+		}
+	}
+	/**
+	 * @description 添加websocket/window监听事件
+	 */
+	addEvents() {
+		const webSocket = this.webSocket;
+		webSocket.addEventListener('open', () => this.onOpen());
+		webSocket.addEventListener('message', (e: any) => this.onMessage(e));
+		webSocket.addEventListener('error', () => this.onError());
+		window.addEventListener('resize', () => this.reLocatedPosition());
+		window.addEventListener('scroll', () => this.reLocatedPosition());
+	}
+	/**
+	 * @description 移除websocket/window监听事件
+	 */
+	removeEvents() {
+		const webSocket = this.webSocket;
+		webSocket.removeEventListener('open', this.onOpen);
+		webSocket.removeEventListener('message', this.onMessage);
+		webSocket.removeEventListener('error', this.onError);
+		webSocket.removeEventListener('resize', this.reLocatedPosition);
+		webSocket.removeEventListener('scroll', this.reLocatedPosition);
+	}
+	/**
+	 * @description 连接客户端成功事件
+	 */
+	onOpen() {
+		this.isConnectSuccessQt = true;
+		this.connectEnd = true;
+		if (typeof this.callback.connectResult === 'function') {
+			this.callback.connectResult.call(this, this.isConnectSuccessQt);
+		}
+	}
+	/**
+	 * @description 接收客户端消息
+	 * @params {Object} event 接收客户端的消息数据
+	 */
+	onMessage(event: { data: string; }) {
+		try {
+			const data = JSON.parse(event.data);
+			const { method } = data;
+			const callback = this.listerns.get(method);
+			if (method === 'loginState') {
+				this.loginFailCount ++;
+				if(this.loginFailCount < this.reLoginCount + 1) { // 登录未到最大次数
+					if(data.params.loginResult === 0) { // 登录成功
+						this.isLoginSuccess = data.params.loginResult === 0;
+						if (typeof this.callback.loginResult === 'function') {
+							this.callback.loginResult.call(this, this.isLoginSuccess);
+						}
+					} else { // 登录失败
+						this.loginClient();
+					}
+				} else { // 登录达到最大次数
+					this.loginEnd = true;
+					this.isLoginSuccess = data.params.loginResult === 0;
+					if (typeof this.callback.loginResult === 'function') {
+						this.callback.loginResult.call(this, this.isLoginSuccess);
+					}
+				}
+			}
+			if (callback) {
+				if (method === 'loginState') {
+					callback(this.isLoginSuccess);
+				} else if (method === 'createCtrlResult') {
+					callback(data.params.array);
+				} else {
+					callback(data);
+				}
+			}
+		} catch (e) {
+			// console.error('error', e);
+		}
+	}
+	/**
+	 * @description 客户端发生错误事件
+	 */
+	onError() {
+		this.isConnectSuccessQt = false;
+		clearTimeout(this.heartbeatTimer);
+		this.connectFailCount ++;
+		if(this.connectFailCount === this.reConnectCount + 1) {
+			this.connectEnd = true;
+			if (typeof this.callback.connectResult === 'function') {
+				this.callback.connectResult.call(this, this.isConnectSuccessQt);
+			}
+		}
+	}
+	/**
+	 * @description 判断是否成功连接客户端
+	 */
+	isOpen() {
+		if (!this.webSocket) return false;
+		return this.webSocket.readyState === 1;
+	}
+	/**
+	 * @description 心跳事件
+	 */
+	_heartbeat() {
+		this.heartbeat();
+		clearTimeout(this.heartbeatTimer);
+		this.heartbeatTimer = setTimeout(() => {
+			this._heartbeat();
+		}, 10000);
+	}
+	/**
+	 * @description 获取当前浏览器缩放和滚动条信息
+	 */
+	getScrollInfo() {
+		let ratio = detectZoom();
+		let scrollX = window.pageXOffset;
+		let scrollY = window.pageYOffset;
+		var hasscrollbary = hasScrollbarY();
+		var hasscrollbarx = hasScrollbarX();
+		var scrollbarWidth = getScrollbarWidth();
+		let scrollXH = hasscrollbarx ? scrollbarWidth : 0;
+		let scrollYW = hasscrollbary ? scrollbarWidth : 0;
+		return { ratio, scrollX, scrollY, scrollXH, scrollYW };
+	}
+}
+
+function promisify(func: Function) {
+	return new	Promise((resolve, reject) => {
+		func('1', (data) => resolve(data))
+	})
+}
+
+/**
+ * @description 判断对象是否含有某属性
+ * @params {Object} obj 对象
+ * @params {String} key 属性key
+ */
+function hasKey<O>(obj: O, key: keyof any): key is keyof O {
+	return key in obj
+}
+
+/**
+ * @description 与客户端通讯功能注册
+ * @params {Array} plugins 功能列表
+ */
+function usePlugin(plugins: any[]) {
+	plugins.forEach((plugin) => {
+		Object.getOwnPropertyNames(plugin).forEach(prop => {
+			Ws.prototype[prop] = plugin[prop];
+		});
+	});
+}
+
+function detectZoom() {
+	var ratio = 0,
+		screen = window.screen,
+		ua = navigator.userAgent.toLowerCase();
+
+	if (window.devicePixelRatio !== undefined) {
+		ratio = window.devicePixelRatio;
+	} else if (~ua.indexOf('msie')) {
+		if (screen['deviceXDPI'] && screen['logicalXDPI']) {
+			ratio = screen['deviceXDPI'] / screen['logicalXDPI'];
+		}
+	} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
+		ratio = window.outerWidth / window.innerWidth;
+	}
+
+	if (ratio) {
+		ratio = Math.round(ratio * 100);
+	}
+	return ratio;
+}
+
+function hasScrollbarY() {
+	return (
+		document.body.scrollHeight >
+		(window.innerHeight || document.documentElement.clientHeight)
+	);
+}
+
+function hasScrollbarX() {
+	return (
+		document.body.scrollWidth >
+		(window.innerWidth || document.documentElement.clientWidth)
+	);
+}
+
+function getScrollbarWidth() {
+	var scrollDiv = document.createElement('div');
+	scrollDiv.style.cssText =
+		'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
+	document.body.appendChild(scrollDiv);
+	var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+	document.body.removeChild(scrollDiv);
+
+	return scrollbarWidth;
+}

+ 1 - 0
zhsq_qk-ui/src/dahua/lib/version.txt

@@ -0,0 +1 @@
+version = '1.0.35'

File diff suppressed because it is too large
+ 11965 - 0
zhsq_qk-ui/src/dahua/lib/vue.js


+ 104 - 3
zhsq_qk-ui/src/views/fusion/index.vue

@@ -176,7 +176,8 @@
         <a @click="handleNavigation('csgl')"><i><img src="@/assets/images/qkq_icon2.png"/></i><span>城市管理</span></a>
         <a @click="handleNavigation('jtzl')"><i><img src="@/assets/images/qkq_icon3.png"/></i><span>交通治理</span></a>
         <a @click="handleNavigation('jczl')"><i><img src="@/assets/images/qkq_icon4.png"/></i><span>基层治理</span></a>
-        <a @click="handleNavigation('yshj_new')"><i><img src="@/assets/images/qkq_icon5.png"/></i><span>营商环境</span></a>
+<!--        <a @click="handleNavigation('yshj_new')"><i><img src="@/assets/images/qkq_icon5.png"/></i><span>营商环境</span></a>-->
+        <a @click="showTVWallDiaLog()"><i><img src="@/assets/images/qkq_icon5.png"/></i><span>车路云监控服务</span></a>
         <a @click="handleNavigation('bjzshz')"><i><img src="@/assets/images/qkq_icon6.png"/></i><span>政务运行</span></a>
         <a @click="handleNavigation('aqyj')"><i><img src="@/assets/images/qkq_icon7.png"/></i><span>安全应急</span></a>
         <a @click="handleNavigation('jjyx')"><i><img src="@/assets/images/qkq_icon8.png"/></i><span>经济运行</span></a>
@@ -185,12 +186,12 @@
     <!--中间地图 结束-->
     <!--底部开始-->
     <div class="footer">
-
     </div>
 		<div class="footerbg">
 
 		</div>
     <!--底部开始-->
+    <TVWall ref="TVWall"></TVWall>
   </div>
 </template>
 
@@ -202,12 +203,15 @@ import "@/assets/images/qkq_body.css";
 import "@/assets/images/qkq_index.css";
 import axios from 'axios';
 import Map3D from '@/map3d'; // A
+import TVWall from '@/components/TVWall.vue' //电视墙弹窗
+import DHWs from '@/dahua/lib/DHWs'
 const qikaiJSON = require('@/assets/geoJson/seven.json')
 
 export default {
   name: 'weather',
   components: {
-    Map3D
+    Map3D,
+    TVWall
   },
   data() {
     return {
@@ -238,6 +242,103 @@ export default {
     this.queryMapData(this.mapAdCode);
   },
   methods: {
+    showTVWallDiaLog() {
+      this.initByCameras();
+    },
+    initByCameras() {
+      let that = this
+      let tvListJson = [{
+        "switchTab": "2",
+        "treeLabels": [
+          {
+          "id": null,
+          "labelCode": "999",
+          "labelName": "电视墙",
+          "cameraType": null,
+          "parentLabelCode": ""
+          },
+          {
+            "id": "spcamera00010",
+            "labelCode": 11102223956707520,
+            "labelName": "7-新红旗大街-和谐大街-西向东",
+            "cameraType": 0,
+            "parentLabelCode": "999"
+          },
+          {
+            "id": "spcamera00010",
+            "labelCode": 11102567607765184,
+            "labelName": "4-铸造路-和谐大街-西向东",
+            "cameraType": 0,
+            "parentLabelCode": "999"
+          },
+          {
+            "id": "spcamera00010",
+            "labelCode": 11102296912627904,
+            "labelName": "7-新红旗大街-和谐大街-南向北1",
+            "cameraType": 0,
+            "parentLabelCode": "999"
+          },
+          {
+            "id": "spcamera00010",
+            "labelCode": 11102575245658304,
+            "labelName": "28-新红旗大街-大众街-北向南",
+            "cameraType": 0,
+            "parentLabelCode": "999"
+          }
+        ],
+        "labelChannels": [
+          {
+            "labelCode": 11102223956707520,
+            "channelDates": [{
+              "channelCode": 11102223956707520,
+              "channelName": "7-新红旗大街-和谐大街-西向东",
+              "channelSn": null,
+              "cameraType": 0,
+              "online": "1",
+              "cameraCode": null
+            }]
+          },
+          {
+            "labelCode": 11102567607765184,
+            "channelDates": [{
+              "channelCode": 11102567607765184,
+              "channelName": "4-铸造路-和谐大街-西向东",
+              "channelSn": null,
+              "cameraType": 0,
+              "online": "1",
+              "cameraCode": null
+            }]
+          },
+          {
+            "labelCode": 11102296912627904,
+            "channelDates": [{
+              "channelCode": 11102296912627904,
+              "channelName": "7-新红旗大街-和谐大街-南向北1",
+              "channelSn": null,
+              "cameraType": 0,
+              "online": "1",
+              "cameraCode": null
+            }]
+          },
+          {
+            "labelCode": 11102575245658304,
+            "channelDates": [{
+              "channelCode": 11102575245658304,
+              "channelName": "28-新红旗大街-大众街-北向南",
+              "channelSn": null,
+              "cameraType": 0,
+              "online": "1",
+              "cameraCode": null
+            }]
+          }
+        ]
+      }]
+      this.$refs.TVWall.showTVWall1(125.438769, 43.6897039, tvListJson);
+      this.$refs.bottomMenu.showMeasure = false
+      this.$refs.bottomMenu.showChild = false
+      this.$refs.bottomMenu.showBanChild = false
+      this.$refs.bottomMenu.showChangChild = false
+    },
     queryMapData(code) {
       this.geoJson = qikaiJSON
       // axios.get(`https://geo.datav.aliyun.com/areas_v3/bound/${code}_full.json`)