施工管控前端页面

This commit is contained in:
pengyb 2024-08-13 13:59:43 +08:00
parent b40e203465
commit 5e2a0847e3
36 changed files with 51515 additions and 3 deletions

View File

@ -36,6 +36,7 @@
"url": "http://192.168.0.56:3000/bonus/Bonus-Cloud.git"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0",
"clipboard": "2.0.8",
@ -46,6 +47,7 @@
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"html2canvas": "^1.4.1",
"jquery": "^3.7.1",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
@ -57,10 +59,11 @@
"screenfull": "5.0.2",
"sortablejs": "1.10.2",
"vue": "2.6.12",
"vue-baidu-map": "^0.21.22",
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
"vue-meta": "2.4.0",
"vue-router": "3.4.9",
"vue-router": "^3.5.2",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

BIN
src/assets/images/test.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

1916
src/assets/styles/video-7.19.1-js.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -37,6 +37,8 @@ import DictTag from '@/components/DictTag'
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
//百度地图组件
import BaiduMap from 'vue-baidu-map'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
@ -61,6 +63,9 @@ Vue.component('ImagePreview', ImagePreview)
Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta)
Vue.use(BaiduMap, {
ak: '' //w9lkX7HeUlFoQRUX74F1RV2uckOQpmnA
})
DictData.install()
/**

View File

@ -6,12 +6,12 @@ const cbc_iv = CryptoJS.enc.Utf8.parse('1234567812345678')
* 默认参数需要加密
* @type {boolean}
*/
const jia_mi=false;
const jia_mi=true;
/**
* 默认后台会自动加密
* @type {boolean}
*/
const jie_mi=false;
const jie_mi=true;
/**
* 加密
* @param word

10991
src/utils/jquery-3.6.0.js vendored Normal file

File diff suppressed because it is too large Load Diff

77
src/utils/video/FileSaver.min.js vendored Normal file
View File

@ -0,0 +1,77 @@
(function (a, b) {
if ("function" == typeof define && define.amd) define([], b); else if ("undefined" != typeof exports) b(); else {
b(), a.FileSaver = {exports: {}}.exports
}
})(this, function () {
"use strict";
function b(a, b) {
return "undefined" == typeof b ? b = {autoBom: !1} : "object" != typeof b && (console.warn("Deprecated: Expected third argument to be a object"), b = {autoBom: !b}), b.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type) ? new Blob(["\uFEFF", a], {type: a.type}) : a
}
function c(a, b, c) {
var d = new XMLHttpRequest;
d.open("GET", a), d.responseType = "blob", d.onload = function () {
g(d.response, b, c)
}, d.onerror = function () {
console.error("could not download file")
}, d.send()
}
function d(a) {
var b = new XMLHttpRequest;
b.open("HEAD", a, !1);
try {
b.send()
} catch (a) {
}
return 200 <= b.status && 299 >= b.status
}
function e(a) {
try {
a.dispatchEvent(new MouseEvent("click"))
} catch (c) {
var b = document.createEvent("MouseEvents");
b.initMouseEvent("click", !0, !0, window, 0, 0, 0, 80, 20, !1, !1, !1, !1, 0, null), a.dispatchEvent(b)
}
}
var f = "object" == typeof window && window.window === window ? window : "object" == typeof self && self.self === self ? self : "object" == typeof global && global.global === global ? global : void 0,
a = f.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent),
g = f.saveAs || ("object" != typeof window || window !== f ? function () {
} : "download" in HTMLAnchorElement.prototype && !a ? function (b, g, h) {
var i = f.URL || f.webkitURL, j = document.createElement("a");
g = g || b.name || "download", j.download = g, j.rel = "noopener", "string" == typeof b ? (j.href = b, j.origin === location.origin ? e(j) : d(j.href) ? c(b, g, h) : e(j, j.target = "_blank")) : (j.href = i.createObjectURL(b), setTimeout(function () {
i.revokeObjectURL(j.href)
}, 4E4), setTimeout(function () {
e(j)
}, 0))
} : "msSaveOrOpenBlob" in navigator ? function (f, g, h) {
if (g = g || f.name || "download", "string" != typeof f) navigator.msSaveOrOpenBlob(b(f, h), g); else if (d(f)) c(f, g, h); else {
var i = document.createElement("a");
i.href = f, i.target = "_blank", setTimeout(function () {
e(i)
})
}
} : function (b, d, e, g) {
if (g = g || open("", "_blank"), g && (g.document.title = g.document.body.innerText = "downloading..."), "string" == typeof b) return c(b, d, e);
var h = "application/octet-stream" === b.type, i = /constructor/i.test(f.HTMLElement) || f.safari,
j = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((j || h && i || a) && "undefined" != typeof FileReader) {
var k = new FileReader;
k.onloadend = function () {
var a = k.result;
a = j ? a : a.replace(/^data:[^;]*;/, "data:attachment/file;"), g ? g.location.href = a : location = a, g = null
}, k.readAsDataURL(b)
} else {
var l = f.URL || f.webkitURL, m = l.createObjectURL(b);
g ? g.location = m : location.href = m, g = null, setTimeout(function () {
l.revokeObjectURL(m)
}, 4E4)
}
});
f.saveAs = g.saveAs = g, "undefined" != typeof module && (module.exports = g)
});
//# sourceMappingURL=FileSaver.min.js.map

13131
src/utils/video/flv.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
/**
* This file includes the required ext-all js and css files based upon "theme" and "rtl"
* url parameters. It first searches for these parameters on the page url, and if they
* are not found there, it looks for them on the script tag src query string.
* For example, to include the neptune flavor of ext from an index page in a subdirectory
* of extjs/examples/:
* <script type="text/javascript" src="../../examples/shared/include-ext.js?theme=neptune"></script>
*/
(function() {
// load css
var theme = 'metro';
var css_array = new Array();
var t= new Date().getTime();
// load cu js
var js_array = new Array();
var scriptObjects = document.getElementsByTagName("script");
for(var i = 0;i < scriptObjects.length;i++)
{
var s = scriptObjects[i];
if(s.src && s.src.match(/include\.js(\?.*)?$/)){
var path = s.src.replace(/js\/include\.js(\?.*)?$/,'');
var type = s.src.match(/\?type=([a-z,]*)/);
{
js_array =[
'js/utility/json2.js',
'js/utility/easyui/jquery.min.js',
'js/utility/easyui/jquery.easyui.min.js',
'js/utility/easyui/jquery.xml2json.js',
'js/utility/easyui/locale/easyui-lang-zh_CN.js',
'js/utility/jquery.fullscreen-min.js',
];
}
break;
}
}
css_array = css_array.concat([
"js/utility/easyui/themes/"+theme+"/easyui.css",
"js/utility/easyui/themes/icon.css",
"js/utility/easyui/themes/color.css"
// "demo.css"
]);
for(var j = 0;j < css_array.length;j++)
{
document.write('<link rel="stylesheet" type="text/css" href="'+css_array[j]+'?t='+t+'" />');
};
for(var j = 0;j < js_array.length;j++)
{
if(js_array[j].indexOf("?") > 0){
document.write('<script type="text/javascript" src="'+js_array[j]+'&t='+t+'"></script>');
}else{
document.write('<script type="text/javascript" src="'+js_array[j]+'?t='+t+'"></script>');
}
};
})();

346
src/utils/video/talk.js Normal file
View File

@ -0,0 +1,346 @@
(function(window) {
//兼容
window.URL = window.URL || window.webkitURL;
//请求麦克风
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
var recorder = {};
var dtcWs = {};
var cb = {};
var Recorder = function(stream, config, name) {
config = config || {};
config.sampleBits = config.sampleBits || 16; //输出采样数位 8, 16
config.sampleRate = config.sampleRate || (8000); //输出采样率(1/6 48000)
// 音频上下文对象可创建不同的AudioNode
var context = new AudioContext();
//将声音输入这个对像
var audioInput = context.createMediaStreamSource(stream);
//设置音量节点
// var volume = context.createGain();
// audioInput.connect(volume);
var recorder = context.createScriptProcessor(4096, 1, 1);
var audioData = {
size: 0 //录音文件长度
,
buffer: [] //录音缓存
,
inputSampleRate: context.sampleRate //输入采样率
,
inputSampleBits: 16 //输入采样数位 8, 16
,
outputSampleRate: config.sampleRate,
oututSampleBits: config.sampleBits,
clear: function() {
this.buffer = [];
this.size = 0;
}
/**
* @param {!Float32Array} data
*/
,
input: function(data) {
this.buffer.push(new Float32Array(data));
this.size += data.length;
},
compress: function() { //合并压缩
//合并
var data = new Float32Array(this.size);
var offset = 0;
for (var i = 0; i < this.buffer.length; i++) {
data.set(this.buffer[i], offset);
offset += this.buffer[i].length;
}
//压缩
var compression = parseInt(this.inputSampleRate / this.outputSampleRate);
var length = data.length / compression;
var result = new Float32Array(length);
var index = 0,
j = 0;
while (index < length) {
result[index] = data[j];
j += compression;
index++;
}
return result;
},
floatTo16BitPCM: function(input, output) {
for (var i = 0; i < input.length; i++) {
var s = Math.max(-1, Math.min(1, input[i]));
output[i] = (s < 0 ? s * 0x8000 : s * 0x7FFF);
}
},
convertBuffer: function() {
var bytes = this.compress();
//console.log(bytes);
var data = new Float32Array(bytes);
var out = new Int16Array(bytes.length);
this.floatTo16BitPCM(data, out);
return out;
},
encodePCM: function() {
// PCM
var bytes = this.convertBuffer();
var data = new DataView(bytes.buffer);
return data;
},
encodeG711A: function() { //转G711A
// G711A
var smaples = this.convertBuffer();
var g7111aBuf = alawmulaw.alaw.encode(smaples);
return g7111aBuf;
},
encodeG711aBuffer: function() {
// DataView
var smaples = this.convertBuffer();
var g7111aBuf = alawmulaw.alaw.encode(smaples);
var data = new DataView(g7111aBuf.buffer);
return data;
}
};
//开始录音
this.start = function() {
audioInput.connect(recorder);
recorder.connect(context.destination);
};
//停止
this.stop = function() {
audioInput.disconnect();
recorder.disconnect();
};
this.getData = function() {
return audioData.encodeG711A();
};
//回放
this.play = function(audio) {
audio.src = window.URL.createObjectURL(this.getBlob());
};
//获取音频文件
this.getBuffer = function() {
//return audioData.encodePCM();
return audioData.encodeG711aBuffer();
};
//清空缓存
this.clear = function() {
audioData.clear();
};
//音频采集
var that = this;
recorder.onaudioprocess = function(e) {
audioData.input(e.inputBuffer.getChannelData(0));
var data = that.getData();
// getG711A(data);
if (dtcWs[name]) {
dtcWs[name].send(data);
};
that.clear();
};
};
//抛出异常
Recorder.throwError = function(message) {
throw new function() { this.toString = function() { console.log(message) }; };
};
//是否支持录音
Recorder.canRecording = (navigator.getUserMedia != null);
//获取录音机
Recorder.get = function(callback, config, name) {
if (callback) {
if (navigator.getUserMedia) {
navigator.getUserMedia({ audio: true } //只启用音频
,
function(stream) {
var rec = new Recorder(stream, config, name);
callback(rec);
},
function(error) {
switch (error.code || error.name) {
case 'PERMISSION_DENIED':
case 'PermissionDeniedError':
STRecorder.throwErr('用户拒绝提供信息。');
break;
case 'NOT_SUPPORTED_ERROR':
case 'NotSupportedError':
STRecorder.throwErr('浏览器不支持硬件设备。');
break;
case 'MANDATORY_UNSATISFIED_ERROR':
case 'MandatoryUnsatisfiedError':
STRecorder.throwErr('无法发现指定的硬件设备。');
break;
default:
console.log('无法打开麦克风。异常信息:', error);
STRecorder.throwErr('无法打开麦克风。异常信息:' + (error.code || error.name));
break;
}
}
);
return;
} else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
audio: true
})
.then(function(stream) {
var rec = new Recorder(stream, config, name);
callback(rec);
}).catch(function(error) {
switch (error.code || error.name) {
case 'PERMISSION_DENIED':
case 'PermissionDeniedError':
Recorder.throwError('用户拒绝提供信息。');
break;
case 'NOT_SUPPORTED_ERROR':
case 'NotSupportedError':
Recorder.throwError('浏览器不支持硬件设备。');
break;
case 'MANDATORY_UNSATISFIED_ERROR':
case 'MandatoryUnsatisfiedError':
Recorder.throwError('无法发现指定的硬件设备。');
break;
default:
Recorder.throwError('无法打开麦克风。异常信息:' + (error.code || error.name));
break;
}
});
return;
} else {
Recorder.throwError('当前浏览器不支持录音功能。');
return;
}
}
};
function dtcWebsocket(websocket_url, IP, Port, Token, queryToken, name) { // 连接websocket
var ws = new WebSocket(websocket_url + '?token=' + queryToken + '&IP=' + IP + '&Port=' + Port + '&Token=' + Token + '&dtc=true');
console.log(ws)
ws.onopen = function(evt) {
var message = {
type: "websocket_success",
msg: "dtc websocket连接成功"
};
if (cb[name]) {
cb[name](message)
};
Recorder.get(function(rec) {
recorder[name] = rec;
recorder[name].start();
}, {}, name);
};
ws.onmessage = function(data) {};
ws.onclose = function(evt) {
var message = {
type: "websocket_close",
msg: "dtc websocket连接断开"
};
if (cb[name]) {
cb[name](message)
};
recorder[name].stop(); //关闭采集数据
recorder[name].clear(); //清空采集数据缓存
recorder[name] = null;
dtcWs[name] = null; //清空websocket
cb[name] = null;
};
ws.onerror = function(evt) {
var message = {
type: "websocket_error",
msg: evt
};
if (cb[name]) {
cb[name](message)
};
recorder[name].stop();
recorder[name].clear();
recorder[name] = null;
dtcWs[name] = null; //清空websocket
cb[name] = null;
};
return ws;
}
window.Recorder = Recorder;
window.startCall = function(q2http_url, websocket_url, token, puid, idx, name, callback) { //开启对讲,每开启一个对讲就开启一个websocket,关闭对讲就要关闭websocket
if (callback) {
cb[name] = callback;
}
var params = {
puid: puid,
idx: idx
}
$.ajax({
type: 'post',
url: q2http_url + "audio/startCall?token=" + token,
data: params,
traditional: true,
dataType: 'json',
async: false,
complete: function(rv) {
console.log(rv)
var res = rv.responseJSON;
console.log(res)
if (res.hasOwnProperty('errcode')) {
var message = {
type: "startTalk_error",
msg: res.data.message
};
if (cb[name]) {
cb[name](message)
};
return;
} else {
console.log(name)
dtcWs[name] = dtcWebsocket(websocket_url, res.IP, res.Port, res.Token, token, name);
var message = {
type: "startTalk_success",
msg: "打开喊话成功"
};
if (cb[name]) {
cb[name](message)
};
return;
};
},
error: function(err) {
console.log(err);
}
})
};
window.stopCall = function(name) {
if (recorder[name]) {
dtcWs[name].close(); //关闭websocket
var message = {
type: "stopTalk_success",
msg: "关闭喊话成功"
};
if (cb[name]) {
cb[name](message)
};
return;
} else {
var message = {
type: "stopTalk_error",
msg: "未找到喊话无法停止喊话"
};
if (cb[name]) {
cb[name](message)
};
return;
};
};
})(window);

