代码提交

This commit is contained in:
luoshiwen 2025-01-06 14:24:58 +08:00
parent cc19658b97
commit a5e2243cad
98 changed files with 11697 additions and 3114 deletions

8
.env.development Normal file
View File

@ -0,0 +1,8 @@
# 开发环境配置
VITE_APP_ENV = 'development'
VITE_BASE_URL = 'http://192.168.17.4:8001/'
#文件管理
VITE_PREVIEW_URL = "http://192.168.17.4:8001/"

7
.env.production Normal file
View File

@ -0,0 +1,7 @@
# 开发环境配置
VITE_APP_ENV = 'production'
VITE_BASE_URL = 'http://192.168.17.4:8001'
#文件管理
VITE_PREVIEW_URL = "http://192.168.17.4:8001"

48
.gitignore vendored
View File

@ -1,24 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -1,7 +1,7 @@
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

View File

@ -1,14 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" />-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>xxx部队一张图</title>
<script src="config.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" />-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>营房数据一张图</title>
</head>
<body>
<div id="app"></div>
<script src="./src/utils/protocolcheck.js"></script>
<script type="module" src="/src/main.js"></script>
</body>
</html>

4654
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,27 @@
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@enhances/bigscreen-fit-vue3": "^0.2.6",
"element-plus": "^2.3.14",
"less": "^4.2.0",
"three": "^0.164.1",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"sass": "^1.77.6",
"sass-loader": "^14.2.1",
"vite": "^4.4.5"
}
}
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@enhances/bigscreen-fit-vue3": "^0.2.6",
"axios": "^1.7.7",
"element-plus": "^2.3.14",
"less": "^4.2.0",
"moment": "^2.30.1",
"three": "^0.164.1",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"sass": "^1.77.6",
"sass-loader": "^14.2.1",
"vite": "^4.4.5"
}
}

BIN
public/model/22.fbx Normal file

Binary file not shown.

BIN
public/model/333.fbx Normal file

Binary file not shown.

BIN
public/model/YFSJ_Model.fbx Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/modelPng/baojing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
public/modelPng/fontBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

