MSI\liwei 3 năm trước cách đây
mục cha
commit
66afa6ec09

+ 18 - 0
public/webClient/defaultConfig.js

@@ -0,0 +1,18 @@
+/*
+ * @Author: awj
+ * @Date: 2020-03-09 11:10:23
+ * @LastEditors: awj
+ * @LastEditTime: 2021-09-14 19:05:51
+ * @Description:  瘦客户端默认参数
+ */
+
+/*
+    注释:客户端视频插件启动IP为大华服务器对应的IP、端口为大华服务器对应端口
+*/
+let defaultConfig = { // 默认配置,可以通过option覆盖
+    // 协议
+    protocol: location.protocol === "file:" ? "http" : location.protocol.split(":")[0],
+    // 开发环境配置
+    loginIp: '10.55.134.3', // DEMO采用登陆页面的地址,   若第三方自行开发,请填写大华服务器对应的IP
+    port: '6699'  //  DEMO采用登陆页面的映射端口,若第三方自行开发,请填写大华服务器对应的端口
+};

+ 336 - 0
public/webClient/initWebSocket.js

@@ -0,0 +1,336 @@
+function getRandomString(len = 10) {
+    const chars =
+        "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"; /** **默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
+    const maxPos = chars.length;
+    let randomString = "";
+    for (let i = 0; i < len; i++) {
+        randomString += chars.charAt(Math.floor(Math.random() * maxPos));
+    }
+    return randomString;
+}
+class InitWebSocketClass {
+    // console.log(1111);
+    // 为了防止user获取不到,从外面调用ras/user/info接口传入userCode,不要从cookie读,否则可能第一次出现读取不到的状况
+    constructor(
+        userCode = localStorage.getItem("userId"),
+        token = localStorage.getItem("token"),
+        options,
+        socketCode = getRandomString()
+    ) {
+        this.websocket = null; // 初始化websocket
+        this.socketCode = socketCode;
+        this.defaults = {
+            // 默认配置,可以通过option覆盖
+            protocol: defaultConfig.protocol, // 协议
+            letLoginIp: defaultConfig.loginIp, // 环境配置
+            letPort: defaultConfig.port, // 端口配置
+            letUserCode: userCode, // 用户code
+            letUserName: "system", // 环境登陆账号
+            wsUri: "ws://localhost:1234",
+            token: token, // token
+            getVersion: null, // option里面的获取版本信息的回调函数通知
+            loginSuccess: null, // 登陆成功会调通知
+            errorInfo: null, // 异常回调通知
+            onCreateVideoSuccess: false, // 客户端被拉起通知
+            oncheckSocket: null,
+            onCreateGroupChatSuccess: null, // 群聊创建成功通知
+            onSocketBackInfos: null // 客户端返回信息
+        };
+        this.settings = Object.assign({}, this.defaults, options); // 覆盖默认配置操作
+        this.websocketOnerror = false;
+        this.ClientLocalVersion = 0; // 获取本地版本号
+        this.timeId = null;
+    }
+    getSettings() {
+        return this.settings;
+    }
+    webSocketSend(data) {
+        // console.log(data);
+        // console.log(this.websocket);
+        if (this.websocket == null) {
+            return;
+        }
+        if (this.websocket.readyState === 1) {
+            console.log(this.websocket.readyState)
+            this.websocket.send(data);
+        } else {
+            setTimeout(() => {
+                this.webSocketSend(data);
+            }, 1000);
+        }
+    }
+
+    initWebSocket() {
+        console.log(1111);
+        // 初始化WebSocket
+        return new Promise((resolve, reject) => {
+            try {
+                if (typeof WebSocket === "function") {
+                    this.WebSocket = WebSocket;
+                }
+                if (this.websocket && this.websocket.readyState === 1) {
+                    this.websocket.close();
+                }
+                const settings = this.settings;
+                window.initWebSocket = this.websocket = new WebSocket(
+                    settings.wsUri
+                );
+                this.websocket.onopen = () => {
+                    this.login();
+                };
+                this.websocket.onclose = () => {
+                    // DISCONNECTED
+                };
+                this.websocket.onmessage = evt => {
+                    console.log(evt);
+                    if (evt && evt.data) {
+                        if (evt.data === "client is runing!") {
+                            // 用隐藏方法,只断连接去拉视频后的返回
+                            this.startNotice();
+                            this.settings.loginSuccess &&
+                                this.settings.loginSuccess("success");
+                            resolve("success");
+                            return;
+                        }
+                        const data = JSON.parse(evt.data);
+                        console.log(data);
+                        if (
+                            data &&
+                            data.params &&
+                            data.params.loginResult === 0
+                        ) {
+                            this.startNotice(); // 去获取本地版本号
+                            this.settings.loginSuccess &&
+                                this.settings.loginSuccess("success");
+                            resolve("success");
+                        } else if (
+                            data &&
+                            data.method === "notifyClientLocalVersion"
+                        ) {
+                            this.ClientLocalVersion = Number(
+                                JSON.parse(evt.data).params.clientVersion
+                            );
+                            this.settings.getVersion &&
+                                this.settings.getVersion(
+                                    Number(
+                                        JSON.parse(evt.data).params
+                                            .clientVersion
+                                    )
+                                );
+                        } else if (
+                            data &&
+                            data.method === "createVideoDialogReuslt"
+                        ) {
+                            // 客户端被拉起通知
+                            const createVideoReuslt = Number(
+                                JSON.parse(evt.data).params.result
+                            );
+                            const flag = createVideoReuslt === 0;
+                            this.settings.onCreateVideoSuccess &&
+                                this.settings.onCreateVideoSuccess(flag);
+                        } else if (data && data.method === "runinfo") {
+                            // 运行异常状态通知
+                            this.settings.errorInfo &&
+                                this.settings.errorInfo(data.params.info);
+                        } else {
+                            //
+                        }
+                        // 重点:统一分发客户端ws消息
+                        this.settings.onSocketBackInfos &&
+                            this.settings.onSocketBackInfos(data);
+                    }
+                };
+                this.websocket.onerror = () => {
+                    this.websocketOnerror = true;
+                    reject("error");
+                };
+            } catch (exception) {
+                // this.debug('ERROR: ' + exception);
+            }
+        });
+    }
+    login() {
+        this.checkSocket();
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "login",
+            params: {
+                loginPort: 6699,
+                protocol: this.settings.protocol,
+                token: this.settings.token,
+                userName: this.settings.letUserName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode,
+            webTitle: document.title // 视频存在的tab业标题不能重复
+        };
+        console.log(params);
+        this.webSocketSend(JSON.stringify(params));
+        this.timer();
+    }
+    UpdateWebTitle() {
+        //切换路由的的时候需要调用此方法更新页面标题。路由标题名不能重复。
+        // this.checkSocket();
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "UpdateWebTitle",
+            params: {
+                webTitle: document.title
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+    }
+    // 客户端心跳
+    timer() {
+        this.timeId = setInterval(() => {
+            const params = {
+                loginIp: this.settings.letLoginIp,
+                method: "heartbeat",
+                userCode: this.settings.letUserCode,
+                socketCode: this.socketCode
+            };
+            if (this.websocket) {
+                this.webSocketSend(JSON.stringify(params));
+            }
+        }, 10000);
+    }
+    // 停止socket连接
+    stopWebSocket() {
+        if (this.websocket) {
+            this.websocket.close();
+        }
+        this.websocket = null;
+        this.timeId && clearInterval(this.timeId);
+    }
+    //检查socket状态,通过oncheckSocket回调参数,可以判断本地有木有安装客户端
+    checkSocket() {
+        if (this.websocket != null) {
+            let stateStr;
+            // console.log(this.websocket.readyState);
+            switch (this.websocket.readyState) {
+                case 0: {
+                    stateStr = "CONNECTING";
+                    break;
+                }
+                case 1: {
+                    stateStr = "OPEN";
+                    break;
+                }
+                case 2: {
+                    stateStr = "CLOSING";
+                    break;
+                }
+                case 3: {
+                    stateStr = "CLOSED";
+                    break;
+                }
+                default: {
+                    stateStr = "UNKNOW";
+                    break;
+                }
+            }
+            this.settings.oncheckSocket &&
+                this.settings.oncheckSocket(stateStr === "OPEN");
+        } else {
+            //
+        }
+    }
+    //获取本地客户端版本号
+    startNotice() {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "getClientVersion",
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 升级客户端方法
+    setClientDownInfo() {
+        const origin = location.origin;
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "setClientDownInfo",
+            params: {
+                newClientVersion: this.ClientLocalVersion, // 获取的本地版本号
+                clientDownUrl: `${origin}/data/VSL/DSSEnterpriseClient/DSS_LightWeight_Client.zip` // 客户端在服务器上的地址,本地调试放开下面你的getCookie("ip")
+                // "clientDownUrl": `http://${getCookie("ip")}:8314/TheNextWebApp/resources/DSS_LightWeight_Client.zip` // 客户端在服务器上的地址文件
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    closeClient() {
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "logout",
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+        this.stopWebSocket();
+        this.websocket = null;
+    }
+    // 通用方法第三方传方法名和参数体
+    commonUse(method, paramsObj) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: method,
+            userCode: this.settings.letUserCode,
+            params: paramsObj,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 创建群聊界面
+    openCreateGroupChatDlg() {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "openCreateGroupChatDlg",
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 创建群聊会商-邀请一个用户进去会商
+    createGroupChat(obj) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "createGroupChat",
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode,
+            params: {
+                chatName: obj.chatName,
+                bOpenDirect: obj.bOpenDirect, // 是否打开音视频通话标志,true 创建成功后打开音视频通话,false 创建成功后不打开音视频通话
+                memberInfo: [
+                    // 成员信息
+                    {
+                        memberId: obj.memberId, // 成员id
+                        memberName: obj.memberName, // 成员名称
+                        regionId: obj.regionId, // 成员的pass域id
+                        memberType: obj.memberType, // 成员类型,Integer ,1 单兵;2 普通电话;3 对讲机;4 app|客户端;6 可是话机; 7 汇接话机(PSTN、手机号码等); 8 车载;9 无人机喊话云台; 10 无人机地面站对讲平台; 11 ipc; 12 NVR
+                        memberCode: obj.memberCode, // 成员设备编码
+                        memberNumber: obj.memberNumber // 成员号码
+                    }
+                ]
+            }
+        });
+        this.webSocketSend(params);
+    }
+    // 打开客户端指定模块
+    openClientModule(moduleID) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "openClientModule",
+            userCode: this.settings.letUserCode,
+            params: {
+                moduleID: moduleID // 模块ID,0 视频监控;1 录像回放;2 视频上墙;3 下载中心
+            },
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+}

+ 16 - 0
public/webClient/random.js

@@ -0,0 +1,16 @@
+/*
+ * @Author: awj
+ * @Date: 2020-03-23 18:57:52
+ * @LastEditors: awj
+ * @LastEditTime: 2020-03-23 19:03:50
+ * @Description: description
+ */
+export function getRandomString(len = 10) {
+    const chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"; /** **默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
+    const maxPos = chars.length;
+    let randomString = "";
+    for (let i = 0; i < len; i++) {
+        randomString += chars.charAt(Math.floor(Math.random() * maxPos));
+    }
+    return randomString;
+}

+ 568 - 0
public/webClient/webClient_initWnd.js

@@ -0,0 +1,568 @@
+class VideoPlay {
+    constructor(spaceId, websocket, socketCode, vModeObj = {}, options) {
+        // spaceId,socketCode不能相同,vModeObj播放模式,是否轮播
+        this.handleName = spaceId;
+        this.socketCode = socketCode;
+        this.vModeObj = vModeObj;
+        this.toolL = null; // 浏览器左侧、下方、右侧条宽度
+        this.toolH = null; // 浏览器上方的高度,放大缩小时会变化
+        this.fullToolL = null; // 最大化时浏览器左侧、下方、右侧条宽度
+        this.fullToolH = null; // 最大化时浏览器上方高度
+        this.space = document.querySelector(spaceId); // 传入的存放视频区域id或者class
+        this.spaceStartOffsetLeft = document.querySelector(spaceId).offsetLeft; // 传入的存放视频区域距离浏览器左侧的距离,iframe另计算;
+        this.spaceStartOffsetTop = document.querySelector(spaceId).offsetTop; // //传入的存放视频区域距离浏览器顶部的距离,iframe另计算;
+        this.space = document.querySelector(spaceId);
+        this.websocket = websocket; // 初始化websocket
+        this.display = true; // 防止切换页面视频闪烁
+        this.iframetoWinX = 0; // iframe距离浏览器左边的距离
+        this.iframetoWinY = 0; // iframe距离浏览器顶部的距离
+        this.width = 0; // 实时存放视频区域宽度
+        this.height = 0; // 实存放视频区域高度
+        this.posX = 0; // 实时存放视频区域距离浏览器左边的距离
+        this.posY = 0; // 实时存放视频区域距离浏览器顶部的距离
+        this.scale = false; // 是否开始伸缩网页
+        this.defaults = {
+            // 默认配置,可以通过option覆盖
+            protocol: defaultConfig.protocol, // 协议
+            letLoginIp: defaultConfig.loginIp, // 环境配置
+            letPort: defaultConfig.port, // 端口配置
+            letUserCode: localStorage.getItem("userId"), // 用户code
+            wsUri: "ws://localhost:1234",
+            token: localStorage.getItem("token"), // token
+            getVersion: null, // option里面的获取版本信息的回调函数通知
+            loginSuccess: null, // 登陆成功会调通知
+            errorInfo: null, // 异常回调通知
+            isDefaultShow: true, // 是否默认显示视频
+            onCreateVideoSuccess: false // 客户端被拉起通知
+        };
+        this.startCoinRegionPOX = 0; // 默认menu菜单距离浏览器左边的距离
+        this.startCoinRegionPOY = 0; // 默认menu菜单距离浏览器顶部的距离
+        this.zoom = 1; // 默认伸缩;实时存放网页伸缩倍数
+        this.ifmToTop = 0; // iframe距离区域的距离
+        this.menuWidth1 = 0; // 实时菜单宽度
+        this.menuHeight1 = 0; // 实时菜单高度
+        this.settings = Object.assign({}, this.defaults, options); // 覆盖默认配置操作
+        this.websocketOnerror = false;
+        this.ServerVersion = 8888888; // 模拟服务器版本号
+        this.ClientLocalVersion = 0; // 获取本地版本号
+        this._toolHeight = 0; // 顶部高度
+        this.status = true; // 记录显示隐藏
+        this.status = document.querySelector(spaceId).clientHeight !== 0;
+    }
+
+    // 初始化
+    init() {
+        this.calcTools();
+        this.initClientPanel();
+        this.winMaxMinOpt();
+        window.addEventListener("resize", () => {
+            this.resize();
+        });
+        window.onunload = () => {
+            this.closeClient();
+        };
+    }
+    // webSocket交互
+    webSocketSend(data) {
+        if (this.websocket == null) {
+            return;
+        }
+        if (this.websocket.readyState === 1) {
+            this.websocket.send(data);
+        } else {
+            setTimeout(() => {
+                this.webSocketSend(data);
+            }, 1000);
+        }
+    }
+    // 检测浏览器的缩放状态实现代码
+    detectZoom() {
+        var ratio = 0;
+        var screen = window.screen;
+        var 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;
+    }
+    // 实时传递给客户端的位置大小
+    dragResize(width, height, posX, posY) {
+        // 实时存储目前视频的大小位置;
+        this.width = width;
+        this.height = height;
+        this.posX = posX;
+        this.posY = posY;
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "adjustSizePosition",
+            params: {
+                width: width,
+                height: height,
+                posX: this.posX,
+                posY: this.posY,
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+    }
+    // 设置菜单遮挡问题
+    setCoinRegion(flag, dorpDownIdArr) {
+        const isEmbed = flag;
+        let menu;
+        let menuLeftX = 0;
+        let menuLeftY = 0;
+        const arr = [];
+        this.zoom = this.detectZoom() / 100; // 910add
+        if (flag === true) {
+            // const obj = {};
+            dorpDownIdArr.map((item, index) => {
+                arr.push({});
+                // obj[index] = document.querySelector(v);
+                menu = document.querySelector(item);
+                // 菜单宽高
+                arr[index]["width"] = Math.round(menu.clientWidth * this.zoom);
+                arr[index]["height"] = Math.round(
+                    menu.clientHeight * this.zoom
+                );
+                // 菜单左上角相对浏览器左上角的坐标
+                // 菜单左上角相对浏览器左上角的坐标
+                menuLeftX = Math.round(
+                    menu.getBoundingClientRect().left * this.zoom - 2
+                );
+                menuLeftY = Math.round(
+                    menu.getBoundingClientRect().top * this.zoom +
+                        this._toolHeight
+                );
+                arr[index]["posX"] = Math.round(
+                    menuLeftX + this.iframetoWinX * this.zoom
+                );
+                arr[index]["posY"] = Math.round(
+                    menuLeftY + this.iframetoWinY * this.zoom
+                );
+            });
+            /* Array.from(arguments).splice(1, Array.from(arguments).length - 1).forEach((v, index) => {
+				arr.push({});
+				obj[index] = document.querySelector(v);
+				menu = document.querySelector(dorpDownId);
+				// 菜单宽高
+				arr[index]["width"] = Math.round(obj[index].clientWidth * _this.zoom);
+				arr[index]["height"] = Math.round(obj[index].clientHeight * _this.zoom);
+				// 菜单左上角相对浏览器左上角的坐标
+				menuLeftX = Math.round(obj[index].getBoundingClientRect().left* _this.zoom - 2);
+				menuLeftY = Math.round(obj[index].getBoundingClientRect().top* _this.zoom + _this._toolHeight);
+				arr[index]["posX"] = Math.round(menuLeftX + _this.iframetoWinX * _this.zoom);
+				if (_this.zoom == 1) { //正常比例
+					arr[index]["posY"] = Math.round(menuLeftY + _this.iframetoWinY * _this.zoom);
+				} else { //缩放比例
+					if (menu) {
+						arr[index]["posY"] = Math.round(obj[index].getBoundingClientRect().top * _this.zoom + _this.ifmToTop * _this.zoom +_this._toolHeight);
+						//console.log(_this.startCoinRegionPOY,menu.getBoundingClientRect().top*_this.zoom,_this.ifmToTop,Math.round(window.parent.outerHeight - (window.parent.innerHeight)*_this.zoom),_this.zoom);
+					}
+				}
+			}) */
+        }
+        // console.log(arr);
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "setCoinRegion",
+            params: {
+                bCoincide: isEmbed,
+                region: arr,
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+    }
+    // 计算顶部距离,网页伸缩不变,这个针对不同分辨率的电脑,如果不准,第三方自己修改,只提供如下几种适配电脑。
+    calcTools() {
+        // const toolh = Math.round(window.outerHeight - (window.innerHeight) * this.detectZoom() / 100);
+        // this._toolHeight = toolh < 0 ? 80 : toolh;
+        // this.zoom = this.detectZoom() / 100;
+        this.zoom = this.detectZoom() / 100;
+        if (this.zoom === 0.67) {
+            // 现场笔记本
+            this._toolHeight = 80;
+        } else if (this.zoom === 1.5) {
+            this._toolHeight = 110;
+        } else if (this.zoom === 3) {
+            this._toolHeight = 232;
+        } else {
+            const toolh = Math.round(
+                window.outerHeight -
+                    (window.innerHeight * this.detectZoom()) / 100
+            );
+            this._toolHeight = toolh < 0 ? 90 : toolh;
+        }
+    }
+    // 网页变操作化大小
+    resize() {
+        if (!this.status || !this.vModeObj.embedVideoMode) {
+            return false;
+        }
+        const calcDomWidth =
+            this.space.clientWidth || this.space.getBoundingClientRect().width;
+        const calcDomheight =
+            this.space.clientHeight ||
+            this.space.getBoundingClientRect().height;
+        const zoom = this.detectZoom() / 100;
+        const realClientWidth = Math.round(calcDomWidth * zoom);
+        const realClientHeight = Math.round(calcDomheight * zoom);
+        console.log("zoom---_toolHeight---", zoom, this._toolHeight);
+        // 防止初始化后设置隐藏hide后拖动浏览器再show显示在左上方问题
+        if (this.space.clientWidth === 0 && this.space.clientHeight === 0) {
+            return;
+        }
+        if (zoom === 1) {
+            // 默认伸缩状态
+            // posX:距离浏览器左顶点横轴距离;posY:距离浏览器左顶点纵轴距离
+            let posX = this.space.getBoundingClientRect().left;
+            let posY;
+            if (window.outerWidth === window.innerWidth) {
+                // 普通浏览器最大化状态
+                if (this.fullToolH == null) {
+                    // 为空时才计算,避免上下拖动改变浏览器大小事,视频窗口抖动
+                    this.fullToolL =
+                        (window.outerWidth - window.innerWidth) / 2;
+                    // _this.fullToolH = window.outerHeight - window.innerHeight - _this.fullToolL + 10;
+                    this.fullToolH = this._toolHeight;
+                }
+                posY = this.space.getBoundingClientRect().top + this.fullToolH;
+            } else if (window.outerWidth - window.innerWidth < 0) {
+                // F11全屏窗口计算
+                posX = this.space.getBoundingClientRect().left;
+                posY = this.space.getBoundingClientRect().top;
+            } else {
+                // 浏览器非最大化状态
+                if (this.toolH == null) {
+                    this.toolL = (window.outerWidth - window.innerWidth) / 2;
+                    this.toolH =
+                        window.outerHeight - window.innerHeight - this.toolL;
+                }
+                posX = this.space.getBoundingClientRect().left;
+                posY = this.space.getBoundingClientRect().top + this.toolH + 0;
+            }
+            posX = Math.round(posX);
+            posY = Math.round(posY);
+            this.dragResize(realClientWidth, realClientHeight, posX, posY);
+            console.log(
+                "dragResize1-->",
+                realClientWidth,
+                realClientHeight,
+                posX,
+                posY
+            );
+        } else {
+            if (
+                window.outerHeight - window.innerHeight === 288 ||
+                window.outerWidth - window.innerWidth < 0
+            ) {
+                // 最大化
+                const longW = Math.round(
+                    this.space.getBoundingClientRect().left * zoom
+                );
+                const longH = Math.round(
+                    this.space.getBoundingClientRect().top * zoom
+                );
+                this.dragResize(
+                    realClientWidth,
+                    realClientHeight,
+                    longW,
+                    longH
+                );
+                console.log(
+                    "最大化dragResize2-->",
+                    realClientWidth,
+                    realClientHeight,
+                    longW,
+                    longH
+                );
+            } else {
+                const longW = Math.round(
+                    this.space.getBoundingClientRect().left * zoom
+                );
+                const longH = Math.round(
+                    this.space.getBoundingClientRect().top * zoom +
+                        this._toolHeight
+                );
+                this.dragResize(
+                    realClientWidth,
+                    realClientHeight,
+                    longW,
+                    longH
+                );
+                console.log(
+                    "dragResize2-->",
+                    realClientWidth,
+                    realClientHeight,
+                    longW,
+                    longH
+                );
+            }
+        }
+    }
+    // 创建视频窗口
+    createVideoDialog(obj) {
+        const {
+            rows = 2,
+            cols = 2,
+            wndSpaceing = 0,
+            embedVideoMode = true,
+            playerCtrlBarEnable = false,
+            displayMode = 0,
+            playMode = 0,
+            playParams = {},
+            webControlExpend = false
+        } = obj;
+        let playParamsObj = null;
+        playMode === 0 ? (playParamsObj = {}) : (playParamsObj = playParams);
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode,
+            method: "CreateVideoDialog",
+            params: {
+                handleName: this.handleName,
+                rows: rows,
+                cols: cols,
+                wndSpaceing: wndSpaceing, // 视频播放窗口间隔,默认为0
+                embedVideoMode: embedVideoMode, // 视频窗口是否为嵌入式。true:嵌入式(列表框云台和标题栏不展示),false:弹出式(展示列表框云台和标题栏)
+                playerCtrlBarEnable: playerCtrlBarEnable, // 视频窗口上的鼠标云台是否使能。true:展示,false:不展示
+                displayMode: displayMode, // 窗口显示模式,用于播放控制栏0:视频监控,显示播放控制栏;  1:轮播,隐藏播放控制栏
+                playMode: playMode, // playMode:播放模式,0: 普通模式,1:轮播模式,默认为普通播放模式
+                playParams: playParamsObj, // playMode=0,playParams为空;playMode=1,playParams格式如下:// 轮播时间间隔,单位秒,默认为5s
+                webControlExpend: webControlExpend
+            }
+        });
+        this.webSocketSend(params);
+    }
+    //初始化窗口
+    initClientPanel() {
+        this.createVideoDialog(this.vModeObj);
+    }
+    // 实时预览视频
+    realTimeVideo(
+        arr = [
+            {
+                channelId: ""
+            }
+        ]
+    ) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "openVideo",
+            params: {
+                array: arr, // [{"channelId": channelId}]
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+        this.winMaxMinOpt();
+    }
+    // 录像回放 //paramsArr传开始时间,结束时间,通道号
+    playBack(paramsArr) {
+        this.resize();
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "openRecord",
+            params: {
+                array: paramsArr, // [{"beginTime": "2019-12-27 00:00:00","channelId": "mA2I9l1kA1BOPTAPHT74P8","endTime": "2019-12-27 23:59:59"}]
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+        this.winMaxMinOpt();
+        setTimeout(() => {
+            this.resize();
+        }, 1000);
+    }
+    // 关闭客户端
+    closeClient() {
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "logout",
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+
+        this.stopWebSocket();
+        this.websocket = null;
+    }
+    // debug(message) { // 客户端调试返回信息操作
+    //     debugTextArea.value += message + "\n\n";
+    //     debugTextArea.scrollTop = debugTextArea.scrollHeight;
+    // }
+    sendMessage() {
+        const msg = document.getElementById("inputText").value;
+        const strToSend = msg;
+        if (this.websocket != null) {
+            document.getElementById("inputText").value = "";
+            this.webSocketSend(strToSend);
+        }
+    }
+    stopWebSocket() {
+        if (this.websocket) {
+            this.websocket.close();
+        }
+        this.websocket = null;
+    }
+    // 客户端显示隐藏操作;
+    showBrower(flag) {
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "whetherShowVideoWnd",
+            params: {
+                bShow: flag,
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.display = flag;
+        this.status = flag;
+        this.resize(); // 隐藏时候不走resize,显示时候感知下位置,但是,这不能加延时,否则切换标签页有问题。
+        this.webSocketSend(JSON.stringify(params));
+    }
+    // 客户端-释放窗口
+    destroyVideoDialog() {
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "DestroyVideoDialog",
+            params: {
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+    }
+    // 视频置顶操作
+    setVideoWndOnTop(flag) {
+        const params = {
+            loginIp: this.settings.letLoginIp,
+            method: "setVideoWndOnTop",
+            params: {
+                bOnTop: flag,
+                handleName: this.handleName
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        };
+        this.webSocketSend(JSON.stringify(params));
+    }
+    // 最大化最小化操作;
+    winMaxMinOpt() {
+        if (document.addEventListener) {
+            document.addEventListener("webkitvisibilitychange", () => {
+                if (document.webkitVisibilityState === "hidden") {
+                    // 最小化
+                    const temp = this.status;
+                    this.showBrower(false);
+                    this.status = temp;
+                    console.log("hidden");
+                } else if (document.webkitVisibilityState === "visible") {
+                    // 最大化
+                    // 延时的目的:最大化的瞬间 走resize中的window.outerWidth - window.innerWidth < 0这个条件,缺少浏览器顶部栏的高度,导致高度上移
+                    console.log("visible");
+                    setTimeout(() => {
+                        this.showBrower(this.status);
+                    }, 200);
+                }
+            });
+        }
+    }
+    // 关闭所有视频
+    closeAllVideo() {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "closeVideo",
+            userCode: this.settings.letUserCode,
+            params: {
+                handleName: this.handleName
+            },
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 拉app视频
+    openAppVideo(paramsArr) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "openAppVideo",
+            params: {
+                handleName: this.handleName,
+                array: paramsArr
+            },
+            userCode: this.settings.letUserCode,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 设置窗口分割数
+    setDesignDivision(rows, cols) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "SetDesignDivision",
+            userCode: this.settings.letUserCode,
+            params: {
+                handleName: this.handleName,
+                rows: Number(rows),
+                cols: Number(cols)
+            },
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 设置视频双击后位置大小
+    setDesignDivision(obj) {
+        const { width = "0", height = "0", posX = "0", posY = "0" } = obj;
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: "expendVideoCtrl",
+            userCode: this.settings.letUserCode,
+            params: {
+                handleName: this.handleName,
+                expend: true,
+                width: width,
+                height: height,
+                posX: posX,
+                posY: posY
+            },
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+    // 通用方法第三方传方法名和参数体
+    commonUse(method, paramsObj) {
+        const params = JSON.stringify({
+            loginIp: this.settings.letLoginIp,
+            method: method,
+            userCode: this.settings.letUserCode,
+            params: paramsObj,
+            socketCode: this.socketCode
+        });
+        this.webSocketSend(params);
+    }
+}

+ 81 - 3
src/components/MarkerMap/index.tsx

@@ -72,6 +72,7 @@ interface State {
   markers: MarkerType[];
   positions: string[];
   hasTypes: string[];
+  // theSocket: null;
 }
 
 interface ActionType {
@@ -84,6 +85,10 @@ interface ActionType {
 // 路况信息刷新间隔
 const REFRESH_TRAFFIC_TIME = 60000;
 
+let theSocket = null;
+
+let vPlayArea =null;
+
 const getIncidentImage = (status: MarkerType['status']) =>
   status?.toString() === '1'
     ? icon_map_yjsj
@@ -113,6 +118,7 @@ export default defineComponent({
       markers: [],
       positions: [],
       hasTypes: [],
+      // theSocket:null
     });
 
     const store = useMarkerStore();
@@ -120,6 +126,7 @@ export default defineComponent({
     const daHuaStore = useDaHuaStore();
     const router = useRouter();
     const route = useRoute();
+    // const theSocket = null;
 
     const adrsMapTypes = computed(() =>
       props.adrsMapTypes.map((i) => ({
@@ -196,6 +203,7 @@ export default defineComponent({
           var callback = () => {
             console.log(marker["deviceCode"])
             console.log(marker["userId"])
+            const self = this;
             daHuaStore.DAHUAUserObj(marker["userId"]).then(deviceUser=>{
                          console.log(deviceUser);
                          let memberObj = {
@@ -210,13 +218,14 @@ export default defineComponent({
                          }
                          let meetObj = JSON.parse(localStorage.getItem('meeting'));
                          let memberList = [];
-                         memberList.push(memberObj);
                          memberList.push(meetObj.member[0]);
+                         memberList.push(memberObj);
                          meetObj.member = memberList
                          console.log(meetObj);
                          daHuaStore.DAHUAMeetingMember(meetObj).then(data=>{
-                                   console.log(11111111)
-                                   daHuaStore.DAHUAMeetingUser(meetObj.meetId);
+                                  //  console.log(11111111)
+                                  //  daHuaStore.DAHUAMeetingUser(meetObj.meetId);
+                                initSocket(meetObj.user.userCode);
                          })
                          
                         //  console.log(memberObj);
@@ -279,6 +288,75 @@ export default defineComponent({
           );
       }
     };
+
+    const initSocket =(userCode) => {
+      const self = this;
+      console.log(userCode);
+      //初始websocket实例,保存在window中方便调用。一个浏览器tab页面只能初始化一次。所有的控件窗口,通过该websocket实例去生成不同的窗口实例,不同的控件窗口通过自己的窗口实例去调用初始化、关闭、隐藏等
+      window.theSocket = theSocket = new InitWebSocketClass(
+        userCode,localStorage.getItem("DAHUA_token"), {
+          //客户端登陆成功通知;
+          loginSuccess: (v)=> {
+            console.log(2222222222222222);
+            console.log("loginSuccess-->", v);
+            initWnd();
+          },
+          //客户端窗口被拉起通知
+          onCreateVideoSuccess: v => {
+            console.log("客户端onCreateVideoSuccess-----", v);
+          },
+          //重点:统一分发客户端ws消息;vue 可以统一用$bus分发.第三方消息分发自定
+          onSocketBackInfos: data => {
+            //视频窗口创建成功通知
+            if (data && data.method === "createVideoDialogReuslt" && data.params.result === 0) {
+              if (
+                data.params.handleName === "#vPlayArea") {
+                //客户端窗口创建好后,界面显示窗口;
+                self.vPlayArea.resize();
+                this.$Message.warning("视频窗口创建成功!");
+              }
+            }
+          }
+        }
+      );
+      console.log(theSocket);
+      //socket实例初始化websocket回调方法;
+      theSocket
+        .initWebSocket()
+        .then(v => {
+          if (v) {
+            this.$Message.warning("视频插件登陆完成!");
+          }
+        })
+        .catch(v => {
+          this.$Message.warning("若要观看实时视频,请先安装视频插件");
+        });
+    }
+
+    const initWnd =() => {
+      console.log(1111);
+      //左边窗口类型参数 分割 2行2列
+      const typeObj = {
+        rows: 2,
+        cols: 2,
+        wndSpaceing: 10,
+        embedVideoMode: true,
+        playerCtrlBarEnable: false,
+        displayMode: 0,
+        playMode: 0,
+        playParams: {}
+      };
+      //左边窗口实例
+      window.vPlayArea = this.vPlayArea = new VideoPlay(
+        "#vPlayArea",
+        window.theSocket.websocket,//一个浏览器tab页面公用一个
+        window.theSocket.socketCode,//一个浏览器tab页面公用一个
+        typeObj
+      );
+      //左边窗口初始化
+       vPlayArea.init();
+    }
+
     const updateTrafficSource = () => {
       if (state.map.getSource('Traffic')) {
         state.map.removeSource('Traffic');