20916
src/utils/video/video-7.19.1.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,347 @@
let dataUrl = "http://sgwpdm.ah.sgcc.com.cn/basfs/";
let puId = 201115203158708879 //new GetRequest().puid;
let token=new GetRequest().token;
console.log("token===="+token);
let type;
let connparam={};
let _cf ={
ver:'debug',
q2http_url: '',
websocket_url:'',
// - 配置登录参数
connParams : {
// - 登录平台IP
address : "",
port : "",
// - 登录平台用户名
user : "",
// - 登录平台密码
password :"",
// - 登录平台企业ID
epid : "",
// - 登录平台是否通过网闸模式
bfix :1
}
}
export const initPlate = async () => {
if (isNumber(puId)) {
let num = puId.indexOf("15");
type = num === 0 ? '1' : '2'
} else {
alert("puId错误!!!")
}
$.ajax({
url: dataUrl + "proteam/api/ballrisk/getDeviceState?token="+token,
type: "POST",
data: {
puid: encrypt(puId),
type: encrypt(type)
},
success: function (data) {
var configData=data.config;
if(typeof(configData)!='undefined'){
_cf.q2http_url=configData.q2httpUrl;
_cf.websocket_url=configData.websocketUrl;
_cf.connParams.address=configData.videoIp;
_cf.connParams.port=configData.videoPort;
_cf.connParams.user=configData.videoUser;
_cf.connParams.password=configData.videoPassword;
_cf.connParams.epid=configData.epid;
_cf.connParams.bfix=configData.bfix*1;
}else{
_cf.q2http_url='http://220.248.250.3:29605/icvs2/';
_cf.websocket_url='ws://220.248.250.3:29605/wss';
_cf.connParams.address="10.138.219.3";
_cf.connParams.port="29988";
_cf.connParams.user="bns4";
_cf.connParams.password="";
_cf.connParams.epid="system";
_cf.connParams.bfix=1;
}
console.log(_cf);
introduce("videoQX.js")
console.log(data);
if (data.code === "1") {
if (data.status !== "1") {
layer.msg("球机不在线", {
icon: 2,
time: 2000 //2秒关闭如果不配置默认是3秒
});
} else {
}
} else {
layer.msg("服务链接异常", {
icon: 2,
time: 2000 //2秒关闭如果不配置默认是3秒
});
}
},
error: function (error) {
introduce("videoQX.js");
_cf.q2http_url='http://220.248.250.31:29605/icvs2/';
_cf.websocket_url='ws://220.248.250.31:29605/wss';
_cf.connParams.address="10.138.219.3";
_cf.connParams.port="29988";
_cf.connParams.user="bns4";
_cf.connParams.password="";
_cf.connParams.epid="system";
_cf.connParams.bfix=1;
layer.msg('服务链接异常', {
icon: 2,
time: 2000 //2秒关闭如果不配置默认是3秒
});
}
});
$('#return').on('click', function () {
window.close();
window.history.back(-1);
});
$('.div').height($('.div').width())
};
/***引入 js / css 文件
@param {string} url js/css文件路径
@example: aui.import('js/aui.picker.js')
@example: aui.import(['js/aui.picker.js', 'css/aui.picker.css'])
*/
function introduce(url) {
switch (url.constructor) {
case Array:
for (const [index, item] of url.entries()) {
creat(item);
}
break;
case String:
creat(url);
break;
default:
break;
}
}
function creat(file) {
if (/^.+?\.js$/.test(file)) { //JS文件引入
let script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", file);
document.querySelector('head').appendChild(script);
}
if (/^.+?\.css$/.test(file)) { //CSS文件引入
let css = document.createElement('link');
css.rel = 'stylesheet';
css.type = 'text/css';
css.href = file;
document.querySelector('head').appendChild(css);
}
}
/**
* 获取链接中的参数
* @returns {Object}
* @constructor
*/
function GetRequest() {
let theRequest = {};
let param = filterJS(location.hash); //获取url中"?"符后的字串
if(param){
param=param.substr(1);
params=param.split("&");
for (var i = 0; i < params.length; i++) {
theRequest[params[i].split("=")[0]] = (params[i].split("=")[1]);
}
return theRequest;
}else{
alert("请求参数异常");
}
return theRequest;
}
/**
* 判断字符是否为空的方法
* @param obj
* @returns {boolean}
*/
function isEmpty(obj) {
if (typeof obj == "undefined" || obj == null || obj == "") {
return true;
} else {
return false;
}
}
function isNumber(val) {
let regPos = /^\d+(\.\d+)?$/;
if (regPos.test(val)) {
return true;
} else {
return false;
}
}
function screenshot(videos) {
let image = new Image();
let video = videos[0];
let canvas = $('#canvas')[0];
let ctx = canvas.getContext('2d');
let H = window.innerHeight;
let W = window.innerWidth;
const pixelRatio = window.devicePixelRatio || 1;
const backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
const ratio = pixelRatio / backingStoreRatio;
canvas.width = videos.width() * ratio;
canvas.height = videos.height() * ratio;
canvas.style.width = W + 'px';
canvas.style.height = H + 'px';
ctx.scale(ratio, ratio);
ctx.drawImage(video, 0, 0, videos.width(), videos.height()); // 将video中的数据绘制到canvas里
image.src = canvas.toDataURL('image/jpg')/*.replace('image/jpg', 'image/octet-stream')*/;
popUps(image)
}
/**
* @param {Object} param
*/
function filterJS(param){
if(param==null ||param==""){
return null;
}
var filteArr = 'script,alert,console';
var splitArr = filteArr.split(',');
for(var i=0;i<splitArr.length;i++){
console.log(splitArr[i]);
if(param.indexOf(splitArr[i])== -1){
return param
}else{
return '*****';
}
}
}
function popUps(image) {
let height = '30%';
let width = '90%';
layer.open({
title: ['截屏(长按保存图片)', 'font-size:18px;align-items: center;'],
type: 1,
content: '<img src="' + image.src + '" width="100%" height="100%" alt="' + '" />',
area: [width, height]
});
}
function videoFullscreen() {
window.open('video.html?puid=' + puId+"&token="+token, '_self');
}
$(document).ready(function(){
let up = $('#up');
let time;
up.mousedown(function () {
control(1);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(1);
}, 1000);
});
up.mouseup(function () {
clearInterval(time);
setTimeout("control(0)", 1000);
});
let down = $('#down');
down.mousedown(function () {
control(2);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(2);
}, 1000);
});
down.mouseup(function () {
clearInterval(time);
setTimeout("control(0)", 1000);
});
let left = $('#left');
left.mousedown(function () {
control(3);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(3);
}, 1000);
});
left.mouseup(function () {
clearInterval(time);
setTimeout("control(0)", 1000);
});
let right = $('#right');
right.mousedown(function () {
control(4);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(4);
}, 1000);
});
right.mouseup(function () {
clearInterval(time);
setTimeout("control(0)", 1000);
});
let zoomin = $('#zoomin');
zoomin.mousedown(function () {
control(5);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(5);
}, 1000);
});
zoomin.mouseup(function () {
clearInterval(time);
setTimeout("control(9)", 1000);
});
let zoominout = $('#zoominout');
zoominout.mousedown(function () {
control(6);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(6);
}, 1000);
});
zoominout.mouseup(function () {
clearInterval(time);
setTimeout("control(9)", 1000);
});
let near = $('#near');
near.mousedown(function () {
control(7);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(7);
}, 1000);
});
near.mouseup(function () {
clearInterval(time);
setTimeout("control(10)", 1000);
});
let faraway = $('#faraway');
faraway.mousedown(function () {
control(8);
time = setInterval(function () {//启动内层定时器每隔30毫秒重复执行事件函数
control(8);
}, 1000);
});
faraway.mouseup(function () {
clearInterval(time);
setTimeout("control(10)", 1000);
});
});
function hintPopUps(str) {
let height = '30%';
let width = '90%';
layer.open({
title: ['提示', 'font-size:18px;align-items: center;'],
type: 1,
content: str,
area: [width, height]
});
}

278
src/utils/video/videoQX.js Normal file
View File

@ -0,0 +1,278 @@
import $ from 'jquery';
let tokens;
let start = [];
function hint() {
layer.msg('视频播放失败,请检查网络!!!', {
icon: 2,
time: 2000 //2秒关闭如果不配置默认是3秒
});
}
// 执行一次函数的定时器
let time = setTimeout(hint, 1000 * 30);
$(function () {
if (isNumber(puId)) {
createVideo();
connect();
} else {
alert("puId错误!!!")
}
});
/**
* post 请求
* @param router
* @param params
* @param callback
*/
function requestPost(router, params, callback) {
$.ajax({
type: 'post',
url: _cf.q2http_url + router,
data: params,
traditional: true,
dataType: 'json',
async: false,
complete: function (rv) {
$('#hint').show();
setTimeout(" $('#hint').hide();", 3000);
if (typeof callback == 'function') callback(rv)
}
})
}
/**
* 创建平台连接
*/
function connect() {
// let params = {
// "address": _cf.connParams.address,
// "port": _cf.connParams.port,
// "user": _cf.connParams.user,
// "password": _cf.connParams.password,
// "epid": _cf.connParams.epid,
// "fixaddr": _cf.connParams.bfix
// }
var allDataParams="address="+_cf.connParams.address+"&port="+_cf.connParams.port+
"&user="+ _cf.connParams.user+"&password="+_cf.connParams.password+"&epid="+_cf.connParams.epid+"&fixaddr="+_cf.connParams.bfix;
let params = {
"params":videoEncrypt(allDataParams)
}
console.log(params)
requestPost('login2', params, function (rv) {
let result = {
errcode: -1,
token: ''
}
let respJSON = JSON.parse(rv.responseText);
if (respJSON.hasOwnProperty('errcode')) {
result.errcode = respJSON.errcode;
}
if (respJSON.hasOwnProperty('token')) {
result.token = respJSON.token;
result.errcode = 0;
tokens = result.token;
if (!isEmpty(tokens)) {
playVideo(puId, "0");
}
}
});
}
/**
* 播放视频
* @param puId
* @param idx
*/
function playVideo(puId, idx) {
//播视频接口
let url = _cf.q2http_url + "stream.flv?puid=" + puId + "&idx=" + idx + "&stream=0&token=" + tokens;
console.log(url);
if (flvjs.isSupported()) {
let videoElement = document.getElementById('video_html5_api');
let flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true,
hasAudio: false,
url: url
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
}
}
function createVideo() {
let play = videojs('video', {
muted: true,
controls: false,
loop: true,
preload: "auto",
autoplay: true,
});
play.play();
$('.vjs-loading-spinner').hide();
$('.vjs-big-play-button').hide();
$('.vjs-poster').removeAttr("class");
var elevideo = document.getElementById("video_html5_api");
elevideo.addEventListener('play', function () { //播放开始执行的函数
console.log(time);
clearTimeout(time);
});
}
function shot() {
screenshot($('#video_html5_api'));
}
//缩放功能
function zoomcontrol(option) {
let params = {
puid: puId,
idx: "0"
}
switch (option) {
case "stop":
//停止缩放接口
requestPost('PTZ/C_PTZ_StopPictureZoom?token=' + tokens, params, rv => {
})
break;
case "zoomin":
//放大图像接口
requestPost('PTZ/C_PTZ_ZoomInPicture?token=' + tokens, params, rv => {
})
break;
default:
//缩小图像接口
requestPost('PTZ/C_PTZ_ZoomOutPicture?token=' + tokens, params, rv => {
})
break;
}
}
//远近焦点功能
function focuscontrol(option) {
let params = {
puid: puId,
idx: "0"
}
switch (option) {
case "near":
requestPost('PTZ/C_PTZ_MakeFocusNear?token=' + tokens, params, rv => {
console.log(rv)
})
break;
case "faraway":
requestPost('PTZ/C_PTZ_MakeFocusFar?token=' + tokens, params, rv => {
console.log(rv)
})
break;
default:
requestPost('PTZ/C_PTZ_StopFocusMove?token=' + tokens, params, rv => {
console.log(rv)
})
break;
}
}
function aperture(option) {
let camera = {
puid: puId,
idx: "0"
};
let xml = "";
switch (option) {
case "augment":
xml = `<?xml version="1.0" encoding="UTF-8"?>
<M Type="ComReq">
<C Type="G" Prio="1" EPID="${_cf.connParams.epid}" Lang="zh_CN">
<Res Type="IV" Idx="${camera.idx}" OptID="C_PTZ_AugmentAperture" Stream="0"><Param></Param></Res>
</C>
</M>`;
requestPost(`RawRequest?dstType=201&dstID=${camera.puid}&token=${tokens}`, {xml: xml}, rv => {
console.log(rv);
});
break;
case "minish":
xml = `<?xml version="1.0" encoding="UTF-8"?>
<M Type="ComReq">
<C Type="G" Prio="1" EPID="${_cf.connParams.epid}" Lang="zh_CN">
<Res Type="IV" Idx="${camera.idx}" OptID="C_PTZ_MinishAperture" Stream="0"><Param></Param></Res>
</C>
</M>`;
requestPost(`RawRequest?dstType=201&dstID=${camera.puid}&token=${tokens}`, {xml: xml}, rv => {
console.log(rv)
});
break;
default:
xml = `<?xml version="1.0" encoding="UTF-8"?>
<M Type="ComReq">
<C Type="G" Prio="1" EPID="${_cf.connParams.epid}" Lang="zh_CN">
<Res Type="IV" Idx="${camera.idx}" OptID="C_PTZ_StopApertureZoom" Stream="0"><Param></Param></Res>
</C>
</M>`;
requestPost(`RawRequest?dstType=201&dstID=${camera.puid}&token=${tokens}`, {xml: xml}, rv => {
console.log(rv);
});
break;
}
}
//旋转平台功能
async function turncontrol(option) {
let params = {
puid: puId,
idx: "0",
motion: option
};
if (!isEmpty(option)) {
requestPost('PTZ/C_PTZ_Turn?token=' + tokens, params, (rv) => {
});
}
}
function control(key) {
switch (key) {
case 0:
turncontrol('stop');
break;
case 1:
turncontrol('up');
break;
case 2:
turncontrol('down');
break;
case 3:
turncontrol('left');
break;
case 4:
turncontrol('right');
break;
case 5:
zoomcontrol('zoomin');
break;
case 6:
zoomcontrol('zoominout');
break;
case 7:
focuscontrol('near');
break;
case 8:
focuscontrol('faraway');
break;
case 9:
zoomcontrol('stop');
break;
case 10:
focuscontrol('stop');
break;
default:
break;
}
}

View File

