张延森 3 年前
父节点
当前提交
e26cb58a1f

+ 74
- 0
public/js/jquery-1.12.4.min.js
文件差异内容过多而无法显示
查看文件


+ 36
- 0
public/js/jsWebControl-1.0.0.min.js
文件差异内容过多而无法显示
查看文件


+ 14
- 11
src/components/GeoMap/VideoModel.jsx 查看文件

@@ -1,10 +1,15 @@
1 1
 import { Modal, Button } from 'antd';
2
-import React, { useEffect, useMemo, useState } from 'react';
2
+import React, { useEffect, useMemo, useRef, useState } from 'react';
3
+import Hatc from '@/components/Hatc';
4
+import { getPreviewInfo } from '@/services/machinery';
3 5
 
4 6
 export default (props) => {
5
-  const { width = 600, machineryRef, visible, toggleVisible } = props;
7
+  const width = 960;
8
+  const height = 540;
9
+  const { machineryRef, visible, toggleVisible } = props;
6 10
 
7
-  const [url, setURL] = useState();
11
+  const [preview, setPreview] = useState();
12
+  const hatcRef = useRef();
8 13
 
9 14
   const TitleHolder = useMemo(() => <div>这是标题占位</div>, []);
10 15
 
@@ -14,12 +19,12 @@ export default (props) => {
14 19
 
15 20
   useEffect(() => {
16 21
     // 隐藏的时候取消视频播放
17
-    if (!visible) {
18
-      setURL(undefined);
22
+    if (visible) {
23
+      getPreviewInfo('05a281758ccfe9c68fcada81faee7cae').then(setPreview);
19 24
     } else {
20
-      setURL(
21
-        'https://yz-offical.oss-cn-shanghai.aliyuncs.com/%E7%9C%81%E5%8F%98%E7%94%B5%E5%9F%B9%E8%AE%AD%E5%9F%BA%E5%9C%B0%E8%A7%86%E9%A2%91%20A%20copy.mov',
22
-      );
25
+      if (hatcRef.current) {
26
+        hatcRef.current.stop();
27
+      }
23 28
     }
24 29
   }, [visible]);
25 30
 
@@ -32,9 +37,7 @@ export default (props) => {
32 37
       visible={visible}
33 38
       onCancel={handleCancel}
34 39
     >
35
-      <video style={{ display: 'block' }} width={width} controls src={url}>
36
-        您的浏览器不支持 video 。
37
-      </video>
40
+      <Hatc width={width} ref={hatcRef} height={height} previewParams={preview} />
38 41
     </Modal>
39 42
   );
40 43
 };

+ 61
- 0
src/components/Hatc/index.jsx 查看文件

@@ -0,0 +1,61 @@
1
+import React, {
2
+  useEffect,
3
+  useMemo,
4
+  useRef,
5
+  useState,
6
+  forwardRef,
7
+  useImperativeHandle,
8
+} from 'react';
9
+import { Card } from 'antd';
10
+import SDK from './sdk';
11
+
12
+export default forwardRef((props, ref) => {
13
+  const id = useMemo(() => `hatc-${Math.random().toString(36).substring(2, 8)}`, []);
14
+
15
+  const { previewParams, width, height } = props;
16
+  const ctrlRef = useRef();
17
+  const [inited, setInited] = useState(false);
18
+  const [loading, setLoading] = useState(false);
19
+
20
+  useEffect(() => {
21
+    setLoading(true);
22
+    SDK({ id, width, height }).then((res) => {
23
+      ctrlRef.current = res;
24
+      setInited(true);
25
+      setLoading(false);
26
+    });
27
+
28
+    return () => {
29
+      if (ctrlRef.current) {
30
+        ctrlRef.current.destroy();
31
+      }
32
+    };
33
+  }, [id, width, height]);
34
+
35
+  useEffect(() => {
36
+    if (inited) {
37
+      if (previewParams) {
38
+        setLoading(true);
39
+        ctrlRef.current
40
+          .preview(previewParams)
41
+          .then(() => {
42
+            setLoading(false);
43
+          })
44
+          .catch((err) => {
45
+            setLoading(false);
46
+            console.log('-------err----->', err);
47
+          });
48
+      }
49
+    }
50
+  }, [inited, previewParams]);
51
+
52
+  useImperativeHandle(ref, () => ({
53
+    stop: () => {
54
+      if (ctrlRef.current) {
55
+        ctrlRef.current.stopPreview();
56
+      }
57
+    },
58
+  }));
59
+
60
+  return <div id={id} />;
61
+});

+ 111
- 0
src/components/Hatc/sdk.js 查看文件

@@ -0,0 +1,111 @@
1
+/**
2
+ * https://yz-websit.oss-cn-hangzhou.aliyuncs.com/nanyang/%E8%B7%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E5%AA%92%E4%BD%93%E6%8F%92%E4%BB%B6%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.pdf
3
+ * SDK 使用大致说明
4
+ * 1、npm i web-control
5
+ * 2、使用 new WebControl 实例化插件
6
+ * 3、使用 JS_StartService 开启服务
7
+ * 4、使用 JS_SetWindowControlCallback 注册回调
8
+ * 5、使用 JS_CreateWnd 创建窗口
9
+ * 6、使用 JS_DestroyWnd 销毁窗口
10
+ * 7、使用 JS_Disconnect 断开连接
11
+ */
12
+
13
+/**
14
+ * SDK
15
+ */
16
+export default function SDK({ id, width, height }) {
17
+  return new Promise((resolve, reject) => {
18
+    const ctx = {};
19
+    const ctrl = new WebControl({
20
+      szPluginContainer: id,
21
+      iServicePortStart: 14430, // 固定值
22
+      iServicePortEnd: 14439, // 固定值
23
+      szClassId: '29DDBC9A-8AEA-4827-9C3A-805D697CF38F', // 固定值
24
+      cbConnectSuccess: function () {
25
+        console.log('cbConnectSuccess');
26
+
27
+        // ctrl.SetWindowControlCallback({
28
+        //   cbIntegrationCallBack: callback,
29
+        // });
30
+
31
+        ctrl
32
+          .JS_StartService('window', {
33
+            dllPath: './WebPreview.dll',
34
+          })
35
+          .then(() => {
36
+            resolve(ctx);
37
+          })
38
+          .catch((err) => {
39
+            console.error(err);
40
+            reject(err);
41
+          });
42
+      },
43
+      cbConnectError: function () {
44
+        console.log('cbConnectError');
45
+        reject(new Error('cbConnectError'));
46
+      },
47
+      cbConnectClose: function (bNormalClose) {
48
+        console.log('cbConnectClose');
49
+      },
50
+    });
51
+    ctx.ctrl = ctrl;
52
+
53
+    // 实时预览
54
+    function preview(params) {
55
+      console.log('------preview-------', params);
56
+      return ctrl.JS_CreateWnd(id, width, height).then(function (resp) {
57
+        console.log('------JS_CreateWnd-------', resp);
58
+        return ctrl
59
+          .JS_RequestInterface({
60
+            funcName: 'setPreviewLayout',
61
+            arguments: {
62
+              devSerialNum: params.devSerialNum,
63
+              productKey: params.productKey,
64
+              layout: 1,
65
+              channels: [{ channel: params.channel, channelName: '前视' }],
66
+              channelName: '前视',
67
+              channel: params.channel,
68
+            },
69
+          })
70
+          .then(function (oData) {
71
+            console.log('------setPreviewLayout-------', oData);
72
+            return ctrl
73
+              .JS_RequestInterface({
74
+                funcName: 'startPreview',
75
+                arguments: {
76
+                  url: params.url,
77
+                  devSerialNum: params.devSerialNum,
78
+                  productKey: params.productKey,
79
+                  channel: params.channel,
80
+                  streamType: params.streamType,
81
+                  code: params.code,
82
+                  protocol: params.protocol,
83
+                },
84
+              })
85
+              .then((res) => {
86
+                console.log('------startPreview-------', res);
87
+              });
88
+          });
89
+      });
90
+    }
91
+    ctx.preview = preview;
92
+
93
+    // 停止播放
94
+    function stopPreview() {
95
+      ctrl.JS_RequestInterface({
96
+        funcName: 'stopAllPreview',
97
+        arguments: {},
98
+      });
99
+      ctrl.JS_DestroyWnd();
100
+    }
101
+    ctx.stopPreview = stopPreview;
102
+
103
+    // 销毁
104
+    function destroy() {
105
+      // 关闭所有预览
106
+      stopPreview();
107
+      ctrl.JS_Disconnect();
108
+    }
109
+    ctx.destroy = destroy;
110
+  });
111
+}

+ 15
- 13
src/pages/MonitoringScreen/index.jsx 查看文件

@@ -129,19 +129,21 @@ export default (props) => {
129 129
   ]);
130 130
 
131 131
   useEffect(() => {
132
-    getWeather('邓州市').then((res) => {
133
-      if (res && res.length) {
134
-        const { casts } = res[0];
135
-        const { dayweather, nighttemp, daytemp } = casts[0];
136
-        const [min, max] =
137
-          parseInt(nighttemp) > parseInt(daytemp) ? [daytemp, nighttemp] : [nighttemp, daytemp];
138
-        setWeather(`${dayweather} ${min}-${max} °C`);
139
-      } else {
140
-        setWeather('暂无天气信息');
141
-      }
142
-    }).catch((err) => {
143
-      console.log(err.message)
144
-    });
132
+    getWeather('邓州市')
133
+      .then((res) => {
134
+        if (res && res.length) {
135
+          const { casts } = res[0];
136
+          const { dayweather, nighttemp, daytemp } = casts[0];
137
+          const [min, max] =
138
+            parseInt(nighttemp) > parseInt(daytemp) ? [daytemp, nighttemp] : [nighttemp, daytemp];
139
+          setWeather(`${dayweather} ${min}-${max} °C`);
140
+        } else {
141
+          setWeather('暂无天气信息');
142
+        }
143
+      })
144
+      .catch((err) => {
145
+        console.log(err.message);
146
+      });
145 147
   }, []);
146 148
 
147 149
   useParticlesJs(Styles['particles-js']);

+ 1
- 0
src/pages/document.ejs 查看文件

@@ -25,6 +25,7 @@
25 25
     <title>Ant Design Pro</title>
26 26
     <link rel="icon" href="<%= context.config.publicPath +'favicon.ico'%>" type="image/x-icon" />
27 27
     <script src="./js/particles.min.js"></script>
28
+    <script src="./js/jsWebControl-1.0.0.min.js"></script>
28 29
   </head>
29 30
   <body>
30 31
     <noscript>

+ 7
- 0
src/services/machinery.js 查看文件

@@ -41,3 +41,10 @@ export const getMachineryDetail = (id) => request(`/machinery/${id}`);
41 41
  * @returns
42 42
  */
43 43
 export const getduty = (id, params) => request(`/machinery/${id}/duty`, { params });
44
+
45
+/**
46
+ * 查询实时预览信息
47
+ * @param {*} id
48
+ * @returns
49
+ */
50
+export const getPreviewInfo = (id) => request(`/machinery/${id}/preview`);