Commit 2e576186 authored by 张牧越's avatar 张牧越

bugfix

parent 26ca99b7
NODE_ENV = "development" NODE_ENV = "development"
Mock: true Mock: true
VUE_APP_API_URL = "http://192.168.0.127:8002" VUE_APP_API_URL = "http://yth.vnet.io"
...@@ -86,6 +86,10 @@ export default { ...@@ -86,6 +86,10 @@ export default {
type: String, type: String,
default: "", default: "",
}, },
deviceType: {
type: String,
default: "",
},
}, },
data() { data() {
return { return {
...@@ -104,6 +108,7 @@ export default { ...@@ -104,6 +108,7 @@ export default {
handleCurrentChange(current) { handleCurrentChange(current) {
getDeviceList({ getDeviceList({
...this.searchForm, ...this.searchForm,
top_cat: this.deviceType,
limit: this.pageSize, limit: this.pageSize,
page: current, page: current,
}).then((res) => { }).then((res) => {
...@@ -115,6 +120,7 @@ export default { ...@@ -115,6 +120,7 @@ export default {
handleSizeChange(size) { handleSizeChange(size) {
getDeviceList({ getDeviceList({
...this.searchForm, ...this.searchForm,
top_cat: this.deviceType,
limit: size, limit: size,
page: 1, page: 1,
}).then((res) => { }).then((res) => {
...@@ -126,6 +132,7 @@ export default { ...@@ -126,6 +132,7 @@ export default {
searchRecords() { searchRecords() {
getDeviceList({ getDeviceList({
...this.searchForm, ...this.searchForm,
top_cat: this.deviceType,
limit: this.pageSize, limit: this.pageSize,
page: 1, page: 1,
}).then((res) => { }).then((res) => {
......
...@@ -313,25 +313,24 @@ ...@@ -313,25 +313,24 @@
class="status-count" class="status-count"
v-for="(status, index) in deviceStatus" v-for="(status, index) in deviceStatus"
:key="index" :key="index"
@click="jumpPage(status)"
> >
<img class="status-img" :src="status.icon_path" alt="" /> <img class="status-img" :src="status.icon_path" alt="" />
<div class="status-text"> <div class="status-text">
{{ status.name }} {{ status.name }}
</div> </div>
<div class="status-number"> <div class="status-number" @click="showDeviceList(status, '')">
总数:<span 总数:<span
><span class="number">{{ status.total }}</span ><span class="number">{{ status.total }}</span
></span ></span
> >
</div> </div>
<div class="status-number"> <div class="status-number" @click="showDeviceList(status, '1')">
在线:<span style="color: #1bc8b6" 在线:<span style="color: #1bc8b6"
><span class="number">{{ status.zx_total }}</span ><span class="number">{{ status.zx_total }}</span
></span ></span
> >
</div> </div>
<div class="status-number"> <div class="status-number" @click="showDeviceList(status, '0')">
离线:<span style="color: #bf9063" 离线:<span style="color: #bf9063"
><span class="number">{{ status.lx_total }}</span ><span class="number">{{ status.lx_total }}</span
></span ></span
...@@ -394,7 +393,8 @@ ...@@ -394,7 +393,8 @@
<DeviceDialog <DeviceDialog
:visible="deviceDialogVisible" :visible="deviceDialogVisible"
:type="onlineStatus" :type="onlineStatus"
@changeVisible="(val) => (deviceDialogVisible = val)" :deviceType="deviceType"
@changeVisible="changeDeviceVisible"
></DeviceDialog> ></DeviceDialog>
<WarningRecordDialog <WarningRecordDialog
:visible="warningRecordVisible" :visible="warningRecordVisible"
...@@ -458,6 +458,7 @@ export default { ...@@ -458,6 +458,7 @@ export default {
deviceDialogVisible: false, deviceDialogVisible: false,
onlineStatus: "online", onlineStatus: "online",
warningRecordVisible: false, warningRecordVisible: false,
deviceType: "",
}; };
}, },
methods: { methods: {
...@@ -676,52 +677,15 @@ export default { ...@@ -676,52 +677,15 @@ export default {
this.autoScrollStatus(1, 50, 1500, element); this.autoScrollStatus(1, 50, 1500, element);
}); });
}, },
jumpPage(item) { showDeviceList(item, onlineStatus) {
if (item.type == 1) { this.deviceType = item.type;
this.$router.push({ this.onlineStatus = onlineStatus;
path: "/tower", this.deviceDialogVisible = true;
query: { ...this.$route.query }, },
}); changeDeviceVisible(val) {
} else if (item.type == 2) { this.deviceDialogVisible = val;
this.$router.push({ if (!val) {
path: "/supervisory", this.deviceType = "";
query: { ...this.$route.query },
});
} else if (item.type == 3) {
this.$router.push({
path: "/realname",
query: { ...this.$route.query },
});
} else if (item.type == 4) {
this.$router.push({
path: "/safecap",
query: { ...this.$route.query },
});
} else if (item.type == 8) {
this.$router.push({
path: "/earlywarning",
query: { ...this.$route.query },
});
} else if (item.type == 9) {
this.$router.push({
path: "/noise",
query: { ...this.$route.query },
});
} else if (item.type == 13) {
this.$router.push({
path: "/fallprotection",
query: { ...this.$route.query },
});
} else if (item.type == 14) {
this.$router.push({
path: "/unloadingplatform",
query: { ...this.$route.query },
});
} else if (item.type == 15) {
this.$router.push({
path: "/elevator",
query: { ...this.$route.query },
});
} }
}, },
}, },
...@@ -906,19 +870,19 @@ table { ...@@ -906,19 +870,19 @@ table {
} }
.step-title { .step-title {
position: relative; position: relative;
color: #c0c4cc; // color: #c0c4cc;
font-size: 12px; font-size: 12px;
.step-status { .step-status {
position: absolute; position: absolute;
top: -130%; top: -130%;
color: #c0c4cc; // color: #c0c4cc;
font-size: 12px; font-size: 12px;
} }
} }
.step-description { .step-description {
font-size: 14px; font-size: 14px;
color: #c0c4cc; // color: #c0c4cc;
} }
.progress-contains { .progress-contains {
...@@ -1002,7 +966,7 @@ table { ...@@ -1002,7 +966,7 @@ table {
padding: 8px 10px; padding: 8px 10px;
background: rgba(44, 96, 162, 0.2); background: rgba(44, 96, 162, 0.2);
text-align: left; text-align: left;
cursor: pointer;
margin-bottom: 10px; margin-bottom: 10px;
white-space: nowrap; white-space: nowrap;
.status-img { .status-img {
...@@ -1026,6 +990,7 @@ table { ...@@ -1026,6 +990,7 @@ table {
vertical-align: middle; vertical-align: middle;
} }
.status-number { .status-number {
cursor: pointer;
font-weight: 400; font-weight: 400;
color: #25d2ff; color: #25d2ff;
font-size: 13px; font-size: 13px;
......
...@@ -59,14 +59,41 @@ ...@@ -59,14 +59,41 @@
</div> </div>
<div <div
id="video-container" id="video-container"
v-if="deviceData.is_camera == 1" v-if="deviceData.camera_list && deviceData.camera_list.length > 0"
v-loading="videoLoading" v-loading="videoLoading"
element-loading-background="rgba(0, 0, 0, 0.8)" element-loading-background="rgba(0, 0, 0, 0.8)"
></div> >
<div v-show="player" id="video-container-inner"></div>
<div class="video-container-img" v-show="!player">
<img src="@/assets/tower/no_camera.png" alt="" />
<div>暂无监控信息</div>
</div>
</div>
<div id="video-container-img" v-else> <div id="video-container-img" v-else>
<img src="@/assets/tower/no_camera.png" alt="" /> <img src="@/assets/tower/no_camera.png" alt="" />
<div>暂无监控信息</div> <div>暂无监控信息</div>
</div> </div>
<div
class="video-buttons"
v-if="deviceData.camera_list && deviceData.camera_list.length > 1"
>
<div class="all-video" @click="watchAll">全部监控</div>
<div class="video-list">
<div
:class="['camera-button', videoIndex == index ? 'active' : '']"
v-for="(camera, index) in deviceData.camera_list"
:key="index"
@click="switchCamera(camera, index)"
>
{{ camera.link_device_position_name }}
</div>
</div>
</div>
<VideoDialog
:visible="videoDialogVisible"
:idList="videoIdArray"
@changeVisible="(val) => (videoDialogVisible = val)"
></VideoDialog>
</div> </div>
<div class="title-label"> <div class="title-label">
...@@ -83,8 +110,10 @@ import { getDeviceTodayChart, getTowerLiveUrl } from "@/api/index"; ...@@ -83,8 +110,10 @@ import { getDeviceTodayChart, getTowerLiveUrl } from "@/api/index";
require("vue-video-player/node_modules/video.js/dist/video-js.css"); require("vue-video-player/node_modules/video.js/dist/video-js.css");
import videojs from "video.js"; import videojs from "video.js";
import "videojs-contrib-hls"; import "videojs-contrib-hls";
import VideoDialog from "./videoDialog";
export default { export default {
name: "DeviceDialog", name: "DeviceDialog",
components: { VideoDialog },
props: { props: {
visible: { visible: {
type: Boolean, type: Boolean,
...@@ -106,9 +135,20 @@ export default { ...@@ -106,9 +135,20 @@ export default {
todayData: [], todayData: [],
player: null, player: null,
videoLoading: false, videoLoading: false,
videoIndex: 0,
videoDialogVisible: false,
videoIdArray: [],
}; };
}, },
methods: { methods: {
watchAll() {
this.videoIdArray = this.deviceData.camera_list.map((item) => {
return item;
});
this.$nextTick(() => {
this.videoDialogVisible = true;
});
},
renderTodayChart() { renderTodayChart() {
const xAxisData = this.todayData.map((item) => { const xAxisData = this.todayData.map((item) => {
return item.time; return item.time;
...@@ -189,10 +229,17 @@ export default { ...@@ -189,10 +229,17 @@ export default {
}); });
}, },
openedEvents() { openedEvents() {
if (this.deviceData.is_camera == 1) { getDeviceTodayChart(this.deviceId).then((result) => {
this.todayData = result.data;
this.$nextTick(() => {
this.renderTodayChart();
});
});
if (this.deviceData.camera_list.length > 0) {
this.videoLoading = true; this.videoLoading = true;
getTowerLiveUrl(this.deviceData.camera_id).then((res) => { getTowerLiveUrl(this.deviceData.camera_list[0].id).then((res) => {
const myVideoDiv = document.getElementById(`video-container`); if (res.data.live_address_url) {
const myVideoDiv = document.getElementById(`video-container-inner`);
myVideoDiv.innerHTML = `<video myVideoDiv.innerHTML = `<video
id="singleVideo" id="singleVideo"
autoplay="autoplay" autoplay="autoplay"
...@@ -210,22 +257,44 @@ export default { ...@@ -210,22 +257,44 @@ export default {
}); });
singlePlayer.play(); singlePlayer.play();
this.player = singlePlayer; this.player = singlePlayer;
} else {
this.player = null;
}
this.videoLoading = false; this.videoLoading = false;
getDeviceTodayChart(this.deviceId).then((result) => {
this.todayData = result.data;
this.$nextTick(() => {
this.renderTodayChart();
}); });
}
},
switchCamera(camera, index) {
this.player && this.player.dispose();
this.videoIndex = index;
this.$nextTick(() => {
this.videoLoading = true;
getTowerLiveUrl(camera.id).then((res) => {
if (res.data.live_address_url) {
const myVideoDiv = document.getElementById(`video-container-inner`);
myVideoDiv.innerHTML = `<video
id="singleVideo"
autoplay="autoplay"
class="video-js vjs-default-skin"
></video>`;
const singlePlayer = videojs(`singleVideo`, {
autoplay: true, // 自动播放
controls: true, // 控件显示
preload: "auto", //定义视频加载模式
loop: true, //是否循环播放
}); });
singlePlayer.src({
src: res.data.live_address_url,
type: "application/x-mpegURL",
}); });
singlePlayer.play();
this.player = singlePlayer;
} else { } else {
getDeviceTodayChart(this.deviceId).then((result) => { this.player = null;
this.todayData = result.data; }
this.$nextTick(() => { this.videoLoading = false;
this.renderTodayChart();
}); });
}); });
}
}, },
}, },
computed: { computed: {
...@@ -242,12 +311,14 @@ export default { ...@@ -242,12 +311,14 @@ export default {
dialogVisible(val) { dialogVisible(val) {
if (!val) { if (!val) {
this.player && this.player.dispose(); this.player && this.player.dispose();
this.videoIndex = 0;
} }
}, },
}, },
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import "@/assets/common/element.less";
.title-label { .title-label {
border-bottom: 2px solid #00b7ee; border-bottom: 2px solid #00b7ee;
height: 18px; height: 18px;
...@@ -268,6 +339,52 @@ export default { ...@@ -268,6 +339,52 @@ export default {
} }
#video-container { #video-container {
width: calc(40% - 20px); width: calc(40% - 20px);
position: relative;
margin-left: 12px;
#video-container-inner {
width: 100%;
height: 100%;
}
.video-container-img {
width: calc(100% - 40px);
height: calc(100% - 40px);
text-align: center;
border: 1px solid #00b7ee;
box-shadow: 0px 21px 24px 0px rgba(42, 78, 169, 0.4);
border-radius: 4px;
padding: 20px;
background: #113e77;
text-align: center;
font-size: 14px;
color: #3f6fab;
img {
width: 130px;
vertical-align: top;
}
}
.switch-prev {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 30px;
vertical-align: top;
cursor: pointer;
z-index: 999;
}
.switch-next {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 30px;
vertical-align: top;
cursor: pointer;
z-index: 999;
}
} }
#video-container-img { #video-container-img {
width: calc(40% - 50px); width: calc(40% - 50px);
...@@ -279,6 +396,7 @@ export default { ...@@ -279,6 +396,7 @@ export default {
background: #113e77; background: #113e77;
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
margin-left: 12px;
color: #3f6fab; color: #3f6fab;
img { img {
width: 130px; width: 130px;
...@@ -327,4 +445,47 @@ export default { ...@@ -327,4 +445,47 @@ export default {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.video-buttons {
width: 140px;
margin-left: 4px;
.all-video {
height: 40px;
background: #113e77;
border: 1px solid #00b7ee;
box-shadow: 0px 21px 24px 0px rgba(42, 78, 169, 0.4);
border-radius: 4px;
line-height: 40px;
text-align: center;
color: #c6def9;
cursor: pointer;
font-size: 14px;
&:hover {
color: #13e0ff;
}
}
.video-list {
margin-top: 4px;
height: 164px;
background: #113e77;
border: 1px solid #00b7ee;
box-shadow: 0px 21px 24px 0px rgba(42, 78, 169, 0.4);
border-radius: 4px;
text-align: center;
color: #c6def9;
font-size: 14px;
padding: 0 12px;
line-height: 54px;
overflow-y: auto;
.camera-button {
border-bottom: 1px solid #00b7ee;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
cursor: pointer;
&.active {
color: #13e0ff;
}
}
}
}
</style> </style>
\ No newline at end of file
<template>
<el-dialog
:visible.sync="dialogVisible"
title="全部监控"
append-to-body
width="1200px"
v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<div class="video-area">
<div
v-for="(videoImg, index) in idList.length == 2 ? 2 : activeSplice"
:key="index"
:class="['camera', idList.length == 2 ? `camera-in-2` : `camera-in-4`]"
>
<div v-if="!cameraList[index] || cameraList[index].player === null">
<div class="video-info">
<div class="video-no">
{{ cameraList[index] && cameraList[index].name }}
</div>
<div class="video-description">暂无画面~</div>
</div>
</div>
<div v-else class="video-pic" :ref="`video-js-container-${index}`">
<div
style="width: 100%; height: 100%"
:id="[`video-out-container-${index + 1}`]"
class="video-out-container-area"
>
<div
:id="[`video-container-${index + 1}`]"
style="width: 100%; height: 100%"
></div>
</div>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
import { getTowerLiveUrl } from "@/api/index";
require("vue-video-player/node_modules/video.js/dist/video-js.css");
import videojs from "video.js";
import "videojs-contrib-hls";
export default {
name: "VideoDialog",
props: {
visible: {
type: Boolean,
default: false,
},
idList: {
type: Array,
default: () => {
return [];
},
},
},
data() {
return {
activeSplice: 4,
cameraList: [],
loading: false,
};
},
computed: {
dialogVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit("changeVisible", val);
},
},
},
watch: {
dialogVisible(val) {
if (!val) {
this.closeAll();
} else {
this.viewAll();
}
},
},
methods: {
viewAll() {
console.log(this.idList);
if (this.idList.length > 4) {
this.activeSplice = this.idList.length;
}
this.loading = true;
this.cameraList.map((item) => {
item.player && item.player.dispose();
item.player = null;
item.id = "";
item.live_address_url = "";
});
this.cameraList = [];
this.idList.map((item, index) => {
this.cameraList.push({
player: null,
id: item.id,
name: item.link_device_position_name,
});
getTowerLiveUrl(item.id).then((res) => {
this.cameraList[index].player = undefined;
if (res.data.live_address_url) {
console.log(index);
let ts = new Date().getTime();
setTimeout(() => {
this.$nextTick(() => {
const myVideoDiv = document.getElementById(
`video-container-${index + 1}`
);
myVideoDiv.innerHTML = `<video
id="singleVideo${ts}"
autoplay="autoplay"
class="video-js vjs-default-skin"
muted="muted"
data-setup='{"userActions": {"doubleClick": false }}'
></video>`;
const singlePlayer = videojs(`singleVideo${ts}`, {
autoplay: true, // 自动播放
controls: true, // 控件显示
preload: "auto", //定义视频加载模式
loop: true, //是否循环播放
});
singlePlayer.src({
src: res.data.live_address_url,
type: "application/x-mpegURL",
});
this.$nextTick(() => {
singlePlayer.play();
});
this.cameraList[index].player = singlePlayer;
this.$forceUpdate();
});
}, 500);
} else {
this.cameraList[index].player = null;
}
if (index == this.idList.length - 1) {
this.loading = false;
}
});
});
},
closeAll() {
this.cameraList.map((item) => {
item.id = "";
item.live_address_url = "";
item.player && item.player.dispose();
item.player = null;
});
this.cameraList = [];
},
},
};
</script>
<style lang="less" scoped>
.video-area {
height: 600px;
width: 100%;
overflow-y: auto;
.camera {
font-size: 0;
&:hover {
box-shadow: inset 0 0 10px rgba(0, 162, 255, 1);
}
&.active {
box-shadow: inset 0 0 10px rgba(0, 162, 255, 1);
}
cursor: pointer;
border: 1px solid #0f95d4;
position: relative;
vertical-align: top;
box-sizing: border-box;
float: left;
background: linear-gradient(
0deg,
rgba(28, 135, 207, 0.2) 0%,
rgba(15, 60, 89, 0.37) 28%,
rgba(11, 41, 80, 0.8) 100%
);
&.camera-in-1 {
width: 100%;
height: 100%;
}
&.camera-in-2 {
width: 100%;
height: 50%;
}
&.camera-in-4 {
width: 50%;
height: 50%;
}
&.camera-in-6 {
width: calc(100% / 3);
height: calc(100% / 3 + 0.2px);
&:first-child {
width: calc(calc(100% / 3) * 2);
height: calc(calc(100% / 3) * 2);
}
}
&.camera-in-9 {
width: calc(100% / 3);
height: calc(100% / 3);
}
.video-info {
width: 80%;
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
text-align: center;
.video-no {
font-size: 26px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-weight: bold;
color: #c6eaf9;
margin-bottom: 12px;
}
.video-description {
font-size: 16px;
color: #c6def9;
}
}
.video-pic {
padding: 8px;
height: calc(100% - 16px);
&:hover {
.el-icon-circle-close {
display: block;
cursor: pointer;
}
}
img {
width: 100%;
vertical-align: top;
height: 100%;
}
.play {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
cursor: pointer;
}
}
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment