Merge pull request !25 from 打豆豆/master
This commit is contained in:
打豆豆
2024-04-08 01:19:48 +00:00
committed by Gitee
14 changed files with 506 additions and 709 deletions

View File

@@ -44,9 +44,12 @@
"dhtmlx-gantt": "^7.1.11",
"echarts": "4.9.0",
"element-ui": "2.15.6",
"ezuikit-js": "^0.7.2",
"file-saver": "2.0.5",
"flv.js": "^1.6.2",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"jquery": "^3.7.1",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",

View File

@@ -205,8 +205,5 @@
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
<script type="text/javascript" src="./static/haikang/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="./static/haikang/jsencrypt.min.js"></script>
<script type="text/javascript" src="./static/haikang/web-control_1.2.5.min.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -37,9 +37,10 @@
{{ this.title }}
</div>
<div
style="color: rgb(9 207 255); font-size: 21px; margin-bottom: 4%"
style="color: rgb(9 207 255); font-size: 18px; margin-bottom: 4%"
>
2024.01.11 09:18:18
<span>{{ this.dateYear }}</span> {{ this.dateDay }}
<span>{{ this.dateWeek }}</span>
</div>
</el-col>
<el-col :span="10"
@@ -367,6 +368,7 @@
</template>
<script>
import dayjs from "dayjs";
// import * as statisServer from "@/api/statistics";
// import { getInfo } from "@/api/user";
import screenfull from "screenfull";
@@ -378,9 +380,31 @@ import roboticRate from "./components/roboticRate.vue";
import AGVrate from "./components/AGVrate.vue";
export default {
components: { online, offline, fault, onlineRate, roboticRate, AGVrate },
components: {
online,
offline,
fault,
onlineRate,
roboticRate,
AGVrate,
dayjs,
},
data() {
return {
dateDay: null,
dateYear: null,
dateWeek: null,
weekday: [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
],
timer: null,
screenfull: false,
title: "设备监控分析",
titleVisible: false,
@@ -414,6 +438,12 @@ export default {
},
created() {
this.timer = setInterval(() => {
const date = dayjs(new Date());
this.dateDay = date.format("HH:mm:ss");
this.dateYear = date.format("YYYY-MM-DD");
this.dateWeek = date.format(this.weekday[date.day()]);
}, 1000);
// 监听事件
window.addEventListener("resize", this.onresize);
this.getList();
@@ -426,10 +456,13 @@ export default {
this.factorNumber();
},
// beforeDestroy() {
// // 取消监听事件
// window.removeEventListener("resize", this.onresize);
// },
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer);
}
// 取消监听事件
window.removeEventListener("resize", this.onresize);
},
methods: {
// 监听是否全屏状态
onresize(event) {

View File

@@ -97,16 +97,16 @@ export default {
type: "category",
boundaryGap: true, //坐标轴两边留白
data: [
"2023-03",
"2023-04",
"2023-05",
"2023-06",
"2023-07",
"2023-08",
"2023-09",
"2023-10",
"2023-11",
"2023-12",
"2024-01",
"2024-02",
"2024-03",
"2024-04",
],
axisLabel: {
//坐标轴刻度标签的相关设置。

View File

@@ -46,19 +46,19 @@ export default {
var scale = 1;
var echartData = [
{
value: 50,
value: 5,
name: "材料不良",
},
{
value: 100,
value: 1,
name: "工序不良",
},
{
value: 300,
value: 2,
name: "尺寸不良",
},
{
value: 50,
value: 1,
name: "其他不良",
},
];

View File

@@ -1,91 +0,0 @@
import { getPubKey, setEncrypt } from './pubKey'
var initCount = 0;
var oWebControl;
/**
*
* @param {*} id :组件容器id
* @param {*} iWidth :组件容器宽
* @param {*} iHeight :组件容器高
* @param {*}cbIntegrationCallBack消息推送回调函数
* @param {*} argument:初始化api参数
* @param {*} completeCallBack初始化成功回调函数
* @param {*} plugErrorCallBack插件启动失败回调函数
*/
const initPlugin = (id, iWidth, iHeight, argument, cbIntegrationCallBack = () => { }, completeCallBack = () => { }, plugErrorCallBack = () => { }) => {
// eslint-disable-next-line no-undef
oWebControl = new WebControl({
szPluginContainer: id, // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15909,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () { // 创建WebControl实例成功
oWebControl.JS_StartService("window", { // WebControl实例创建成功后需要启动服务
dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"写死
}).then(function () { // 启动插件服务成功
oWebControl.JS_SetWindowControlCallback({ // 设置消息回调
cbIntegrationCallBack: cbIntegrationCallBack
});
oWebControl.JS_CreateWnd(id, iWidth, iHeight).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
init(argument, iWidth, iHeight,completeCallBack()); // 创建播放实例成功后初始化
});
}, function () { // 启动插件服务失败
});
},
// eslint-disable-next-line no-unused-vars
cbConnectError: function (e) { // 创建WebControl实例失败
oWebControl = null;
// eslint-disable-next-line no-undef
// $(id).html("插件未启动,正在尝试启动,请稍候...");
// eslint-disable-next-line no-undef
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数采用wakeup来启动程序
initCount++;
if (initCount < 2) {
setTimeout(function () {
initPlugin(id, iWidth, iHeight, argument, cbIntegrationCallBack,completeCallBack,plugErrorCallBack);
}, 1000)
} else {
// eslint-disable-next-line no-undef
// $(id).html("插件启动失败,请检查插件是否安装!");
plugErrorCallBack()
}
},
// eslint-disable-next-line no-unused-vars
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
console.log("cbConnectClose");
oWebControl = null;
}
});
return oWebControl
}
//初始化
function init(argument, iWidth, iHeight,callback=()=>{}) {
getPubKey(oWebControl, function () {
oWebControl.JS_RequestInterface({
funcName: "init",
argument: JSON.stringify({
...argument,
secret: setEncrypt(argument.secret)
})
// eslint-disable-next-line no-unused-vars
}).then(function (oData) {
callback()
//oWebControl.JS_Resize(iWidth, iHeight); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
})
}
export default initPlugin

View File

@@ -1,24 +0,0 @@
var pubKey;
//获取公钥
export function getPubKey(oWebControl,callback) {
// eslint-disable-next-line no-undef
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
})
}
//RSA加密
export function setEncrypt(value) {
// eslint-disable-next-line no-undef
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}

View File

@@ -1,495 +1,115 @@
<template>
<div class="hk-video-container" id="playWnd">
<!-- 下载插件提示框 -->
<el-dialog
v-if="downloadDialog"
title="提示"
:visible.sync="dialogVisible"
width="30%"
<div style="overflow-y: scroll; overflow-x: hidden; height: 100%">
<section
style="display: flex; justify-content: space-around; flex-wrap: wrap"
>
<span
>{{downloadText}}</span
class="video_warp_item"
v-for="(item, index) in liveAddress"
v-if="index < 3"
:key="index"
>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleDownloadExe">下载</el-button>
<div :id="'video-player-' + index"></div>
</span>
</el-dialog>
</section>
</div>
</template>
<script>
import initPlugin from "./lib/initPlugin";
import $ from "jquery"; // npm i jquery
import EZUIKit from "ezuikit-js";
export default {
name: "hkVideo",
props: {
width: {
type: Number,
default: 500,
},
height: {
type: Number,
default: 300,
},
//初始化参数,
// 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 //自定义工具条按钮
argument: {
type: Object,
default: () => {},
},
//模式0预览1回放
playMode: {
type: Number,
default: 0,
},
//浏览器窗口改变时候是否动态变化组件宽度,将按照初始化组件占浏览器可视区域比例缩放组件宽度
autoResize: {
type: Boolean,
default: true,
},
//未安装插件时候是否显示插件下载对话框提示用户下载功能
downloadDialog: {
type: Boolean,
default: false,
},
//海康插件下载url
downloadUrl: {
type: String,
default: "",
},
downloadText:{
type:String,
default:'插件启动失败,请检查插件是否安装,如果未安装请点击下载安装,安装后刷新页面'
}
},
name: "dashboard",
data() {
return {
curWindIndex: 1, //当前选中窗口号从1开始
oWebControl: null, //插件实例
iWidth: "", //组件宽
iHeight: "", //组件高
options: {
appkey: "admin", //API网关提供的appkey
secret: "mygymygy.", //API网关提供的secret
ip: "192.168.2.107", //API网关IP地址
playMode: 0, //播放模式(决定显示预览还是回放界面)
port: 443, //端口
snapDir: "D:\\SnapDir", //抓图存储路径
videoDir: "D:\\VideoDir", //紧急录像或录像剪辑存储路径
layout: "3x3", //布局
enableHTTPS: 1, //是否启用HTTPS协议
encryptedFields: "secret", //加密字段
showToolbar: 1,
showSmart: 1,
buttonIDs:
"0,1,16,256,257,258,259,260,512,513,514,515,516,517,768,769,770", //自定义工具条按钮
},
rate: 0, //组件宽度与窗口宽度比例
isInitComolete: false, //第一次初始化是否完成
dialogVisible: false,
accessToken: "",
liveAddress: [],
diveType: "",
players: [],
};
},
watch: {
width: {
handler(val) {
this.iWidth = val;
if (this.isInitComolete) {
this.setRate();
this.setResize(this.iWidth, this.iHeight);
}
},
immediate: true,
},
height: {
handler(val) {
this.iHeight = val;
if (this.isInitComolete) {
this.setRate();
this.setResize(this.iWidth, this.iHeight);
}
},
immediate: true,
},
playMode() {
this.reInit();
},
},
mounted() {
this.init();
this.handleWindEvent();
this.$nextTick(() => {
this.setRate();
});
},
beforeDestroy() {
if (this.oWebControl != null) {
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
this.oWebControl.JS_Disconnect().then(
function () {
// 断开与插件服务连接成功
},
function () {
// 断开与插件服务连接失败
}
);
}
created() {
this.getbagndianID();
},
methods: {
//初始化插件
init() {
let argument = {
...this.options,
...this.argument,
};
if (this.playMode > -1 && this.playMode < 2) {
argument.playMode = this.playMode;
}
// eslint-disable-next-line no-undef
this.iWidth = Math.min(this.iWidth, $(window).width());
this.oWebControl = initPlugin(
"playWnd",
this.iWidth,
this.iHeight,
argument,
this.cbIntegrationCallBack,
() => {
this.setRate();
this.setResize(this.iWidth, this.iHeight);
this.isInitComolete = true;
this.$emit("initFinish");
// 获取磅点摄像头ID列表
getbagndianID() {
const This = this;
// 获取萤石云的accessToken
$.ajax({
url: "https://open.ys7.com/api/lapp/token/get",
type: "POST",
dataType: "json",
data: {
appKey: "4aea64fb66cd46e8ae2ded25e6dbf5bf", //String appKey Y
appSecret: "9011246f97d2d65ce33ab7c23e7a72de", // String appSecret Y
},
() => {
if (this.downloadDialog) {
this.dialogVisible = true;
}
this.$emit("pluginError");
}
);
cache: false,
success: function (response) {
This.accessToken = response.data.accessToken;
$.ajax({
url: "https://open.ys7.com/api/lapp/camera/list",
header: {
"Content-Type": "application/x-www-form-urlencoded",
},
//重新初始化
reInit() {
if (this.oWebControl) {
this.oWebControl
.JS_RequestInterface({
funcName: "uninit",
})
.then(() => {
this.init();
});
}
type: "POST",
dataType: "json",
data: {
accessToken: This.accessToken, // String 授权过程获取的access_token Y
pageStart: 0,
pageSize: 10,
},
setRate() {
// eslint-disable-next-line no-undef
var iWidth = $(window).width();
this.rate = this.iWidth / iWidth;
},
//窗口事件
handleWindEvent() {
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
// eslint-disable-next-line no-undef
if (this.autoResize) {
// eslint-disable-next-line no-undef
$(window).resize(() => {
if (this.oWebControl) {
// eslint-disable-next-line no-undef
var iWidth = $(window).width();
// eslint-disable-next-line no-undef
this.iWidth = iWidth * this.rate;
this.oWebControl.JS_Resize(this.iWidth, this.iHeight);
this.setWndCover();
}
});
}
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
// eslint-disable-next-line no-undef
$(window).scroll(() => {
if (this.oWebControl) {
this.oWebControl.JS_Resize(this.iWidth, this.iHeight);
this.setWndCover();
}
});
},
//推送消息回调
cbIntegrationCallBack(oData) {
if (oData?.responseMsg?.type) {
let data = oData.responseMsg;
switch (data.type) {
//窗口号改变
case 1:
if (this.curWindIndex !== data.msg.wndId) {
this.curWindIndex = data.msg.wndId;
this.$emit("windowChange", this.curWindIndex);
}
break;
//布局改变
case 6:
this.$emit("layoutChange", data.msg);
break;
}
}
},
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
setWndCover() {
// eslint-disable-next-line no-undef
var iWidth = $(window).width();
// eslint-disable-next-line no-undef
var iHeight = $(window).height();
// eslint-disable-next-line no-undef
var oDivRect = $("#playWnd").get(0).getBoundingClientRect();
var iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0;
var iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0;
var iCoverRight =
oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0;
var iCoverBottom =
oDivRect.bottom - iHeight > 0
? Math.round(oDivRect.bottom - iHeight)
: 0;
iCoverLeft = iCoverLeft > this.iWidth ? this.iWidth : iCoverLeft;
iCoverTop = iCoverTop > this.iHeight ? this.iHeight : iCoverTop;
iCoverRight = iCoverRight > this.iWidth ? this.iWidth : iCoverRight;
iCoverBottom = iCoverBottom > this.iHeight ? this.iHeight : iCoverBottom;
this.oWebControl.JS_RepairPartWindow(
0,
0,
this.iWidth + 1,
this.iHeight + 1
); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, this.iHeight);
}
if (iCoverTop != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
0,
this.iWidth + 1,
iCoverTop + 1
); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
this.oWebControl.JS_CuttingPartWindow(
this.iWidth - iCoverRight,
0,
iCoverRight,
this.iHeight
);
}
if (iCoverBottom != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
this.iHeight - iCoverBottom,
this.iWidth,
iCoverBottom
);
}
},
/** 预览
* @param {*} cameraIndexCode :获取输入的监控点编号值,必填
* @param {*} argument:api参数,
* argument属性cameraIndexCode优先级高于函数参数cameraIndexCode
*/
startPreview(cameraIndexCode, argument = {}) {
if (this.oWebControl) {
let params = {
cameraIndexCode: cameraIndexCode, //监控点编号
streamMode: 0, //主子码流标识
transMode: 1, //传输协议
gpuMode: 1, //是否开启GPU硬解
wndId: -1,
};
this.oWebControl
.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
...params,
...argument,
}),
})
.then(() => {});
}
},
//停止所有预览
stopAllPreview() {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPreview",
});
},
//批量(指定窗口)停止播放
/**
* idArr:播放窗口序号数组
*/
stopListPreview(idArr) {
let list = idArr.map((item) => {
return {
wndId: item,
};
});
this.oWebControl.JS_RequestInterface({
funcName: "stopMultiPlay",
argument: {
list,
},
});
},
/** 根据监控点编号录像回放
* @param {*} cameraIndexCode :获取输入的监控点编号值,必填
* @param {*} startTime:开始时间
* @param {*} endTime:结束时间
* @param {*} recordLocation://录像存储位置0-中心存储1-设备存储
* @param {*} argument:api参数
* argument属性cameraIndexCode优先级高于函数参数cameraIndexCode
*/
startPlayBack(
cameraIndexCode,
startTime,
endTime,
recordLocation = 0,
argument = {}
) {
var startTimeStamp = new Date(
startTime.replace("-", "/").replace("-", "/")
).getTime(); //回放开始时间戳,必填
var endTimeStamp = new Date(
endTime.replace("-", "/").replace("-", "/")
).getTime(); //回放结束时间戳,必填
// var recordLocation = 0; //录像存储位置0-中心存储1-设备存储
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = -1; //播放窗口序号在2x2以上布局下可指定播放窗口
this.oWebControl.JS_RequestInterface({
funcName: "startPlayback",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //监控点编号
startTimeStamp: Math.floor(startTimeStamp / 1000).toString(), //录像查询开始时间戳,单位:秒
endTimeStamp: Math.floor(endTimeStamp / 1000).toString(), //录像结束开始时间戳,单位:秒
recordLocation: recordLocation, //录像存储类型0-中心存储1-设备存储
transMode: transMode, //传输协议0-UDP1-TCP
gpuMode: gpuMode, //是否启用GPU硬解0-不启用1-启用
wndId: wndId, //可指定播放窗口
...argument,
}),
});
},
//停止所有回放
stopAllPlayBack() {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPlayback",
});
},
//设置布局
//latyou布局2x2
setLayout(layout) {
this.oWebControl.JS_RequestInterface({
funcName: " setLayout",
argument: {
layout,
},
});
},
/** 画面字符叠加
* @param {*} text :文字
* @param {*} x:相对播放窗口左上角的横坐标起点
* @param {*} y:相对播放窗口左上角的纵坐标起点
* @param {*} fontSize:字体大小
* @param {*} color:字体颜色,默认白色
* @param {*} argument:api参数
* argument属性cameraIndexCode优先级高于函数参数cameraIndexCode
*/
drawText(
text,
x = 5,
y = 5,
fontSize = 20,
color = 16777215,
argument = {}
) {
this.oWebControl.JS_RequestInterface({
funcName: "drawOSD",
argument: {
text,
x,
y,
fontSize,
color,
...argument,
},
});
},
//进入全屏
setFullScreen() {
this.oWebControl.JS_RequestInterface({
funcName: "setFullScreen",
});
},
//退出全屏
exitFullScreen() {
this.oWebControl.JS_RequestInterface({
funcName: "exitFullScreen",
});
},
//播放抓图
snapShot(argument = {}) {
this.oWebControl.JS_RequestInterface({
funcName: "snapShot",
argument,
});
},
//隐藏窗口
hideWindow() {
this.oWebControl.JS_HideWnd();
},
//显示窗口
showWindow() {
this.oWebControl.JS_ShowWnd();
},
//设置窗口尺寸
setResize(width, height) {
this.oWebControl.JS_Resize(width, height);
this.setWndCover();
},
//下载安装包
handleDownloadExe() {
this.dialogVisible = false;
if (this.downloadUrl) {
this.downloadFile(this.downloadUrl);
cache: false,
success: function (response) {
var arr = [];
response.data.forEach((item, index) => {
if (item.channelNo == 3 || item.channelNo == 4) {
} else {
console.log("下载地址为空");
arr.push(item);
}
this.$emit("clickDownload");
});
console.log(arr);
arr.forEach((item, index) => {
$.ajax({
url: "https://open.ys7.com/api/lapp/v2/live/address/get",
type: "POST",
dataType: "json",
data: {
accessToken: This.accessToken, // String 授权过程获取的access_token Y
deviceSerial: item.deviceSerial,
channelNo: item.channelNo,
},
//下载文件
downloadFile(url, fileName = "") {
const a = document.createElement("a");
a.style.display = "none";
if (fileName) {
a.setAttribute("download", fileName);
cache: false,
success: (response) => {
let player = new EZUIKit.EZUIKitPlayer({
id: "video-player-" + index, // 视频容器ID
accessToken: This.accessToken,
url: response.data.url,
template: "voice", // simple - 极简版;standard-标准版;security - 安防版(预览回放);voice-语音版; theme-可配置主题;
audio: 0, // 是否默认开启声音 0 - 关闭 1 - 开启
autoplay: false,
width: 190,
height: 150,
});
This.liveAddress.push(player);
console.log(This.liveAddress);
},
});
});
},
});
},
});
},
},
//销毁视频
destroyed() {
for (var j = 0; j < this.players.length; j++) {
this.liveAddress[j].stop();
}
a.setAttribute("href", url);
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(a.href);
document.body.removeChild(a);
},
},
};
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,306 @@
var WebRtcStreamer = (function() {
/**
* Interface with WebRTC-streamer API
* @constructor
* @param {string} videoElement - id of the video element tag
* @param {string} srvurl - url of webrtc-streamer (default is current location)
*/
var WebRtcStreamer = function WebRtcStreamer (videoElement, srvurl) {
if (typeof videoElement === "string") {
this.videoElement = document.getElementById(videoElement);
} else {
this.videoElement = videoElement;
}
this.srvurl = srvurl || location.protocol+"//"+window.location.hostname+":"+window.location.port;
this.pc = null;
this.mediaConstraints = { offerToReceiveAudio: true, offerToReceiveVideo: true };
this.iceServers = null;
this.earlyCandidates = [];
}
WebRtcStreamer.prototype._handleHttpErrors = function (response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
/**
* Connect a WebRTC Stream to videoElement
* @param {string} videourl - id of WebRTC video stream
* @param {string} audiourl - id of WebRTC audio stream
* @param {string} options - options of WebRTC call
* @param {string} stream - local stream to send
*/
WebRtcStreamer.prototype.connect = function(videourl, audiourl, options, localstream) {
this.disconnect();
// getIceServers is not already received
if (!this.iceServers) {
console.log("Get IceServers");
fetch(this.srvurl + "/api/getIceServers")
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.then( (response) => this.onReceiveGetIceServers(response, videourl, audiourl, options, localstream))
.catch( (error) => this.onError("getIceServers " + error ))
} else {
this.onReceiveGetIceServers(this.iceServers, videourl, audiourl, options, localstream);
}
}
/**
* Disconnect a WebRTC Stream and clear videoElement source
*/
WebRtcStreamer.prototype.disconnect = function() {
if (this.videoElement?.srcObject) {
this.videoElement.srcObject.getTracks().forEach(track => {
track.stop()
this.videoElement.srcObject.removeTrack(track);
});
}
if (this.pc) {
fetch(this.srvurl + "/api/hangup?peerid=" + this.pc.peerid)
.then(this._handleHttpErrors)
.catch( (error) => this.onError("hangup " + error ))
try {
this.pc.close();
}
catch (e) {
console.log ("Failure close peer connection:" + e);
}
this.pc = null;
}
}
/*
* GetIceServers callback
*/
WebRtcStreamer.prototype.onReceiveGetIceServers = function(iceServers, videourl, audiourl, options, stream) {
this.iceServers = iceServers;
this.pcConfig = iceServers || {"iceServers": [] };
try {
this.createPeerConnection();
var callurl = this.srvurl + "/api/call?peerid=" + this.pc.peerid + "&url=" + encodeURIComponent(videourl);
if (audiourl) {
callurl += "&audiourl="+encodeURIComponent(audiourl);
}
if (options) {
callurl += "&options="+encodeURIComponent(options);
}
if (stream) {
this.pc.addStream(stream);
}
// clear early candidates
this.earlyCandidates.length = 0;
// create Offer
this.pc.createOffer(this.mediaConstraints).then((sessionDescription) => {
console.log("Create offer:" + JSON.stringify(sessionDescription));
this.pc.setLocalDescription(sessionDescription)
.then(() => {
fetch(callurl, { method: "POST", body: JSON.stringify(sessionDescription) })
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.catch( (error) => this.onError("call " + error ))
.then( (response) => this.onReceiveCall(response) )
.catch( (error) => this.onError("call " + error ))
}, (error) => {
console.log ("setLocalDescription error:" + JSON.stringify(error));
});
}, (error) => {
alert("Create offer error:" + JSON.stringify(error));
});
} catch (e) {
this.disconnect();
alert("connect error: " + e);
}
}
WebRtcStreamer.prototype.getIceCandidate = function() {
fetch(this.srvurl + "/api/getIceCandidate?peerid=" + this.pc.peerid)
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.then( (response) => this.onReceiveCandidate(response))
.catch( (error) => this.onError("getIceCandidate " + error ))
}
/*
* create RTCPeerConnection
*/
WebRtcStreamer.prototype.createPeerConnection = function() {
console.log("createPeerConnection config: " + JSON.stringify(this.pcConfig));
this.pc = new RTCPeerConnection(this.pcConfig);
var pc = this.pc;
pc.peerid = Math.random();
pc.onicecandidate = (evt) => this.onIceCandidate(evt);
pc.onaddstream = (evt) => this.onAddStream(evt);
pc.oniceconnectionstatechange = (evt) => {
console.log("oniceconnectionstatechange state: " + pc.iceConnectionState);
if (this.videoElement) {
if (pc.iceConnectionState === "connected") {
this.videoElement.style.opacity = "1.0";
}
else if (pc.iceConnectionState === "disconnected") {
this.videoElement.style.opacity = "0.25";
}
else if ( (pc.iceConnectionState === "failed") || (pc.iceConnectionState === "closed") ) {
this.videoElement.style.opacity = "0.5";
} else if (pc.iceConnectionState === "new") {
this.getIceCandidate();
}
}
}
pc.ondatachannel = function(evt) {
console.log("remote datachannel created:"+JSON.stringify(evt));
evt.channel.onopen = function () {
console.log("remote datachannel open");
this.send("remote channel openned");
}
evt.channel.onmessage = function (event) {
console.log("remote datachannel recv:"+JSON.stringify(event.data));
}
}
pc.onicegatheringstatechange = function() {
if (pc.iceGatheringState === "complete") {
const recvs = pc.getReceivers();
recvs.forEach((recv) => {
if (recv.track && recv.track.kind === "video") {
console.log("codecs:" + JSON.stringify(recv.getParameters().codecs))
}
});
}
}
try {
var dataChannel = pc.createDataChannel("ClientDataChannel");
dataChannel.onopen = function() {
console.log("local datachannel open");
this.send("local channel openned");
}
dataChannel.onmessage = function(evt) {
console.log("local datachannel recv:"+JSON.stringify(evt.data));
}
} catch (e) {
console.log("Cannor create datachannel error: " + e);
}
console.log("Created RTCPeerConnnection with config: " + JSON.stringify(this.pcConfig) );
return pc;
}
/*
* RTCPeerConnection IceCandidate callback
*/
WebRtcStreamer.prototype.onIceCandidate = function (event) {
if (event.candidate) {
if (this.pc.currentRemoteDescription) {
this.addIceCandidate(this.pc.peerid, event.candidate);
} else {
this.earlyCandidates.push(event.candidate);
}
}
else {
console.log("End of candidates.");
}
}
WebRtcStreamer.prototype.addIceCandidate = function(peerid, candidate) {
fetch(this.srvurl + "/api/addIceCandidate?peerid="+peerid, { method: "POST", body: JSON.stringify(candidate) })
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.then( (response) => {console.log("addIceCandidate ok:" + response)})
.catch( (error) => this.onError("addIceCandidate " + error ))
}
/*
* RTCPeerConnection AddTrack callback
*/
WebRtcStreamer.prototype.onAddStream = function(event) {
console.log("Remote track added:" + JSON.stringify(event));
this.videoElement.srcObject = event.stream;
var promise = this.videoElement.play();
if (promise !== undefined) {
promise.catch((error) => {
console.warn("error:"+error);
this.videoElement.setAttribute("controls", true);
});
}
}
/*
* AJAX /call callback
*/
WebRtcStreamer.prototype.onReceiveCall = function(dataJson) {
console.log("offer: " + JSON.stringify(dataJson));
var descr = new RTCSessionDescription(dataJson);
this.pc.setRemoteDescription(descr).then(() => {
console.log ("setRemoteDescription ok");
while (this.earlyCandidates.length) {
var candidate = this.earlyCandidates.shift();
this.addIceCandidate(this.pc.peerid, candidate);
}
this.getIceCandidate()
}
, (error) => {
console.log ("setRemoteDescription error:" + JSON.stringify(error));
});
}
/*
* AJAX /getIceCandidate callback
*/
WebRtcStreamer.prototype.onReceiveCandidate = function(dataJson) {
console.log("candidate: " + JSON.stringify(dataJson));
if (dataJson) {
for (var i=0; i<dataJson.length; i++) {
var candidate = new RTCIceCandidate(dataJson[i]);
console.log("Adding ICE candidate :" + JSON.stringify(candidate) );
this.pc.addIceCandidate(candidate).then( () => { console.log ("addIceCandidate OK"); }
, (error) => { console.log ("addIceCandidate error:" + JSON.stringify(error)); } );
}
this.pc.addIceCandidate();
}
}
/*
* AJAX callback for Error
*/
WebRtcStreamer.prototype.onError = function(status) {
console.log("onError:" + status);
}
return WebRtcStreamer;
})();
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
window.WebRtcStreamer = WebRtcStreamer;
}
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = WebRtcStreamer;
}