BIN
public/modelPng/heat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
public/modelPng/menjin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
public/modelPng/shuijin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
public/modelPng/store.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
public/modelPng/yangan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,446 @@
<!doctype html>
<html>
<head>
<title>预览Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
<meta http-equiv="Expires" content="0" />
</head>
<style>
html, body {
padding: 0;
margin: 0;
}
.playWnd {
margin: 30px 0 0 50px;
width: 800px;
height: 400px;
border: 1px solid red;
}
.cbInfoDiv {
float: left;
width: 360px;
margin-left: 16px;
border:1px solid #7F9DB9;
}
.cbInfo {
height: 200px;
padding: 5px;
border: 1px solid #7F9DB9;
word-break: break-all;
overflow: scrollauto;
}
.operate {
margin-top: 24px;
}
.operate::after {
content: '';
display: block;
clear: both;
}
.operate .btns {
height: 32px;
}
.module {
float: left;
width: 120px;
min-height: 290px;
margin-left: 10px;
padding: 16px 8px;
box-sizing: border-box;
border: 1px solid #e5e5e5;
}
.module .item {
margin-bottom: 4px;
}
.module .label {
width: 150px;
display: inline-block;
vertical-align: middle;
margin-right: 8px;
text-align: right;
}
.module input[type="text"],
.module select {
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: 16px;
margin-left: 158px;
}
</style>
<body>
<div id="playWnd" class="playWnd" style="left: 109px; top: 133px;"></div>
<div id="operate" class="operate">
<!--初始化、反初始化、设置认证信息接口调用入口。
1.插件所有接口都需要在调用初始化并返回成功后才能调用
2.设置认证信息仅适用于对接多平台时的情况,具体参照开发指南
3.反初始化后,插件资源销毁-->
<div class="module" style="left:30px;height:30px;width:280px;padding:10;margin:10;">
<div class="item">
<label >初始化相关参数:</label>
<textarea id="initParam" type="text" style="width:260px;height:200px;">
{
"argument": {
"appkey": "",
"ip": "",
"port": 443,
"secret": "",
"enableHTTPS": 1,
"layout": "2x2",
"playMode": 0
},
"funcName": "init"
}
</textarea>
</div>
<div class="item">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:10px;padding:0;margin:0;" id="initBtn" class="btn">执行</button>
</div>
</div>
<!--单个点位播放、批量点位播放、批量停止播放、全部停止播放接口调用入口。
1.authUuid为对接多平台时必须的播放字段对接单平台时可不指定-->
<div class="module" style="height:30;width:280px;padding:10;margin:10;">
<div class="item">
<label >播放相关参数:</label>
<textarea id="playParam" type="text" style="width:260px;height:200px;">
{
"argument": {
"cameraIndexCode": "",
"ezvizDirect": 0,
"gpuMode": 0,
"streamMode": 0,
"transMode": 1,
"wndId": -1
},
"funcName": "startPreview"
}
</textarea>
</div>
<div class="item">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:10px;padding:0;margin:0;" id="playBtn" class="btn">执行</button>
</div>
</div>
<div class="module" style="height:50;width:300px;padding:10;margin:10;">
<legend>返回值信息</legend>
<div id="cbInfo" class="cbInfo"></div>
<button style="width:80px;height:24px;padding:30;margin:0;" id="clear">清空</button>
</div>
</div>
</body>
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script src="web-control_1.2.7.min.js"></script>
<script type="text/javascript">
// 插件对象实例初始化为null需要创建多个插件窗口时需要定义多个插件对象实例变量各个变量唯一标志对应的插件实例
var oWebControl = null;
var bIE = (!!window.ActiveXObject || 'ActiveXObject' in window);// 是否为IE浏览器
var pubKey = ''; // demo中未使用加密可根据需求参照开发指南自行使用加密功能
var initCount = 0; // 异常重启计数
var iframePos = {}; // iframe相对文档的位置
var parentTitle = ''; // 父页面标题
var iframeClientPos = null; // iframe相对视窗的位置
var iframeParentShowSize = null; // 视窗大小 width height
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){}, function() {});
}
});
//监听父页面的消息
window.addEventListener('message', function(e){
if(e && e.data){
switch (e.data.action){
case 'sendTitle': // 父页面将其标题发送过来,子页面保存该标题,以便创建插件窗口成功后将标题设置回给父页面
parentTitle = e.data.info;
break;
case 'updatePos': // 更新插件位置
var scrollValue = e.data.scrollValue; // 滚动条滚动偏移量
oWebControl.JS_SetDocOffset({
left: iframePos.left + scrollValue.left,
top: iframePos.top + scrollValue.top
}); // 更新插件窗口位置
oWebControl.JS_Resize(800, 400);
setWndCover();
break;
case 'scroll':
iframeParentShowSize = e.data.showSize; // 视窗大小
iframePos = e.data.iframeOffset; // iframe与文档的偏移量
iframeClientPos = e.data.iframeClientPos; // iframe相对视窗的位置
var scrollValue = e.data.scrollValue; // 滚动条滚动偏移量
if(oWebControl){
oWebControl.JS_SetDocOffset({
left: iframePos.left + scrollValue.left,
top: iframePos.top + scrollValue.top
}); // 更新插件窗口位置
oWebControl.JS_Resize(800, 400);
setWndCover();
}
break;
default:
break;
}
}
});
// 顶部iframe.getBoundingClientRect().top小于0并且其绝对值超过DIV.get(0).getBoundingClientRect().top部分需要剪切
// 底部:(iframe.getBoundingClientRect().bottom - iframe父窗口可视域高度为H1)为不可见部分
// ($(window).height() - DIV.get(0).getBoundingClientRect().bottom)
// 为DIV底部与其所在iframe底部之间的距离H2H1-H2的值大于0则表示DIV有部分在不可见区域
// 左边iframe.getBoundingClientRect().left小于0并且其绝对值超过DIV.get(0).getBoundingClientRect().left部分需要剪切
// 右边:(iframe宽度 - DIV.get(0).getBoundingClientRect().right表示DIV右边与其父iframe右边之间的距离为W1)
// (iframe父窗口可视域宽度-iframe.getBoundingClientRect().left表示iframe左边与iframe父窗口可视域右边之间的距离为W2)
// (iframe宽度 - W2 - W1)如果大于0则表示DIV右边超出了iframe父窗口可视域需要剪切超过的部分
function setWndCover() {
if (oWebControl){
// 准备要用到的一些数据
var iframeWndHeight = $(window).height(); // iframe窗口高度
var iframeWndWidth = $(window).width(); // iframe窗口宽度
var divLeft = $("#playWnd").get(0).getBoundingClientRect().left;
var divTop = $("#playWnd").get(0).getBoundingClientRect().top;
var divRight = $("#playWnd").get(0).getBoundingClientRect().right;
var divBottom = $("#playWnd").get(0).getBoundingClientRect().bottom;
var divWidth = $("#playWnd").width();
var divHeight = $("#playWnd").height();
oWebControl.JS_RepairPartWindow(0, 0, 801, 401); // 多1个像素点防止还原后边界缺失一个像素条
// 判断剪切矩形的上边距
if (iframeClientPos.top < 0 && Math.abs(iframeClientPos.top) > divTop){
var deltaTop = Math.abs(iframeClientPos.top) - divTop;
oWebControl.JS_CuttingPartWindow(0, 0, 801, deltaTop + 1);
//console.log({deltaTop: deltaTop});
}
// 判断剪切矩形的左边距
if (iframeClientPos.left < 0 && Math.abs(iframeClientPos.left) > divLeft){
var deltaLeft = Math.abs(iframeClientPos.left) - divLeft;
//console.log({deltaLeft: deltaLeft});
oWebControl.JS_CuttingPartWindow(0, 0, deltaLeft, 401); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
// 判断剪切矩形的右边距
var W1 = iframeWndWidth - divRight;
var W2 = iframeParentShowSize.width - iframeClientPos.left;
if (W2 < divWidth){
var deltaRight = iframeWndWidth - W2 - W1;
if (deltaRight > 0) {
oWebControl.JS_CuttingPartWindow(800 - deltaRight, 0, deltaRight + 1, 401);
}
}
// 判断剪切矩形的下边距
var H1 = iframeClientPos.bottom - iframeParentShowSize.height;
var H2 = iframeWndHeight - divBottom;
var deltaBottom = H1 - H2;
//console.log({deltaBottom: deltaBottom});
if (deltaBottom > 0) {
oWebControl.JS_CuttingPartWindow(0, 400 - deltaBottom, 801, deltaBottom + 1);
}
}
}
// 创建插件实例并启动本地服务建立websocket连接创建插件窗口
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd",
iServicePortStart: 15900,
iServicePortEnd: 15900,
szClassId:"23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () {
initCount = 0;
setCallbacks();
oWebControl.JS_StartService("window", {
dllPath: "./VideoPluginConnect.dll"
}).then(function () {
// 步骤2JS_CreateWnd时指定cbSetDocTitle回调并在回调中向父页面发送更新标题消息标题为回调出来的uuid
oWebControl.JS_CreateWnd("playWnd", 800, 400, {
bEmbed: true,
cbSetDocTitle: function (uuid) {
oWebControl._pendBg = false;
window.parent.postMessage({
action:'updateTitle',
msg:'子页面通知父页面修改title',
info:uuid
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
}).then(function () {
// 步骤3JS_CreateWnd成功后通知父页面将其标题修改回去
console.log("JS_CreateWnd success");
window.parent.postMessage({
action:'updateTitle',
msg:'子页面通知父页面更新title',
info: parentTitle
}, '\*');
// 步骤4发消息更新插件窗口位置这里不直接更新的原因是父页面默认可能就存在滚动条此时有滚动量
window.parent.postMessage({
action:'updatePos',
msg:'更新Pos'
}, '\*');
initBtnClicked();
});
}, function () {
console.log("JS_CreateWnd fail");
});
},
cbConnectError: function () {
console.log("cbConnectError");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
if (true == bNormalClose){
console.log("cbConnectClose normal");
}else{
console.log("cbConnectClose exception");
}
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
initPlugin();
// 获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData)
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data
callback()
}
})
}
// 设置窗口控制回调
function setCallbacks() {
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: cbIntegrationCallBack
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
showCBInfo(JSON.stringify(oData.responseMsg));
}
// RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
function requestInterface(value)
{
oWebControl.JS_RequestInterface(JSON.parse(value)).then(function (oData) {
console.log(oData)
showCBInfo(JSON.stringify(oData ? oData.responseMsg : ''));
});
}
// 显示接口返回的消息及插件回调信息
function showCBInfo(szInfo, type) {
if (type === 'error') {
szInfo = "<div style='color: red;'>" + dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") + " " + szInfo + "</div>";
} else {
szInfo = "<div>" + dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") + " " + szInfo + "</div>";
}
$("#cbInfo").html(szInfo + $("#cbInfo").html());
}
function initBtnClicked(){
var param = $("#initParam").val();
//删除字符串中的回车换行
param = param.replace(/(\s*)/g, "");
// 执行初始化
requestInterface(param);
}
$("#initBtn").click(function() {
initBtnClicked();
})
$("#playBtn").click(function() {
var param = $("#playParam").val();
//删除字符串中的回车换行
param = param.replace(/(\s*)/g, "");
// 执行预览
requestInterface(param);
})
// 清空
$("#clear").click(function() {
$("#cbInfo").html('');
})
// 格式化时间
function dateFormat(oDate, fmt) {
var o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小时
"m+": oDate.getMinutes(), //分
"s+": oDate.getSeconds(), //秒
"q+": Math.floor((oDate.getMonth() + 3) / 3), //季度
"S": oDate.getMilliseconds()//毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (oDate.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
</script>
</html>

View File

@ -0,0 +1,178 @@
<!doctype html>
<html>
<head>
<title>Window Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
<meta http-equiv="Expires" content="0" />
</head>
<style>
html, body {
padding: 0;
margin: 0;
}
.iframe {
margin: 100px;
border: 1px solid blue;
}
</style>
<body>
<!-- 步骤1src指定待嵌入的子页面scrolling指定no禁用滚动条 -->
<iframe id="iframe1" class="iframe" src="http://127.0.0.1/demo_embedded_for_iframe.html" scrolling="no" frameborder="0" width="900" height="750"></iframe>
</body>
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script src="web-control_1.2.7.min.js"></script>
<!-- <script src="JsonToXml.js"></script>
<script src="jsWebControl-Bridge.js"></script> -->
<script type="text/javascript">
// 步骤2嵌入子页面的页面中在iframe的onload事件中向子页面抛以下消息
var iframeWin = document.getElementById("iframe1");
{
iframeWin.onload = function(){
iframeWin.contentWindow.postMessage({
action:'sendTitle', // 告诉子页面本页面的标题action自行指定但需要与子页面中监听的action保持一致
msg: '将标题发给子页面',
info: document.title
}, '\*');
iframeWin.contentWindow.postMessage({
action:'updateInitParam', // 告诉子页面一些初始值包括浏览器视窗高度与宽度、iframe偏离文档的位置、iframe相对视窗的位置
msg: '更新子页面一些初始值',
showSize: { // 浏览器视窗高度与宽度
width: $(window).width(),
height: $(window).height()
},
iframeOffset: { // iframe偏离文档的位置
left: iframeWin.offsetLeft,
top: iframeWin.offsetTop
},
iframeClientPos: { // iframe相对视窗的位置
left: iframeWin.getBoundingClientRect().left,
right: iframeWin.getBoundingClientRect().right,
top: iframeWin.getBoundingClientRect().top,
bottom: iframeWin.getBoundingClientRect().bottom
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
}
// 步骤3监听嵌入子页面的事件
window.addEventListener('message', function(e){
console.log(e.data.msg);
if(e && e.data){
switch (e.data.action){
case 'updateTitle': // 本页面收到子页面通知更新标题通知,更新本页面标题
document.title = e.data.info;
break;
case 'updatePos':
var scrollLeftValue = document.documentElement.scrollLeft;
var scrollTopValue = document.documentElement.scrollTop;
iframeWin.contentWindow.postMessage({
action:'updatePos',
msg: '更新Pos',
scrollValue: { // 滚动条滚动的偏移量
left: -1 * scrollLeftValue,
top: -1 * scrollTopValue,
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
break;
default:
break;
}
}
});
// 步骤4兼听本页面的resize事件并将一些状态值发送给嵌入的子页面
var resizeTimer = null;
var resizeDate;
$(window).resize(function () {
resizeDate = new Date();
if (resizeTimer === null){
resizeTimer = setTimeout(checkResizeEndTimer, 100);
}
});
function checkResizeEndTimer(){
if (new Date() - resizeDate > 100){ // resize结束后再发消息避免残影问题
clearTimeout(resizeTimer);
resizeTimer = null;
postResizeEvent();
} else{
setTimeout(checkResizeEndTimer, 100);
}
}
function postResizeEvent(){
iframeWin.contentWindow.postMessage({
action: 'resize',
msg: 'resize事件',
showSize: { // 告诉嵌入的子页面视窗高度与宽度
width: $(window).width(),
height: $(window).height()
},
iframeClientPos: { // iframe相对视窗的位置
left: iframeWin.getBoundingClientRect().left,
right: iframeWin.getBoundingClientRect().right,
top: iframeWin.getBoundingClientRect().top,
bottom: iframeWin.getBoundingClientRect().bottom
},
iframeOffset: { // iframe偏离文档的位置
left: iframeWin.offsetLeft,
top: iframeWin.offsetTop
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
// 步骤5兼听本页面的scroll事件并将一些状态值发送给嵌入的子页面
// 为性能考虑,可以在定时器中处理
var scrollTimer = null;
var scrollDate;
$(window).scroll(function (event) {
postScrollEvent();
scrollDate = new Date();
if (scrollTimer === null){
scrollTimer = setTimeout(checkScrollEndTimer, 100);
}
});
function checkScrollEndTimer(){
if (new Date() - scrollDate > 100){ // resize结束后再发消息避免残影问题
clearTimeout(scrollTimer);
scrollTimer = null;
} else{
postScrollEvent();
setTimeout(checkScrollEndTimer, 100);
}
}
function postScrollEvent(){
// 计算滚动条偏移量
var scrollLeftValue = document.documentElement.scrollLeft;
var scrollTopValue = document.documentElement.scrollTop;
iframeWin.contentWindow.postMessage({
action:'scroll',
msg: 'scroll事件',
scrollValue: { // 滚动条滚动的偏移量
left: -1 * scrollLeftValue,
top: -1 * scrollTopValue,
},
iframeClientPos: { // iframe相对视窗的位置
left: iframeWin.getBoundingClientRect().left,
right: iframeWin.getBoundingClientRect().right,
top: iframeWin.getBoundingClientRect().top,
bottom: iframeWin.getBoundingClientRect().bottom
},
showSize: { // 告诉嵌入的子页面视窗高度与宽度
width: $(window).width(), // 视窗宽度
height: $(window).height() // 视窗高度
},
iframeOffset: { // iframe偏离文档的位置
left: iframeWin.offsetLeft,
top: iframeWin.offsetTop
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
</script>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<hservice>
<service name="videoplugin_demo_service" disp="videoplugin_demo_service" desc="videoplugin_demo_service"/>
<dump enable="true" isfull="true" count="-1" path=""/>
<dso file="DemoWebServer.dll"/>
<function init="WebServer_Init" uinit="WebServer_Uninit" start="WebServer_Start" stop="WebServer_Stop" error="WebServer_GetLastError" version="WebServer_GetVersion" gtest="WebServer_Gtest"/>
</hservice>

View File

@ -0,0 +1,36 @@
#缺省不输出日志到控制台
log4j.rootLogger=DEBUG, default
#log4j.rootLogger=TRACE, default
#log4j.logger用于控制日志采集级别及采集内容Threshold用于控制日志输出级别
#应用于控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p - %m%n
#应用于文件回滚
log4j.appender.default=org.apache.log4j.RollingFileAppender
log4j.appender.default.File=./log/DefaultServer.log
log4j.appender.default.MaxFileSize=10MB
log4j.appender.default.MaxBackupIndex=12
log4j.appender.default.Append=true
log4j.appender.default.Threshol= TRACE
log4j.appender.default.layout=org.apache.log4j.PatternLayout
log4j.appender.default.layout.ConversionPattern=%d [%t] %-5p %.16c - %m%n
#设置VMS
log4j.logger.Crash=TRACE, Crash
#每天产生一个日志文件
log4j.appender.Crash=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Crash.File=./log/CrashServer.log
log4j.appender.Crash.DatePattern='.'yyyy-MM-dd
log4j.appender.Crash.Append=true
log4j.appender.Crash.Threshold=TRACE
log4j.appender.Crash.layout=org.apache.log4j.PatternLayout
log4j.appender.Crash.layout.ConversionPattern=%d [%t] %-5p %.16c - %m%n
##hlog.async=false
##hlog.secret.show=false
##hlog.secret.encrypt=true

View File

@ -0,0 +1,457 @@
<!doctype html>
<html>
<head>
<title>预览Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
<meta http-equiv="Expires" content="0" />
</head>
<style>
html, body {
padding: 0;
margin: 0;
}
.playWnd {
margin: 30px 0 0 50px;
width: 800px;
height: 400px;
border: 1px solid red;
}
.cbInfoDiv {
float: left;
width: 360px;
margin-left: 16px;
border:1px solid #7F9DB9;
}
.cbInfo {
height: 200px;
padding: 5px;
border: 1px solid #7F9DB9;
word-break: break-all;
overflow: scrollauto;
}
.operate {
margin-top: 24px;
}
.operate::after {
content: '';
display: block;
clear: both;
}
.operate .btns {
height: 32px;
}
.module {
float: left;
width: 120px;
min-height: 290px;
margin-left: 10px;
padding: 16px 8px;
box-sizing: border-box;
border: 1px solid #e5e5e5;
}
.module .item {
margin-bottom: 4px;
}
.module .label {
width: 150px;
display: inline-block;
vertical-align: middle;
margin-right: 8px;
text-align: right;
}
.module input[type="text"],
.module select {
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: 16px;
margin-left: 158px;
}
</style>
<body>
<div id="playWnd" class="playWnd" style="left: 109px; top: 133px;"></div>
<div id="operate" class="operate">
<!--初始化、反初始化、设置认证信息接口调用入口。
1.插件所有接口都需要在调用初始化并返回成功后才能调用
2.设置认证信息仅适用于对接多平台时的情况,具体参照开发指南
3.反初始化后,插件资源销毁-->
<div class="module" style="left:30px;height:30px;width:280px;padding:10;margin:10;">
<div class="item">
<label >初始化相关参数:</label>
<textarea id="initParam" type="text" style="width:260px;height:200px;">
{
"argument": {
"appkey": "",
"ip": "",
"port": 443,
"secret": "",
"enableHTTPS": 1,
"layout": "2x2",
"playMode": 0
},
"funcName": "init"
}
</textarea>
</div>
<div class="item">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:10px;padding:0;margin:0;" id="initBtn" class="btn">执行</button>
</div>
</div>
<!--单个点位播放、批量点位播放、批量停止播放、全部停止播放接口调用入口。
1.authUuid为对接多平台时必须的播放字段对接单平台时可不指定-->
<div class="module" style="height:30;width:280px;padding:10;margin:10;">
<div class="item">
<label >播放相关参数:</label>
<textarea id="playParam" type="text" style="width:260px;height:200px;">
{
"argument": {
"cameraIndexCode": "",
"ezvizDirect": 0,
"gpuMode": 0,
"streamMode": 0,
"transMode": 1,
"wndId": -1
},
"funcName": "startPreview"
}
</textarea>
</div>
<div class="item">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:10px;padding:0;margin:0;" id="playBtn" class="btn">执行</button>
</div>
</div>
<div class="module" style="height:50;width:300px;padding:10;margin:10;">
<legend>返回值信息</legend>
<div id="cbInfo" class="cbInfo"></div>
<button style="width:80px;height:24px;padding:30;margin:0;" id="clear">清空</button>
</div>
</div>
</body>
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script src="web-control_1.2.5.min.js"></script>
<script type="text/javascript">
// 插件对象实例初始化为null需要创建多个插件窗口时需要定义多个插件对象实例变量各个变量唯一标志对应的插件实例
var oWebControl = null;
var bIE = (!!window.ActiveXObject || 'ActiveXObject' in window);// 是否为IE浏览器
var pubKey = ''; // demo中未使用加密可根据需求参照开发指南自行使用加密功能
var initCount = 0; // 异常重启计数
var iframePos = {}; // iframe相对文档的位置
var parentTitle = ''; // 父页面标题
var iframeClientPos = null; // iframe相对视窗的位置
var iframeParentShowSize = null; // 视窗大小 width height
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){}, function() {});
}
});
// 步骤1监听父页面的消息
window.addEventListener('message', function(e){
if(e && e.data){
switch (e.data.action){
case 'sendTitle': // 父页面将其标题发送过来,子页面保存该标题,以便创建插件窗口成功后将标题设置回给父页面
parentTitle = e.data.info;
break;
case 'updatePos': // 更新插件位置JS_CreateWnd时需要父页面计算滚动条偏移量初始偏移量叠加该偏移量作为iframe的偏移量防止插件窗口与DIV窗口初始不贴合情况
var scrollValue = e.data.scrollValue; // 滚动条滚动偏移量
oWebControl.JS_SetDocOffset({
left: iframePos.left + scrollValue.left,
top: iframePos.top + scrollValue.top
}); // 更新插件窗口位置
oWebControl.JS_Resize(800, 400);
setWndCover();
break;
case 'updateInitParam':
iframePos = e.data.iframeOffset; // iframe与文档的偏移量
iframeClientPos = e.data.iframeClientPos; // iframe相对视窗的位置
iframeParentShowSize = e.data.showSize; // 视窗大小
break;
case 'resize':
iframeParentShowSize = e.data.showSize; // 视窗大小
iframePos = e.data.iframeOffset; // iframe与文档的偏移量
iframeClientPos = e.data.iframeClientPos; // iframe相对视窗的位置
setWndCover();
break;
case 'scroll':
iframeParentShowSize = e.data.showSize; // 视窗大小
iframePos = e.data.iframeOffset; // iframe与文档的偏移量
iframeClientPos = e.data.iframeClientPos; // iframe相对视窗的位置
var scrollValue = e.data.scrollValue; // 滚动条滚动偏移量
if(oWebControl){
oWebControl.JS_SetDocOffset({
left: iframePos.left + scrollValue.left,
top: iframePos.top + scrollValue.top
}); // 更新插件窗口位置
oWebControl.JS_Resize(800, 400);
setWndCover();
}
break;
default:
break;
}
}
});
// 顶部iframe.getBoundingClientRect().top小于0并且其绝对值超过DIV.get(0).getBoundingClientRect().top部分需要剪切
// 底部:(iframe.getBoundingClientRect().bottom - iframe父窗口可视域高度为H1)为不可见部分
// ($(window).height() - DIV.get(0).getBoundingClientRect().bottom)
// 为DIV底部与其所在iframe底部之间的距离H2H1-H2的值大于0则表示DIV有部分在不可见区域
// 左边iframe.getBoundingClientRect().left小于0并且其绝对值超过DIV.get(0).getBoundingClientRect().left部分需要剪切
// 右边:(iframe宽度 - DIV.get(0).getBoundingClientRect().right表示DIV右边与其父iframe右边之间的距离为W1)
// (iframe父窗口可视域宽度-iframe.getBoundingClientRect().left表示iframe左边与iframe父窗口可视域右边之间的距离为W2)
// (iframe宽度 - W2 - W1)如果大于0则表示DIV右边超出了iframe父窗口可视域需要剪切超过的部分
function setWndCover() {
if (oWebControl){
// 准备要用到的一些数据
var iframeWndHeight = $(window).height(); // iframe窗口高度
var iframeWndWidth = $(window).width(); // iframe窗口宽度
var divLeft = $("#playWnd").get(0).getBoundingClientRect().left;
var divTop = $("#playWnd").get(0).getBoundingClientRect().top;
var divRight = $("#playWnd").get(0).getBoundingClientRect().right;
var divBottom = $("#playWnd").get(0).getBoundingClientRect().bottom;
var divWidth = $("#playWnd").width();
var divHeight = $("#playWnd").height();
oWebControl.JS_RepairPartWindow(0, 0, 801, 401); // 多1个像素点防止还原后边界缺失一个像素条
// 判断剪切矩形的上边距
if (iframeClientPos.top < 0 && Math.abs(iframeClientPos.top) > divTop){
var deltaTop = Math.abs(iframeClientPos.top) - divTop;
oWebControl.JS_CuttingPartWindow(0, 0, 801, deltaTop + 1);
//console.log({deltaTop: deltaTop});
}
// 判断剪切矩形的左边距
if (iframeClientPos.left < 0 && Math.abs(iframeClientPos.left) > divLeft){
var deltaLeft = Math.abs(iframeClientPos.left) - divLeft;
//console.log({deltaLeft: deltaLeft});
oWebControl.JS_CuttingPartWindow(0, 0, deltaLeft, 401); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
// 判断剪切矩形的右边距
var W1 = iframeWndWidth - divRight;
var W2 = iframeParentShowSize.width - iframeClientPos.left;
if (W2 < divWidth){
var deltaRight = iframeWndWidth - W2 - W1;
if (deltaRight > 0) {
oWebControl.JS_CuttingPartWindow(800 - deltaRight, 0, deltaRight + 1, 401);
}
}
// 判断剪切矩形的下边距
var H1 = iframeClientPos.bottom - iframeParentShowSize.height;
var H2 = iframeWndHeight - divBottom;
var deltaBottom = H1 - H2;
//console.log({deltaBottom: deltaBottom});
if (deltaBottom > 0) {
oWebControl.JS_CuttingPartWindow(0, 400 - deltaBottom, 801, deltaBottom + 1);
}
}
}
// 创建插件实例并启动本地服务建立websocket连接创建插件窗口
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd",
iServicePortStart: 15900,
iServicePortEnd: 15900,
szClassId:"23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () {
initCount = 0;
setCallbacks();
oWebControl.JS_StartService("window", {
dllPath: "./VideoPluginConnect.dll"
}).then(function () {
// 步骤2JS_CreateWnd时指定cbSetDocTitle回调并在回调中向父页面发送更新标题消息标题为回调出来的uuid
oWebControl.JS_CreateWnd("playWnd", 800, 400, {
bEmbed: true,
cbSetDocTitle: function (uuid) {
oWebControl._pendBg = false;
window.parent.postMessage({
action:'updateTitle',
msg:'子页面通知父页面修改title',
info:uuid
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
}).then(function () {
// 步骤3JS_CreateWnd成功后通知父页面将其标题修改回去
console.log("JS_CreateWnd success");
window.parent.postMessage({
action:'updateTitle',
msg:'子页面通知父页面更新title',
info: parentTitle
}, '\*');
// 步骤4发消息更新插件窗口位置这里不直接更新的原因是父页面默认可能就存在滚动条此时有滚动量
window.parent.postMessage({
action:'updatePos',
msg:'更新Pos'
}, '\*');
initBtnClicked();
});
}, function () {
console.log("JS_CreateWnd fail");
});
},
cbConnectError: function () {
console.log("cbConnectError");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
if (true == bNormalClose){
console.log("cbConnectClose normal");
}else{
console.log("cbConnectClose exception");
}
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
initPlugin();
// 获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData)
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data
callback()
}
})
}
// 设置窗口控制回调
function setCallbacks() {
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: cbIntegrationCallBack
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
showCBInfo(JSON.stringify(oData.responseMsg));
}
// RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
function requestInterface(value)
{
oWebControl.JS_RequestInterface(JSON.parse(value)).then(function (oData) {
console.log(oData)
showCBInfo(JSON.stringify(oData ? oData.responseMsg : ''));
});
}
// 显示接口返回的消息及插件回调信息
function showCBInfo(szInfo, type) {
if (type === 'error') {
szInfo = "<div style='color: red;'>" + dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") + " " + szInfo + "</div>";
} else {
szInfo = "<div>" + dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") + " " + szInfo + "</div>";
}
$("#cbInfo").html(szInfo + $("#cbInfo").html());
}
function initBtnClicked(){
var param = $("#initParam").val();
//删除字符串中的回车换行
param = param.replace(/(\s*)/g, "");
// 执行初始化
requestInterface(param);
}
$("#initBtn").click(function() {
initBtnClicked();
})
$("#playBtn").click(function() {
var param = $("#playParam").val();
//删除字符串中的回车换行
param = param.replace(/(\s*)/g, "");
// 执行预览
requestInterface(param);
})
// 清空
$("#clear").click(function() {
$("#cbInfo").html('');
})
// 格式化时间
function dateFormat(oDate, fmt) {
var o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小时
"m+": oDate.getMinutes(), //分
"s+": oDate.getSeconds(), //秒
"q+": Math.floor((oDate.getMonth() + 3) / 3), //季度
"S": oDate.getMilliseconds()//毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (oDate.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
</script>
</html>

View File

@ -0,0 +1,178 @@
<!doctype html>
<html>
<head>
<title>Window Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
<meta http-equiv="Expires" content="0" />
</head>
<style>
html, body {
padding: 0;
margin: 0;
}
.iframe {
margin: 100px;
border: 1px solid blue;
}
</style>
<body>
<!-- 步骤1src指定待嵌入的子页面scrolling指定no禁用滚动条 -->
<iframe id="iframe1" class="iframe" src="http://127.0.0.1:36963/demo_embedded_for_iframe.html" scrolling="no" frameborder="0" width="900" height="750"></iframe>
</body>
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script src="web-control_1.2.5.min.js"></script>
<!-- <script src="JsonToXml.js"></script>
<script src="jsWebControl-Bridge.js"></script> -->
<script type="text/javascript">
// 步骤2嵌入子页面的页面中在iframe的onload事件中向子页面抛以下消息
var iframeWin = document.getElementById("iframe1");
{
iframeWin.onload = function(){
iframeWin.contentWindow.postMessage({
action:'sendTitle', // 告诉子页面本页面的标题action自行指定但需要与子页面中监听的action保持一致
msg: '将标题发给子页面',
info: document.title
}, '\*');
iframeWin.contentWindow.postMessage({
action:'updateInitParam', // 告诉子页面一些初始值包括浏览器视窗高度与宽度、iframe偏离文档的位置、iframe相对视窗的位置
msg: '更新子页面一些初始值',
showSize: { // 浏览器视窗高度与宽度
width: $(window).width(),
height: $(window).height()
},
iframeOffset: { // iframe偏离文档的位置
left: iframeWin.offsetLeft,
top: iframeWin.offsetTop
},
iframeClientPos: { // iframe相对视窗的位置
left: iframeWin.getBoundingClientRect().left,
right: iframeWin.getBoundingClientRect().right,
top: iframeWin.getBoundingClientRect().top,
bottom: iframeWin.getBoundingClientRect().bottom
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
}
// 步骤3监听嵌入子页面的事件
window.addEventListener('message', function(e){
console.log(e.data.msg);
if(e && e.data){
switch (e.data.action){
case 'updateTitle': // 本页面收到子页面通知更新标题通知,更新本页面标题
document.title = e.data.info;
break;
case 'updatePos':
var scrollLeftValue = document.documentElement.scrollLeft;
var scrollTopValue = document.documentElement.scrollTop;
iframeWin.contentWindow.postMessage({
action:'updatePos',
msg: '更新Pos',
scrollValue: { // 滚动条滚动的偏移量
left: -1 * scrollLeftValue,
top: -1 * scrollTopValue,
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
break;
default:
break;
}
}
});
// 步骤4兼听本页面的resize事件并将一些状态值发送给嵌入的子页面
var resizeTimer = null;
var resizeDate;
$(window).resize(function () {
resizeDate = new Date();
if (resizeTimer === null){
resizeTimer = setTimeout(checkResizeEndTimer, 100);
}
});
function checkResizeEndTimer(){
if (new Date() - resizeDate > 100){ // resize结束后再发消息避免残影问题
clearTimeout(resizeTimer);
resizeTimer = null;
postResizeEvent();
} else{
setTimeout(checkResizeEndTimer, 100);
}
}
function postResizeEvent(){
iframeWin.contentWindow.postMessage({
action: 'resize',
msg: 'resize事件',
showSize: { // 告诉嵌入的子页面视窗高度与宽度
width: $(window).width(),
height: $(window).height()
},
iframeClientPos: { // iframe相对视窗的位置
left: iframeWin.getBoundingClientRect().left,
right: iframeWin.getBoundingClientRect().right,
top: iframeWin.getBoundingClientRect().top,
bottom: iframeWin.getBoundingClientRect().bottom
},
iframeOffset: { // iframe偏离文档的位置
left: iframeWin.offsetLeft,
top: iframeWin.offsetTop
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
// 步骤5兼听本页面的scroll事件并将一些状态值发送给嵌入的子页面
// 为性能考虑,可以在定时器中处理
var scrollTimer = null;
var scrollDate;
$(window).scroll(function (event) {
postScrollEvent();
scrollDate = new Date();
if (scrollTimer === null){
scrollTimer = setTimeout(checkScrollEndTimer, 100);
}
});
function checkScrollEndTimer(){
if (new Date() - scrollDate > 100){ // resize结束后再发消息避免残影问题
clearTimeout(scrollTimer);
scrollTimer = null;
} else{
postScrollEvent();
setTimeout(checkScrollEndTimer, 100);
}
}
function postScrollEvent(){
// 计算滚动条偏移量
var scrollLeftValue = document.documentElement.scrollLeft;
var scrollTopValue = document.documentElement.scrollTop;
iframeWin.contentWindow.postMessage({
action:'scroll',
msg: 'scroll事件',
scrollValue: { // 滚动条滚动的偏移量
left: -1 * scrollLeftValue,
top: -1 * scrollTopValue,
},
iframeClientPos: { // iframe相对视窗的位置
left: iframeWin.getBoundingClientRect().left,
right: iframeWin.getBoundingClientRect().right,
top: iframeWin.getBoundingClientRect().top,
bottom: iframeWin.getBoundingClientRect().bottom
},
showSize: { // 告诉嵌入的子页面视窗高度与宽度
width: $(window).width(), // 视窗宽度
height: $(window).height() // 视窗高度
},
iframeOffset: { // iframe偏离文档的位置
left: iframeWin.offsetLeft,
top: iframeWin.offsetTop
}
}, '\*'); // '\*'表示跨域参数,请结合自身业务合理设置
}
</script>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,338 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>playback</title>
</head>
<style>
html, body {
padding: 0;
margin: 0;
}
.playWnd {
margin: 30px 0 0 400px;
width: 1000px; /*播放容器的宽和高设定*/
height: 600px;
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;
}
</style>
<body>
<!--回放界面-->
<div id="operate" class="operate">
<div class="module">
<div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text" value=""></div>
<div class="item"><span class="label">回放开始时间:</span><input id="startTimeStamp" type="text" placeholder="yyyy-MM-dd hh:mm:ss格式"></div>
<div class="item"><span class="label">回放结束时间:</span><input id="endTimeStamp" type="text" placeholder="yyyy-MM-dd hh:mm:ss格式"></div>
<div class="item" style="margin-top: 20px;margin-left: -20px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="startPlayback" class="btn">回放</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="stopAllPlayback" class="btn">停止全部回放</button>
</div>
</div>
</div>
<!--视频窗口展示-->
<div id="playWnd" class="playWnd" style="left: 109px; top: 133px;"></div>
</body>
<!--三个必要的js文件引入-->
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script src="web-control_1.2.5.min.js"></script>
<script type="text/javascript">
//页面加载时创建播放实例初始化
$(window).load(function () {
initPlugin();
});
//声明公用变量
var initCount = 0;
var pubKey = '';
// 创建WebControl实例与启动插件
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd", //指定容器id
iServicePortStart: 15900, //指定起止端口号,建议使用该值
iServicePortEnd: 15900,
cbConnectSuccess: function () {
// setCallbacks();
//实例创建成功后需要启动服务
oWebControl.JS_StartService("window", {
dllPath: "./VideoPluginConnect.dll"
}).then(function () {
oWebControl.JS_SetWindowControlCallback({ // 设置消息回调
cbIntegrationCallBack: cbIntegrationCallBack
});
oWebControl.JS_CreateWnd("playWnd", 1000, 600).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
console.log("JS_CreateWnd success");
init(); //创建播放实例成功后初始化
});
}, function () {
});
},
cbConnectError: function () {
console.log("cbConnectError");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); //程序未启动时执行error函数采用wakeup来启动程序
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function () {
console.log("cbConnectClose");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
console.log(JSON.stringify(oData.responseMsg));
}
//初始化
function init()
{
getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
var appkey = "28730366"; //综合安防管理平台提供的appkey必填
var secret = setEncrypt("HSZkCJpSJ7gSUYrO6wVi"); //综合安防管理平台提供的secret必填
var ip = "10.19.132.75"; //综合安防管理平台IP地址必填
var playMode = 1; //初始播放模式0-预览1-回放
var port = 443; //综合安防管理平台端口若启用HTTPS协议默认443
var snapDir = "D:\\SnapDir"; //抓图存储路径
var videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
var layout = "1x1"; //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"; //自定义工具条按钮
//var reconnectTimes = 2; // 重连次数,回放异常情况下有效
//var reconnectTime = 4; // 每次重连的重连间隔 >= reconnectTime
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
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 //自定义工具条按钮
//reconnectTimesreconnectTimes, //重连次数
//reconnectDurationreconnectTime //重连间隔
})
}).then(function (oData) {
oWebControl.JS_Resize(1000, 600); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
});
}
// 获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
})
}
// RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
setWndCover();
}
});
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
}
//录像回放功能
$("#startPlayback").click(function () {
var cameraIndexCode = $("#cameraIndexCode").val(); //获取输入的监控点编号值,必填
var startTimeStamp = new Date($("#startTimeStamp").val().replace('-', '/').replace('-', '/')).getTime(); //回放开始时间戳,必填
var endTimeStamp = new Date($("#endTimeStamp").val().replace('-', '/').replace('-', '/')).getTime(); //回放结束时间戳,必填
var recordLocation = 0; //录像存储位置0-中心存储1-设备存储
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = -1; //播放窗口序号在2x2以上布局下可指定播放窗口
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 //可指定播放窗口
})
})
});
// 停止回放
$("#stopAllPlayback").click(function () {
oWebControl.JS_RequestInterface({
funcName: "stopAllPlayback"
})
});
//设置录像回放时间的默认值
var endTime = dateFormat(new Date(), "yyyy-MM-dd 23:59:59");
var startTime = dateFormat(new Date(), "yyyy-MM-dd 00:00:00");
$("#startTimeStamp").val(startTime);
$("#endTimeStamp").val(endTime);
// 格式化时间
function dateFormat(oDate, fmt) {
var o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小时
"m+": oDate.getMinutes(), //分
"s+": oDate.getSeconds(), //秒
"q+": Math.floor((oDate.getMonth() + 3) / 3), //季度
"S": oDate.getMilliseconds()//毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (oDate.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){}, function() {});
}
});
</script>
</html>

View File

@ -0,0 +1,309 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>preview_demo</title>
</head>
<style>
html, body {
padding: 0;
margin: 0;
}
.playWnd {
margin: 30px 0 0 400px;
width: 1000px; /*播放容器的宽和高设定*/
height: 600px;
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;
}
</style>
<body>
<!--预览界面-->
<div id="operate" class="operate">
<div class="module">
<div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text" value=""></div>
<div class="item" style="margin-top: 20px;margin-left: -20px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:20px;padding:0;margin:0;" id="startPreview" class="btn">预览</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="stopAllPreview" class="btn">停止全部预览</button>
</div>
</div>
</div>
<!--视频窗口展示-->
<div id="playWnd" class="playWnd" style="left: 109px; top: 133px;"></div>
</body>
<!--三个必要的js文件引入-->
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script> <!-- 用于RSA加密 -->
<script src="web-control_1.2.5.min.js"></script> <!-- 用于前端与插件交互 -->
<script type="text/javascript">
//页面加载时创建播放实例初始化
$(window).load(function () {
initPlugin();
});
//声明公用变量
var initCount = 0;
var pubKey = '';
// 创建播放实例
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
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("playWnd", 1000, 600).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
init(); // 创建播放实例成功后初始化
});
}, function () { // 启动插件服务失败
});
},
cbConnectError: function () { // 创建WebControl实例失败
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数采用wakeup来启动程序
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
console.log("cbConnectClose");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
// 设置窗口控制回调
function setCallbacks() {
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: cbIntegrationCallBack
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
showCBInfo(JSON.stringify(oData.responseMsg));
}
//初始化
function init()
{
getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
var appkey = "28730366"; //综合安防管理平台提供的appkey必填
var secret = setEncrypt("HSZkCJpSJ7gSUYrO6wVi"); //综合安防管理平台提供的secret必填
var ip = "10.19.132.75"; //综合安防管理平台IP地址必填
var playMode = 0; //初始播放模式0-预览1-回放
var port = 443; //综合安防管理平台端口若启用HTTPS协议默认443
var snapDir = "D:\\SnapDir"; //抓图存储路径
var videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
var layout = "1x1"; //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"; //自定义工具条按钮
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
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) {
oWebControl.JS_Resize(1000, 600); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
});
}
//获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
})
}
//RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
setWndCover();
}
});
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
}
//视频预览功能
$("#startPreview").click(function () {
var cameraIndexCode = $("#cameraIndexCode").val(); //获取输入的监控点编号值,必填
var streamMode = 0; //主子码流标识0-主码流1-子码流
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = -1; //播放窗口序号在2x2以上布局下可指定播放窗口
cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode:cameraIndexCode, //监控点编号
streamMode: streamMode, //主子码流标识
transMode: transMode, //传输协议
gpuMode: gpuMode, //是否开启GPU硬解
wndId:wndId //可指定播放窗口
})
})
});
//停止全部预览
$("#stopAllPreview").click(function () {
oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
});
});
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){ // 断开与插件服务连接成功
},
function() { // 断开与插件服务连接失败
});
}
});
</script>
</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

