<template>
|
<div>
|
<div class="form flex a-center j-between mt--23">
|
<div class="form-left ml--30">
|
<el-form :inline="true" :model="queryForm" class="demo-form-inline">
|
<el-form-item label="预警类型:" prop="warnType" class="unset_m" style="margin-right: 15px;">
|
<el-select :popper-append-to-body="false" v-model="queryForm.warnType" placeholder="请选择">
|
<el-option label="超速报警" value="超速报警"></el-option>
|
<el-option label="疲劳驾驶报警" value="疲劳驾驶报警"></el-option>
|
<el-option label="紧急报警" value="紧急报警"></el-option>
|
<el-option label="进入指定区域报警" value="进入指定区域报警"></el-option>
|
<el-option label="离开指定区域报警" value="离开指定区域报警"></el-option>
|
<el-option label="路段堵塞报警" value="路段堵塞报警"></el-option>
|
<el-option label="危险路段报警" value="危险路段报警"></el-option>
|
<el-option label="越界报警" value="越界报警"></el-option>
|
<el-option label="盗警" value="盗警"></el-option>
|
<el-option label="劫警" value="劫警"></el-option>
|
<el-option label="偏离路线报警" value="偏离路线报警"></el-option>
|
<el-option label="车辆移动报警" value="车辆移动报警"></el-option>
|
<el-option label="超时驾驶报警" value="超时驾驶报警"></el-option>
|
<el-option label="其他报警" value="其他报警"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="车辆号牌:" prop="vehicleNumber" class="unset_m" style="margin-right: 15px;">
|
<el-input v-model="queryForm.vehicleNumber" placeholder="请输入"></el-input>
|
</el-form-item>
|
<el-form-item label="驾驶员姓名:" prop="driverName" class="unset_m" style="margin-right: 15px;">
|
<el-input v-model="queryForm.driverName" placeholder="请输入"></el-input>
|
</el-form-item>
|
<el-form-item label="公司名称:" prop="enterpriseName" class="unset_m" style="margin-right: 15px;">
|
<el-input v-model="queryForm.enterpriseName" placeholder="请输入"></el-input>
|
</el-form-item>
|
<el-form-item label="预警时间:" prop="date" class="unset_m" style="margin-right: 15px;">
|
<el-date-picker :append-to-body="false" v-model="queryForm.date" type="daterange"
|
range-separator=" " start-placeholder="开始日期" end-placeholder="结束日期">
|
</el-date-picker>
|
</el-form-item>
|
<el-form-item label="处理类型:" prop="treatmentState" class="unset_m" style="margin-right: 15px;">
|
<el-select :popper-append-to-body="false" v-model="queryForm.treatmentState" placeholder="请选择">
|
<el-option label="处理中" value="处理中"></el-option>
|
<el-option label="已处理完毕" value="已处理完毕"></el-option>
|
<el-option label="不作处理" value="不作处理"></el-option>
|
<el-option label="将来处理" value="将来处理"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick"
|
style="margin-left: 30px;border: none;">
|
<el-tab-pane v-for="(item, index) in options" :key="index" :label="item.name"
|
:name="item.name"></el-tab-pane>
|
</el-tabs>
|
</el-form>
|
</div>
|
<div class="form-right mr--24 mb--22 shrink0">
|
<el-button class="search-button h--40 w--90 fs--14" icon="el-icon-search" type="primary" size="small"
|
@click="fetchData">查询</el-button>
|
<el-button @click="reset" icon="el-icon-refresh-right" class="reset-button h--40 w--90 fs--14"
|
size="small">重置</el-button>
|
</div>
|
|
</div>
|
|
<!-- 新增统计卡片 -->
|
<el-row :gutter="20" class="mt--20 ml--30 mr--30">
|
<el-col :span="6">
|
<div class="stat-card">
|
<div class="title fs--14 color-grey-6">总预警数</div>
|
<div class="value fs--20 color1 mt--10">
|
{{ totalAll }}
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="6">
|
<div class="stat-card">
|
<div class="title fs--14 color-grey-6">已处理数</div>
|
<div class="value fs--20 color1 mt--10">
|
{{ processed }}
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="6">
|
<div class="stat-card">
|
<div class="title fs--14 color-grey-6">未处理数</div>
|
<div class="value fs--20 color1 mt--10">
|
{{ unprocessed }}
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="6">
|
<div class="stat-card">
|
<div class="title fs--14 color-grey-6">处置率</div>
|
<div class="value fs--20 color1 mt--10">
|
{{ progress }}%
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
|
<div class="table-box-btn ml--30">
|
<el-button v-permission="11" class="search-button h--40 w--90 fs--14" icon="el-icon-top" type="primary"
|
size="small" @click="exportExc">导出</el-button>
|
</div>
|
|
<div class="table-box ml--30 mr--30">
|
<el-table :data="list" border stripe style="width: 100%" v-loading="listLoading">
|
<!-- 固定前三列 -->
|
<el-table-column prop="date" label="序号" fixed="left" type="index" width="50"></el-table-column>
|
<el-table-column prop="carName" label="车辆名称" fixed="left"></el-table-column>
|
<el-table-column prop="vehicleNumber" label="车牌号码" fixed="left"></el-table-column>
|
<!-- 其余列不固定,可滚动 -->
|
<el-table-column prop="name" label="近15分钟情况">
|
<template #default="{ row }">
|
<img v-permission="35" src="@/assets/homeImg/eye-fill.png" alt="" @click="viewDetail(row)"
|
style="width: 30px;cursor: pointer;">
|
</template>
|
</el-table-column>
|
<el-table-column prop="driverName" label="驾驶员名称"></el-table-column>
|
<el-table-column prop="enterpriseName" label="所属公司"></el-table-column>
|
<el-table-column prop="terminalNumber" label="终端编号"></el-table-column>
|
<el-table-column prop="startTime" label="开始报警时间"></el-table-column>
|
<el-table-column prop="endTime" label="结束报警时间"></el-table-column>
|
<el-table-column prop="keepTime" label="持续时长"></el-table-column>
|
<el-table-column prop="keepDistance" label="持续里程数"></el-table-column>
|
<el-table-column prop="warnType" label="报警类型"></el-table-column>
|
<el-table-column prop="warnLevel" label="报警等级"></el-table-column>
|
<el-table-column prop="warnNumber" label="报警次数"></el-table-column>
|
<el-table-column prop="warnSource" label="报警来源"></el-table-column>
|
<el-table-column prop="treatmentState" label="处理状态">
|
<template #default="{ row }">
|
<span v-if="row.treatmentState == '处理中'" style="color: red;">未处理</span>
|
<span v-else style="color: #ccc;">已处理</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="treatmentUser" label="处理人"></el-table-column>
|
<el-table-column prop="treatmentTime" label="处理时间"></el-table-column>
|
<el-table-column prop="treatmentRemark" label="处理描述"></el-table-column>
|
</el-table>
|
<div class="pagination-box relative mt--23 flex j-end">
|
<el-pagination :popper-append-to-body="false" @size-change="handleSizeChange"
|
@current-change="handleCurrentChange" :current-page="queryForm.page" background
|
layout="total,sizes,prev, pager, next,jumper" :total="total">
|
</el-pagination>
|
</div>
|
<el-drawer :visible.sync="drawer" append-to-body :size="450" @close="closeDrawer">
|
<div class="flex j-between a-center fs--20 pl--15 pr--15">
|
<!-- 使用 Tailwind CSS 的内联十六进制颜色类 -->
|
<div>{{ info.vehicleNumber }}<span v-if="info.warnList && info.warnList.length > 0">({{
|
info.warnList.length
|
}})</span></div><i @click="closeDrawer" class="el-icon-s-unfold color1 pointer"></i>
|
</div>
|
<hr class="mt--10" />
|
<div class="pl--15 pr--15">
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">当前司机:</div>
|
<div class="color2">{{ info.driverName }}</div>
|
</div>
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">当前车速:</div>
|
<div class="color2">{{ info.speed }}km/h</div>
|
</div>
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">当前位置:</div>
|
<div class="color2">{{ info.nowAddress }}</div>
|
</div>
|
<div v-if="info.imageUrl" class="flex mt--15">
|
<div class="w--100 shrink0 color1">抓拍照片:</div>
|
<el-image style="height: 100px" :src="info.imageUrl" :preview-src-list="[info.imageUrl]">
|
</el-image>
|
</div>
|
</div>
|
<hr class="mt--10" />
|
<div class="flex j-between a-center fs--15 pl--15 pr--15 mt--15 color2">
|
近15分钟报警
|
</div>
|
<div class="block pl--15 pr--15 mt--15">
|
<el-timeline>
|
<el-timeline-item v-for="(item, index) in info.warnList" :key="index" color='#0E6EFD'
|
:timestamp="item.warnTime" placement="top">
|
<div @click="initMap(item)">
|
<el-card class="pointer">
|
<h4>{{ item.warnType }}</h4>
|
<p class="color1">{{ item.speed }}km/h</p>
|
</el-card>
|
</div>
|
|
</el-timeline-item>
|
</el-timeline>
|
</div>
|
<div v-if="showWarnDetail" class="fixed">
|
<div class="card">
|
<div class="title fs--18 color2">视频信号遮挡报警</div>
|
<div id="mapContainer"></div>
|
<div class="">
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">司机:</div>
|
<div class="color2">{{ info.driverName }}</div>
|
</div>
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">车速:</div>
|
<div class="color2">{{ activeInfo.speed }}km/h</div>
|
</div>
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">时间:</div>
|
<div class="color2">{{ activeInfo.warnTime }}</div>
|
</div>
|
<div class="flex mt--15">
|
<div class="w--100 shrink0 color1">地点:</div>
|
<div class="color2">{{ activeInfo.address }}</div>
|
</div>
|
|
</div>
|
</div>
|
</div>
|
</el-drawer>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import AMapLoader from "@amap/amap-jsapi-loader";
|
import { getList, getDetail } from './service'
|
import { getCarType } from '../car-manage/service'
|
import moment from 'moment'
|
import { exportExcell } from '@/utils/utils.js'
|
|
export default {
|
data() {
|
return {
|
computed: {
|
statItems() {
|
return [
|
{ label: '总预警数', value: this.totalAll },
|
{ label: '已处理数', value: this.processed },
|
{ label: '未处理数', value: this.unprocessed },
|
{
|
label: '处理进度',
|
value: `${this.totalAll > 0
|
? ((this.processed / this.totalAll * 100).toFixed(2))
|
: 0}%`
|
}
|
]
|
}
|
},
|
activeName: '全部',
|
drawer: false,
|
queryForm: {
|
pageCurr: 1,
|
pageSize: 10
|
},
|
listLoading: false,
|
list: [],
|
total: 0,
|
info: {},
|
showWarnDetail: false,
|
activeInfo: {},
|
options: [],
|
totalAll: 0, // 总预警数
|
processed: 0, // 已处理数
|
unprocessed: 0, // 未处理数
|
progress: 0, // 占比
|
};
|
},
|
created() {
|
this.$checkPermission(10)
|
this.fetchData()
|
getCarType().then(res => {
|
let arr = [{ name: '全部' }]
|
this.options = [ ...res,...arr,];
|
});
|
const query = this.$route.query;
|
if (query && Object.keys(query).length > 0) {
|
if (query.name) {
|
this.activeName = query.name;
|
}
|
}
|
},
|
methods: {
|
closeDrawer() {
|
this.drawer = false
|
this.showWarnDetail = false
|
},
|
// 查看详情
|
viewDetail(row) {
|
this.drawer = true
|
getDetail({ vehicleNumber: row.vehicleNumber }).then(res => {
|
this.info = res
|
})
|
},
|
handleClick(tab, event) {
|
this.activeName = tab.name;
|
this.fetchData();
|
},
|
async fetchData() {
|
let params = JSON.parse(JSON.stringify(this.queryForm))
|
params.carType = this.activeName
|
if (params.carType === '全部') {
|
delete params.carType
|
}
|
if (params.date) {
|
params.startTime = moment(params.date[0]).format('YYYY-MM-DD')
|
params.endTime = moment(params.date[1]).format('YYYY-MM-DD')
|
delete params.date
|
}
|
this.listLoading = true
|
const res = await getList(params)
|
this.totalAll = res.total || 0
|
this.processed = res.processed || 0
|
this.unprocessed = res.unprocessed || 0
|
this.progress = res.processed / this.totalAll * 100 //占比
|
this.list = res.page.records
|
this.total = res.page.total
|
this.listLoading = false
|
},
|
// 初始化地图
|
initMap(row) {
|
this.showWarnDetail = true
|
this.activeInfo = row
|
this.$nextTick(() => {
|
window._AMapSecurityConfig = {
|
securityJsCode: "37ce61ae86efa5ad82b649a277f5097c",
|
};
|
AMapLoader.load({
|
key: "67968c82f27c7e2cb9f40c1a9aa3042b",
|
version: "2.0",
|
plugins: [
|
"AMap.ToolBar",
|
"AMap.AutoComplete",
|
"AMap.Geocoder",
|
"AMap.MarkerCluster",
|
],
|
})
|
.then((AMap) => {
|
this.map = new AMap.Map("mapContainer", {
|
center: [row.lon, row.lat],
|
zoom: 15,
|
});
|
|
// 添加标记
|
new AMap.Marker({
|
position: [row.lon, row.lat],
|
map: this.map,
|
title: row.warnType
|
});
|
})
|
.catch((e) => {
|
console.log(e);
|
});
|
})
|
},
|
reset() {
|
this.queryForm = {
|
pageCurr: 1,
|
pageSize: 10
|
}
|
this.fetchData()
|
},
|
search() {
|
|
},
|
exportExc() {
|
let params = JSON.parse(JSON.stringify(this.queryForm))
|
params.carType = this.activeName
|
if (params.carType === '全部') {
|
delete params.carType
|
}
|
if (params.date) {
|
params.startTime = moment(params.date[0]).format('YYYY-MM-DD')
|
params.endTime = moment(params.date[1]).format('YYYY-MM-DD')
|
delete params.date
|
}
|
exportExcell('预警列表', params, '/system/warn/exportCarWarnList')
|
},
|
handleSizeChange(e) {
|
this.queryForm.pageSize = e
|
this.fetchData()
|
|
},
|
handleCurrentChange(e) {
|
this.queryForm.pageCurr = e
|
this.fetchData()
|
|
},
|
}
|
}
|
</script>
|
|
<style scoped lang="less">
|
::v-deep .el-tabs--card>.el-tabs__header {
|
border: none !important;
|
}
|
.color1 {
|
color: #0E6EFD;
|
}
|
|
.color2 {
|
color: rgb(52, 52, 52);
|
}
|
|
#mapContainer {
|
width: 100%;
|
height: 500px;
|
margin: 20px 0;
|
}
|
|
::v-deep .el-drawer__body {
|
position: relative;
|
|
.fixed {
|
right: 470px;
|
top: 0;
|
bottom: 0;
|
margin: auto;
|
display: flex;
|
align-items: center;
|
|
.card {
|
background: #fff;
|
width: 500px;
|
max-height: 1000px;
|
padding: 15px;
|
}
|
}
|
}
|
|
::v-deep .pagination-popper {
|
position: fixed !important;
|
transform:
|
scale(calc(1 / var(--scale))) translate(calc(100px * (1 - 1 / var(--scale))),
|
calc(5px * (1 - 1 / var(--scale)))) !important;
|
transform-origin: right top !important;
|
right: calc(30px * (1 - 1 / var(--scale))) !important;
|
margin-top: 5px;
|
min-width: 100px !important;
|
}
|
</style>
|
|
<style scoped>
|
.stat-card {
|
background: #f8f9fa;
|
border-radius: 4px;
|
padding: 16px 20px;
|
margin-bottom: 20px;
|
text-align: center;
|
}
|
|
.color-grey-6 {
|
color: #606266;
|
}
|
</style>
|