feat: 内网视频功能添加以及BUG修改

This commit is contained in:
kun 2024-01-17 18:48:47 +08:00
parent 427703fa5c
commit 5a4d182c0d
13 changed files with 4710 additions and 106 deletions

View File

@ -34,8 +34,11 @@
let configValue = {
viewToken: "",
urn: "",
bimComponent: [],
hideArr: [],
colorArr: [],
};
let firstEnter = 0;
let dealArr = [];
async function main() {
// 创建实例需要传入的参数部署环境serviceConfig 和 用户有效期getAccessToken
const applicationOptions = {
@ -67,7 +70,59 @@
obvDocument: obvDocument,
viewer3dItem: viewer3dItems[0],
});
// 设置监听事件
// 监听模型树加载完成可以查询模型树getObjectTree
obvApi.addEventListener(
OBV.ViewerEventTypes.V3dModelTreeLoadedEvent,
(event) => {
console.log("V3dModelTreeLoadedEvent", event);
// 设置监听事件(主要用于模型树隐藏)
obvApi.addEventListener(
OBV.ViewerEventTypes.V3dHideEvent,
(event) => {
console.log(event);
// obvApi
// .getObjectTree(event.nodeIdArray[0].modelId)
// .then(async (modelTreeData) => {
// console.log(JSON.parse(JSON.stringify(modelTreeData)));
// let responseData = JSON.parse(JSON.stringify(modelTreeData))
// dealArr.push({modelId: responseData.modelId, dbId: responseData.rootId})
// await dealArrData(responseData.root.children);
// // 往父级传递
// window.parent.postMessage({ msg: dealArr, tip: 'hidden' });
// });
// 往父级传递
window.parent.postMessage({
msg: event.nodeIdArray,
tip: "hidden",
});
}
);
// 设置监听事件(主要用于模型树显示)
obvApi.addEventListener(
OBV.ViewerEventTypes.V3dShowEvent,
(event) => {
console.log(event);
// obvApi
// .getObjectTree(event.nodeIdArray[0].modelId)
// .then(async (modelTreeData) => {
// console.log(JSON.parse(JSON.stringify(modelTreeData)));
// let responseData = JSON.parse(JSON.stringify(modelTreeData))
// dealArr.push({dbId: responseData.rootId})
// await dealArrData(responseData.root.children);
// // 往父级传递
// window.parent.postMessage({ msg: dealArr, tip: 'hidden' });
// });
// 往父级传递
window.parent.postMessage({
msg: event.nodeIdArray,
tip: "show",
});
}
);
}
);
// 设置监听事件(构件选择)
obvApi.addEventListener(
OBV.ViewerEventTypes.V3dSelectionChangedEvent,
(event) => {
@ -76,33 +131,60 @@
window.parent.postMessage({ msg: event.nodeIdArray });
}
);
// 监听相机改变
obvApi.addEventListener(
OBV.ViewerEventTypes.V3dCameraChangeEvent,
(event) => {
console.log("V3dCameraChangeEvent", event);
// 操作模型
renderConfigModel(obvApi);
if (firstEnter == 0) {
// 首次进入才操作模型
// 操作模型
renderConfigModel(obvApi);
}
}
);
}
// 处理数据
function dealArrData(arr) {
arr.map((item) => {
if (item.children && item.children.length > 0) {
dealArrData(item.children);
}
dealArr.push({ dbId: item.dbId });
});
}
function renderConfigModel(obvApi) {
console.log(obvApi);
console.log(configValue.bimComponent);
console.log(configValue.hideArr);
++firstEnter; // 避免多次调用
// 隐藏构件
if (configValue.hideArr.length > 0) {
obvApi.hide(configValue.hideArr);
}
// else {
// obvApi.showAll();
// }
// 构件着色
if (configValue.bimComponent.length > 0) {
// 构件着色
configValue.bimComponent.map((item) => {
if(item.modelId){
if (configValue.colorArr.length > 0) {
configValue.colorArr.map((item) => {
if (item.modelId) {
let firstIndex = item.color.indexOf(",");
let secondIndex = item.color.indexOf(",", firstIndex + 1);
let thirdIndex = item.color.indexOf(")", -1);
// 构件着色
obvApi.setObjectsColor([item], 51, 122, 183, 1);
obvApi.setObjectsColor(
[item],
item.color.substring(4, firstIndex),
item.color.substring(firstIndex + 2, secondIndex),
item.color.substring(secondIndex + 2, thirdIndex),
1
);
}
});
// obvApi.setObjectsColor(configValue.bimComponent, 51, 122, 183, 1);
} else {
obvApi.restoreObjectsColor();
}
// else {
// obvApi.restoreObjectsColor();
// }
}
// 访问的令牌 getAccessToken 和 令牌有效期 expiresIn
function getAccessToken(callBack) {
@ -113,7 +195,9 @@
window.addEventListener("message", async function(e) {
// const modelId = e.data.modelId
const data = e.data || {};
console.log(data);
console.log(data.token);
console.log(data.urn);
firstEnter = 0;
if (data.token && data.urn) {
configValue.viewToken = data.token;
configValue.urn = data.urn;
@ -121,10 +205,9 @@
document.getElementById("viewer").innerHTML = "";
// 调用main函数进行代码的实现
main();
if (data.bimComponent) {
configValue.bimComponent = data.bimComponent;
} else {
configValue.bimComponent = [];
if (data.hideArr && data.colorArr) {
configValue.hideArr = data.hideArr;
configValue.colorArr = data.colorArr;
}
}
});

3514
public/lib/adapter.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 497 B

View File

@ -83,8 +83,8 @@ if (process.env.NODE_ENV == 'development') {
// axios.defaults.baseURL ='http://huli.zjzhiliao.com/jxjgdapi/' //金林湾测试线上
// axios.defaults.baseURL ='http://101.43.164.214:45001/' //上海张江
// axios.defaults.baseURL ='http://101.43.164.214:45011/' //上海优益(上海建工)
axios.defaults.baseURL = 'http://192.168.34.221:28889/' //郭圣雄本地
// axios.defaults.baseURL ='http://192.168.34.221:9111/' //郭圣雄本地
// axios.defaults.baseURL = 'http://192.168.34.221:28889/' //郭圣雄本地
axios.defaults.baseURL ='http://192.168.34.221:9111/' //郭圣雄本地
// axios.defaults.baseURL = 'http://182.90.224.237:51234' //郭圣雄远程
// axios.defaults.baseURL ='http://101.43.164.214:45020/' //沈阳和盈
// axios.defaults.baseURL ='http://183.249.224.118:9000/' //嘉兴王江泾公用码头

View File

@ -17,6 +17,9 @@
<script src="/lib/jquery-1.12.4.min.js"></script>
<script src="/lib/jsencrypt.min.js"></script>
<script src="/lib/jsWebControl-1.0.0.min.js"></script>
<!-- webrtc播放器视频文件 -->
<script type="text/javascript" src="/lib/adapter.min.js"></script>
<script type="text/javascript" src="/lib/webrtcstreamer.js"></script>
<!-- 注:中建项目不用引入以下这些资源 -->
<title>

View File

@ -2755,6 +2755,13 @@ const routes2 = [
component: (resolve) =>
require(["@/views/projectFront/videoManage/overview.vue"], resolve),
},
// 内网视频
{
path: "/project/insideVideo",
name: "insideVideo",
component: (resolve) =>
require(["@/views/projectFront/insideVideo/overview.vue"], resolve),
},
{
path: "/project/imgRanging",
name: "imgRanging",

View File

@ -200,17 +200,27 @@
:visible.sync="showRelative"
title="关联构件"
>
<div class="data-show">
<span>选中的数据值</span>
<div class="selected-box">
<template v-show="selectedList.length > 0">
<div v-for="(item, index) in selectedList" :key="index">
<span>{{ item ? item.dbId : "" }}</span>
<i class="el-icon-close" @click="deleteSelected(index)"></i>
</div>
</template>
</div>
<el-button type="primary" size="small" @click="saveSelected"
<div class="select-operate">
<span>模型构件操作</span>
<el-select v-model="formData.type" placeholder="请选择" size="small">
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-color-picker
v-model="formData.color"
v-if="formData.type == 2"
style="margin-left: 10px;"
color-format="rgb"
></el-color-picker>
<el-button
type="primary"
size="small"
@click="saveSelected"
style="margin-left: 10px;"
>保存</el-button
>
</div>
@ -239,6 +249,16 @@ export default {
mounted() {},
data() {
return {
selectedHideList: [],
selectedColorList: [],
typeOptions: [
{ label: "隐藏", value: 1 },
{ label: "着色", value: 2 },
],
formData: {
type: 1,
color: "",
},
urn: "",
token: "",
url: "",
@ -291,17 +311,56 @@ export default {
},
methods: {
getIframeMessage(e) {
console.log("Message from iframe", e.data.msg);
if (e.data.msg) {
let dataIndex = null;
dataIndex = this.selectedList.find((item) => {
return item.dbId == e.data.msg[0].dbId;
});
if (!dataIndex) {
this.selectedList.push({
...e.data.msg[0],
});
console.log("Message from iframe", e.data);
if (e.data.msg && e.data.msg.length > 0) {
if (this.formData.type == 1) {
if (e.data.tip == "show") {
let dataShowIndex = null;
e.data.msg.map((item) => {
dataShowIndex = this.selectedHideList.findIndex((item2) => {
return item2.dbId == item.dbId;
});
console.log(dataShowIndex);
if (dataShowIndex >= 0) {
this.selectedHideList.splice(dataShowIndex, 1);
}
});
} else {
let dataHiddenIndex = null;
e.data.msg.map((item) => {
dataHiddenIndex = this.selectedHideList.find((item2) => {
return item2.dbId == item.dbId;
});
if (!dataHiddenIndex) {
this.selectedHideList.push({
...item,
});
}
});
}
} else {
if (!e.data.tip) {
let dataIndex = null;
e.data.msg.map((item) => {
dataIndex = this.selectedColorList.findIndex((item2) => {
return item2.dbId == item.dbId;
});
if (dataIndex == -1) {
this.selectedColorList.push({
...item,
color: this.formData.color,
});
} else {
this.selectedColorList[dataIndex] = {
...item,
color: this.formData.color,
};
}
});
}
}
this.selectedColorList = this.selectedColorList;
this.$forceUpdate();
}
},
//
@ -309,15 +368,17 @@ export default {
let that = this;
editProgressBindComponentApi({
id: this.rowData.id,
bimComponent: JSON.stringify(this.selectedList),
hiddenComponentId: JSON.stringify(this.selectedHideList),
componentColorJson: JSON.stringify(this.selectedColorList),
}).then((res) => {
if (res.code == 200) {
this.$message.success("操作成功");
that.getProgressListData();
that.iframe.contentWindow.postMessage({
token: that.token,
urn: that.urn,
bimComponent: that.selectedList,
token: this.token,
urn: this.urn,
hideArr: this.selectedHideList,
colorArr: this.selectedColorList,
});
}
});
@ -332,10 +393,15 @@ export default {
let that = this;
this.rowData = row;
console.log(row);
if (row.bimComponent) {
this.selectedList = JSON.parse(row.bimComponent);
if (row.hiddenComponentId) {
this.selectedHideList = JSON.parse(row.hiddenComponentId);
} else {
this.selectedList = [];
this.selectedHideList = [];
}
if (row.componentColorJson) {
this.selectedColorList = JSON.parse(row.componentColorJson);
} else {
this.selectedColorList = [];
}
this.showRelative = true;
const res = await getBimBaseDetailsApi({
@ -364,7 +430,8 @@ export default {
this.iframe.contentWindow.postMessage({
token: that.token,
urn: that.urn,
bimComponent: JSON.parse(row.bimComponent),
hideArr: this.selectedHideList,
colorArr: this.selectedColorList,
});
});
},
@ -428,35 +495,8 @@ export default {
height: 800px;
overflow: auto;
}
.data-show {
width: max-content;
max-width: 100%;
.select-operate {
@include flex;
margin-top: 10px;
.selected-box {
flex: 1%;
min-width: 208px;
min-height: 32px;
border: 1px solid #c0c4cc;
border-radius: 4px;
@include flex;
flex-wrap: wrap;
padding-left: 6px;
margin-right: 15px;
> div {
@include flex;
background-color: #f4f4f5;
padding: 3px 5px;
margin: 3px 6px 3px 0;
span {
color: #909399;
margin-right: 3px;
}
.el-icon-close {
cursor: pointer;
}
}
}
}
.model-box {
display: flex;

View File

@ -86,9 +86,7 @@
label="分部分项工程名称"
>
<template slot-scope="scope">
<span
:title="scope.row.taskName"
>
<span :title="scope.row.taskName">
{{ scope.row.taskName }}
</span>
</template>
@ -452,7 +450,7 @@
:visible.sync="showRelative"
title="关联构件"
>
<div class="data-show">
<!-- <div class="data-show">
<span>选中的数据值</span>
<div class="selected-box">
<template v-show="selectedList.length > 0">
@ -465,6 +463,30 @@
<el-button type="primary" size="small" @click="saveSelected"
>保存</el-button
>
</div> -->
<div class="select-operate">
<span>模型构件操作</span>
<el-select v-model="formData.type" placeholder="请选择" size="small">
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-color-picker
v-model="formData.color"
v-if="formData.type == 2"
style="margin-left: 10px;"
color-format="rgb"
></el-color-picker>
<el-button
type="primary"
size="small"
@click="saveSelected"
style="margin-left: 10px;"
>保存</el-button
>
</div>
<div class="model-box">
<iframe
@ -495,13 +517,28 @@ import {
export default {
data() {
return {
selectedHideList: [],
selectedColorList: [],
typeOptions: [
{ label: "隐藏", value: 1 },
{ label: "着色", value: 2 },
],
formData: {
type: 1,
color: "",
},
urn: "",
token: "",
url: "",
iframe: "",
selectedList: [],
showRelative: false,
rowData: {},
parentTaskName: "", // taskName
urn: "",
token: "",
url: "",
iframe: "",
selectedList: [],
showRelative: false,
options: [
{
@ -742,33 +779,75 @@ export default {
this.dialogVisible = true;
},
getIframeMessage(e) {
console.log("Message from iframe", e.data.msg);
if (e.data.msg) {
let dataIndex = null;
dataIndex = this.selectedList.find((item) => {
return item.dbId == e.data.msg[0].dbId;
});
if (!dataIndex) {
this.selectedList.push({
...e.data.msg[0],
});
console.log("Message from iframe", e.data);
if (e.data.msg && e.data.msg.length > 0) {
if (this.formData.type == 1) {
if (e.data.tip == "show") {
let dataShowIndex = null;
e.data.msg.map((item) => {
dataShowIndex = this.selectedHideList.findIndex((item2) => {
return item2.dbId == item.dbId;
});
console.log(dataShowIndex);
if (dataShowIndex >= 0) {
this.selectedHideList.splice(dataShowIndex, 1);
}
});
} else {
let dataHiddenIndex = null;
e.data.msg.map((item) => {
dataHiddenIndex = this.selectedHideList.find((item2) => {
return item2.dbId == item.dbId;
});
if (!dataHiddenIndex) {
this.selectedHideList.push({
...item,
});
}
});
}
} else {
if (!e.data.tip) {
let dataIndex = null;
e.data.msg.map((item) => {
dataIndex = this.selectedColorList.findIndex((item2) => {
return item2.dbId == item.dbId;
});
if (dataIndex == -1) {
this.selectedColorList.push({
...item,
color: this.formData.color,
});
} else {
this.selectedColorList[dataIndex] = {
...item,
color: this.formData.color,
};
}
});
}
}
this.selectedColorList = this.selectedColorList;
this.$forceUpdate();
}
},
//
saveSelected() {
console.log(this.selectedColorList);
let that = this;
editProgressBindComponentRtApi({
id: this.rowData.id,
bimComponent: JSON.stringify(this.selectedList),
hiddenComponentId: JSON.stringify(this.selectedHideList),
componentColorJson: JSON.stringify(this.selectedColorList),
}).then((res) => {
if (res.code == 200) {
this.$message.success("操作成功");
that.getProgressListData();
that.iframe.contentWindow.postMessage({
token: that.token,
urn: that.urn,
bimComponent: that.selectedList,
token: this.token,
urn: this.urn,
hideArr: this.selectedHideList,
colorArr: this.selectedColorList,
});
}
});
@ -783,10 +862,15 @@ export default {
let that = this;
this.rowData = row;
console.log(row);
if (row.bimComponent) {
this.selectedList = JSON.parse(row.bimComponent);
if (row.hiddenComponentId) {
this.selectedHideList = JSON.parse(row.hiddenComponentId);
} else {
this.selectedList = [];
this.selectedHideList = [];
}
if (row.componentColorJson) {
this.selectedColorList = JSON.parse(row.componentColorJson);
} else {
this.selectedColorList = [];
}
this.showRelative = true;
const res = await getBimBaseDetailsApi({
@ -811,14 +895,15 @@ export default {
return;
}
this.$nextTick(() => {
console.log(777)
console.log(777);
this.iframe = document.getElementById("iframe");
this.iframe.contentWindow.postMessage({
token: that.token,
urn: that.urn,
bimComponent: JSON.parse(row.bimComponent),
hideArr: this.selectedHideList,
colorArr: this.selectedColorList,
});
console.log(888)
console.log(888);
});
},
//
@ -1096,8 +1181,8 @@ export default {
.table_wrap {
height: 800px;
overflow: auto;
:deep(){
.cell{
:deep() {
.cell {
display: flex;
align-items: center;
}
@ -1114,6 +1199,9 @@ export default {
margin-bottom: 20px;
}
}
.select-operate {
@include flex;
}
.data-show {
width: max-content;
max-width: 100%;

View File

@ -0,0 +1,39 @@
<!--ckplayer 视频播放-->
<template>
<div style="height: 100%">
<video :id="'videoItem' + name" style="width: 100%; height: 100%; object-fit: fill" :autoplay="autoPlay" muted />
</div>
</template>
<script>
export default {
props: ["videoUrls", "autoPlay", "poster", "deviceIp", "name"],
data() {
return {
player: "",
webRtcServer: null
};
},
// watch: {
// name: {
// handler(newName, oldName) {
// console.log(this.videoUrls, this.deviceIp, this.autoPlay, this.name);
// let webRtcServer = null;
// webRtcServer = new WebRtcStreamer("videoItem" + this.name, this.deviceIp);
// webRtcServer.connect(this.videoUrls);
// },
// immediate: true
// }
// },
mounted: function () {
console.log(this.videoUrls, this.deviceIp, this.autoPlay, this.name);
let webRtcServer = this.webRtcServer;
webRtcServer = new WebRtcStreamer("videoItem" + this.name, this.deviceIp);
webRtcServer.connect(this.videoUrls);
},
beforeDestroy: function () {
this.webRtcServer.disconnect();
},
methods: {}
};
</script>

View File

@ -0,0 +1,494 @@
<template>
<div class="fullHeight videoOverview">
<closePage></closePage>
<div class="header"></div>
<div class="videoContent">
<div class="videoListBox fullHeight">
<div class="pageTitle">视频列表</div>
<div class="videoBox" v-if="dataType == 1">
<vue-scroll>
<ul v-if="devList.length > 0">
<li
@click.stop="changeVideo(item)"
v-for="(item, index) in devList"
:key="index"
>
<img
v-if="item.deviceType == 2"
src="@/assets/images/icon-video2-white.png"
/>
<img v-else src="@/assets/images/icon-video-white.png" />
{{ item.videoName }}
</li>
</ul>
<div class="placeholderBox" v-else>
<img src="@/assets/images/noData2-dark.png" alt="" srcset="" />
</div>
</vue-scroll>
</div>
<div class="videoBox" v-else>
<vue-scroll>
<el-collapse v-model="activeNames" style="padding: 0 20px">
<el-collapse-item
:title="item.name"
:name="index"
v-for="(item, index) in devList"
:key="index"
>
<ul v-if="item.list.length > 0">
<li
@click.stop="changeVideo(data)"
v-for="(data, index2) in item.list"
:key="index2"
>
<img
v-if="data.deviceType == 2"
src="@/assets/images/icon-video2-white.png"
/>
<img v-else src="@/assets/images/icon-video-white.png" />
{{ data.videoName }}
</li>
</ul>
</el-collapse-item>
</el-collapse>
</vue-scroll>
</div>
</div>
<div class="Content">
<div class="flex-col page space-y-16">
<div class="flex-col fullContent">
<div class="flex-row justify-between group">
<div class="flex-row items-center space-x-16"></div>
<div class="flex-row items-center space-x-16">
<img
v-show="showType == 1"
class="shrink-0 image_3 cursorPointer"
src="@/assets/images/videoOne1.png"
/>
<img
v-show="showType != 1"
@click="changeShowType(1)"
class="shrink-0 image_3 cursorPointer"
src="@/assets/images/videoOne.png"
/>
<img
v-show="showType == 4"
class="shrink-0 image_4"
src="@/assets/images/videoTwo1.png"
/>
<img
v-show="showType != 4"
@click="changeShowType(4)"
class="shrink-0 image_4 cursorPointer"
src="@/assets/images/videoTwo.png"
/>
<img
v-show="showType == 8"
class="shrink-0 image_4"
src="@/assets/images/videoThree1.png"
/>
<img
v-show="showType != 8"
@click="changeShowType(8)"
class="shrink-0 image_4 cursorPointer"
src="@/assets/images/videoThree.png"
/>
</div>
</div>
<div class="flex-row items-start relative group_2 space-x-16">
<div
class="flex-row justify-start items-start relative group_3"
:class="'showType' + showType"
>
<div
class="section_8 relative"
v-for="(item, index) in videoList"
:key="item.itemId"
@click="selectFn(index)"
:class="index == winIndex ? 'active' : ''"
>
<div class="flex-col section_3 space-y-7">
<div class="flex-row justify-between">
<div class="flex-row space-x-12 nameBox">
<span class="font_1 desc">设备名称</span>
<span class="font_1 name">{{ item.name }}</span>
</div>
<div class="closeBtn" @click="deletePlayer(index)">×</div>
</div>
</div>
<div class="flex-col section_10">
<ckplayerComp
:name="index"
:poster="''"
:deviceIp="`http://${item.account}:${item.password}`"
:videoUrls="item.serialNumber"
:autoPlay="true"
></ckplayerComp>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {
selectProjectVideoListApi,
selectUserVideoListApi,
} from "@/assets/js/api/equipmentCenter/cameraList";
import closePage from "@/components/closePage";
import ckplayerComp from "./ckplayerComp";
export default {
components: { closePage, ckplayerComp },
data() {
return {
winIndex: 0,
videoList: [],
showType: 1,
devList: [],
dataType: 1,
activeNames: [0],
screens: {},
pluginType: "",
};
},
mounted() {
// console.dir(window.parent)
// console.log(window.parent.document.getElementById("myFrame"), 12312313)
// if (this.$store.state.userInfo.accountType != 6) {
// this.loadData()
// } else {
// this.loadData2()
// }
this.loadData();
},
methods: {
deletePlayer(index) {
this.videoList.splice(index, 1);
this.changeShowType(this.showType);
},
selectFn(index) {
this.winIndex = index;
},
changeShowType(type) {
this.showType = type;
},
changeVideo(item) {
console.log("点击了列表----");
console.log(item, "xxxxxxxxxx");
let itemVal = null;
itemVal = this.videoList.find((item2) => item.itemId == item2.itemId);
console.log(itemVal)
if (!itemVal) {
this.videoList.push(item);
this.changeShowType(this.showType);
}
console.log("右边的值", this.videoList);
},
loadData() {
selectProjectVideoListApi({
projectSn: this.$store.state.projectSn,
}).then((res) => {
var DATA = res.result.videoList;
this.devList = DATA;
this.videoList = this.devList;
console.log("视频的列表", res.result);
this.dataType = res.result.type;
});
},
loadData2() {
selectUserVideoListApi({
projectSn: this.$store.state.projectSn,
userId: this.$store.state.userInfo.userId,
}).then((res) => {
var DATA = res.result.videoList;
this.devList = DATA;
this.videoList = this.devList;
this.dataType = res.result.type;
});
},
},
};
</script>
<style lang="less" scoped>
@import "./style.less";
.videoListBox {
width: 300px;
color: white;
background-color: #01112d;
}
.pageTitle {
margin: 12px 0;
background-color: #01112d;
&::before {
background-color: #00fafa;
}
}
.videoBox {
background-color: #00091a;
height: calc(100% - 30px);
margin: 0 15px 0 0;
position: relative;
li {
padding: 10px 25px;
font-size: 15px;
cursor: pointer;
display: flex;
align-items: center;
img {
margin-right: 8px;
}
&:hover {
background-color: #003e4b;
}
}
/deep/.el-collapse-item__header,
/deep/.el-collapse-item__wrap {
background-color: transparent;
color: white;
}
/deep/.el-collapse-item__content {
color: white;
padding-bottom: 0;
}
}
.Content {
flex: 1;
height: 100%;
background-color: #00091a;
.relative {
position: relative;
}
.cursorPointer {
cursor: pointer;
}
.fullContent {
height: 100%;
}
.page {
padding-top: 16px;
// background-color: #05051a;
// width: 100%;
// overflow-y: auto;
// overflow-x: hidden;
height: calc(100% - 16px);
.image {
margin-left: 24px;
width: 162px;
height: 24px;
}
.group {
padding: 0 56px 0 30px;
// .section {
// background-color: #0071f21a;
// height: 34px;
// border: solid 1px #0071f2;
// .text {
// color: #ffffffcc;
// }
// .image_2 {
// width: 40px;
// height: 32px;
// }
// }
}
.group_2 {
height: calc(100% - 26px);
.group_3 {
margin: 16px 0px;
flex-wrap: wrap;
width: 100%;
height: calc(100% - 32px);
.section_8 {
height: calc(100% - 10px);
width: calc(100% - 11px);
margin: 15px;
// &:nth-child(2n) {
// margin-right: 0;
// }
&.active {
border: 1px solid #064599;
}
.section_10 {
width: 100%;
height: 100%;
background: rgba(14, 81, 156, 0.2);
border: 1px solid rgba(12, 39, 74, 1);
}
}
&.showType4 .section_8 {
width: calc(50% - 32px);
height: calc(50% - 25px);
margin: 15px;
// &:nth-child(3n) {
// margin-right: 0;
// }
}
&.showType8 .section_8 {
width: 31%;
height: 30%;
margin: 15px;
// &:nth-child(4n) {
// margin-right: 0;
// }
}
.space-y-7 {
& > *:not(:first-child) {
margin-top: 7px;
}
}
.space-x-12 {
& > *:not(:first-child) {
margin-left: 12px;
}
}
.space-x-4 {
& > *:not(:first-child) {
margin-left: 4px;
}
.section_6 {
background-color: #00ae4c;
border-radius: 50%;
width: 6px;
height: 6px;
}
.font_2 {
font-size: 12px;
font-family: "PingFang SC";
line-height: 17px;
color: #ffffff;
}
.section_12 {
background-color: #ab353a;
border-radius: 50%;
width: 6px;
height: 6px;
}
}
.font_3 {
font-size: 12px;
font-family: "PingFang SC";
line-height: 17px;
color: #ffffffcc;
}
.section_3 {
padding: 11px 12px;
background-image: linear-gradient(
-90deg,
#174c9c00 0%,
#174c9ce6 100%
);
position: absolute;
left: 0;
top: 0;
width: calc(100% - 24px);
z-index: 3;
.nameBox {
flex: 1;
width: 0;
}
.desc {
width: 55px;
white-space: nowrap;
}
.name {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}
}
.space-x-16 {
& > *:not(:first-child) {
margin-left: 16px;
}
.image_3 {
width: 22px;
height: 22px;
}
.image_4 {
width: 19px;
height: 19px;
}
}
.font_1 {
font-size: 14px;
font-family: "PingFang SC";
line-height: 20px;
color: #ffffff;
}
}
.space-y-16 {
& > *:not(:first-child) {
margin-top: 16px;
}
}
.flex-row {
display: flex;
flex-direction: row;
}
.closeBtn {
width: 12px;
height: 12px;
text-align: center;
line-height: 12px;
color: white;
// border: 1px solid white;
// border-radius: 50%;
font-size: 12px;
position: absolute;
top: 0px;
right: 0px;
cursor: pointer;
}
.flex-col {
display: flex;
flex-direction: column;
}
.justify-start {
justify-content: flex-start;
}
.justify-end {
justify-content: flex-end;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.justify-around {
justify-content: space-around;
}
.justify-evenly {
justify-content: space-evenly;
}
.items-start {
align-items: flex-start;
}
.items-end {
align-items: flex-end;
}
.items-center {
align-items: center;
}
}
</style>

View File

@ -0,0 +1,14 @@
.videoOverview{
background-color: #0D1534;
}
.header{
background: url('../../../assets/images/overview3/headerBG.png') center;
height: 70px;
width: 100%;
}
.videoContent{
display: flex;
height: calc(100% - 70px);
// background-color: #2FBBEC;
overflow: hidden;
}

View File

@ -62,7 +62,7 @@
<img
class="rect"
v-if="select == 3"
src="@/assets/images/videoThree1.png.png"
src="@/assets/images/videoThree1.png"
alt
/>
<img class="rect" v-else src="@/assets/images/videoThree.png" alt />