@ -0,0 +1,244 @@
## 引入
* `web-control.min.js`: IIFE 格式,用于 `<script>` 标签直接引入,通过 `window.WebControl` 获取到对象。编译到兼容 IE10 的 ES5内置 Promise、Object.assign 的 polyfill
* `web-control.umd.min.js`: UMD 格式,一般用不到。编译到兼容 IE10 的 ES5不包含 polyfill
* `web-control.esm.min.js`: ES Module 格式,使用 webpack 时会自动引用这个,通过 `import { WebControl } from 'web-control';` 获取到对象。保留 ES6 语法不进行编译,不包含 polyfill
## API
### 初始化
```html
<div id="playWnd"></div>
```
```js
import { WebControl } from 'web-control';
const oWebControl = new WebControl({
// 对应 LocalServiceConfig.xml 中的 ServicePortStart 值
iServicePortStart: 15960,
// 对应 LocalServiceConfig.xml 中的 ServicePortEnd 值
iServicePortEnd: 15969,
// 页面中 div 的 id只在 IE 加载 ocx 时用到
szPluginContainer: 'playWnd',
// 仅在 IE10 中使用的 ActiveX 的 clsid不用修改
szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11',
// 成功回调
cbConnectSuccess() {},
// 错误回调
cbConnectError() {},
// 连接断开回调
cbConnectClose(isNormalClose) {
// 连接正常断开isNormalClose === true
// 连接异常断开isNormalClose === false
},
});
```
### 开启服务
```js
/**
* @name 开启服务
* 返回 Promise 的状态表明 dll 加载成功或失败
*
* @param {string} type 服务类型,当前为固定值 window
* @param {Object} options 可选参数
* @param {string} options.dllPath 中间件 dll 库相对于安装目录路径
*
* @returns {Promise}
*/
oWebControl.JS_StartService('window', { dllPath: './DllForTest.dll' })
.then(() => {})
.catch(() => {})
```
### 关闭服务
```js
/**
* @name 关闭服务
* @param {string} type 服务类型
*
* @returns {Promise}
*/
oWebControl.JS_StopService('window')
.then(() => {})
.catch(() => {})
```
### 创建窗口
```js
/**
* @name 创建窗口
* 开启服务成功后可调用。返回 Promise 的状态表明窗口创建成功或失败
*
* @param {string} id 窗口元素的 id
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
* @param {Object} options 可选参数
* @param {boolean} options.bEmbed 手动指定窗口模式如果浏览器本身不支持嵌入模式此参数无效。true 表示嵌入false 表示跟随
* @param {boolean} options.bActiveXParentWnd 手动指定是否以 ActiveX 为父窗口,仅在 IE10 下有效。在 Win10 下如果遇到窗口闪烁严重可以使用此参数。true 表示以 ActiveX 为父窗口。
* @param {function} options.cbSetDocTitle 客户端是通过浏览器标题document.title来匹配对应标签页窗口的在发请求时web-control 会在 document.title 中设置一个 uuid请求结束后还原。当 iframe 跨域嵌套时可以自行实现这个逻辑把回调参数uuid通过 postMessage 传递给顶层窗口,在顶层窗口设置 document.title = document.title + ' '.repeat(36) + uuid
* @param {function} options.cbUnsetDocTitle 取消设置浏览器标题,请求结束后会调用
* @param {string} options.HWND 窗口句柄。在网页嵌在业务客户端里的情况下网页的标题不会显示到业务客户端窗口标题上web-control 客户端无法找到对应的窗口。此时可以由业务客户端直接把网页所在窗口的句柄告诉前端通过设置这个字段web-control 客户端直接根据窗口句柄来找到窗口。该参数仅在支持的该功能的 web-control 客户端版本中生效。
*
* @returns {Promise}
*/
oWebControl.JS_CreateWnd('playWnd', 600, 400)
.then(() => {})
.catch(() => {})
```
### 销毁窗口
```js
/**
* @name 销毁窗口
* 窗口创建成功后可调用。返回 Promise 的状态表明窗口销毁成功或失败。中间件 dll 有实现 DestroyWnd 接口,同一页面多次调用 JS_CreateWnd 和 JS_DestroyWnd 实现业务逻辑时使用。
*
* @returns {Promise}
*/
oWebControl.JS_DestroyWnd()
.then(() => {})
.catch(() => {})
```
### 设置窗口偏移
```js
/**
* @name 设置窗口偏移
* 开启服务成功后可调用,之后再调用 JS_Resize 生效。当 iframe 嵌套时,需要传入该 iframe 相对最顶层窗口的位置。
*
* @param {Object} offset 偏移位置
* @param {Number} offset.left 左偏移
* @param {Number} offset.top 上偏移
*/
oWebControl.JS_SetDocOffset({ left: 100, top: 200 });
```
### 设置回调函数
```js
/**
* @name 设置回调函数
*
* @param {Object} options 可选参数
* @param {string} options.cbIntegrationCallBack 设置三方集成框架异步数据回调
*/
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack(data) {
console.log(data.responseMsg);
},
});
```
### 透传接口
```js
/**
* @name 透传接口
* 窗口创建成功后可调用。返回 Promise 始终为 resolve
*
* @param {*} param 格式自定义,一般会包含函数名称和参数
*
* @returns {Promise}
*/
oWebControl.JS_RequestInterface({
funcName: 'add',
arguments: { arg1: 1, arg2: 2 },
})
.then((data) => {
console.log(data.responseMsg);
});
```
### 唤醒 exe
```js
/**
* @name 唤醒 exe
* 在连接失败后调用WebControl 的静态方法
*
* @param {string} protocal exe 唤醒协议,安装包时写入注册表,默认为 WebControlPlugin://
*/
WebControl.JS_WakeUp('WebControlPlugin://');
```
### 窗口大小、位置改变
```js
/**
* @name 窗口大小、位置改变
* 窗口创建成功后可调用。在窗口大小位置变化、resize 事件、scroll 事件触发时调用。
*
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
*/
oWebControl.JS_Resize(600, 400);
```
### 断开连接
```js
/**
* @name 断开连接
* unload 事件、路由离开页面时调用。
*
* @returns {Promise}
*/
oWebControl.JS_Disconnect();
```
### 扣除部分窗口
```js
/**
* @name 扣除部分窗口
* 窗口创建成功后可调用。当需要在窗口上叠加网页元素时可以使用,位置相对于窗口左上角。
*
* @param {number} x 左边距
* @param {number} y 上边距
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
*/
oWebControl.JS_CuttingPartWindow(0, 0, 200, 200);
```
### 还原部分窗口
```js
/**
* @name 还原部分窗口
* 与 JS_CuttingPartWindow 成对使用。
*
* @param {number} x 左边距
* @param {number} y 上边距
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
*/
oWebControl.JS_RepairPartWindow(0, 0, 200, 200);
```
### 隐藏窗口
```js
/**
* @name 隐藏窗口
* 窗口创建成功后可调用。
*/
oWebControl.JS_HideWnd();
```
### 显示窗口
```js
/**
* @name 显示窗口
* 窗口创建成功后可调用。
*/
oWebControl.JS_ShowWnd();
```

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,61 @@
################################################################################
## 系统日志文件打印配置 -- 开始
##
## 如要增加自定义模块日志打印配置:
## appender名称格式为log4j.appender.default_debug_模块名
## 文件名格式:组件标识.段标识.模块名.debug.log
## log4j.logger.模块名=INFO,default_debug_模块名
## log4j.additivity.模块名=false
## 日志打印文件越多, 越影响磁盘I/O效率, 造成程度卡顿, 尽量按标准配置打印
##
## 所有级别(DEBUG及以上)的日志输出配置, 所有级别打印在*.debug.log中, 文件名用debug表示调试用, 便于理解
##
log4j.logger.DEFAULT_Debug = DEBUG, DEFAULT_Debug
log4j.appender.DEFAULT_Debug=org.apache.log4j.RollingFileAppender
log4j.appender.DEFAULT_Debug.File=./logs/ccs_service.debug.log
log4j.appender.DEFAULT_Debug.MaxFileSize=25MB
log4j.appender.DEFAULT_Debug.MaxBackupIndex=10
log4j.appender.DEFAULT_Debug.Append=true
log4j.appender.DEFAULT_Debug.Threshold=DEBUG
log4j.appender.DEFAULT_Debug.layout=org.apache.log4j.PatternLayout
log4j.appender.DEFAULT_Debug.layout.ConversionPattern=%d %-p %.16c [%t] %m%n
##
## 所有级别(INFO及以上)的日志输出配置, 所有级别打印在*.info.log中, 文件名用debug表示调试用, 便于理解
##
log4j.logger.DEFAULT_Info = INFO, DEFAULT_Info
log4j.appender.DEFAULT_Info=org.apache.log4j.RollingFileAppender
log4j.appender.DEFAULT_Info.File=./logs/ccs_service.other.log
log4j.appender.DEFAULT_Info.MaxFileSize=25MB
log4j.appender.DEFAULT_Info.MaxBackupIndex=10
log4j.appender.DEFAULT_Info.Append=true
log4j.appender.DEFAULT_Info.Threshold=INFO
log4j.appender.DEFAULT_Info.layout=org.apache.log4j.PatternLayout
log4j.appender.DEFAULT_Info.layout.ConversionPattern=%d %-p %.16c [%t] %m%n
##
## 错误日志输出配置, error及以上日志单独再打印一个*.error.log, 防止重要信息被覆盖
##
log4j.logger.DEFAULT_Error = ERROR, DEFAULT_Error
log4j.appender.DEFAULT_Error=org.apache.log4j.RollingFileAppender
log4j.appender.DEFAULT_Error.File=./logs/ccs_service.error.log
log4j.appender.DEFAULT_Error.MaxFileSize=25MB
log4j.appender.DEFAULT_Error.MaxBackupIndex=10
log4j.appender.DEFAULT_Error.Append=true
log4j.appender.DEFAULT_Error.Threshold=ERROR
log4j.appender.DEFAULT_Error.layout=org.apache.log4j.PatternLayout
log4j.appender.DEFAULT_Error.layout.ConversionPattern=%d %-p %.16c [%t] %m%n
##
## 日志级别控制:由","分割的第一个字段控制
## 出厂默认输出级别INFO, 排查问题时, 可以通过工具切换为TRACE
## 自定义模块日志打印 添加在后面
##
log4j.rootLogger=INFO
##hlog.async=false
##hlog.secret.show=true
##hlog.secret.encrypt=true

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>videoplugin_demo</title>
</head>
<body>
<a href="http://127.0.0.1:36963/demo_window_integration.html">完整demo</a><br/>
<a href="http://127.0.0.1:36963/demo_window_simple_preview.html">预览demo</a><br/>
<a href="http://127.0.0.1:36963/demo_window_simple_playback.html">回放demo</a><br/>
<a href="http://127.0.0.1:36963/demo_for_iframe.html">demo_for_iframe</a><br/>
<a href="http://127.0.0.1:36963/demo_embedded_for_iframe.html">demo_embedded_for_iframe</a><br/>
</body>
</html>

