466 lines
8.9 KiB
Vue
466 lines
8.9 KiB
Vue
<template>
|
|
<view class="topstatistics">
|
|
<view class="li">
|
|
<view class="num">{{info.statistics?.warningLevel || '暂无'}}</view>
|
|
<view class="title">预警级别</view>
|
|
</view>
|
|
<view class="li">
|
|
<view class="num">{{info.statistics?.regionalNetworkDistance || '暂无'}}</view>
|
|
<view class="title">区间距离</view>
|
|
</view>
|
|
<view class="li">
|
|
<view class="num">{{info.statistics?.intervalSpeedLimit || '暂无'}}</view>
|
|
<view class="title">区间限速</view>
|
|
</view>
|
|
<view class="li">
|
|
<view class="num">{{info.statistics?.longestDrivingDuration || '暂无'}}</view>
|
|
<view class="title">最短行驶时长</view>
|
|
</view>
|
|
</view>
|
|
<view class="tabs">
|
|
<view class="left">
|
|
<view class="nav" :class="{on:status==2}" @click="setstatus(2)">
|
|
超速车辆
|
|
</view>
|
|
<view class="nav" :class="{on:status==3}" @click="setstatus(3)">
|
|
暂扣车辆
|
|
</view>
|
|
<view class="nav" :class="{on:status==4}" @click="setstatus(4)">
|
|
放行车辆
|
|
</view>
|
|
</view>
|
|
<view class="right">
|
|
<input placeholder="搜索超速车辆" @confirm="getinfo" v-model="keyword" />
|
|
<uni-icons type="search" size="16rpx" @click="getinfo"></uni-icons>
|
|
</view>
|
|
</view>
|
|
<scroll-view :scroll-y="true" class="scroll-view">
|
|
<view v-for="(item,index) in info.data" :class="{hide:itemanimation && index==0}" class="item"
|
|
@click.stop="listwithhold(item.encoding,gettype(status))">
|
|
<view class="left">
|
|
<view class="t">
|
|
<image v-if="status==2" src="/static/err.png"></image>
|
|
车牌号码
|
|
</view>
|
|
<view class="num" :class="`numcolor${item.vehicleNumberColor}`">
|
|
{{item.vehicleNumber}}
|
|
</view>
|
|
</view>
|
|
<view class="center" v-if="status==2">
|
|
<view class="thead">
|
|
<view>平均车速</view>
|
|
<view>超速比例</view>
|
|
<view>实际行驶时长</view>
|
|
<view>待休息时长</view>
|
|
</view>
|
|
<view class="tbody">
|
|
<view>{{item.averageSpeed}}</view>
|
|
<view>{{item.overspeedRatio}}</view>
|
|
<view>{{item.actualDrivingDuration}}</view>
|
|
<view>{{item.restDuration}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="center center2" v-if="status==3">
|
|
<view class="thead">
|
|
<view>待休息时长</view>
|
|
<view>待放行时间</view>
|
|
|
|
</view>
|
|
<view class="tbody">
|
|
<view>{{item.restDuration}}</view>
|
|
<view>{{item.restDurationEndtime}}</view>
|
|
|
|
</view>
|
|
</view>
|
|
<view class="center center3" v-if="status==4">
|
|
<view class="thead">
|
|
<view>平均车速</view>
|
|
<view>超速比例</view>
|
|
<view>休息时长</view>
|
|
<view style="flex: 1.5;">放行时间</view>
|
|
</view>
|
|
<view class="tbody">
|
|
<view>{{item.averageSpeed}}</view>
|
|
<view>{{item.overspeedRatio}}</view>
|
|
<view>{{item.restDuration}}</view>
|
|
<view style="flex: 1.5;">{{item.releaseTime}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="right red" v-if="status==2" @click.stop="withhold(item.encoding,1)">暂扣</view>
|
|
<view class="right green" v-if="status==3" @click.stop="withhold(item.encoding,2)">放行</view>
|
|
</view>
|
|
<nynull v-if="!info.data?.length"></nynull>
|
|
</scroll-view>
|
|
<pageanimation v-model="showdetails" @close="refdetails.hide()">
|
|
<pagedetails ref="refdetails" @opneinfo='opneshowdetails' @refresh="getinfo" />
|
|
</pageanimation>
|
|
|
|
</template>
|
|
|
|
<script setup>
|
|
import {
|
|
ref
|
|
} from "vue";
|
|
import {
|
|
getwarningList
|
|
} from "/appapi/index.js"
|
|
import pagedetails from "./details.vue";
|
|
const refdetails = ref()
|
|
const showdetails = ref(false)
|
|
const status = ref(2)
|
|
|
|
// 分页相关
|
|
const pageSize = ref(50);
|
|
const pageNum = ref(1);
|
|
const hasNextPage = ref(true)
|
|
|
|
|
|
const info = ref({
|
|
data: []
|
|
});
|
|
const keyword = ref("")
|
|
|
|
function load() {
|
|
console.log('预警信息load')
|
|
}
|
|
|
|
function opneshowdetails() {
|
|
showdetails.value = true;
|
|
}
|
|
|
|
function hide() {
|
|
console.log('预警信息hide')
|
|
showdetails.value = false;
|
|
refdetails.value.hide()
|
|
}
|
|
|
|
function getinfo() {
|
|
info.value.data = [];
|
|
pageNum.value = 1;
|
|
hasNextPage.value = true;
|
|
getlist()
|
|
}
|
|
|
|
function gettype(t) {
|
|
if (t == 2) {
|
|
return 1
|
|
}
|
|
if (t == 3) {
|
|
return 2
|
|
}
|
|
return ""
|
|
}
|
|
|
|
function getlist() {
|
|
if (hasNextPage.value) {
|
|
getwarningList({
|
|
status: status.value,
|
|
keyword: keyword.value,
|
|
pageSize: pageSize.value,
|
|
pageNum: pageNum.value
|
|
}).then(r => {
|
|
r.data.data = r.data.data.map(res => {
|
|
res["hide"] = 2;
|
|
return res;
|
|
})
|
|
info.value = {
|
|
...r.data,
|
|
data: info.value.data.concat(r.data.data)
|
|
};
|
|
|
|
hasNextPage.value = r.data.hasPreviousPage;
|
|
pageNum.value = pageNum.value + 1;
|
|
})
|
|
}
|
|
}
|
|
|
|
function setstatus(type) {
|
|
status.value = type;
|
|
getinfo()
|
|
}
|
|
|
|
function show() {
|
|
getinfo()
|
|
}
|
|
|
|
const itemanimation=ref(false)
|
|
// 监听推送数据
|
|
uni.onSkt("SPEEDNEWDATA", (res) => {
|
|
// 预警列表接收推送数据
|
|
if (status.value == 2) {
|
|
itemanimation.value=true;
|
|
info.value.data = [...res, ...info.value.data]
|
|
setTimeout(()=>{
|
|
itemanimation.value=false;
|
|
},50)
|
|
// #ifdef APP
|
|
res.map(r=>{
|
|
uni.createPushMessage({
|
|
title: "超速预警",
|
|
content: `${r.vehicleNumber}超速${r.overspeedRatio}`
|
|
})
|
|
})
|
|
|
|
// #endif
|
|
}
|
|
})
|
|
|
|
|
|
|
|
|
|
// 打开详情页面
|
|
function listwithhold(id, type) {
|
|
showdetails.value = true;
|
|
refdetails.value.show(id, type)
|
|
}
|
|
|
|
function withhold(id, type) {
|
|
// 打开详情弹窗
|
|
refdetails.value.opneshowupimg(id, type)
|
|
}
|
|
|
|
defineExpose({
|
|
load,
|
|
hide,
|
|
show
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.scroll-view {
|
|
height: calc(100vh - 140rpx);
|
|
padding: 1rpx 15rpx;
|
|
|
|
box-sizing: border-box;
|
|
|
|
.item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
background: #fff;
|
|
border-radius: 3rpx;
|
|
margin-bottom: 10rpx;
|
|
overflow: hidden;
|
|
padding: 10rpx 15rpx;
|
|
position: relative;
|
|
left: 0%;
|
|
transition:0.5s;
|
|
height: 75rpx;
|
|
opacity: 1;
|
|
&.hide{
|
|
left: 100%;
|
|
height: 0rpx;
|
|
transition:0s;
|
|
opacity: 0;
|
|
}
|
|
&.show{
|
|
|
|
left: 0%;
|
|
|
|
}
|
|
|
|
&.show {
|
|
left: 0%;
|
|
}
|
|
|
|
.left {
|
|
.t {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 9rpx;
|
|
color: #333333;
|
|
|
|
image {
|
|
width: 13rpx;
|
|
height: 13rpx;
|
|
margin-right: 8rpx;
|
|
}
|
|
}
|
|
|
|
.num {
|
|
width: 81rpx;
|
|
line-height: 20rpx;
|
|
margin-top: 8rpx;
|
|
text-align: center;
|
|
|
|
font-weight: 800;
|
|
font-size: 11rpx;
|
|
|
|
}
|
|
}
|
|
|
|
.center {
|
|
border-radius: 5rpx;
|
|
overflow: hidden;
|
|
border: 1rpx solid rgba(162, 181, 207, 0.67);
|
|
|
|
.thead {
|
|
background: rgba(162, 181, 207, 0.13);
|
|
padding: 7rpx 0;
|
|
display: flex;
|
|
|
|
view {
|
|
width: 90rpx;
|
|
text-align: center;
|
|
font-size: 9rpx;
|
|
color: #76849D;
|
|
flex: 1;
|
|
position: relative;
|
|
|
|
&:before {
|
|
content: "";
|
|
position: absolute;
|
|
width: 1rpx;
|
|
height: 13rpx;
|
|
background: #C0CDDE;
|
|
left: 0rpx;
|
|
top: 50%;
|
|
transform: translate(-0, -50%);
|
|
}
|
|
|
|
&:nth-of-type(1) {
|
|
&:before {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.tbody {
|
|
display: flex;
|
|
|
|
view {
|
|
text-align: center;
|
|
padding: 7rpx 0;
|
|
flex: 1;
|
|
font-size: 11rpx;
|
|
color: #333333;
|
|
}
|
|
}
|
|
|
|
&.center2 {
|
|
.thead {
|
|
view {
|
|
width: 180rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
&.center3 {
|
|
.thead {
|
|
view {
|
|
width: 110rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.right {
|
|
border-radius: 15rpx;
|
|
|
|
font-weight: 600;
|
|
font-size: 11rpx;
|
|
width: 60rpx;
|
|
text-align: center;
|
|
padding: 5rpx 0;
|
|
|
|
&.green {
|
|
border: 1rpx solid #4D7BFF;
|
|
color: #4D7BFF;
|
|
}
|
|
|
|
&.red {
|
|
border: 1rpx solid #D10B0B;
|
|
color: #D10B0B;
|
|
}
|
|
|
|
&.grey {
|
|
border: 1rpx solid #666666;
|
|
color: #666666;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.tabs {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin: 15rpx;
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
background: #fff;
|
|
border-radius: 3rpx;
|
|
line-height: 31rpx;
|
|
overflow: hidden;
|
|
|
|
.nav {
|
|
width: 91rpx;
|
|
text-align: center;
|
|
font-weight: 500;
|
|
font-size: 11rpx;
|
|
color: #4D7BFF;
|
|
|
|
&:nth-of-type(1) {
|
|
border: none;
|
|
}
|
|
|
|
border-left: 1px solid #eee;
|
|
|
|
&.on {
|
|
background: linear-gradient(45deg, #4F8AFF 0%, #4B5EFF 100%);
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.right {
|
|
background: #FFFFFF;
|
|
border-radius: 3rpx;
|
|
width: 282rpx;
|
|
align-items: center;
|
|
height: 31rpx;
|
|
padding: 5rpx 10rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
input {
|
|
font-size: 11rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.topstatistics {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
background: #fff;
|
|
padding: 15rpx 0;
|
|
|
|
.li {
|
|
flex: 1;
|
|
text-align: center;
|
|
border-left: 2rpx solid #eee;
|
|
|
|
&:nth-of-type(1) {
|
|
border: none;
|
|
}
|
|
|
|
.num {
|
|
font-weight: 800;
|
|
font-size: 13rpx;
|
|
color: #4D7BFF;
|
|
|
|
}
|
|
|
|
.title {
|
|
font-size: 9rpx;
|
|
color: #333333;
|
|
margin-top: 5rpx;
|
|
}
|
|
}
|
|
}
|
|
</style> |