View File

@@ -37,9 +37,10 @@
{{ this.title }}
</div>
<div
style="color: rgb(9 207 255); font-size: 21px; margin-bottom: 4%"
style="color: rgb(9 207 255); font-size: 18px; margin-bottom: 4%"
>
2024.02.27 14:11:00
<span>{{ this.dateYear }}</span> {{ this.dateDay }}
<span>{{ this.dateWeek }}</span>
</div>
</el-col>
<el-col :span="10"
@@ -105,7 +106,7 @@
class="grid-content bg-purple"
style="margin: 10% 10% 10% 37%"
>
50%
80%
</div></el-col
>
<el-col :span="4"
@@ -113,7 +114,7 @@
class="grid-content bg-purple"
style="margin: 10% 10% 10% 44%"
>
121
9
</div></el-col
>
<el-col :span="4"
@@ -146,7 +147,7 @@
<defective :message="this.defectiveData" />
</div>
<div style="width: 30%; margin-top: 50px">
<hkVideo :monitoringNumber="cameraIndexCode"></hkVideo>
<ezuikit></ezuikit>
</div>
</div>
<div style="height: 50%; display: flex">
@@ -247,6 +248,7 @@
</template>
<script>
import dayjs from "dayjs";
import axios from "axios";
import { listWorkorder } from "@/api/mes/pro/workorder";
@@ -256,24 +258,28 @@ import screenfull from "screenfull";
import defective from "./components/defective.vue";
import complete from "./components/complete.vue";
import ticket from "./components/ticket.vue";
import hkVideo from "./components/video.vue";
import ezuikit from "./components/video.vue";
export default {
components: { defective, complete, ticket, hkVideo },
components: { defective, complete, ticket, ezuikit, dayjs },
data() {
return {
cameraIndexCode: "1a033f81-a404-4a66-aabf-cb0ead6cc2be", //wed插件监控点
//海康wed插件初始化数据
objData: {
appkey: "", //综合安防管理平台提供的appkey必填
ip: "", //综合安防管理平台IP地址必填
secret: "", //综合安防管理平台提供的secret必填
port: 443, //综合安防管理平台端口若启用HTTPS协议默认443
playMode: 0, // 0 预览 1回放
layout: "2x2", //页面展示的模块数【16】
showToolbar: 1, //是否显示工具栏0-不显示非0-显示
},
dateDay: null,
dateYear: null,
dateWeek: null,
weekday: [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
],
timer: null,
rtSp1: "",
screenfull: false,
title: "生产监控分析",
titleVisible: false,
@@ -300,10 +306,18 @@ export default {
thisYear: false,
isFullscreen: false,
radio4: 1,
monitorPoints: [],
};
},
created() {
this.timer = setInterval(() => {
const date = dayjs(new Date());
this.dateDay = date.format("HH:mm:ss");
this.dateYear = date.format("YYYY-MM-DD");
this.dateWeek = date.format(this.weekday[date.day()]);
}, 1000);
// 监听事件
window.addEventListener("resize", this.onresize);
this.getList();
@@ -316,10 +330,13 @@ export default {
this.factorNumber();
},
// beforeDestroy() {
// // 取消监听事件
// window.removeEventListener("resize", this.onresize);
// },
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer);
}
// 取消监听事件
window.removeEventListener("resize", this.onresize);
},
methods: {
// 监听是否全屏状态
onresize(event) {

View File

@@ -526,6 +526,8 @@ export default {
},
// 表单参数
form: {},
arrquantityRecived: "",
arraccepted: "",
// 表单校验
rules: {
recptCode: [
@@ -685,13 +687,22 @@ export default {
//执行入库
handleExecute(row) {
console.log(row);
this.remainingquantity = 0;
this.recptIdsData = row.recptId;
this.perform.recptId = row.recptId;
this.warehousing = true;
// 物料查询
listItemrecptline({ recptId: row.recptId }).then((response) => {
this.itemrecptlineList = response.rows;
response.rows.forEach((item) => {
var arr = 0;
this.arrquantityRecived = arr + item.quantityRecived;
});
response.rows.forEach((item) => {
var arr1 = 0;
this.arraccepted = arr1 + item.accepted;
});
this.remainingquantity = this.arrquantityRecived - this.arraccepted;
});
var queryParams = {
pageNum: 1,
@@ -719,10 +730,12 @@ export default {
submitFileForm() {
if (this.remainingquantity != 0) {
axios
.get("http://192.168.2.104:8077/manage/matter/storageItem", {
params: this.perform,
})
.then((res) => {
// .get("http://192.168.2.104:8077/manage/matter/storageItem", {
.post(
"http://192.168.2.7:8077/manage/matter/storageItem",
this.perform
)
.then(function (res) {
if (res.data.code === 200) {
this.$modal.msgSuccess("入库成功");
this.warehousing = false;