674 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>