@ -0,0 +1,360 @@
<template>
<div class="hoistManage" style="width: 100%;height: 80vh;background-color: #ffffff;box-shadow: 10px 10px 5px #000000;float: left;">
<div class="one">
<div style="color: #1E3850;font-size: 14x; font-weight: 600;">吊装作业</div>
<div class="title">
<el-input v-model="keyword" placeholder="请输入关键字" style="width: 100%;margin-top: 10px;">
<template #prepend>
<el-button class="el-icon-search" @click="searchClick"/>
</template>
</el-input>
<div class="content" style="width: 100%;height: 70vh;margin-top:10px; overflow: auto;">
<div
v-for="(item, index) in hoistData"
@click="hoistClick(item.id)"
style="display: flex;justify-content: center;border: 1px solid #E2E2E2;border-radius: 5px;margin-bottom: 10px;cursor: pointer;">
<div class="left" style="width: 30%;margin: 10px 0 10px 10px;">
<img src="../../../../assets/images/camera.png" style="width: 100%;height: 100%;"/>
</div>
<div class="right" style="width: 70%;font-size: 14px;color: #344B60;margin: 10px 10px 10px 10px;">
<div style="">{{ item.proName }}</div>
<div style="margin-top: 5px;">
<span>班组</span>
<span>{{ item.teamName }}</span>
</div>
<div style="margin-top: 5px;">
<span>组长</span>
<span>{{ item.teamLeader }}</span>
</div>
<div style="margin-top: 5px;">{{ item.hoistName }}</div>
<div style="margin-top: 5px;margin-bottom: 10px;">{{ item.number }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="two">
<img :src="photoPath" style="width: 100%;height: 100%;"/>
</div>
<div class="three">
<div style="width: 100%;height: 24%;display: flex;justify-content: center;border: 1px solid #40A3FF;margin-bottom: 8px;">
<div style="width: 5%;height: 100%;display: flex;justify-content: center;align-items: center;color: #364D62;font-size: 14px;">前面</div>
<div style="width: 95%;height: 100%;">
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="width:100%;height: 100%;object-fit: fill"></video>
</div>
</div>
<div style="width: 100%;height: 24%;display: flex;justify-content: center;border: 1px solid #40A3FF;margin-bottom: 8px;">
<div style="width: 5%;height: 100%;display: flex;justify-content: center;align-items: center;color: #364D62;font-size: 14px;">前面</div>
<div style="width: 95%;height: 100%;">
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="width:100%;height: 100%;object-fit: fill"></video>
</div>
</div>
<div style="width: 100%;height: 24%;display: flex;justify-content: center;border: 1px solid #40A3FF;margin-bottom: 8px;">
<div style="width: 5%;height: 100%;display: flex;justify-content: center;align-items: center;color: #364D62;font-size: 14px;">前面</div>
<div style="width: 95%;height: 100%;">
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="width:100%;height: 100%;object-fit: fill"></video>
</div>
</div>
<div style="width: 100%;height: 24%;display: flex;justify-content: center;border: 1px solid #40A3FF;">
<div style="width: 5%;height: 100%;display: flex;justify-content: center;align-items: center;color: #364D62;font-size: 14px;">前面</div>
<div style="width: 95%;height: 100%;">
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="width:100%;height: 100%;object-fit: fill"></video>
</div>
</div>
</div>
<div class="four">
<div class="title" style="border: 1px solid #DFDFDF;border-radius: 3px;">
<div v-for="(item, index) in vibeDeviceData" style="display: flex;justify-content: center;align-items: center;">
<div>{{ item.name }}</div>
<div style="margin-left: 10px;">
<img v-if="item.battery >= 100" :src="batterys.battery1" width="25"/>
<img v-else-if="item.battery >= 50" :src="batterys.battery2" width="25"/>
<img v-else :src="batterys.battery3" width="25"/>
{{ item.battery }}
</div>
<div style="margin-left: 10px;">
<img @click="dialogVisible = true" src="../../../../assets/images/setUp.png" width="20" style="cursor: pointer;" title="设置"/>
</div>
</div>
</div>
<div class="content" style="width: 100%;height: 70vh;margin-top: 20px;overflow: auto;">
<el-table :data="tableData" style="width: 100%" :show-header="false">
<el-table-column prop="deviceName" label="人员姓名"/>
<el-table-column prop="time" label="设备名称"/>
<el-table-column prop="reason" label="操作"/>
</el-table>
</div>
</div>
<el-dialog
title="近电感应配置"
:visible.sync="dialogVisible"
:append-to-body="true"
:draggable="true"
:destroy-on-close="true"
width="40%" custom-class="my-dialog1">
<div style="width: 100%;height: 50vh;overflow: auto;">
<div v-for="(item, index) in hoistSetUpData" style="width: 100%;height: 60%;">
<div>配置{{ index + 1 }}</div>
<el-form label-width="120px">
<el-form-item label="线路属性:">
<el-radio-group v-model="item.lineType" class="ml-4" @change="lineTypeRadioChange(item, index)" style="margin-top: 10px;">
<el-radio label="1" size="large">交流</el-radio>
<el-radio label="2" size="large">直流</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="电压等级:">
<el-radio-group v-model="item.level" class="ml-4" @change="levelRadioChange(item, index)" style="margin-top: 10px;">
<el-radio label="1" size="large">10kV</el-radio>
<el-radio label="2" size="large">20~35kV</el-radio>
<el-radio label="3" size="large">66~110kV</el-radio>
<el-radio label="4" size="large">220kV</el-radio>
<el-radio label="5" size="large">330kV</el-radio>
<el-radio label="6" size="large">500kV</el-radio>
<el-radio label="7" size="large">700kV</el-radio>
<el-radio label="8" size="large">1000kV</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="报警距离:">
<el-input v-model="item.distance" type="number" placeholder="请输入" style="width: 25%;">
</el-input>&nbsp;
</el-form-item>
</el-form>
<el-button @click="delHoistSetUp(index)" v-if="index > 0" style="margin-left: 80%;">删除配置</el-button>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="addHoistSetUp">添加配置</el-button>
<el-button @click="provingDialogClose">取消</el-button>
<el-button type="primary" @click="provingDialogConfirm">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'hoistManage',
data() {
return {
//
keyword: '',
//
hoistData: [
{
id: 'id1',
proName: 'xxxxxxx工程',
teamName: 'xxx班组',
teamLeader: '张三 15232325654',
hoistName: '1号吊装预警设备',
number: '232532323235623'
},
{
id: 'id2',
proName: 'xxxxxxx工程',
teamName: 'xxx班组',
teamLeader: '张三 15232325654',
hoistName: '1号吊装预警设备',
number: '232532323235623'
},
{
id: 'id3',
proName: 'xxxxxxx工程',
teamName: 'xxx班组',
teamLeader: '张三 15232325654',
hoistName: '1号吊装预警设备',
number: '232532323235623'
},
{
id: 'id4',
proName: 'xxxxxxx工程',
teamName: 'xxx班组',
teamLeader: '张三 15232325654',
hoistName: '1号吊装预警设备',
number: '232532323235623'
},
{
id: 'id5',
proName: 'xxxxxxx工程',
teamName: 'xxx班组',
teamLeader: '张三 15232325654',
hoistName: '1号吊装预警设备',
number: '232532323235623'
}
],
//
photoPath: require('../../../../assets/images/test.jpg'),
//
batterys: {
battery1: require('../../../../assets/images/battery1.png'),
battery2: require('../../../../assets/images/battery2.png'),
battery3: require('../../../../assets/images/battery3.png'),
},
//
vibeDeviceData: [
{
name: '近电感应设备DX-J431',
battery: 90
},
{
name: '近电感应设备DX-J431',
battery: 30
}
],
//
tableData: [
{
deviceName: '近电感应设备DX-J431',
time: '2024-03-03 13:26',
reason: '低于安全施工sss距离'
},
{
deviceName: '近电感应设备DX-J431',
time: '2024-03-03 13:26',
reason: '低于安全施工sss距离'
},
{
deviceName: '近电感应设备DX-J431',
time: '2024-03-03 13:26',
reason: '低于安全施工sss距离'
},
],
//
dialogVisible: false,
//
hoistSetUpData: [
{
lineType: '1',
level: '1',
distance: 10
}
]
};
},
created() {
},
methods: {
//
searchClick(){
console.log(this.keyword)
},
//
hoistClick(id){
alert(id)
},
//线
lineTypeRadioChange(item, index){
},
//
levelRadioChange(item, index){
},
//
addHoistSetUp(){
let json = {lineType: '1', level: '1', distance: 10};
this.hoistSetUpData.push(json)
},
//
delHoistSetUp(index){
this.hoistSetUpData.splice(index, 1);
},
//
provingDialogClose(){
this.dialogVisible = false;
},
//
provingDialogConfirm(){
this.dialogVisible = false;
}
}
};
</script>
<style>
.my-dialog1{
top: 100px
}
.hoistManage>div{
float: left;
}
.hoistManage .one{
width: 16.6%;
height: 100%;
}
.hoistManage .two{
width: 32.2%;
height: 100%;
margin-left: 1%;
}
.hoistManage .three{
width: 24%;
height: 100%;
margin-left: 1%;
}
.hoistManage .four{
width: 24%;
height: 100%;
margin-left: 1%;
}
.hoistManage .four>.title>div:nth-child(1){
margin-top: 10px;
}
.hoistManage .four>.title>div:nth-child( n + 1 ){
margin-bottom: 10px;
}
.hoistManage .center{
}
.hoistManage .right{
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px #e8eceb;
border-radius: 5px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #ffffff;
-webkit-box-shadow: inset 0 0 6px #cbb7b7;
}
::-webkit-scrollbar-thumb:window-inactive {
background: #e8eceb;
}
::-webkit-scrollbar-corner {
background-color: #e8eceb;
}
::v-deep .el-dialog{
height: 78vh;
overflow: auto;
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<div class="app-container" style="background-color: #F9F9F9;">
<el-tabs v-model="activeName" class="demo-tabs">
<el-tab-pane label="实时监控" class="realTimeManage" name="first">
<realTimeManage/>
</el-tab-pane>
<el-tab-pane label="人员管控" class="personManage" name="second">
<personManage/>
</el-tab-pane>
<el-tab-pane label="吊装管控" class="hoistManage" name="three">
<hoistManage/>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import realTimeManage from './realTimeManage/realTimeManage.vue';
import personManage from './personManage/personManage.vue';
import hoistManage from './hoistManage/hoistManage.vue';
export default {
name: "manage",
components: {
realTimeManage,
personManage,
hoistManage
},
data() {
return {
activeName: 'first'
};
},
created() {
},
methods: {
// test();
}
};
</script>
<style>
</style>

View File

@ -0,0 +1,586 @@
<template>
<div class="personManage" style="width: 100%;height: 80vh;background-color: #ffffff;box-shadow: 10px 10px 5px #000000;float: left;">
<div class="left">
<div class="title">
<el-input v-model="keyword" placeholder="请输入关键词" style="width: 90%;">
<template #prepend>
<el-button class="el-icon-search" @click="searchClick"/>
</template>
</el-input>
</div>
<div class="content">
<el-tree :data="treeData" icon="el-icon-search" node-key="id" :default-expanded-keys="[1]"
@node-click="handleNodeClick" :render-content="renderContent" style="font-size: 14px;"/>
</div>
</div>
<div class="center">
<div class="title">
<el-button type="primary" link icon="el-icon-search" @click="dialogVisible1 = true">手环人脸验证抽检</el-button>
<el-button type="primary" link icon="el-icon-setting" @click="dialogVisible2 = true">自动验证配置</el-button>
</div>
<div class="content">
<baidu-map map-style-v2="light" class="map" :zoom="zoom" :center="center" @ready="handler">
<bm-marker v-for="(item, index) in deviceData" :position="item.position" :dragging="true"
:icon="{url: mapIcon1, size: { width: 24, height: 24 }}" animation=""
@click="infoWindowOpen(item)" @mouseover="infoWindowOpen(item)" @mouseout="infoWindowClose(item)">
<!-- <bm-label v-if="item.deviceName != ''" :content="item.deviceName" :labelStyle="{color:'red', fontSize: '14px'}" :offset="{width:-20, height:10}"></bm-label> -->
<bm-info-window :show="item.show">
{{ item.deviceName }}
</bm-info-window>
</bm-marker>
<bm-circle :center="circleRange.center" @click="infoWindowClose" :radius="circleRange.radius" stroke-color="blue" :stroke-opacity="0.5" :stroke-weight="2" @lineupdate="updateCirclePath" :editing="true"></bm-circle>
</baidu-map>
</div>
</div>
<div class="right">
<div class="title" style="float: left;text-indent: 10px;">
<div style="color: #3E5469;font-size: 12px;margin-top: 4%;">
今日施工班组{{ buildData.teamNum }}
</div>
<div style="color: #3E5469;font-size: 12px;margin-top: 2%;">
今日施工人数{{ buildData.personNum }}
</div>
</div>
<div class="content">
<div class="title" style="color: #3E5469;font-size: 1px;font-weight: 600;text-indent: 10px;">
智能安全帽
</div>
<div class="table" style="margin-top: 2%;">
<el-table :data="tableData" style="width: 100%" :show-header="false">
<el-table-column prop="username" label="人员姓名"/>
<el-table-column prop="deviceName" label="设备名称"/>
<el-table-column prop="warnContent" label="操作">
<template #default="scope">
<!-- <div>{{ scope.row.username }}</div> -->
<img src="../../../../assets/images/mike.png" style="width: 20px;height: 20px;cursor: pointer;">
<img src="../../../../assets/images/camera.png" style="width: 20px;height: 20px;cursor: pointer;">
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<el-dialog
title="选择"
:visible.sync="dialogVisible1"
:append-to-body="true"
:draggable="true"
:destroy-on-close="true"
width="20%" top="50vh">
<div style="height: 60vh;overflow: auto;">
<div class="title" style="margin-bottom: 4%;">
<el-input v-model="keyword2" placeholder="请输入关键词" style="width: 90%;">
<template #prepend>
<el-button class="el-icon-search" @click="searchClick2"/>
</template>
</el-input>
</div>
<el-tree :data="teamTreeData" icon="el-icon-search" show-checkbox
@node-click="teamTreeNodeClick" style="font-size: 14px;" @check-change="teamTreeCheckChange"
ref="teamTree"/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="spotCheckDialogClose">取消</el-button>
<el-button type="primary" @click="startSpotCheck">发起抽检</el-button>
</span>
</template>
</el-dialog>
<el-dialog
title="自动验证人脸配置"
:visible.sync="dialogVisible2"
:append-to-body="true"
:draggable="true"
:destroy-on-close="true"
width="20%" custom-class="my-dialog">
<div style="width: 100%;height: 30vh;">
<div>模式选择</div>
<el-radio-group v-model="provingTypeRadioValue" class="ml-4" @change="provingTypeRadioChange" style="margin-top: 10px;">
<el-radio label="1" size="large">固定时间验证</el-radio>
<el-radio label="2" size="large">间隔时间验证</el-radio>
</el-radio-group>
<div v-if="provingTypeRadioValue == '1'">
<div @click="addTimeInput" style="color: #1890FF;margin-top: 20px;margin-bottom: 10px;cursor: pointer;">+ 添加时间</div>
<div style="overflow: auto;width: 100%;height: 22vh;">
<div
v-for="(item, index) in provingTimeValue">
<el-time-picker
v-model="provingTimeValue[index]"
format="HH:mm:ss"
placeholder="选择时间"
value-format="HH-mm-ss"
style="margin-bottom: 10px;">
</el-time-picker>
<el-button v-if="index != 0" class="el-icon-delete" @click="delTimeInput(index)"/>
</div>
</div>
</div>
<div v-if="provingTypeRadioValue == '2'">
<div style="margin-top: 10%;margin-left: 30px;">
每隔&nbsp;<el-input v-model="intervalTime" type="number" min="1" style="width: 100px;"/>&nbsp;小时自动验证人脸
</div>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="provingDialogClose">取消</el-button>
<el-button type="primary" @click="provingDialogConfirm">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'personManage',
data() {
return {
//
defaultProp: {
children: 'children',
label: 'label',
disabled: 'disabled',
},
//
deviceData: [
{"position": {lng: 116.404, lat: 39.915}, "deviceName": "设备11",show: false,},
{"position": {lng: 116.405, lat: 39.915}, "deviceName": "设备22",show: false,},
{"position": {lng: 116.404, lat: 39.916}, "deviceName": "设备33",show: false,},
{"position": {lng: 116.404, lat: 39.917}, "deviceName": "设备44",show: false,},
],
//
circleRange: {
//
center: {
lng: 116.404,
lat: 39.915
},
//
radius: 500
},
//
infoWindow: {
//
show: false,
},
//1
mapIcon1: require("../../../../assets/images/greenDrop.png"),
//2
mapIcon2: require("../../../../assets/images/redDrop.png"),
//
center: { lng: 0, lat: 0 },
//
zoom: 15,
//
keyword: '',
//
treeData: [
{
id: '1',
label: '工程xxxxxxx',
children: [
{
label: '#1',
children: [
{
label: '张三班组',
children: [
{
label: '张三',
},
]
},
],
},
],
},
{
label: '工程xxxxxxx',
children: [
{
label: '#2',
children: [
{
label: '张三班组',
children: [
{
label: '张三',
},
]
},
],
},
{
label: '工程xxxxxxx',
children: [
{
label: '#3',
},
],
},
],
},
{
label: '工程xxxxxxx',
children: [
{
label: '#4',
children: [
{
label: '张三班组',
children: [
{
label: '张三',
},
]
},
],
},
{
label: '#5',
children: [
{
label: '张三班组',
children: [
{
label: '张三',
},
]
},
],
},
],
},
],
//
buildData: {
teamNum: '5',
personNum: '30'
}
//
,tableData: [
{
username: '张三',
deviceName: '1号智能安全帽'
},
{
username: '张xx',
deviceName: 'xxxxxxxxxx'
},
{
username: '张xx',
deviceName: 'xxxxxxxxxx'
},
{
username: '张xx',
deviceName: 'xxxxxxxxxx'
},
],
//
dialogVisible1: false,
dialogVisible2: false,
//
keyword2: "",
//
teamTreeData: [
{
id: '1',
label: '在施班组及人员',
children: [
{
label: '张三班组',
children: [
{
label: '张三',
},
],
},
{
id: '1-1',
label: 'xx班组',
children: [
{
label: 'xx1',
},
{
label: 'xx2',
},
],
},
{
id: '1-2',
label: 'xx班组',
children: [
{
label: 'xx1',
},
{
label: 'xx2',
},
],
},
],
},
],
//
intervalTime: 1,
//
provingTypeRadioValue: "1",
provingTimeValue: [''],
};
},
created() {
},
methods: {
handler ({ BMap, map }){
console.log(BMap, map);
this.center.lng = 116.404;
this.center.lat = 39.915;
this.zoom = 15;
//
map.enableScrollWheelZoom(true);
//
let mapStyle = {style: 'midnight'}
map.setMapStyle(mapStyle)
// map.setMapType(BMAP_PERSPECTIVE_MAP); //3D
map.setMapType(BMAP_NORMAL_MAP); //
// map.setMapType(BMAP_HYBRID_MAP); //
// map.setMapType(BMAP_SATELLITE_MAP); //
},
//
searchClick() {
alert(this.keyword)
},
//
handleNodeClick(data){
console.log(data.id)
},
//icon
renderContent(h, { node, data }) {
// 使
let icon;
if (node.level === 1) {
icon = 'el-icon-coin'; // 使
} else if (node.level === 2) {
icon = 'el-icon-s-unfold'; // 使
} else {
icon = 'el-icon-user'; // 使
}
return (
<span class="custom-tree-node">
<i class={icon}></i>
<span>{node.label}</span>
</span>
);
},
updateCirclePath (e) {
this.circleRange.center = e.target.getCenter()
this.circleRange.radius = e.target.getRadius()
},
//
showWindow(event){
console.log(event.target.getAttribute("class"))
// // 使 event.target
// const triggerElement = event.target;
// // 'data-value'
// const attributeValue = triggerElement.getAttribute('position');
// console.log(attributeValue);
},
infoWindowClose(item) {
item.show = false;
},
infoWindowOpen(item) {
item.show = true;
},
//
searchClick2() {
alert(this.keyword2)
},
//
teamTreeNodeClick(data){
console.log(data.id)
},
//
teamTreeCheckChange (data,checked,indeterminate) {
console.log(data, checked, indeterminate)
},
//
spotCheckDialogClose(){
//
this.keyword2 = "";
//
this.dialogVisible1 = false
},
//
spotCheckDialogClose(){
//
this.dialogVisible2 = false
},
//
startSpotCheck(){
//
const checkedNodes = this.$refs.teamTree.getCheckedNodes();
console.log(checkedNodes);
// this.dialogVisible1 = false
},
//
provingTypeRadioChange(value){
console.log(value)
},
//
addTimeInput(){
this.provingTimeValue.push('')
},
//
delTimeInput(index){
this.provingTimeValue.splice(index, 1);
},
//
provingDialogClose(){
this.dialogVisible2 = false;
},
//
provingDialogConfirm(){
// provingTypeRadioValue intervalTime
if(this.provingTypeRadioValue == "1"){
console.log(this.provingTimeValue)
}else{
console.log(this.intervalTime)
}
}
}
};
</script>
<style>
.my-dialog{
top: 200px
}
.map {
display: inline-block;
width: 100%;
height: 100%;
}
.personManage .bm-view {
width: 100%;
height: 100%;
}
.personManage .left{
width: 19.5%;
height: 100%;
float: left;
}
.personManage .left>.title{
width: 100%;
height: 8%;
display: flex;
justify-content: center;
align-items: center;
}
.personManage .left>.content{
width: 100%;
height: 92%;
}
.personManage .center{
margin-left: 0.5%;
width: 59.5%;
height: 100%;
float: left;
}
.personManage .center>.title{
width: 100%;
height: 8%;
display: flex;
align-items: center;
}
.personManage .center>.content{
background-color: aqua;
width: 100%;
height: 92%;
}
.personManage .right{
margin-left: 0.5%;
width: 20%;
height: 100%;
float: left;
}
.personManage .right>.title{
width: 100%;
height: 10%;
}
.personManage .right>.content{
width: 100%;
height: 90%;
overflow: auto;
}
.dialog-footer button:first-child {
margin-right: 10px;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px #e8eceb;
border-radius: 5px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #ffffff;
-webkit-box-shadow: inset 0 0 6px #cbb7b7;
}
::-webkit-scrollbar-thumb:window-inactive {
background: #e8eceb;
}
::-webkit-scrollbar-corner {
background-color: #e8eceb;
}
::v-deep .el-dialog{
height: 78vh;
overflow: auto;
}
</style>