View File

@ -0,0 +1,3 @@
1 启动WebServer目录下WebServer.exe提示窗口中输入r启动web服务器监听端口36963
2 浏览器中输入http://127.0.0.1:36963/demo名称.html访问demo页面
3 demo源文件存放于WebServer下的demo目录

74
public/player/jquery-1.12.4.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/player/jsencrypt.min.js vendored Normal file

File diff suppressed because one or more lines are too long

382
public/player/playback.html Normal file
View File

@ -0,0 +1,382 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>playback</title>
</head>
<style>
html,
body {
padding: 0;
margin: 0;
overflow: hidden;
}
.playWnd {
/* margin: 30px 0 0 400px;
width: 1000px;
/*播放容器的宽和高设定*/
/* height: 600px;
border: 1px solid red; */
position: absolute;
width: 100%;
height: 100%;
left: 38.8%;
top: 50%;
}
.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;
}
</style>
<body>
<!--回放界面-->
<!-- <div id="operate" class="operate">
<div class="module">
<div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text" value=""></div>
<div class="item"><span class="label">回放开始时间:</span><input id="startTimeStamp" type="text"
placeholder="yyyy-MM-dd hh:mm:ss格式"></div>
<div class="item"><span class="label">回放结束时间:</span><input id="endTimeStamp" type="text"
placeholder="yyyy-MM-dd hh:mm:ss格式"></div>
<div class="item" style="margin-top: 20px;margin-left: -20px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="startPlayback" class="btn">回放</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="stopAllPlayback" class="btn">停止全部回放</button>
</div>
</div>
</div>
<div style="margin-left: 15px;">注意: 开始回放前请打开该文件的源代码将appkey、录像存储位置等信息修改为实际项目中的信息</div> -->
<!--视频窗口展示-->
<div id="playWnd" class="playWnd"></div>
</body>
<!--三个必要的js文件引入-->
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script src="web-control_1.2.7.min.js"></script>
<script type="text/javascript">
//页面加载时创建播放实例初始化
$(window).load(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth - 10
playerHeight = palyer.offsetHeight - 10
initPlugin();
});
//声明公用变量
var initCount = 0;
var pubKey = '';
if (self.frameElement) {
var url = location.search.split("=")[1]
console.log(url, 'aaa');
var cameraIndex = url.split(',')[0]
var startTime = url.split(',')[1]
var endTime = url.split(',')[2]
}
// 创建WebControl实例与启动插件
function initPlugin() {
oWebControl = new WebControl({
szPluginContainer: "playWnd", //指定容器id
iServicePortStart: 15900, //指定起止端口号,建议使用该值
iServicePortEnd: 15900,
cbConnectSuccess: function () {
// setCallbacks();
//实例创建成功后需要启动服务
oWebControl.JS_StartService("window", {
dllPath: "./VideoPluginConnect.dll"
}).then(function () {
oWebControl.JS_SetWindowControlCallback({ // 设置消息回调
cbIntegrationCallBack: cbIntegrationCallBack
});
oWebControl.JS_CreateWnd("playWnd", playerWidth, playerHeight).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
console.log("JS_CreateWnd success");
init(); //创建播放实例成功后初始化
});
}, function () {
});
},
cbConnectError: function () {
console.log("cbConnectError");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); //程序未启动时执行error函数采用wakeup来启动程序
initCount++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function () {
console.log("cbConnectClose");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
console.log(JSON.stringify(oData.responseMsg));
}
//初始化
function init() {
getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
var appkey = "24603469"; //综合安防管理平台提供的appkey必填
var secret = setEncrypt("ku1Y8R41fch9J5saqLB2"); //综合安防管理平台提供的secret必填
var ip = "192.168.17.3"; //综合安防管理平台IP地址必填
var playMode = 1; //初始播放模式0-预览1-回放
var port = 443; //综合安防管理平台端口若启用HTTPS协议默认443
var snapDir = "D:\\SnapDir"; //抓图存储路径
var videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
var layout = "1x1"; //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"; //自定义工具条按钮
//var reconnectTimes = 2; // 重连次数,回放异常情况下有效
//var reconnectTime = 4; // 每次重连的重连间隔 >= reconnectTime
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
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 //自定义工具条按钮
//reconnectTimesreconnectTimes, //重连次数
//reconnectDurationreconnectTime //重连间隔
})
}).then(function (oData) {
oWebControl.JS_Resize(playerWidth, playerHeight); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
});
}
// 获取公钥
function getPubKey(callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
startPlayBack()
})
}
// RSA加密
function setEncrypt(value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth -10
playerHeight = palyer.offsetHeight -10
if (oWebControl != null) {
oWebControl.JS_Resize(playerWidth, playerHeight);
// setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth
playerHeight = palyer.offsetHeight
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
// setWndCover();
}
});
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
}
//录像回放功能
$("#startPlayback").click(function () {
startPlayBack()
});
function startPlayBack() {
console.log(startTime,endTime,cameraIndex,'播放参数');
var cameraIndexCode = $("#cameraIndexCode").val(); //获取输入的监控点编号值,必填
var startTimeStamp = startTime; //回放开始时间戳,必填
var endTimeStamp = endTime; //回放结束时间戳,必填
// var startTimeStamp = new Date($("#startTimeStamp").val().replace('-', '/').replace('-', '/')).getTime(); //回放开始时间戳,必填
// var endTimeStamp = new Date($("#endTimeStamp").val().replace('-', '/').replace('-', '/')).getTime(); //回放结束时间戳,必填
var recordLocation = 0; //录像存储位置0-中心存储1-设备存储
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = -1; //播放窗口序号在2x2以上布局下可指定播放窗口
oWebControl.JS_RequestInterface({
funcName: "startPlayback",
argument: JSON.stringify({
cameraIndexCode: cameraIndex, //监控点编号
startTimeStamp: Math.floor(startTimeStamp / 1000).toString(), //录像查询开始时间戳,单位:秒
endTimeStamp: Math.floor((endTimeStamp / 1000) + 10).toString(), //录像结束开始时间戳,单位:秒
recordLocation: recordLocation, //录像存储类型0-中心存储1-设备存储
transMode: transMode, //传输协议0-UDP1-TCP
gpuMode: gpuMode, //是否启用GPU硬解0-不启用1-启用
wndId: wndId //可指定播放窗口
})
})
}
// 停止回放
$("#stopAllPlayback").click(function () {
oWebControl.JS_RequestInterface({
funcName: "stopAllPlayback"
})
});
//设置录像回放时间的默认值
// var endTime = dateFormat(new Date(), "yyyy-MM-dd 23:59:59");
// var startTime = dateFormat(new Date(), "yyyy-MM-dd 00:00:00");
// $("#startTimeStamp").val(startTime);
// $("#endTimeStamp").val(endTime);
// 格式化时间
function dateFormat(oDate, fmt) {
var o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小时
"m+": oDate.getMinutes(), //分
"s+": oDate.getSeconds(), //秒
"q+": Math.floor((oDate.getMonth() + 3) / 3), //季度
"S": oDate.getMilliseconds()//毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (oDate.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
// 标签关闭
$(window).unload(function () {
if (oWebControl != null) {
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function () { }, function () { });
}
});
</script>
</html>

View File

@ -0,0 +1,340 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>preview_demo</title>
</head>
<style>
html, body {
padding: 0;
margin: 0;
overflow: hidden;
}
.playWnd {
/* margin: 30px 0 0 400px; */
/* width: 1000px;
height: 600px; */
/* border: 1px solid red;
*/
position: absolute;
width: 100%;
height: 100%;
left:38.8%;
top:50%;
}
.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;
}
</style>
<body>
<!--预览界面-->
<!-- <div id="operate" class="operate">
<div class="module">
<div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text" value=""></div>
<div class="item" style="margin-top: 20px;margin-left: -20px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:20px;padding:0;margin:0;" id="startPreview" class="btn">预览</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="stopAllPreview" class="btn">停止全部预览</button>
</div>
</div>
</div> -->
<!--视频窗口展示-->
<div id="playWnd" class="playWnd"></div>
</body>
<!--三个必要的js文件引入-->
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script> <!-- 用于RSA加密 -->
<script src="web-control_1.2.7.min.js"></script> <!-- 用于前端与插件交互 -->
<script type="text/javascript">
window.addEventListener("message", getData)
var iframeData
var cameraCode
function getData(event) {
// console.log(event.data, 'aaaaa');
cameraCode = event.data.cameraIndex
iframeData = event.data.iframeOffset
// console.log(iframeData);
var phy = document.querySelector('#playWnd')
console.log(iframeData, phy);
// phy.style.left = iframeData.left + 'px'
// phy.style.top = iframeData.top + 'px'
}
var playerWidth,playerHeight
//页面加载时创建播放实例初始化
$(window).load(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth - 10
playerHeight = palyer.offsetHeight - 10
initPlugin();
});
//声明公用变量
var initCount = 0;
var pubKey = '';
// 创建播放实例
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
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("playWnd",playerWidth,playerHeight).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
init(); // 创建播放实例成功后初始化
});
}, function () { // 启动插件服务失败
});
},
cbConnectError: function () { // 创建WebControl实例失败
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数采用wakeup来启动程序
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
console.log("cbConnectClose");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
// 设置窗口控制回调
function setCallbacks() {
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: cbIntegrationCallBack
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
showCBInfo(JSON.stringify(oData.responseMsg));
}
//初始化
function init()
{
getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
var appkey = "24603469"; //综合安防管理平台提供的appkey必填
var secret = setEncrypt("ku1Y8R41fch9J5saqLB2"); //综合安防管理平台提供的secret必填
var ip = "192.168.17.3"; //综合安防管理平台IP地址必填
var playMode = 0; //初始播放模式0-预览1-回放
var port = 443; //综合安防管理平台端口若启用HTTPS协议默认443
var snapDir = "D:\\SnapDir"; //抓图存储路径
var videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
var layout = "1x1"; //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"; //自定义工具条按钮
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
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) {
oWebControl.JS_Resize(playerWidth,playerHeight); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
});
}
//获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
startPlay()
})
}
//RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth -10
playerHeight = palyer.offsetHeight -10
if (oWebControl != null) {
oWebControl.JS_Resize(playerWidth,playerHeight);
// setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
setWndCover();
}
});
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
}
//视频预览功能
$("#startPreview").click(
startPlay()
);
function startPlay(){
// var cameraIndexCode = $("#cameraIndexCode").val(); //获取输入的监控点编号值,必填
var streamMode = 0; //主子码流标识0-主码流1-子码流
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = 0; //播放窗口序号在2x2以上布局下可指定播放窗口
// cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
// cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode:cameraCode, //监控点编号
streamMode: streamMode, //主子码流标识
transMode: transMode, //传输协议
gpuMode: gpuMode, //是否开启GPU硬解
wndId:wndId //可指定播放窗口
})
})
}
//停止全部预览
$("#stopAllPreview").click(function () {
oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
});
});
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){ // 断开与插件服务连接成功
},
function() { // 断开与插件服务连接失败
});
}
});
</script>
</html>

View File

@ -0,0 +1,329 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>preview_demo</title>
</head>
<style>
html, body {
padding: 0;
margin: 0;
overflow: hidden;
}
.playWnd {
/* margin: 30px 0 0 400px; */
/* width: 1000px;
height: 600px; */
/* border: 1px solid red;
*/
position: absolute;
width: 100%;
height: 100%;
left:73%;
top:56%;
}
.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;
}
</style>
<body>
<!--预览界面-->
<!-- <div id="operate" class="operate">
<div class="module">
<div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text" value=""></div>
<div class="item" style="margin-top: 20px;margin-left: -20px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:20px;padding:0;margin:0;" id="startPreview" class="btn">预览</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="stopAllPreview" class="btn">停止全部预览</button>
</div>
</div>
</div> -->
<!--视频窗口展示-->
<div id="playWnd" class="playWnd"></div>
</body>
<!--三个必要的js文件引入-->
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script> <!-- 用于RSA加密 -->
<script src="web-control_1.2.7.min.js"></script> <!-- 用于前端与插件交互 -->
<script type="text/javascript">
var playerWidth,playerHeight
//页面加载时创建播放实例初始化
$(window).load(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth
playerHeight = palyer.offsetHeight
initPlugin();
});
//声明公用变量
var initCount = 0;
var pubKey = '';
// 创建播放实例
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
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("playWnd",playerWidth,playerHeight).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
init(); // 创建播放实例成功后初始化
});
}, function () { // 启动插件服务失败
});
},
cbConnectError: function () { // 创建WebControl实例失败
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数采用wakeup来启动程序
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
console.log("cbConnectClose");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
// 设置窗口控制回调
function setCallbacks() {
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: cbIntegrationCallBack
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
console.log(oData,'数据');
}
//初始化
function init()
{
getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
var appkey = "24603469"; //综合安防管理平台提供的appkey必填
var secret = setEncrypt("ku1Y8R41fch9J5saqLB2"); //综合安防管理平台提供的secret必填
var ip = "192.168.17.3"; //综合安防管理平台IP地址必填
var playMode = 0; //初始播放模式0-预览1-回放
var port = 443; //综合安防管理平台端口若启用HTTPS协议默认443
var snapDir = "D:\\SnapDir"; //抓图存储路径
var videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
var layout = "1x1"; //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"; //自定义工具条按钮
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
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, //自定义工具条按钮
layout: "2x2"
})
}).then(function (oData) {
oWebControl.JS_Resize(playerWidth,playerHeight); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
});
}
//获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
})
}
//RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth
playerHeight = palyer.offsetHeight
if (oWebControl != null) {
oWebControl.JS_Resize(playerWidth,playerHeight);
// setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(1000, 600);
setWndCover();
}
});
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
}
//视频预览功能
$("#startPreview").click(
startPlay()
);
function startPlay(id){
// console.log(id);
// var cameraIndexCode = $("#cameraIndexCode").val(); //获取输入的监控点编号值,必填
var streamMode = 0; //主子码流标识0-主码流1-子码流
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = 0; //播放窗口序号在2x2以上布局下可指定播放窗口
// cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
// cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode:id, //监控点编号
streamMode: streamMode, //主子码流标识
transMode: transMode, //传输协议
gpuMode: gpuMode, //是否开启GPU硬解
wndId:wndId //可指定播放窗口
})
})
}
//停止全部预览
$("#stopAllPreview").click(function () {
oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
});
});
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){ // 断开与插件服务连接成功
},
function() { // 断开与插件服务连接失败
});
}
});
</script>
</html>

2
public/player/web-control.esm.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,244 @@
## 引入
* `web-control.min.js`: IIFE 格式,用于 `<script>` 标签直接引入,通过 `window.WebControl` 获取到对象。编译到兼容 IE10 的 ES5内置 Promise、Object.assign 的 polyfill
* `web-control.umd.min.js`: UMD 格式,一般用不到。编译到兼容 IE10 的 ES5不包含 polyfill
* `web-control.esm.min.js`: ES Module 格式,使用 webpack 时会自动引用这个,通过 `import { WebControl } from 'web-control';` 获取到对象。保留 ES6 语法不进行编译,不包含 polyfill
## API
### 初始化
```html
<div id="playWnd"></div>
```
```js
import { WebControl } from 'web-control';
const oWebControl = new WebControl({
// 对应 LocalServiceConfig.xml 中的 ServicePortStart 值
iServicePortStart: 15960,
// 对应 LocalServiceConfig.xml 中的 ServicePortEnd 值
iServicePortEnd: 15969,
// 页面中 div 的 id只在 IE 加载 ocx 时用到
szPluginContainer: 'playWnd',
// 仅在 IE10 中使用的 ActiveX 的 clsid不用修改
szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11',
// 成功回调
cbConnectSuccess() {},
// 错误回调
cbConnectError() {},
// 连接断开回调
cbConnectClose(isNormalClose) {
// 连接正常断开isNormalClose === true
// 连接异常断开isNormalClose === false
},
});
```
### 开启服务
```js
/**
* @name 开启服务
* 返回 Promise 的状态表明 dll 加载成功或失败
*
* @param {string} type 服务类型,当前为固定值 window
* @param {Object} options 可选参数
* @param {string} options.dllPath 中间件 dll 库相对于安装目录路径
*
* @returns {Promise}
*/
oWebControl.JS_StartService('window', { dllPath: './DllForTest.dll' })
.then(() => {})
.catch(() => {})
```
### 关闭服务
```js
/**
* @name 关闭服务
* @param {string} type 服务类型
*
* @returns {Promise}
*/
oWebControl.JS_StopService('window')
.then(() => {})
.catch(() => {})
```
### 创建窗口
```js
/**
* @name 创建窗口
* 开启服务成功后可调用。返回 Promise 的状态表明窗口创建成功或失败
*
* @param {string} id 窗口元素的 id
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
* @param {Object} options 可选参数
* @param {boolean} options.bEmbed 手动指定窗口模式如果浏览器本身不支持嵌入模式此参数无效。true 表示嵌入false 表示跟随
* @param {boolean} options.bActiveXParentWnd 手动指定是否以 ActiveX 为父窗口,仅在 IE10 下有效。在 Win10 下如果遇到窗口闪烁严重可以使用此参数。true 表示以 ActiveX 为父窗口。
* @param {function} options.cbSetDocTitle 客户端是通过浏览器标题document.title来匹配对应标签页窗口的在发请求时web-control 会在 document.title 中设置一个 uuid请求结束后还原。当 iframe 跨域嵌套时可以自行实现这个逻辑把回调参数uuid通过 postMessage 传递给顶层窗口,在顶层窗口设置 document.title = document.title + ' '.repeat(36) + uuid
* @param {function} options.cbUnsetDocTitle 取消设置浏览器标题,请求结束后会调用
* @param {string} options.HWND 窗口句柄。在网页嵌在业务客户端里的情况下网页的标题不会显示到业务客户端窗口标题上web-control 客户端无法找到对应的窗口。此时可以由业务客户端直接把网页所在窗口的句柄告诉前端通过设置这个字段web-control 客户端直接根据窗口句柄来找到窗口。该参数仅在支持的该功能的 web-control 客户端版本中生效。
*
* @returns {Promise}
*/
oWebControl.JS_CreateWnd('playWnd', 600, 400)
.then(() => {})
.catch(() => {})
```
### 销毁窗口
```js
/**
* @name 销毁窗口
* 窗口创建成功后可调用。返回 Promise 的状态表明窗口销毁成功或失败。中间件 dll 有实现 DestroyWnd 接口,同一页面多次调用 JS_CreateWnd 和 JS_DestroyWnd 实现业务逻辑时使用。
*
* @returns {Promise}
*/
oWebControl.JS_DestroyWnd()
.then(() => {})
.catch(() => {})
```
### 设置窗口偏移
```js
/**
* @name 设置窗口偏移
* 开启服务成功后可调用,之后再调用 JS_Resize 生效。当 iframe 嵌套时,需要传入该 iframe 相对最顶层窗口的位置。
*
* @param {Object} offset 偏移位置
* @param {Number} offset.left 左偏移
* @param {Number} offset.top 上偏移
*/
oWebControl.JS_SetDocOffset({ left: 100, top: 200 });
```
### 设置回调函数
```js
/**
* @name 设置回调函数
*
* @param {Object} options 可选参数
* @param {string} options.cbIntegrationCallBack 设置三方集成框架异步数据回调
*/
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack(data) {
console.log(data.responseMsg);
},
});
```
### 透传接口
```js
/**
* @name 透传接口
* 窗口创建成功后可调用。返回 Promise 始终为 resolve
*
* @param {*} param 格式自定义,一般会包含函数名称和参数
*
* @returns {Promise}
*/
oWebControl.JS_RequestInterface({
funcName: 'add',
arguments: { arg1: 1, arg2: 2 },
})
.then((data) => {
console.log(data.responseMsg);
});
```
### 唤醒 exe
```js
/**
* @name 唤醒 exe
* 在连接失败后调用WebControl 的静态方法
*
* @param {string} protocal exe 唤醒协议,安装包时写入注册表,默认为 WebControlPlugin://
*/
WebControl.JS_WakeUp('WebControlPlugin://');
```
### 窗口大小、位置改变
```js
/**
* @name 窗口大小、位置改变
* 窗口创建成功后可调用。在窗口大小位置变化、resize 事件、scroll 事件触发时调用。
*
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
*/
oWebControl.JS_Resize(600, 400);
```
### 断开连接
```js
/**
* @name 断开连接
* unload 事件、路由离开页面时调用。
*
* @returns {Promise}
*/
oWebControl.JS_Disconnect();
```
### 扣除部分窗口
```js
/**
* @name 扣除部分窗口
* 窗口创建成功后可调用。当需要在窗口上叠加网页元素时可以使用,位置相对于窗口左上角。
*
* @param {number} x 左边距
* @param {number} y 上边距
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
*/
oWebControl.JS_CuttingPartWindow(0, 0, 200, 200);
```
### 还原部分窗口
```js
/**
* @name 还原部分窗口
* 与 JS_CuttingPartWindow 成对使用。
*
* @param {number} x 左边距
* @param {number} y 上边距
* @param {number} width 窗口宽度
* @param {number} height 窗口高度
*/
oWebControl.JS_RepairPartWindow(0, 0, 200, 200);
```
### 隐藏窗口
```js
/**
* @name 隐藏窗口
* 窗口创建成功后可调用。
*/
oWebControl.JS_HideWnd();
```
### 显示窗口
```js
/**
* @name 显示窗口
* 窗口创建成功后可调用。
*/
oWebControl.JS_ShowWnd();
```

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,327 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>preview_demo</title>
</head>
<style>
html, body {
padding: 0;
margin: 0;
overflow: hidden;
}
.playWnd {
/* margin: 30px 0 0 400px; */
/* width: 1000px;
height: 600px; */
/* border: 1px solid red;
*/
position: absolute;
width: 100%;
height: 100%;
left:386.2%;
top:197%;
}
.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;
}
</style>
<body>
<!--预览界面-->
<!-- <div id="operate" class="operate">
<div class="module">
<div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text" value=""></div>
<div class="item" style="margin-top: 20px;margin-left: -20px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:20px;padding:0;margin:0;" id="startPreview" class="btn">预览</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button style="width:90px;padding:0;margin:0;" id="stopAllPreview" class="btn">停止全部预览</button>
</div>
</div>
</div> -->
<!--视频窗口展示-->
<div id="playWnd" class="playWnd"></div>
</body>
<!--三个必要的js文件引入-->
<script src="jquery-1.12.4.min.js"></script>
<script src="jsencrypt.min.js"></script> <!-- 用于RSA加密 -->
<script src="web-control_1.2.7.min.js"></script> <!-- 用于前端与插件交互 -->
<script type="text/javascript">
var playerWidth,playerHeight
//页面加载时创建播放实例初始化
$(window).load(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth
playerHeight = palyer.offsetHeight
initPlugin();
});
//声明公用变量
var initCount = 0;
var pubKey = '';
// 创建播放实例
function initPlugin () {
oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
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("playWnd",playerWidth,playerHeight).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定
init(); // 创建播放实例成功后初始化
});
}, function () { // 启动插件服务失败
});
},
cbConnectError: function () { // 创建WebControl实例失败
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数采用wakeup来启动程序
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
console.log("cbConnectClose");
oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
initCount ++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000)
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
}
});
}
// 设置窗口控制回调
function setCallbacks() {
oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: cbIntegrationCallBack
});
}
// 推送消息
function cbIntegrationCallBack(oData) {
console.log(oData,'数据');
}
//初始化
function init()
{
getPubKey(function () {
////////////////////////////////// 请自行修改以下变量值 ////////////////////////////////////
var appkey = "24603469"; //综合安防管理平台提供的appkey必填
var secret = setEncrypt("ku1Y8R41fch9J5saqLB2"); //综合安防管理平台提供的secret必填
var ip = "192.168.17.3"; //综合安防管理平台IP地址必填
var playMode = 0; //初始播放模式0-预览1-回放
var port = 443; //综合安防管理平台端口若启用HTTPS协议默认443
var snapDir = "D:\\SnapDir"; //抓图存储路径
var videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
var layout = "1x1"; //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"; //自定义工具条按钮
////////////////////////////////// 请自行修改以上变量值 ////////////////////////////////////
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) {
oWebControl.JS_Resize(playerWidth,playerHeight); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
});
});
}
//获取公钥
function getPubKey (callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
})
}
//RSA加密
function setEncrypt (value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {
var palyer = document.querySelector('#playWnd')
playerWidth = palyer.offsetWidth
playerHeight = palyer.offsetHeight
if (oWebControl != null) {
oWebControl.JS_Resize(playerWidth,playerHeight);
// setWndCover();
}
});
// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {
if (oWebControl != null) {
oWebControl.JS_Resize(playerWidth,playerHeight);
setWndCover();
}
});
// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
}
//视频预览功能
$("#startPreview").click(
startPlay()
);
function startPlay(id){
// console.log(id);
// var cameraIndexCode = $("#cameraIndexCode").val(); //获取输入的监控点编号值,必填
var streamMode = 0; //主子码流标识0-主码流1-子码流
var transMode = 1; //传输协议0-UDP1-TCP
var gpuMode = 0; //是否启用GPU硬解0-不启用1-启用
var wndId = 0; //播放窗口序号在2x2以上布局下可指定播放窗口
// cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
// cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode:id, //监控点编号
streamMode: streamMode, //主子码流标识
transMode: transMode, //传输协议
gpuMode: gpuMode, //是否开启GPU硬解
wndId:wndId //可指定播放窗口
})
})
}
//停止全部预览
$("#stopAllPreview").click(function () {
oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
});
});
// 标签关闭
$(window).unload(function () {
if (oWebControl != null){
oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_Disconnect().then(function(){ // 断开与插件服务连接成功
},
function() { // 断开与插件服务连接失败
});
}
});
</script>
</html>

View File

@ -0,0 +1,6 @@
1、demo_window_simple_playback.html、demo_window_simple_preview.html为简化版demo可在此基础上开发
2、demo_window_integration.html为包含了所有功能的demo可参照此demo来开发、验证功能、排查问题
3、demo_for_iframe.html、demo_embedded_for_iframe.html为iframe对接场景demo前者嵌入了后者。验证iframe对接需要运行webs.exe模拟WEB服务或将这两个文件放到WEB服务器中通过IP:PORT的方式访问如http:127.0.0.1:80/demo_for_iframe.html。
4、其它js文件为demo依赖文件
5、demo_with_QTWebserver目录中提供了新的本地web服务器当webs.exe在部分操作系统中不可用时可使用此目录下新的web服务器具体参考此目录中的使用前必读文件。

BIN
public/qiangzhi.reg Normal file

Binary file not shown.

BIN
public/xungeng.reg Normal file

Binary file not shown.

View File

@ -1,18 +1,18 @@
<script setup>
import NAV from '@/components/nav.vue'
</script>
<template>
<div id="app">
<NAV />
<router-view></router-view>
</div>
<!-- <div id="three3D">
<Three />
</div> -->
<!-- 头部-->
</template>
<style scoped lang="scss">
</style>
<script setup>
import NAV from '@/components/nav.vue'
</script>
<template>
<div id="app">
<NAV />
<router-view></router-view>
</div>
<!-- <div id="three3D">
<Three />
</div> -->
<!-- 头部-->
</template>
<style scoped lang="scss">
</style>

44
src/api/index.js Normal file
View File

