674 lines
16 KiB
Vue
674 lines
16 KiB
Vue
<template>
|
||
<div class="speed-box">
|
||
<!-- 地图背景 -->
|
||
<div class="speed-top">
|
||
<div class="speedtop-item">
|
||
<div class="title-speed">测速设备统计</div>
|
||
<div class="title-con">
|
||
<div class="statis-left">
|
||
<div class="statisl-img"></div>
|
||
<div class="statisl-text">
|
||
{{staticspeed.offlinePercent || '0%'}}
|
||
<p>设备离线率</p>
|
||
</div>
|
||
</div>
|
||
<div class="statis-right">
|
||
<div class="staisr-icon">
|
||
<div class="staisr-text">
|
||
设备总数
|
||
<p>{{staticspeed.total || '--'}}</p>
|
||
</div>
|
||
</div>
|
||
<div class="staisr-icon">
|
||
<div class="staisr-text">
|
||
在线
|
||
<p>{{staticspeed.online || '--'}}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="speedtop-item speed-margin">
|
||
<div class="title-speed">实时违章抓拍</div>
|
||
<div class="title-con">
|
||
<div class="photot-left">
|
||
<img
|
||
src="https://img2.baidu.com/it/u=1391264209,1710483683&fm=253&fmt=auto&app=138&f=JPEG?w=857&h=500"
|
||
alt
|
||
/>
|
||
</div>
|
||
<div class="photot-right">
|
||
<div class="overspeed-box" v-if="speeddatalist.isExceed == 1">已超速</div>
|
||
|
||
<div class="overspeed-boxs" v-if="speeddatalist.isExceed == 0">未超速</div>
|
||
<div class="overspeed-boxs" v-if="Object.keys(speeddatalist).length == 0">暂无数据</div>
|
||
|
||
<div class="overspeed-tiem">{{speeddatalist.uploadTime || '--'}}</div>
|
||
<div class="overspeed-con">
|
||
<p>
|
||
抓拍设备名称:
|
||
<i>{{speeddatalist.deviceName || '--'}}</i>
|
||
</p>
|
||
<p>
|
||
车牌号:
|
||
<i>{{speeddatalist.carNumber || '--'}}</i>
|
||
</p>
|
||
<p>
|
||
当时车速:
|
||
<i>{{speeddatalist.currentSpeed || '--'}}</i>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="speedtop-item">
|
||
<div class="title-speed" @click="onblackswitch">实时监控</div>
|
||
<div class="title-con" v-if="videoname !== 1">
|
||
<VideoSpeed ref="VideoSpeedbox" />
|
||
</div>
|
||
<div class="title-con" v-else>
|
||
<ysyPlayAndPlayback :ref="'ysy'" :ysyParams="ysyParams"></ysyPlayAndPlayback>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="speed-bottom">
|
||
<div class="speedbottom-irem">
|
||
<div class="title-speed">一周内变化趋势</div>
|
||
<div class="title-con">
|
||
<StatLine />
|
||
</div>
|
||
</div>
|
||
<div class="speedbottom-irem speed-margin">
|
||
<div class="title-speed">每日车辆数</div>
|
||
<div class="title-con">
|
||
<StstCross />
|
||
</div>
|
||
</div>
|
||
<div class="speedbottom-irem">
|
||
<div class="title-speed">历史违章记录</div>
|
||
<div class="title-con">
|
||
<div class="table-title">
|
||
<el-form
|
||
:inline="true"
|
||
class="demo-form-inline"
|
||
ref="queryForm"
|
||
label-width="65px"
|
||
size="small"
|
||
>
|
||
<el-form-item label="车牌号码">
|
||
<el-input v-model="carNumber" placeholder="请输入" @keyup.enter.native="getAndExitListApi"></el-input>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="设备名称">
|
||
<el-input v-model="deviceName" placeholder="请输入" @keyup.enter.native="getAndExitListApi"></el-input>
|
||
</el-form-item>
|
||
|
||
<!-- <el-form-item label="上传时间">
|
||
<el-date-picker
|
||
v-model="updateDate"
|
||
type="datetimerange"
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
value-format="yyyy-MM-dd HH:mm:ss"
|
||
format="yyyy-MM-dd HH:mm:ss"
|
||
></el-date-picker>
|
||
</el-form-item>-->
|
||
|
||
<el-form-item>
|
||
<!-- <el-button type="primary" icon="el-icon-search" @click="getAndExitListApi">搜索</el-button> -->
|
||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div class="table-con">
|
||
<div class="tabList">
|
||
<div>序号</div>
|
||
<div>设备名称</div>
|
||
<div>车牌号</div>
|
||
<div>行驶状态</div>
|
||
<div>当前车速</div>
|
||
<div>抓拍时间</div>
|
||
<div>抓拍照片</div>
|
||
</div>
|
||
<el-scrollbar class="listBox" ref="refScrollbar">
|
||
<template v-if="nametabledata.length > 0">
|
||
<div
|
||
v-for="(item, index) in nametabledata"
|
||
class="listStyle"
|
||
:key="item.id"
|
||
@click="handleRowClick(item)"
|
||
>
|
||
<div>
|
||
<span>{{ index + 1 }}</span>
|
||
</div>
|
||
<div>
|
||
<span>{{ item.deviceName }}</span>
|
||
</div>
|
||
<div>
|
||
<span>{{ item.carNumber }}</span>
|
||
</div>
|
||
<div>
|
||
<span>{{ item.isExceed == 1 ? '是' : '否' }}</span>
|
||
</div>
|
||
<div>
|
||
<span>{{ item.currentSpeed }} (km/h)</span>
|
||
</div>
|
||
<div>
|
||
<span>{{ item.uploadTime }}</span>
|
||
</div>
|
||
<div>
|
||
<el-image
|
||
:src="item.snapshotImage"
|
||
:preview-src-list="[item.snapshotImage]"
|
||
:initial-index="0"
|
||
fit="cover"
|
||
style="width: 30px; height: 30px;"
|
||
>
|
||
<template #error>
|
||
<div class="image-slot">
|
||
<i class="el-icon-picture-outline"></i>
|
||
</div>
|
||
</template>
|
||
</el-image>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<div class="notoDta" v-if="nametabledata.length == 0">
|
||
<img src="@/assets/images/noData.png" alt />
|
||
<p>暂无数据</p>
|
||
</div>
|
||
</el-scrollbar>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import ysyPlayAndPlayback from "@/components/ysyPlayAndPlayback.vue";
|
||
|
||
import { ref, onMounted, onBeforeUnmount, watchEffect, nextTick } from "vue";
|
||
// api
|
||
import { statSpeedBigScreen, carMeasureSpeedData, carMeasureItemList } from "@/api/modules/vehicle";
|
||
|
||
// sn
|
||
import { GlobalStore } from "@/stores";
|
||
const store = GlobalStore();
|
||
|
||
// const VideoSpeedbox = ref(true);
|
||
// 摄像头
|
||
const VideoSpeedbox = ref(null);
|
||
|
||
onBeforeUnmount(() => {
|
||
console.log("主组件销毁===============");
|
||
VideoSpeedbox.value.onclose();
|
||
});
|
||
|
||
// 获取摄像头头数据
|
||
// 萤石云开关
|
||
let videoType = ref("") as any;
|
||
let ysyParams = ref({} as any);
|
||
let videoname = ref(3);
|
||
|
||
const onblackswitch = async () => {
|
||
VideoSpeedbox.value.previewVideo(videoname);
|
||
};
|
||
|
||
const getvideodata = async () => {
|
||
const res: any = await carMeasureItemList({
|
||
projectSn: store.sn
|
||
});
|
||
|
||
if (res.result.list.length < 1) return;
|
||
|
||
console.log("测速-视频列表", res);
|
||
videoType.value = res.result.projectVideoConfig.videoType;
|
||
videoname.value = res.result.list[0].serialNumber;
|
||
|
||
if (res.result.projectVideoConfig.videoType === 1) {
|
||
// 萤石云
|
||
ysyParams.value = res.result.list[0];
|
||
} else {
|
||
setTimeout(() => {
|
||
VideoSpeedbox.value.previewVideo(res.result.list[0].serialNumber);
|
||
}, 3000);
|
||
}
|
||
};
|
||
|
||
onMounted(() => {
|
||
getAndExitListApi();
|
||
getstatSpeedBigScreen();
|
||
getvideodata();
|
||
console.log("store.sn", store.sn);
|
||
});
|
||
|
||
const BASEURL = import.meta.env.VITE_API_URL;
|
||
const pageNo = ref(1 as any);
|
||
const pageSize = ref(30 as any);
|
||
const moreScroll = ref(true as any);
|
||
const refScrollbar = ref(null as any); // 绑定到滚动的盒子上
|
||
|
||
const nametabledata = ref([] as any);
|
||
const updateDate = ref([] as any);
|
||
const carNumber = ref(null as any);
|
||
const deviceName = ref(null as any);
|
||
const uploadTime_begin = ref(null as any);
|
||
const uploadTime_end = ref(null as any);
|
||
|
||
const getAndExitListApi = async () => {
|
||
if (updateDate.value.length > 1) {
|
||
uploadTime_begin.value = updateDate[0];
|
||
uploadTime_end.value = updateDate[1];
|
||
}
|
||
|
||
const res: any = await carMeasureSpeedData({
|
||
// projectSn: store.sn,
|
||
// timeType: checked.value,
|
||
pageNo: 1,
|
||
pageSize: 50,
|
||
carNumber: carNumber.value,
|
||
deviceName: deviceName.value,
|
||
uploadTime_begin: uploadTime_begin.value,
|
||
uploadTime_end: uploadTime_end.value
|
||
});
|
||
|
||
console.log("测速-历史记录", res);
|
||
nametabledata.value = res.result.records;
|
||
speeddatalist.value = res.result.records[0];
|
||
};
|
||
|
||
// 点击某一行数据
|
||
const speeddatalist = ref({});
|
||
|
||
const handleRowClick = item => {
|
||
console.log("item", item);
|
||
|
||
if (nametabledata.value.length == 0) return;
|
||
speeddatalist.value = item;
|
||
|
||
// VideoSpeedbox.value.previewVideo("d0d865c1a3874b5d9399f640619ee8e4");
|
||
// VideoSpeedbox.value.previewVideo('d0d865c1a3874b5d9399f640619ee8e4');
|
||
};
|
||
|
||
const resetQuery = () => {
|
||
carNumber.value = null;
|
||
deviceName.value = null;
|
||
uploadTime_begin.value = null;
|
||
uploadTime_end.value = null;
|
||
getAndExitListApi();
|
||
};
|
||
|
||
// 统计
|
||
const staticspeed = ref({});
|
||
const getstatSpeedBigScreen = async () => {
|
||
const res: any = await statSpeedBigScreen({
|
||
projectSn: store.sn
|
||
});
|
||
|
||
console.log("测速-大屏统计", res);
|
||
staticspeed.value = res.result;
|
||
};
|
||
|
||
// 折线图
|
||
import StatLine from "./components/StatLine.vue";
|
||
|
||
// 折线图-车辆数
|
||
import StstCross from "./components/StstCross.vue";
|
||
|
||
// 摄像头
|
||
import VideoSpeed from "./components/VideoSpeed.vue";
|
||
import { log } from "console";
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.speed-margin {
|
||
margin: 0 20px;
|
||
}
|
||
|
||
.speedtop-item,
|
||
.speedbottom-irem {
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.title-speed {
|
||
height: 40px;
|
||
line-height: 40px;
|
||
padding-left: 30px;
|
||
background: url("@/assets/images/titleBig.webp") no-repeat;
|
||
background-size: 100% 100%;
|
||
// margin-left: 50px;
|
||
font-family: OPPOSansH;
|
||
color: #ffffff;
|
||
margin-bottom: 5px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.title-con {
|
||
width: 100%;
|
||
flex: 1;
|
||
background: url("@/assets/images/cardImg.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
// background: skyblue;
|
||
}
|
||
}
|
||
|
||
.speed-box {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: relative;
|
||
// background: skyblue;
|
||
|
||
.speed-top {
|
||
width: 100%;
|
||
height: 49%;
|
||
margin-bottom: 1%;
|
||
display: flex;
|
||
|
||
.speedtop-item {
|
||
height: 100%;
|
||
flex: 1;
|
||
// background: skyblue;
|
||
|
||
&:nth-child(1) {
|
||
.title-con {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
.statis-left {
|
||
flex: 1;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
.statisl-img {
|
||
width: 266px;
|
||
height: 263px;
|
||
background: url("@/assets/images/vehicleManagespeed/Group 1000015883.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
|
||
.statisl-text {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-33%, -50%);
|
||
text-align: center;
|
||
font-family: Alibaba PuHuiTi, Alibaba PuHuiTi;
|
||
font-weight: 500;
|
||
font-size: 48px;
|
||
color: #00acff;
|
||
|
||
p {
|
||
font-family: Alibaba PuHuiTi, Alibaba PuHuiTi;
|
||
font-weight: 500;
|
||
font-size: 14px;
|
||
color: #c2e7f9;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.statis-right {
|
||
width: 180px;
|
||
height: 100%;
|
||
// background: skyblue;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding-top: 20px;
|
||
padding-right: 30px;
|
||
|
||
.staisr-icon {
|
||
width: 164px;
|
||
height: 170px;
|
||
background: url("@/assets/images/vehicleManagespeed/Group 1000015862.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
position: relative;
|
||
margin-bottom: 10px;
|
||
|
||
.staisr-text {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
text-align: center;
|
||
font-family: ABeeZee, ABeeZee;
|
||
font-weight: 400;
|
||
font-size: 20px;
|
||
color: #ffffff;
|
||
|
||
p {
|
||
font-family: ABeeZee, ABeeZee;
|
||
font-weight: 400;
|
||
font-size: 45px;
|
||
color: #ffffff;
|
||
margin: 0;
|
||
padding: 0;
|
||
margin-top: 15px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
&:nth-child(2) {
|
||
.title-con {
|
||
padding: 0 15px;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.photot-left {
|
||
width: 350px;
|
||
height: 340px;
|
||
background: url("@/assets/images/vehicleManagespeed/Group 1000015889.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
margin-right: 20px;
|
||
|
||
img {
|
||
width: 89%;
|
||
height: 89%;
|
||
margin: 7% 5%;
|
||
}
|
||
}
|
||
|
||
.photot-right {
|
||
flex: 1;
|
||
height: 340px;
|
||
background: url("@/assets/images/cardImg.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: space-evenly;
|
||
|
||
.overspeed-box {
|
||
width: 220px;
|
||
height: 70px;
|
||
// background: skyblue !important;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-family: OPPOSans, OPPOSans;
|
||
font-weight: bold;
|
||
font-size: 35px;
|
||
color: #ff0000;
|
||
background: url("@/assets/images/vehicleManagespeed/Snipaste_2024-09-24_16-31-42.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
|
||
.overspeed-boxs {
|
||
width: 220px;
|
||
height: 70px;
|
||
// background: skyblue !important;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-family: OPPOSans, OPPOSans;
|
||
font-weight: bold;
|
||
font-size: 35px;
|
||
color: #36eaff;
|
||
}
|
||
|
||
.overspeed-tiem {
|
||
font-family: OPPOSans, OPPOSans;
|
||
font-weight: bold;
|
||
font-size: 20px;
|
||
color: #ffffff;
|
||
}
|
||
.overspeed-con {
|
||
font-family: OPPOSans, OPPOSans;
|
||
text-align: center;
|
||
|
||
p {
|
||
font-weight: bold;
|
||
font-size: 16px;
|
||
color: #ffffff;
|
||
}
|
||
|
||
i {
|
||
font-style: normal;
|
||
font-weight: bold;
|
||
font-size: 20px;
|
||
color: #36eaff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.speed-bottom {
|
||
width: 100%;
|
||
height: 50%;
|
||
display: flex;
|
||
|
||
.speedbottom-irem {
|
||
height: 100%;
|
||
flex: 1;
|
||
// background: skyblue;
|
||
|
||
&:nth-child(3) {
|
||
.title-con {
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.table-title {
|
||
height: 35px;
|
||
margin: 10px 0;
|
||
|
||
::v-deep .el-form {
|
||
.el-form-item--small .el-form-item__label {
|
||
color: #fff !important;
|
||
}
|
||
input {
|
||
background: #071f3d !important;
|
||
color: #fff !important;
|
||
}
|
||
.el-input--small .el-input__wrapper {
|
||
box-sizing: border-box;
|
||
background: #071f3d !important;
|
||
// border: 1px solid #37547c !important;
|
||
}
|
||
|
||
.el-button {
|
||
background: #071f3d !important;
|
||
border: #071f3d !important;
|
||
color: #fff !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
.table-con {
|
||
flex: 1;
|
||
.tabList {
|
||
display: flex;
|
||
width: 100%;
|
||
height: 10%;
|
||
background: url("@/assets/images/vehicleManagement/ListTitleImg.png") no-repeat;
|
||
background-size: 100% 100%;
|
||
// position: absolute;
|
||
left: 75.5%;
|
||
top: 75%;
|
||
color: #ccc;
|
||
font-size: calc(100vw * 14 / 1920);
|
||
line-height: 30px;
|
||
justify-content: space-around;
|
||
div {
|
||
text-align: center;
|
||
width: 11%;
|
||
}
|
||
}
|
||
.listBox {
|
||
height: 80%;
|
||
position: relative;
|
||
color: #fff;
|
||
|
||
.notoDta {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
|
||
img {
|
||
width: 150px;
|
||
height: 150px;
|
||
}
|
||
}
|
||
|
||
.listStyle {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
color: #fff;
|
||
// line-height: 25px;
|
||
font-size: calc(100vw * 12 / 1920);
|
||
.list-img {
|
||
.el-img {
|
||
width: 50px;
|
||
height: 25px;
|
||
}
|
||
.image-slot {
|
||
width: 50px;
|
||
height: 25px;
|
||
img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
> img {
|
||
width: 62px;
|
||
height: 62px;
|
||
}
|
||
}
|
||
div {
|
||
text-align: center;
|
||
width: 11%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
.listStyle:hover {
|
||
background: #091f3f;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|