View File

@ -0,0 +1,490 @@
<template>
<div class="realTimeManage" style="width: 100%;height: 80vh;background-color: #ffffff;box-shadow: 10px 10px 5px #000000;">
<div class="left">
<div class="leftTop">
<div class="title1">
实时监控
</div>
<div class="controlDeck">
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div>聚焦</div>
<div>缩放</div>
<div>光圈</div>
</div>
</div>
<div class="monitorList" >
<!-- -->
<el-tree :data="monitorList" icon="el-icon-search" node-key="id" :default-expanded-keys="[1]"
@node-click="handleNodeClick" :render-content="renderContent" style="font-size: 14px;"/>
</div>
</div>
<div class="rightTop">
<div class="title">
<el-tabs v-model="splitScreenName" class="demo-tabs" @tab-click="splitScreenClick">
<el-tab-pane label="一画面" class="realTimeManage" name="first">
<div style="width: 100%;height: 52vh;">
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="height:100%;width:100%;object-fit: fill"></video>
</div>
</el-tab-pane>
<el-tab-pane label="四画面" class="personManage" name="second">
<<!-- div style="width: 100%;height: 52vh;">
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="height:50%;width:50%;object-fit: fill"></video>
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="height:50%;width:50%;object-fit: fill"></video>
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="height:50%;width:50%;object-fit: fill"></video>
<video id="video" class="vjs-default-skin" autoplay controls preload="none"
style="height:50%;width:50%;object-fit: fill"></video>
</div> -->
</el-tab-pane>
</el-tabs>
</div>
</div>
<div class="down">
<div v-for="(item, index) in violationPhoto" :key="item.id">
<div>
<img :src="item.path" style="width: 100%;height: 100%;"/>
</div>
<div>
<span>{{ item.cameraName }}</span>
<span>{{ item.time }}</span>
</div>
<div>{{ item.content }}</div>
</div>
</div>
</div>
<div class="right">
<div>预警信息</div>
<div>
<el-table :data="tableData" style="width: 100%" :show-header="false">
<el-table-column prop="deviceType" label="设备类型"/>
<el-table-column prop="deviceName" label="设备名称"/>
<el-table-column prop="time" label="预警时间" />
<el-table-column prop="warnContent" label="预警内容" />
</el-table>
<el-pagination v-model:current-page="pageNo" v-model:page-size="pageSize" :page-sizes="[5, 10, 20, 50]"
:background="true" layout="prev, pager, next, jumper,->,total, sizes" :total="total"
@current-change="getHasRole" @size-change="handler" />
</div>
</div>
</div>
</template>
<script>
import { include } from '../../../../utils/video/include.js'
import { video } from '../../../../utils/video/video-7.19.1.min.js'
import { flv } from '../../../../utils/video/flv.js'
import { talk } from '../../../../utils/video/talk.js'
import { h5live } from '../../../../utils/video/h5live-1.0.6.js'
// import { videoPage } from '../../../../utils/video/videoPage';
import { videoQX } from '../../../../utils/video/videoQX';
import $ from 'jquery';
export default {
name: 'realTimeManage',
data() {
return {
//
pageNo: 1,
//
pageSize: 5,
//
monitorList: [
{
id: '1',
label: '工程xxxxxxx',
children: [
{
label: '张三',
puId: '123123123123'
},
],
},
{
label: '工程xxxxxxx',
children: [
{
label: '张三1',
puId: '798779798779877'
},
],
},
{
label: '工程xxxxxxx',
children: [
{
label: '#张三2',
puId: '565445646464654'
},
],
},
],
splitScreenName: 'first',
//
violationPhoto: [{"id": "1", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "2", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "3", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "4", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "5", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "6", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "7", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "8", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "9", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}, {"id": "10", "path": "http://192.168.0.14:1909/file/ynRealName/violationBlack/2024/05/13/08ffd23539df47ed873058a163249ffe005Qblgkgy1h3h38c7wwrj30q70q7gs5.jpg", "cameraName": "违规10", "time": "2024-03-03", "content": "未正确佩戴安全帽10"}]
//
,tableData: [
{
deviceType: '监控设备',
deviceName: 'xxxxx球机',
time: '2024-03-03',
warnContent: '人员未佩戴安全帽阿三大苏打啊飒飒大苏打飒飒打撒打撒'
},{
deviceType: '监控设备',
deviceName: 'xxxxx球机',
time: '2024-03-03',
warnContent: '人员未佩戴安全帽'
},{
deviceType: '监控设备',
deviceName: 'xxxxx球机',
time: '2024-03-03',
warnContent: '人员未佩戴安全帽'
},{
deviceType: '监控设备',
deviceName: 'xxxxx球机',
time: '2024-03-03',
warnContent: '人员未佩戴安全帽'
},
{
deviceType: '监控设备',
deviceName: 'xxxxx球机',
time: '2024-03-03',
warnContent: '人员未佩戴安全帽'
}
]
};
},
created() {
},
mounted(){
this.loadExternalScript();
// const queryParams = this.$route.query;
// console.log("queryParams");
},
methods: {
async loadExternalScript() {
try {
// JavaScript'/path/to/your/script.js'
const module = await import('../../../../utils/video/videoPage');
// 使module.export
} catch (e) {
console.error('Error loading the external script:', e);
}
},
splitScreenClick(pane, event){
console.log("pane:", );
console.log("event:", event);
if(pane.name === 'first'){
}
if(pane.name === 'second'){
}
},
//
handleNodeClick(data){
console.log(data.puId)
},
//icon
renderContent(h, { node, data }) {
// 使
let icon;
if (node.level === 1) {
icon = 'el-icon-coin'; // 使
} else if (node.level === 2) {
icon = 'el-icon-s-unfold'; // 使
} else {
icon = 'el-icon-user'; // 使
}
return (
<span class="custom-tree-node">
<i class={icon}></i>
<span>{node.label}</span>
</span>
);
},
//
//
handler(){
getHasRole()
},
//
getHasRole (page = 1){
//
this.pageNo = page;
/* let request = await reqAllRoleList(pageNo.value, pageSize.value, keyWord.value);
if (request.data.code == 200) {
total.value = request.data.data.total;
roleArr.value = request.data.data.records;
} */
}
}
};
</script>
<style scoped>
.realTimeManage>div>div{
float: left;
}
.realTimeManage .left{
width: 66%;
height: 100%;
}
.realTimeManage .left>div{
float: left;
}
.realTimeManage .left>.leftTop{
width: 23%;
height: 75%;
}
.realTimeManage .left>.leftTop>.title1{
font-weight: 600;
font-size: 14px;
color: #333333;
width: 100%;
height: 8%;
display: flex;
align-items: center;
text-indent: 20px;
}
.realTimeManage .left>.leftTop>.controlDeck{
width: 100%;
height: 42%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1){
width: 100%;
height: 85%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div{
width: 40px;
height: 40px;
cursor: pointer;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(1){
position: absolute;
top: 7%;
left: 6.35%;
background-image: url('../../../../assets/images/control1.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(2){
position: absolute;
top: 12.55%;
left: 3.7%;
background-image: url('../../../../assets/images/control2.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(3){
position: absolute;
top: 12.5%;
left: 9%;
background-image: url('../../../../assets/images/control3.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(4){
position: absolute;
top: 18%;
left: 6.35%;
background-image: url('../../../../assets/images/control4.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(5){
position: absolute;
top: 21.9%;
left: 1%;
background-image: url('../../../../assets/images/control5.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(6){
position: absolute;
top: 27%;
left: 1%;
background-image: url('../../../../assets/images/control6.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(7){
position: absolute;
top: 27%;
left: 5.3%;
background-image: url('../../../../assets/images/control7.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(8){
position: absolute;
top: 27%;
left: 7.55%;
background-image: url('../../../../assets/images/control8.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(9){
position: absolute;
top: 21.9%;
left: 11.8%;
background-image: url('../../../../assets/images/control9.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(1)>div:nth-child(10){
position: absolute;
top: 27%;
left: 11.8%;
background-image: url('../../../../assets/images/control10.png');
background-repeat: no-repeat;
background-size: 100%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(2){
width: 100%;
height: 15%;
display: flex;
justify-content: space-between;
align-items: center;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(2)>div{
color: #06182E;
font-size: 14px;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(2)>div:nth-child(1){
margin-left: 9%;
}
.realTimeManage .left>.leftTop>.controlDeck>div:nth-child(2)>div:nth-child(3){
margin-right: 9%;
}
.realTimeManage .left>.leftTop>.monitorList{
width: 100%;
height: 50%;
overflow: auto;
}
.realTimeManage .left>.leftTop>.monitorList>div:nth-child(1){
border-top: 0.5px solid #F5F4F4;
}
.realTimeManage .left>.rightTop{
width: 77%;
height: 75%;
}
.realTimeManage .left>.down{
margin-top: 1%;
width: 100%;
height: 23%;
overflow-x: auto;
white-space: nowrap;
overflow-y: hidden;
}
.realTimeManage .left>.down>div{
height: 100%;
width: 17%;
margin-left: 2%;
display: inline-block;
}
.realTimeManage .left>.down>div>div:nth-child(1){
width: 100%;
height: 68%;
}
.realTimeManage .left>.down>div>div:nth-child(2){
width: 100%;
height: 16%;
display: flex;
justify-content: space-between;
align-items: center;
}
.realTimeManage .left>.down>div>div:nth-child(2)>span{
text-indent: 8px;
color: #333333;
font-size: 14px;
}
.realTimeManage .left>.down>div>div:nth-child(3){
width: 100%;
height: 16%;
text-indent: 8px;
color: #333333;
font-size: 14px;
}
.realTimeManage .right{
margin-left: 1%;
width:32%;
height: 100%;
}
.realTimeManage .right>div:nth-child(1){
width: 100%;
height: 6%;
color: #333333;
font-size: 14px;
font-weight: 600;
display: flex;
align-items: center;
text-indent: 20px;
}
.realTimeManage .right>div:nth-child(2){
width: 100%;
height: 94%;
overflow: auto;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px #e8eceb;
border-radius: 5px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #ffffff;
-webkit-box-shadow: inset 0 0 6px #cbb7b7;
}
::-webkit-scrollbar-thumb:window-inactive {
background: #e8eceb;
}
::-webkit-scrollbar-corner {
background-color: #e8eceb;
}
</style>