@ -0,0 +1,44 @@
import request from '@/utils/request.js'
// 海康对接数据接口
export function getHikvision(data) {
return request({
url: '/api/cameras/hikvision/',
method: "POST",
data: data
})
}
// 获取单点登录的token
export function getToken(params){
return request({
url:"/api/cameras/gethikvision/",
method:"GET",
headers:{
url:'/artemis/api/cas/v1/tgt/login'
},
params
})
}
// 获取排班表数据
export function getScheduleList(params) {
return request({
url: 'aps/Handler/GetScheduling.ashx',
method: 'GET',
params
})
}
export function login(params) {
return request({
url: 'aps/Handler/Login.ashx',
method: 'GET',
params
})
}
// 紧急报警数据获取
export function getEmergencyApi(params) {
return request({
url: 'aps/Handler/GetAlarm.ashx',
method: 'GET',
params
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
src/assets/images/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

BIN
src/assets/images/pre.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

View File

@ -1,168 +1,403 @@
<template></template>
<script setup>
import { onMounted } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
import { CSS3DRenderer, CSS3DObject } from "three/examples/jsm/renderers/CSS3DRenderer";
import * as THREE from 'three';
onMounted(() => {
init()
createCamera()
createRender()
createLight()
// console.log(requestAnimationFrame);
animate()
initIcon()
})
//,
window.addEventListener('resize', function () {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
// initIcon()
})
let scene
let camera
let renderer
let mesh //
let labelRenderer //3d
let controls
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, .6, 10000)
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
//
controls = new OrbitControls(camera, renderer.domElement)
// controls.maxPolarAngle = 20*Math.PI
controls.maxDistance = 1000
controls.minDistance = 200
// controls.minAzimuthAngle = 100 * Math.PI;
// controls.maxAzimuthAngle = 100 * Math.PI;
controls.minPolarAngle = 0;
controls.maxPolarAngle = (Math.PI / 4) *2
const emissiveColor = new THREE.Color(0xff0000)
const material = new THREE.MeshStandardMaterial({
color: 0xffffff, //
emissive: emissiveColor,
emissiveIntensity: 1, //
});
// function init() {
// const mtLoader = new MTLLoader()
// const loader = new OBJLoader()
// mtLoader.load('/model/YinFangShuJu_01.mtl', function (material) {
// console.log(material);
// material.preload()
// loader.setMaterials(material)
// //
// loader.load('/model/YinFangShuJu_01.obj', (loadMesh) => {
// mesh = loadMesh
// console.log(mesh);
// //
// scene.add(mesh)
// }, (xhr) => {
// if (xhr.lengthComputable) {
// const percentComplete = xhr.loaded / xhr.total * 100
// console.log(Math.round(percentComplete, 2) + '%')
// }
// })
// })
// }
function init() {
const loader = new FBXLoader()
loader.load('YFSJ_Model.fbx', (fbx) => {
// fbx.traverse(function (child) {
// if (child.isMesh && child.name =='') {
// child.material = new THREE.MeshPhongMaterial({
// color: new THREE.Color('#b4babd'),
// //
// // map: texture, //
// // emissive: 0x00ff00, //
// emissiveIntensity: 1,
// });
// }
// });
console.log(fbx,'模型');
// fbx.children[21].material.emissiveIntensity = 1
// fbx.material = fbx.children[21].material
// console.log(fbx.children[21]);
fbx.scale.set(1, 1, 1);
// fbx.rotation.set(180,20,0)
fbx.position.set(0, 0, 0);
scene.add(fbx);
})
}
function createLight() {
//
const ambientLight = new THREE.AmbientLight(0xffffff, 1.5) //
scene.add(ambientLight) //
const spotLight = new THREE.SpotLight('#ffffff', 0.7) //
spotLight.position.set(1600, 1660, 100)
spotLight.castShadow = true
scene.add(spotLight)
}
function createCamera() {
camera.position.set(500, 400, -500)
console.log(camera);
camera.lookAt(scene.position)
scene.add(camera)
}
function createRender() {
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true //
renderer.shadowMap.type = THREE.PCFSoftShadowMap
renderer.setClearColor('#ffffff') //
document.querySelector('#three3D').appendChild(renderer.domElement)
// document.querySelector('#three3D').appendChild(labelRenderer.domElement);
}
async function initIcon() {
let pointList = [
{
name: "警报",
point: {
x: 40.91436767578125,
y: 0.9466018676757812,
z: 0
},
},
{
name: "馍馍加辣条",
point: {
x:15.29782094726788,
y: 2.00017999999690800907,
z: -75.36294510575863,
},
},
{
name: "xxx",
point: {
x: 50.91436767578125,
y: 0.9466018676757812,
z: 200
},
},
];
}
function animate() {
controls.update()
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
</script>
<style scoped></style>
<template></template>
<script setup>
import { onMounted, watch } from "vue";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader.js";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
import {
CSS3DRenderer,
CSS3DObject,
} from "three/examples/jsm/renderers/CSS3DRenderer";
import * as THREE from "three";
import { getHikvision } from "@/api/index";
import { ref, defineProps, reactive } from "vue";
const props = defineProps({
threeAream: {
default: {},
},
});
console.log(props.threeAream, "报警数据");
//
const storeGroup = new THREE.Group();
//
const cameraGroup = new THREE.Group();
//
const goGroup = new THREE.Group();
//
const alarmGroup = new THREE.Group();
//
const smokeGroup = new THREE.Group();
//
const heatGroup = new THREE.Group();
//
const doorGroup = new THREE.Group();
const cameraIndexList = ref([]);
getHikvision({
path: "/artemis/api/resource/v1/cameras",
data: {
pageNo: 1,
pageSize: 1000,
},
}).then((res) => {
if (res.code == 0) {
cameraIndexList.value = res.result.data.list;
emit('openWebPlayer',cameraIndexList.value)
}
});
const emit = defineEmits(["openRealPlayer",'openWebPlayer']);
onMounted(() => {
init();
createCamera();
createRender();
createLight();
// console.log(requestAnimationFrame);
animate();
initIcon();
});
//,
window.addEventListener("resize", function () {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
// initIcon()
});
let scene;
let camera;
let renderer;
let mesh; //
let labelRenderer; //3d
let controls;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(
25,
window.innerWidth / window.innerHeight,
1,
10000
);
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
//
controls = new OrbitControls(camera, renderer.domElement);
// controls.maxPolarAngle = 20*Math.PI
controls.maxDistance = 1000;
controls.minDistance = 200;
// controls.minAzimuthAngle = 100 * Math.PI;
// controls.maxAzimuthAngle = 100 * Math.PI;
controls.minPolarAngle = 0;
controls.maxPolarAngle = (Math.PI / 4) * 2;
// controls.target = new THREE.Vector3(0, 350, -1800)
const emissiveColor = new THREE.Color(0xff0000);
const material = new THREE.MeshStandardMaterial({
color: 0xffffff, //
emissive: emissiveColor,
emissiveIntensity: 1, //
});
// function init() {
// const mtLoader = new MTLLoader()
// const loader = new OBJLoader()
// mtLoader.load('/model/YinFangShuJu_01.mtl', function (material) {
// console.log(material);
// material.preload()
// loader.setMaterials(material)
// //
// loader.load('/model/YinFangShuJu_01.obj', (loadMesh) => {
// mesh = loadMesh
// console.log(mesh);
// //
// scene.add(mesh)
// }, (xhr) => {
// if (xhr.lengthComputable) {
// const percentComplete = xhr.loaded / xhr.total * 100
// console.log(Math.round(percentComplete, 2) + '%')
// }
// })
// })
// }
function onEnter(event) {
let target = event.target; //
let classNames = target.classList; //
console.log(target);
// console.log(classNames);
// if (classNames.value == 'jiankong') {
// // console.log(target.children[0],'xxxxxx');
// target.children[0].innerHTML = ``
// }
// target.children[1].style.display = "block";
// target.children[0].style.display = "none";
// event.target.onmouseleave = function () {
// // console.log(event.target,'aaaa');
// target.children[1].style.display = "none";
// target.children[0].style.display = "block";
// };
//
target.children[0].onclick = function () {
for (let i = 0; i < cameraIndexList.value.length; i++) {
if (cameraIndexList.value[i].cameraName == target.children[0].innerText) {
emit("openRealPlayer", true, cameraIndexList.value[i].cameraIndexCode);
}
}
};
}
function init() {
const loader = new FBXLoader();
loader.load("model/YFSJ_Model.fbx", (fbx) => {
fbx.traverse(function (child) {
if (
(child.isMesh && child.name == "地面") ||
(child.isMesh && child.name == "新增地面")
) {
child.material = new THREE.MeshPhongMaterial({
color: new THREE.Color("#171d30"),
emissiveIntensity: 1,
});
} else if (child.isMesh && child.name == "路牙") {
child.material = new THREE.MeshPhongMaterial({
color: new THREE.Color("#b4babd"),
emissiveIntensity: 1,
});
}
});
console.log(fbx, "模型");
// fbx.children[21].material.emissiveIntensity = 1
// fbx.material = fbx.children[21].material
// console.log(fbx.children[21]);
fbx.scale.set(1, 1, 1);
// fbx.rotation.set(180,20,0)
fbx.position.set(0, 0, 0);
for (let i = 0; i < fbx.children.length; i++) {
if (fbx.children[i].children.length != 0) {
initIcon(fbx.children[i].children, fbx.children[i].name);
}
}
scene.add(fbx);
});
}
function createLight() {
//
const ambientLight = new THREE.AmbientLight(0xffffff, 10); //
scene.add(ambientLight); //
const spotLight = new THREE.SpotLight("#ffffff", 0.7); //
spotLight.position.set(1600, 1660, 200);
spotLight.castShadow = true;
scene.add(spotLight);
}
function createCamera() {
camera.position.set(-129, 449, 632);
camera.lookAt(scene.position);
controls.target.set(-146, -67, 37);
controls.update();
}
function createRender() {
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true; //
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setClearColor("#000000"); //
document.querySelector("#three3D").appendChild(renderer.domElement);
labelRenderer = new CSS3DRenderer();
console.log(labelRenderer, "渲染");
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = "absolute";
labelRenderer.domElement.style.top = 0;
// labelRenderer.domElement.style.left = 0;
labelRenderer.domElement.style.pointerEvents = "none";
labelRenderer.domElement.className = "allLabel";
document.querySelector("#three3D").appendChild(labelRenderer.domElement);
}
async function initIcon(pointList, type) {
let noStore = [
"新增地面",
"围墙2",
"围墙1",
"人行道",
"地面",
"马路",
"路牙",
"检测间围墙",
"地理式一体化消防泵站",
];
for (let i = 0; i < pointList.length; i++) {
if (type === "IP报警按钮") {
let initIconAble;
initIconAble = createLableObj(
pointList[i].name,
pointList[i].position,
`baojing.png`
);
pointList[i].visible = false;
alarmGroup.add(initIconAble);
alarmGroup.name = "报警主机";
initIconAble.visible = false;
scene.add(alarmGroup);
} else if (type.indexOf("摄像机") !== -1) {
let initIconAble;
initIconAble = createLableObj(
pointList[i].name,
pointList[i].position,
`jiankong.png`
);
pointList[i].visible = false;
cameraGroup.add(initIconAble);
cameraGroup.name = "监控点";
initIconAble.visible = false;
scene.add(cameraGroup);
} else if (type.indexOf("人脸门禁") !== -1) {
let initIconAble;
initIconAble = createLableObj(
pointList[i].name,
pointList[i].position,
`menjin.png`
);
pointList[i].visible = false;
doorGroup.add(initIconAble);
doorGroup.name = "人脸门禁一体机";
initIconAble.visible = false;
scene.add(doorGroup);
} else {
let initIconAble;
if (noStore.indexOf(pointList[i].name) === -1) {
initIconAble = createLableObj(
pointList[i].name,
pointList[i].position,
`store.png`
);
storeGroup.add(initIconAble);
storeGroup.name = "仓库";
scene.add(storeGroup);
}
}
}
}
var elements = [];
//
var pointLabel = [];
function createLableObj(text, vector, url, data) {
let label = url.split(".")[0];
let laberDiv = document.createElement("div");
pointLabel = new CSS3DObject(laberDiv);
pointLabel.name = text;
laberDiv.className = label;
if (label === "threeAream") {
laberDiv.innerHTML = `
<div style="background:url('/modelPng/${url}');width:226px;height:112px;background-size:100% 100%;padding-left:60px;box-sizing:border-box;">
<span style="width:100%;color:#fff;font-size:1rem;display:inline-block;margin-left:30px">${data.address}</span>
<span style="width:100%;color:#fff;font-size:1rem;display:inline-block;line-height:50px">${data.date}</span>
<span>
</span>
</div>
`;
} else {
laberDiv.innerHTML = `
<div class="box" style="display: flex;
justify-content: center;
flex-wrap: wrap;width:100px">
<div class='store_font' style=" overflow: hidden;text-overflow: ellipsis;white-space: nowrap;background-image:url('/modelPng/fontBg.png');line-height:32px;text-align: center;text-algin:center;min-width:100px;height:32px;background-size:100% 100%">
<span class='label-font' style='color:#fff;font-weight:bold'>${text}</span>
</div>
<div class='store_label' style="background-image:url('/modelPng/${url}');width:52px;height:72px;background-size:100% 100%">
</div>
</div>
`;
}
if (label === "jiankong") {
pointLabel.scale.set(0.15, 0.15, 0.15);
pointLabel.position.set(vector.x, 40, -vector.y);
pointLabel.element.addEventListener("mouseenter", onEnter);
} else if (label === "threeAream") {
pointLabel.scale.set(0.25, 0.25, 0.25);
pointLabel.position.set(vector.x + 28, 48, vector.z + 5);
} else {
pointLabel.scale.set(0.25, 0.25, 0.25);
pointLabel.position.set(vector.x, vector.z + 20, -vector.y);
}
return pointLabel;
}
//
let objLabel = [
"仓库",
"监控点",
"报警主机",
"水浸探测器",
"烟感探测器",
"温湿度探测器",
"人脸门禁一体机",
];
function clearLabelObj(name) {
// let dom =
for (let index = 0; index < scene.children.length; index++) {
if (scene.children[index].name == name) {
scene.children[index].traverse((obj) => {
obj.visible = true;
});
// scene.children[index].element.style.display = "none"
} else if (objLabel.indexOf(scene.children[index].name) != -1) {
scene.children[index].traverse((obj) => {
obj.visible = false;
});
}
}
animate();
// console.log(labelDiv);
}
function animate() {
// console.log(controls,'aaaaa');
controls.update();
//
// console.log(camera.position, "1111111111", controls.target);
requestAnimationFrame(animate);
renderer.render(scene, camera);
labelRenderer.render(scene, camera);
}
watch(
() => props.threeAream,
(newVal, oldVal) => {
setTimeout(() => {
let proLabel = scene.getObjectByName("threeAream");
if (proLabel) {
proLabel.parent.remove(proLabel);
}
cameraGroup.children.forEach((ele) => {
if (ele.name == newVal.address) {
console.log(ele.position);
let area = createLableObj(
"3d区域入侵报警",
ele.position,
"threeAream.png",
newVal
);
scene.add(area);
animate();
}
});
}, 1000);
},
{ deep: true, immediate: true }
);
defineExpose({
clearLabelObj,
scene,
});
</script>
<style scoped>
</style>

View File

@ -2,17 +2,36 @@
<div class="el-overlay">
<div class="box">
<div class="box-header">
<div class="box-title">库存消息</div>
<div class="box-title">{{ props.title }}</div>
<div class="box-btn" @click="close"></div>
</div>
<div class="box-content">
<el-table :data="list" style="width: 100%">
<div class="box-content-left">
<el-tree :props="treeProps" :load="loadNode" lazy>
<template v-slot="{ node }">
<span
@dblclick="playCamera(node)"
:title="node.label"
:class="node.leaf?'node-label':'node-label leaf'"
>{{ node.label }}</span
>
</template>
</el-tree>
</div>
<div class="box-content-right">
<iframe
id="realPlayer"
src="player/realPlayer.html"
frameborder="0"
></iframe>
</div>
<!-- <el-table :data="list" style="width: 100%">
<el-table-column prop="batchNum" label="批次号" width="180" />
<el-table-column prop="itemDesc" label="品牌" width="180" />
<el-table-column prop="inTime" label="入库时间" />
<el-table-column prop="weight" label="重量(kg)" />
<el-table-column prop="boxCount" label="箱数" />
</el-table>
</el-table> -->
</div>
</div>
</div>
@ -20,7 +39,22 @@
<script setup>
import { onMounted, ref } from "vue";
import getPath from "@/utils/getPath";
import { getHikvision } from "@/api/index";
const cameraIndexList = ref([]);
const emit = defineEmits(["close"]);
const props = defineProps({
title: {
type: String,
default: "",
},
});
const treeProps = {
label: "name",
children: "children",
isLeaf: "leaf",
};
const list = ref([
{
batchNum: "YXZZP2303001",
@ -30,14 +64,99 @@ const list = ref([
boxCount: "66",
},
]);
function close() {
emit("close", false);
}
async function loadNode(node, resolve, reject) {
if (node.level === 0) {
const node = await getHikvision({
path: "/artemis/api/resource/v1/regions/root",
data: {
pageNo: 1,
pageSize: 1000,
},
});
let nodeList = [];
nodeList.push(node.result.data);
// nodeList.forEach(el=>{
// el.cameraName = el.name
// })
resolve(nodeList);
} else if (node.level >= 1) {
//
const address = await getHikvision({
path: "/artemis/api/resource/v2/regions/subRegions",
data: {
pageNo: 1,
pageSize: 1000,
parentIndexCode: node.data.indexCode,
resourceType: "camera",
},
});
const nodeChildren = await getHikvision({
path: "/artemis/api/irds/v2/resource/subResources",
data: {
pageNo: 1,
pageSize: 1000,
regionIndexCode: node.data.indexCode,
resourceType: "camera",
},
});
nodeChildren.result.data.list.unshift(...address.result.data.list);
nodeChildren.result.data.list.forEach((el) => {
if (el.leaf) {
el.leaf = false;
} else {
el.leaf = true;
}
});
return resolve(nodeChildren.result.data.list);
}
}
//
function playCamera(node) {
let iframeRef = document.querySelector("#realPlayer");
// iframeRef.contentWindow.postMessage(node.data.cameraIndexCode,'*')
iframeRef.contentWindow.startPlay(node.data.indexCode);
}
onMounted(() => {
if (props.title === "视频监控") {
}
});
</script>
<style scoped lang="scss">
:deep(.el-tree) {
background-color: transparent !important;
color: #fff;
--el-tree-node-hover-bg-color: transparent !important;
width: vw(180) !important;
}
:deep(.el-tree .el-tree-node__content.is-checked) {
background-color: transparent !important;
}
:deep(.el-tree-node__content) {
// padding-left: vw(10) !important;
height: vh(32);
}
:deep(.el-tree-node__content:hover) {
background-image: url('@/assets/images/camera-bg.png');
background-size: 100% 100%;
// background-color: transparent !important;
// background-color: #fff !important;
}
:deep(.is-leaf:hover){
}
.node-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.box {
width: vw(1088);
height: vh(636);
@ -61,9 +180,27 @@ onMounted(() => {
line-height: vh(60);
}
&-content {
display: flex;
padding: vh(20) vw(20);
height: vh(636 - 60);
box-sizing: border-box;
justify-content: space-between;
&-left {
width: vw(180);
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
}
&-left::-webkit-scrollbar {
display: none;
}
&-right {
width: vw(1080 - 220);
iframe {
width: 100%;
height: 100%;
}
}
}
&-btn {
background-image: url("@/assets/images/close.png");
@ -75,49 +212,49 @@ onMounted(() => {
cursor: pointer;
}
}
:deep(.el-table__row--striped) {
background-image: none !important;
}
// :deep(tr.el-table__row td.el-table__cell) {
// background-color: rgba(174, 211, 255, 0.20) !important;
// :deep(.el-table__row--striped) {
// background-image: none !important;
// }
:deep(.el-table__inner-wrapper::before) {
background-color: transparent !important;
}
:deep(.el-table .el-table__cell) {
padding: 0;
}
:deep(.el-table .cell) {
height: 100%;
line-height: vh(48);
}
:deep(.el-table tr),
:deep(.el-table),
:deep(.el-table th),
:deep(.el-table td) {
background-color: transparent;
}
:deep(.el-table__row) {
height: vh(48);
}
:deep(.el-table) {
color: rgba(233, 244, 255, 1);
font-size: 0.8rem;
height: 100%;
--el-table-row-hover-bg-color: rgba(174, 211, 255, 0.2) !important;
}
:deep(.el-table thead) {
color: rgba(255, 255, 255, 1);
font-size: 0.8rem;
background-image: url("@/assets/images/dialog/table-thead.png");
line-height: vh(48);
font-weight: normal;
}
:deep(.el-table th.el-table__cell.is-leaf),
:deep(.el-table td.el-table__cell) {
border-color: transparent;
}
// // :deep(tr.el-table__row td.el-table__cell) {
// // background-color: rgba(174, 211, 255, 0.20) !important;
// // }
// :deep(.el-table__inner-wrapper::before) {
// background-color: transparent !important;
// }
// :deep(.el-table .el-table__cell) {
// padding: 0;
// }
// :deep(.el-table .cell) {
// height: 100%;
// line-height: vh(48);
// }
// :deep(.el-table tr),
// :deep(.el-table),
// :deep(.el-table th),
// :deep(.el-table td) {
// background-color: transparent;
// }
// :deep(.el-table__row) {
// height: vh(48);
// }
// :deep(.el-table) {
// color: rgba(233, 244, 255, 1);
// font-size: 0.8rem;
// height: 100%;
// --el-table-row-hover-bg-color: rgba(174, 211, 255, 0.2) !important;
// }
// :deep(.el-table thead) {
// color: rgba(255, 255, 255, 1);
// font-size: 0.8rem;
// background-image: url("@/assets/images/dialog/table-thead.png");
// line-height: vh(48);
// font-weight: normal;
// }
// :deep(.el-table th.el-table__cell.is-leaf),
// :deep(.el-table td.el-table__cell) {
// border-color: transparent;
// }
</style>

166
src/components/linkage.vue Normal file
View File

@ -0,0 +1,166 @@
<template>
<div class="el-overlay">
<div class="box">
<div class="box-header">
<div class="box-title">陌生人报警</div>
<div class="box-btn" @click="close"></div>
</div>
<div class="box-content">
<div class="linkage-left">
<img :src="linkageObj.url" alt="" />
</div>
<div class="linkage-right">
<div class="right-box">
<p><img :src="linkageObj.faceUrl" alt="" /></p>
<p class="p1"><i class="drop"></i>{{ linkageObj.eventTypeName }}</p>
<p class="p2"><i class="drop"></i>{{ linkageObj.address }}</p>
<p class="p3"><i class="drop"></i>{{ linkageObj.regionName }}</p>
<p class="p4"><i class="drop"></i>{{ linkageObj.startTime }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref, reactive ,watch} from "vue";
import getPath from "@/utils/getPath";
import { getHikvision } from "@/api/index";
import moment from "moment";
const cameraIndexList = ref([]);
const emit = defineEmits(["close"]);
const props = defineProps({
title: {
type: String,
default: "",
},
});
function close() {
emit("close", false);
}
const timer = ref(null);
const linkageObj = reactive({});
//
function getLinkageData() {
if (timer.value) {
clearTimeout(timer.value);
}
const historyDay = reactive({
startStamp: moment(
new Date().setHours(0, 0, 0, 0) - 24 * 60 * 60 * 1000 * 30
).format("YYYY-MM-DDTHH:mm:ss.SSSZ"),
endStamp: moment(
new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1
).format("YYYY-MM-DDTHH:mm:ss.SSSZ"),
});
getHikvision({
path: "/artemis/api/els/v1/events/search",
data: {
ability: "event_frs",
pageSize: 1,
pageNo: 1,
startTime: historyDay.startStamp,
endTime: historyDay.endStamp,
},
}).then((res) => {
if (res.result.data.list.length == 0) {
//
linkageShow.value = false;
}
if (res.code == 0 && res.result.data.list.length != 0) {
linkageObj.address = res.result.data.list[0].eventLogSrcList[0].resName;
linkageObj.startTime = res.result.data.list[0].startTime;
linkageObj.url = JSON.parse(
res.result.data.list[0].eventLogSrcList[0].data
).targetAttrs.bkgUrl;
linkageObj.faceUrl = JSON.parse(
res.result.data.list[0].eventLogSrcList[0].data
).faceRecognitionResult.snap.faceUrl;
linkageObj.eventTypeName = res.result.data.list[0].eventTypeName;
linkageObj.regionName =
res.result.data.list[0].eventLogSrcList[0].regionName;
}
});
timer.value = setTimeout(() => {
getLinkageData();
}, 7000);
}
watch(
() => linkageObj.url,
(newVal, oldVal) => {
if (newVal) {
emit("open", true);
}
},
{ deep: true }
);
onMounted(() => {
getLinkageData();
});
</script>
<style scoped lang="scss">
.box {
width: vw(626);
height: vh(424);
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
background-image: url("@/assets/images/dialog-bg.png");
background-size: 100% 100%;
&-header {
width: 100%;
height: vh(40);
font-family: "pangmen";
display: flex;
font-size: 1.3rem;
justify-content: center;
}
&-title {
line-height: vh(40);
}
&-content {
display: flex;
padding: vh(10) vw(10);
height: vh(424 - 40);
box-sizing: border-box;
justify-content: space-between;
}
&-btn {
background-image: url("@/assets/images/close.png");
width: vw(24);
height: vh(24);
background-size: 100% 100%;
position: absolute;
right: vw(20);
top: vh(7);
cursor: pointer;
}
}
.linkage {
&-left {
width: 50%;
height: 100%;
img {
width: 100%;
height: 100%;
}
}
&-right {
width: 47%;
img {
width: vw(128);
height: vh(168);
}
.p1,
.p2,
.p3,
.p4 {
line-height: vh(45);
}
}
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="nav">
<div class="nav-font">xxx部队厂房一张图</div>
<div class="nav-font">中国人民解放军73106部队</div>
</div>
</template>
<script setup>
@ -21,7 +21,7 @@
text-align: center;
background-image: url("@/assets/images/header.png");
&-font {
font-size: 2.75rem;
font-size: 2.5rem;
margin-top: 1rem;
}
}

103
src/components/player.vue Normal file
View File

@ -0,0 +1,103 @@
<template>
<div class="el-overlay">
<div class="box">
<div class="box-header">
<div class="box-title">{{ props.title }}</div>
<div class="box-btn" @click="close"></div>
</div>
<div class="box-content">
<iframe
id="realPlayer"
src="player/player_preview.html"
frameborder="0"
></iframe>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import getPath from "@/utils/getPath";
const emit = defineEmits(["close"]);
const props = defineProps({
videoList: {
default: null,
},
title: {
default: "",
},
});
function close() {
emit("close", false);
}
onMounted(() => {
let iframeRef = document.querySelector("#realPlayer");
let iframeParent = document.querySelector(".box");
if (props.title == "实时视频") {
if (iframeRef) {
iframeRef.src = "player/player_preview.html";
iframeRef.onload = function () {
iframeRef.contentWindow.postMessage(
{
iframeOffset: {
// iframe
left: iframeParent.style.margin,
top: iframeParent.style.margin,
},
cameraIndex: props.videoList.indexCode,
},
"*"
);
};
}
}else {
iframeRef.src = "player/playback.html?src="+props.videoList;
}
});
</script>
<style lang="scss" scoped>
.box {
width: vw(1088);
height: vh(636);
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
background-image: url("@/assets/images/dialog-bg.png");
background-size: 100% 100%;
&-header {
width: 100%;
height: vh(60);
font-family: pangmen;
display: flex;
font-size: 1.875rem;
justify-content: center;
}
&-title {
line-height: vh(60);
}
&-content {
// padding: vh(20) vw(20);
height: vh(636 - 60);
box-sizing: border-box;
iframe {
width: 100%;
height: 100%;
}
}
&-btn {
background-image: url("@/assets/images/close.png");
width: vw(34);
height: vh(34);
position: absolute;
right: vw(20);
top: vh(12);
cursor: pointer;
}
}
</style>

105
src/components/record.vue Normal file
View File

@ -0,0 +1,105 @@
<template>
<!-- 钥匙柜记录 -->
<div class="el-overlay" style="display:none">
<div class="box">
<div class="box-header">
<div class="box-title">取还记录</div>
<div class="box-btn" @click="close"></div>
</div>
<div class="box-content">
<el-table :data="recordList" :row-class-name="tableRowClassName" style="width: 100%">
<el-table-column prop="userName" label="用户姓名" />
<el-table-column prop="keyCapturing" label="钥匙编号" align="center"/>
<el-table-column prop="keyState" label="存取状态" align="center"/>
<el-table-column prop="accessDate" label="上报时间" align="right" />
</el-table>
</div>
</div>
</div>
</template>
<script setup>
import {ref,reactive,onMounted} from 'vue';
const recordList = ref([
{
userName:'张三',
keyState:'取走',
accessDate:'2024-11-21',
keyCapturing:'1'
},
{
userName:'李四',
keyState:'取走',
accessDate:'2024-11-21',
keyCapturing:'2'
},
{
userName:'王五',
keyState:'取走',
accessDate:'2024-11-21',
keyCapturing:'3'
},
])
function tableRowClassName({row,rowIndex}){
if(rowIndex % 2 === 0){
return 'even-row'
}else{
return 'odd-row'
}
}
</script>
<style scoped lang='scss'>
:deep(.even-row){
background-image: url('@/assets/images/tableRow1.png');
background-size: 100% 100%;
}
:deep(.odd-row){
background-image: url('@/assets/images/tableRow2.png');
background-size: 100% 100%;
}
.box {
width: vw(720);
height: vh(520);
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
background-image: url("@/assets/images/record-bg.png");
background-size: 100% 100%;
&-header {
width: 100%;
height: vh(60);
font-family: "pangmen";
display: flex;
font-size: 1.875rem;
justify-content: center;
}
&-title {
line-height: vh(60);
}
&-content {
display: flex;
padding: vh(10) vw(20);
height: vh(520 - 60);
box-sizing: border-box;
justify-content: space-between;
}
&-btn {
background-image: url("@/assets/images/close.png");
width: vw(34);
height: vh(34);
position: absolute;
right: vw(20);
top: vh(12);
cursor: pointer;
}
:deep(.el-table thead) {
color: rgba(233, 244, 255, 1);
font-size: 0.8rem;
background-image: none;
line-height: vh(48);
font-weight: normal;
}
}
</style>

View File

@ -1,11 +1,11 @@
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from "./router/router.js"
import bigScreenFit from '@enhances/bigscreen-fit-vue3';
const app =createApp(App)
app.use(bigScreenFit, {
compress: false, // 不压缩
}).use(ElementPlus).use(router).mount('#app')
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from "./router/router.js"
import bigScreenFit from '@enhances/bigscreen-fit-vue3';
const app =createApp(App)
app.use(bigScreenFit, {
compress: false, // 不压缩
}).use(ElementPlus).use(router).mount('#app')

View File

@ -18,4 +18,36 @@
position: fixed;
top: 0;
right: 0;
}
//公共小圆点
.drop {
margin-right: 0.5rem;
width: 0.8rem;
display: inline-block;
height: 0.8rem;
background-image: url("@/assets/images/drop.png");
}
.box1{
background-size: 100% 100%;
padding-bottom:vh(16);
margin-bottom: vh(20);
background-image: url("@/assets/images/box/box1.png");
}
.box2{
padding-bottom:vh(16);
background-size: 100% 100%;
background-image: url("@/assets/images/box/box2.png");
}
.box3{
background-size: 100% 100%;
background-image: url("@/assets/images/box/box3.png");
}
.box4{
background-size: 100% 100%;
background-image: url("@/assets/images/box/box4.png");
}
.box5{
background-size: 100% 100%;
padding-bottom:vh(16);
background-image: url("@/assets/images/box/box5.png");
}

274
src/utils/protocolcheck.js Normal file
View File

@ -0,0 +1,274 @@
(function (f) {
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f();
} else if (typeof define === "function" && define.amd) {
define([], f);
} else {
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
g = this;
}
g.protocolCheck = f();
}
})(function () {
var define, module, exports;
return (function e(t, n, r) {
function s(o, u) {
if (!n[o]) {
if (!t[o]) {
var a = typeof require == "function" && require;
if (!u && a) return a(o, !0);
if (i) return i(o, !0);
var f = new Error("Cannot find module '" + o + "'");
throw ((f.code = "MODULE_NOT_FOUND"), f);
}
var l = (n[o] = { exports: {} });
t[o][0].call(
l.exports,
function (e) {
var n = t[o][1][e];
return s(n ? n : e);
},
l,
l.exports,
e,
t,
n,
r
);
}
return n[o].exports;
}
var i = typeof require == "function" && require;
for (var o = 0; o < r.length; o++) s(r[o]);
return s;
})(
{
1: [
function (require, module, exports) {
function _registerEvent(target, eventType, cb) {
if (target.addEventListener) {
target.addEventListener(eventType, cb);
return {
remove: function () {
target.removeEventListener(eventType, cb);
},
};
} else {
target.attachEvent(eventType, cb);
return {
remove: function () {
target.detachEvent(eventType, cb);
},
};
}
}
function _createHiddenIframe(target, uri) {
var iframe = document.createElement("iframe");
iframe.src = uri;
iframe.id = "hiddenIframe";
iframe.style.display = "none";
target.appendChild(iframe);
return iframe;
}
function openUriWithHiddenFrame(uri, failCb, successCb) {
var timeout = setTimeout(function () {
failCb();
handler.remove();
}, 1000);
var iframe = document.querySelector("#hiddenIframe");
if (!iframe) {
iframe = _createHiddenIframe(document.body, "about:blank");
}
var handler = _registerEvent(window, "blur", onBlur);
function onBlur() {
clearTimeout(timeout);
handler.remove();
successCb();
}
iframe.contentWindow.location.href = uri;
}
function openUriWithTimeoutHack(uri, failCb, successCb) {
var timeout = setTimeout(function () {
failCb();
handler.remove();
}, 1000);
//handle page running in an iframe (blur must be registered with top level window)
var target = window;
while (target != target.parent) {
target = target.parent;
}
var handler = _registerEvent(target, "blur", onBlur);
function onBlur() {
clearTimeout(timeout);
handler.remove();
successCb();
}
window.location = uri;
}
function openUriUsingFirefox(uri, failCb, successCb) {
var iframe = document.querySelector("#hiddenIframe");
if (!iframe) {
iframe = _createHiddenIframe(document.body, "about:blank");
}
try {
iframe.contentWindow.location.href = uri;
successCb();
} catch (e) {
if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
failCb();
}
}
}
function openUriUsingIEInOlderWindows(uri, failCb, successCb) {
if (getInternetExplorerVersion() === 10) {
openUriUsingIE10InWindows7(uri, failCb, successCb);
} else if (
getInternetExplorerVersion() === 9 ||
getInternetExplorerVersion() === 11
) {
openUriWithHiddenFrame(uri, failCb, successCb);
} else {
openUriInNewWindowHack(uri, failCb, successCb);
}
}
function openUriUsingIE10InWindows7(uri, failCb, successCb) {
var timeout = setTimeout(failCb, 1000);
window.addEventListener("blur", function () {
clearTimeout(timeout);
successCb();
});
var iframe = document.querySelector("#hiddenIframe");
if (!iframe) {
iframe = _createHiddenIframe(document.body, "about:blank");
}
try {
iframe.contentWindow.location.href = uri;
} catch (e) {
failCb();
clearTimeout(timeout);
}
}
function openUriInNewWindowHack(uri, failCb, successCb) {
var myWindow = window.open("", "", "width=0,height=0");
myWindow.document.write("<iframe src='" + uri + "'></iframe>");
setTimeout(function () {
try {
myWindow.location.href;
myWindow.setTimeout("window.close()", 1000);
successCb();
} catch (e) {
myWindow.close();
failCb();
}
}, 1000);
}
function openUriWithMsLaunchUri(uri, failCb, successCb) {
navigator.msLaunchUri(uri, successCb, failCb);
}
function checkBrowser() {
var isOpera =
!!window.opera || navigator.userAgent.indexOf(" OPR/") >= 0;
var ua = navigator.userAgent.toLowerCase();
return {
isOpera: isOpera,
isFirefox: typeof InstallTrigger !== "undefined",
isSafari:
(~ua.indexOf("safari") && !~ua.indexOf("chrome")) ||
Object.prototype.toString
.call(window.HTMLElement)
.indexOf("Constructor") > 0,
isIOS:
/iPad|iPhone|iPod/.test(navigator.userAgent) &&
!window.MSStream,
isChrome: !!window.chrome && !isOpera,
isIE: /*@cc_on!@*/ false || !!document.documentMode, // At least IE6
};
}
function getInternetExplorerVersion() {
var rv = -1;
if (navigator.appName === "Microsoft Internet Explorer") {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");
if (re.exec(ua) != null) rv = parseFloat(RegExp.$1);
} else if (navigator.appName === "Netscape") {
var ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat(RegExp.$1);
}
}
return rv;
}
module.exports = function (uri, failCb, successCb, unsupportedCb) {
function failCallback() {
failCb && failCb();
}
function successCallback() {
successCb && successCb();
}
if (navigator.msLaunchUri) {
//for IE and Edge in Win 8 and Win 10
openUriWithMsLaunchUri(uri, failCb, successCb);
} else {
var browser = checkBrowser();
if (browser.isFirefox) {
openUriUsingFirefox(uri, failCallback, successCallback);
} else if (browser.isChrome || browser.isIOS) {
openUriWithTimeoutHack(uri, failCallback, successCallback);
} else if (browser.isIE) {
openUriUsingIEInOlderWindows(
uri,
failCallback,
successCallback
);
} else if (browser.isSafari) {
openUriWithHiddenFrame(uri, failCallback, successCallback);
} else {
unsupportedCb();
//not supported, implement please
}
}
};
},
{},
],
},
{},
[1]
)(1);
});

40
src/utils/request.js Normal file
View File

@ -0,0 +1,40 @@
import axios from "axios"
const request = axios.create({
// baseURL: HOST,
// baseURL:"http://192.168.3.13:12307",
// baseURL: "http://192.168.3.13:8048",
// 超时时间
timeout: 10000
})
// 请求拦截器
request.interceptors.request.use(config => {
// console.log(config);
let url = config.url
if (config.method === 'get' && config.params) {
url += '?' // 拼接参数
// 获取所有参数,通过循环 拼接所有参数encodeURIComponent对参数编码
Object.keys(config.params).map(key => {
// console.log(key,'请求拦截');
url += `${key}=${encodeURIComponent(config.params[key])}&`
// url += `${key}=${config.params[key].replace(' ','%20')}&`
})
url = url.substring(0, url.length - 1) // 删除最后一个&字符
config.params = {} // 参数已经存在于 url中
}
config.url = url
// config.headers.token = store.state.user.token;
return config;
}, error => {
console.log(error);
});
//响应拦截器
request.interceptors.response.use(res => {
return res.data;
}, error => {
console.log(error);
})
export default request;

26
src/utils/tool.js Normal file
View File

@ -0,0 +1,26 @@
import moment from "moment";
export function getTime(name, date) {
if (name == "日期") {
// console.log(addDate.value);
return moment(date).format("YYYY/MM/DD");
} else if (name == "时间") {
return moment(date).format("HH:mm:ss");
} else {
let day = moment(date).format("dddd");
if (day == "Monday") {
return "星期一";
} else if (day == "Tuesday") {
return "星期二";
} else if (day == "Wednesday") {
return "星期三";
} else if (day == "Thursday") {
return "星期四";
} else if (day == "Friday") {
return "星期五";
} else if (day == "Saturday") {
return "星期六";
} else if (day == "Sunday") {
return "星期天";
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,173 +1,176 @@
<script setup>
import { ElMessage } from 'element-plus'
import {ref,reactive,onMounted} from 'vue'
import {useRouter} from "vue-router";
import { ElMessage } from "element-plus";
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { login } from "@/api/index";
const ruleForm = reactive({
user:'',
password:''
})
const router = useRouter()
login_name: "",
password: "",
});
const router = useRouter();
const rules = reactive({
//
user: [{ required: true, message: "请输入用户名", trigger: "blur" }],
login_name: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
});
const ruleFormRef = ref()
const passwordCheck = ref(false)
function submitForm(elForm){
if(!elForm) return
elForm.validate((valid)=>{
if(valid){
if(passwordCheck.value){
localStorage.setItem('loginInfo',JSON.stringify(ruleForm))
}else{
localStorage.setItem('loginInfo',JSON.stringify({}))
const ruleFormRef = ref();
const passwordCheck = ref(false);
function submitForm(elForm) {
if (!elForm) return;
elForm.validate((valid) => {
if (valid) {
if (passwordCheck.value) {
localStorage.setItem("loginInfo", JSON.stringify(ruleForm));
} else {
localStorage.setItem("loginInfo", JSON.stringify({}));
}
ElMessage({
message:'登录成功',
type:"success"
})
login(ruleForm).then((res) => {
if (res.code == 0) {
ElMessage({
message: "登录成功",
type: "success",
});
router.push('/home')
} else {
ElMessage({
message: "登录失败",
type: "error",
});
}
});
router.push('/home')
}else{
ElMessage({
message:'登录失败',
type:"error"
})
}
})
});
}
//
function checkSavePassword(){
let loginInfo = localStorage.getItem('loginInfo')
console.log(loginInfo,'xxxxxxxxxxxx')
if(loginInfo!==null&&Object.keys(loginInfo).length > 2){
console.log(loginInfo)
ruleForm.user = JSON.parse(loginInfo).user
ruleForm.password = JSON.parse(loginInfo).password
passwordCheck.value = true
}else{
passwordCheck.value = false
function checkSavePassword() {
let loginInfo = localStorage.getItem("loginInfo");
if (loginInfo !== null && Object.keys(loginInfo).length > 2) {
console.log(loginInfo);
ruleForm.login_name = JSON.parse(loginInfo).login_name;
ruleForm.password = JSON.parse(loginInfo).password;
passwordCheck.value = true;
} else {
passwordCheck.value = false;
}
}
onMounted(()=>{
onMounted(() => {
//
checkSavePassword()
})
checkSavePassword();
});
</script>
<template>
<div class="login-bg">
<div class="login-form">
<div class="login-form-title">
欢迎登录
</div>
<el-form
<div class="login-bg">
<div class="login-form">
<div class="login-form-title">欢迎登录</div>
<el-form
ref="ruleFormRef"
:model="ruleForm"
status-icon
class="demo-ruleForm"
:rules="rules"
>
<el-form-item prop="user">
<el-input v-model="ruleForm.user" type="text" placeholder="请输入用户名" >
<!-- <template #prepend>-->
<!-- <div class="user-icon">-->
>
<el-form-item prop="login_name">
<el-input
v-model="ruleForm.login_name"
type="text"
placeholder="请输入用户名"
>
<!-- <template #prepend>-->
<!-- <div class="user-icon">-->
<!-- </div>-->
<!-- </template>-->
<template #prefix>
<i class="user-icon"></i>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
<!-- </div>-->
<!-- </template>-->
<template #prefix>
<i class="user-icon"></i>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="ruleForm.password"
type="password"
placeholder="请输入密码"
>
<!-- <template #prepend>-->
<!-- <div class="password-icon">-->
>
<!-- <template #prepend>-->
<!-- <div class="password-icon">-->
<!-- </div>-->
<!-- </template>-->
<template #prefix>
<i class="password-icon"></i>
</template>
</el-input>
</el-form-item>
<el-form-item>
<div>
<el-checkbox v-model="passwordCheck" label="保存密码" />
</div>
<div class="submit" @click="submitForm(ruleFormRef)">
</div>
</el-form-item>
</el-form>
<!-- </div>-->
<!-- </template>-->
<template #prefix>
<i class="password-icon"></i>
</template>
</el-input>
</el-form-item>
<el-form-item>
<div>
<el-checkbox v-model="passwordCheck" label="保存密码" />
</div>
<div class="submit" @click="submitForm(ruleFormRef)"></div>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
//
.submit{
.submit {
cursor: pointer;
background-image: url('@/assets/images/submit.png');
background-image: url("@/assets/images/submit.png");
width: 100%;
height: 100%;
background-size: 100% 100%;
}
.login-bg{
.login-bg {
width: 100%;
height: 100%;
background-image: url('@/assets/images/login-bg.png');
background-image: url("@/assets/images/login-bg.png");
background-size: 100% 100%;
}
.user-icon,.password-icon{
.user-icon,
.password-icon {
width: 100%;
display: block;
height: 100%;
background-size: 100% 100%;
}
:deep(.el-input__prefix){
:deep(.el-input__prefix) {
width: 15%;
height: 100%;
}
.user-icon{
background-image: url('@/assets/images/user.png');
.user-icon {
background-image: url("@/assets/images/user.png");
}
.password-icon{
background-image: url('@/assets/images/password.png');
.password-icon {
background-image: url("@/assets/images/password.png");
}
:deep(.el-input__prefix-inner){
:deep(.el-input__prefix-inner) {
width: 100%;
height: 100%;
}
:deep(.el-input__wrapper){
:deep(.el-input__wrapper) {
background-color: transparent;
padding-left: 1px;
box-shadow: 0 0 0 0px var(--el-input-border-color,var(--el-border-color)) inset;
box-shadow: 0 0 0 0px var(--el-input-border-color, var(--el-border-color))
inset;
cursor: default;
}
.el-input__inner{
.el-input__inner {
cursor: default !important;
}
:deep(.el-input){
:deep(.el-input) {
width: 100%;
height: 100%;
background-image: url('@/assets/images/el-input.png');
background-image: url("@/assets/images/el-input.png");
background-size: 100% 100%;
}
:deep(.el-checkbox__label){
:deep(.el-checkbox__label) {
color: rgba(233, 244, 255, 1);
}
:deep(.el-form-item) {
@ -177,7 +180,7 @@ onMounted(()=>{
width: 100%;
height: 100%;
}
.login-form{
.login-form {
width: vw(600);
height: vh(400);
padding: 0 6.25rem;
@ -188,16 +191,16 @@ onMounted(()=>{
right: 0;
left: 0;
margin: auto;
background-image: url('@/assets/images/login-form.png');
background-image: url("@/assets/images/login-form.png");
background-size: 100% 100%;
&-title{
&-title {
letter-spacing: 3px;
text-shadow: 0px 0px 7px #129DFF;
text-shadow: 0px 0px 7px #129dff;
font-size: 1.875rem;
font-weight: 400;
font-family: pangmen;
text-align: center;
margin:3.125rem 0 2.25rem 0;
margin: 3.125rem 0 2.25rem 0;
}
}
</style>

View File

@ -1,41 +1,48 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
define: {
'process.env': process.env
},
resolve: {
// 配置路径别名
alias: {
'@': path.resolve(__dirname, './src'),
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
},
// vite 相关配置
server: {
port: 8801,
host: true,
open: true,
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
target: 'http://172.16.1.134:8021/',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
}
}
},
// 全局配置scss方法
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/assets/scss/common.scss";`,
},
},
},
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
publicPath: '/',
plugins: [vue()],
define: {
'process.env': process.env
},
resolve: {
// 配置路径别名
alias: {
'@': path.resolve(__dirname, './src'),
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
},
// vite 相关配置
server: {
// https: true,
port: 3001,
host: true,
open: true,
cors:true,
proxy: {
'/api': { //apiTest是自行设置的请求前缀按照这个来匹配请求有这个字段的请求就会进到代理来
target: 'http://127.0.0.1:12307/',
changeOrigin: true, //是否跨域
rewrite: (path) => path.replace('/api', '')
},
'/aps': {
target: 'http://192.168.17.4:8001/',
changeOrigin: true, //是否跨域
rewrite: (path) => path.replace('/aps', '')
}
}
},
// 全局配置scss方法
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/assets/scss/common.scss";`,
},
},
},
})