修改接口内容
This commit is contained in:
@ -86,3 +86,63 @@ export function interceptNotSuccess(taskId) {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取卡口预警列表
|
||||||
|
* @param {Object} data - 查询参数
|
||||||
|
* @param {string|number} data.taskId - 关联任务ID
|
||||||
|
* @param {number} data.page - 当前页号
|
||||||
|
* @param {number} data.pageSize - 每页大小
|
||||||
|
*/
|
||||||
|
export function getBayonetAlertList(data) {
|
||||||
|
return service({
|
||||||
|
url: '/traffic/bayonetAlert/page',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按任务状态统计数量
|
||||||
|
* @param {Object} data - 查询参数
|
||||||
|
* @param {number} data.userId - 用户ID
|
||||||
|
* @param {string} data.startTime - 开始时间
|
||||||
|
* @param {string} data.endTime - 结束时间
|
||||||
|
*/
|
||||||
|
export function countByTaskStatus(data) {
|
||||||
|
return service({
|
||||||
|
url: '/traffic/eventTask/countByTaskStatus',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拦截预警列表
|
||||||
|
* @param {Object} data - 查询参数
|
||||||
|
* @param {number} data.userId - 用户ID
|
||||||
|
* @param {number} data.status - 状态:0-未执行
|
||||||
|
* @param {number} data.pageSize - 每页大小
|
||||||
|
* @param {number} data.page - 页号,从1开始
|
||||||
|
*/
|
||||||
|
export function getInterceptWarnList(data) {
|
||||||
|
return service({
|
||||||
|
url: '/traffic/eventTask/interceptWarn/page',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取未完成预警事件(地图用)
|
||||||
|
* @param {Object} params - 查询参数
|
||||||
|
* @param {number} params.eventCategory - 事件分类:1-路况预警,2-违章预警
|
||||||
|
* @param {string} params.areaCode - 区域编码
|
||||||
|
*/
|
||||||
|
export function getEventUnfinished(params) {
|
||||||
|
return service({
|
||||||
|
url: '/traffic/event/eventUnfinished',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
20
src/main.js
20
src/main.js
@ -10,16 +10,16 @@ import store from './store';
|
|||||||
import Vconsole from 'vconsole';
|
import Vconsole from 'vconsole';
|
||||||
let vConsole = new Vconsole()
|
let vConsole = new Vconsole()
|
||||||
//NFC
|
//NFC
|
||||||
// router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
// let token = window.localStorage.getItem('token')
|
let token = window.localStorage.getItem('token')
|
||||||
// let user = window.localStorage.getItem('userInfo')
|
let user = window.localStorage.getItem('userInfo')
|
||||||
// if (token && user) {
|
if (token && user) {
|
||||||
// next();
|
next();
|
||||||
// } else {
|
} else {
|
||||||
// if (to.name == 'login') next()
|
if (to.name == 'login') next()
|
||||||
// else next('/')
|
else next('/')
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
|
|
||||||
// .use(vConsole)
|
// .use(vConsole)
|
||||||
createApp(App).use(vant).use(router).use(store).mount('#app');
|
createApp(App).use(vant).use(router).use(store).mount('#app');
|
||||||
@ -82,7 +82,7 @@ const form = reactive({
|
|||||||
const countdown = ref(0);
|
const countdown = ref(0);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const idCardForm = reactive({
|
const idCardForm = reactive({
|
||||||
idCard: "510922199202281888"
|
idCard: "510922199202281887"
|
||||||
});
|
});
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
_idCardlogin(); // 已屏蔽自动登录
|
_idCardlogin(); // 已屏蔽自动登录
|
||||||
@ -91,7 +91,7 @@ onMounted(() => {
|
|||||||
function _idCardlogin() {
|
function _idCardlogin() {
|
||||||
try {
|
try {
|
||||||
// let userinfo = JSON.parse(bridge.getLocation());
|
// let userinfo = JSON.parse(bridge.getLocation());
|
||||||
let sfzh='510922199202281888'
|
let sfzh='510922199202281887'
|
||||||
Toast.loading({
|
Toast.loading({
|
||||||
message: "登录中...",
|
message: "登录中...",
|
||||||
forbidClick: true,
|
forbidClick: true,
|
||||||
|
|||||||
@ -120,9 +120,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed, onMounted, watch } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import BottomTabs from "@/components/bottomTabs.vue";
|
import BottomTabs from "@/components/bottomTabs.vue";
|
||||||
|
import { getEventUnfinished } from "@/api/traffic";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@ -148,63 +149,52 @@ const myLocation = ref({
|
|||||||
left: "40%"
|
left: "40%"
|
||||||
});
|
});
|
||||||
|
|
||||||
// 标记点数据
|
// 标记点数据(从接口获取)
|
||||||
const markers = ref([
|
const markers = ref([]);
|
||||||
{
|
const initLoading = ref(false);
|
||||||
id: 1,
|
|
||||||
type: "road",
|
// 获取未完成的预警事件
|
||||||
title: "中山路拥堵",
|
async function fetchUnfinishedEvents() {
|
||||||
location: "中山路与发展大道",
|
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
|
||||||
time: "10:30",
|
const areaCode = userInfo.areaCode;
|
||||||
color: "marker-blue",
|
const eventCategory = activeAlertType.value === 'road' ? 1 : 2;
|
||||||
position: { top: "15%", left: "15%" }
|
|
||||||
},
|
initLoading.value = true;
|
||||||
{
|
try {
|
||||||
id: 2,
|
const res = await getEventUnfinished({ eventCategory, areaCode });
|
||||||
type: "emergency",
|
console.log('未完成预警事件:', res);
|
||||||
title: "交通事故",
|
if (res) {
|
||||||
location: "解放大道光谷广场",
|
markers.value = (Array.isArray(res) ? res : res.data || []).map(item => ({
|
||||||
time: "09:15",
|
id: item.id,
|
||||||
color: "marker-red",
|
type: activeAlertType.value,
|
||||||
position: { top: "15%", left: "25%" }
|
title: item.eventType || item.title || '预警事件',
|
||||||
},
|
location: item.siteName || item.location || '',
|
||||||
{
|
time: item.eventTime || item.time || '',
|
||||||
id: 3,
|
color: getMarkerColor(item.eventLevel),
|
||||||
type: "road",
|
position: {
|
||||||
title: "道路施工",
|
top: item.latitude ? `${Math.min(Math.max(item.latitude, 5), 95)}%` : `${Math.random() * 80 + 10}%`,
|
||||||
location: "上新河桥",
|
left: item.longitude ? `${Math.min(Math.max(item.longitude, 5), 95)}%` : `${Math.random() * 80 + 10}%`
|
||||||
time: "11:00",
|
}
|
||||||
color: "marker-blue",
|
}));
|
||||||
position: { top: "35%", left: "35%" }
|
}
|
||||||
},
|
} catch (error) {
|
||||||
{
|
console.error('获取预警事件失败:', error);
|
||||||
id: 4,
|
markers.value = [];
|
||||||
type: "violation",
|
} finally {
|
||||||
title: "违停车辆",
|
initLoading.value = false;
|
||||||
location: "武汉大道CBD",
|
}
|
||||||
time: "08:45",
|
}
|
||||||
color: "marker-purple",
|
|
||||||
position: { top: "50%", left: "55%" }
|
// 根据事件等级获取标记颜色
|
||||||
},
|
function getMarkerColor(eventLevel) {
|
||||||
{
|
const colorMap = {
|
||||||
id: 5,
|
1: 'marker-red',
|
||||||
type: "road",
|
2: 'marker-orange',
|
||||||
title: "路面积水",
|
3: 'marker-blue',
|
||||||
location: "汉口江滩大道",
|
4: 'marker-purple'
|
||||||
time: "12:20",
|
};
|
||||||
color: "marker-blue",
|
return colorMap[eventLevel] || 'marker-blue';
|
||||||
position: { top: "50%", left: "45%" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
type: "emergency",
|
|
||||||
title: "紧急疏导",
|
|
||||||
location: "光谷转盘",
|
|
||||||
time: "13:30",
|
|
||||||
color: "marker-red",
|
|
||||||
position: { top: "70%", left: "75%" }
|
|
||||||
}
|
}
|
||||||
]);
|
|
||||||
|
|
||||||
// 过滤后的标记点
|
// 过滤后的标记点
|
||||||
const filteredMarkers = computed(() => {
|
const filteredMarkers = computed(() => {
|
||||||
@ -217,6 +207,16 @@ const filteredMarkers = computed(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 切换预警类型时重新加载数据
|
||||||
|
watch(activeAlertType, () => {
|
||||||
|
fetchUnfinishedEvents();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面加载时获取数据
|
||||||
|
onMounted(() => {
|
||||||
|
fetchUnfinishedEvents();
|
||||||
|
});
|
||||||
|
|
||||||
// 返回
|
// 返回
|
||||||
function goBack() {
|
function goBack() {
|
||||||
router.back();
|
router.back();
|
||||||
@ -370,6 +370,10 @@ function goToDetail() {
|
|||||||
background: #ef4444;
|
background: #ef4444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.marker-orange {
|
||||||
|
background: #f97316;
|
||||||
|
}
|
||||||
|
|
||||||
&.marker-purple {
|
&.marker-purple {
|
||||||
background: #8b5cf6;
|
background: #8b5cf6;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,13 +21,8 @@
|
|||||||
|
|
||||||
<!-- 功能卡片 -->
|
<!-- 功能卡片 -->
|
||||||
<div class="function-cards">
|
<div class="function-cards">
|
||||||
<div
|
<div v-for="(card, index) in functionCards" :key="index" class="card-item" :class="card.bgClass"
|
||||||
v-for="(card, index) in functionCards"
|
@click="handleCardClick(card)">
|
||||||
:key="index"
|
|
||||||
class="card-item"
|
|
||||||
:class="card.bgClass"
|
|
||||||
@click="handleCardClick(card)"
|
|
||||||
>
|
|
||||||
<!-- 装饰性背景图标 -->
|
<!-- 装饰性背景图标 -->
|
||||||
<div class="card-decor">
|
<div class="card-decor">
|
||||||
<van-icon :name="card.icon" class="decor-icon" />
|
<van-icon :name="card.icon" class="decor-icon" />
|
||||||
@ -35,8 +30,8 @@
|
|||||||
|
|
||||||
<!-- 内容 -->
|
<!-- 内容 -->
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h3 class="card-title">{{ card.label }}</h3>
|
<div class="card-title">{{ card.label }}</div>
|
||||||
<p class="card-subtitle">{{ card.subtitle }}</p>
|
<div class="card-subtitle">{{ card.subtitle }}</div>
|
||||||
<div class="card-count">
|
<div class="card-count">
|
||||||
<span class="count-label">{{ card.countLabel }}</span>
|
<span class="count-label">{{ card.countLabel }}</span>
|
||||||
<span class="count-value">{{ card.count }}</span>
|
<span class="count-value">{{ card.count }}</span>
|
||||||
@ -70,19 +65,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<van-list
|
<van-loading v-if="initLoading" class="loading-state" color="#2563eb"
|
||||||
v-model:loading="loading"
|
style="text-align:center;padding:20px;">加载中...</van-loading>
|
||||||
:finished="finished"
|
<van-list v-else v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad"
|
||||||
finished-text="没有更多了"
|
class="alerts-list">
|
||||||
@load="onLoad"
|
<div v-for="alert in alertList" :key="alert.id" class="alert-item" @click="handleAlertClick(alert)">
|
||||||
class="alerts-list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="alert in alertList"
|
|
||||||
:key="alert.id"
|
|
||||||
class="alert-item"
|
|
||||||
@click="handleAlertClick(alert)"
|
|
||||||
>
|
|
||||||
<!-- 类型和等级 -->
|
<!-- 类型和等级 -->
|
||||||
<div class="alert-header">
|
<div class="alert-header">
|
||||||
<span class="alert-type">{{ alert.type }}</span>
|
<span class="alert-type">{{ alert.type }}</span>
|
||||||
@ -92,11 +79,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 违章预警显示车牌信息 -->
|
<!-- 违章预警显示车牌信息 -->
|
||||||
<div v-if="alert.alertType === 'violation'" class="alert-vehicle">
|
<div class="alert-vehicle">
|
||||||
<van-icon name="cart" class="vehicle-icon" />
|
<van-icon name="cart" class="vehicle-icon" />
|
||||||
<span>{{ alert.plateNumber }}</span>
|
<span>{{ alert.plateNo }}</span>
|
||||||
<span class="separator">|</span>
|
<span class="separator">|</span>
|
||||||
<span>{{ alert.plateColor }}</span>
|
<span>{{ alert.vehicleColor }}</span>
|
||||||
<span class="separator">|</span>
|
<span class="separator">|</span>
|
||||||
<span>{{ alert.vehicleType }}</span>
|
<span>{{ alert.vehicleType }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -105,14 +92,14 @@
|
|||||||
<div class="alert-location">
|
<div class="alert-location">
|
||||||
<van-icon name="location" class="info-icon" />
|
<van-icon name="location" class="info-icon" />
|
||||||
<span class="label">检测点位:</span>
|
<span class="label">检测点位:</span>
|
||||||
<span>{{ alert.location }}</span>
|
<span>{{ alert.siteName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 检测时间 -->
|
<!-- 检测时间 -->
|
||||||
<div class="alert-time">
|
<div class="alert-time">
|
||||||
<van-icon name="clock" class="info-icon" />
|
<van-icon name="clock" class="info-icon" />
|
||||||
<span class="label">检测时间:</span>
|
<span class="label">检测时间:</span>
|
||||||
<span>{{ alert.time }}</span>
|
<span>{{ alert.passTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</van-list>
|
</van-list>
|
||||||
@ -128,6 +115,7 @@ import { ref, computed, onMounted } from "vue";
|
|||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { List } from "vant";
|
import { List } from "vant";
|
||||||
import BottomTabs from "@/components/bottomTabs.vue";
|
import BottomTabs from "@/components/bottomTabs.vue";
|
||||||
|
import { countByTaskStatus, getInterceptWarnList } from "@/api/traffic";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@ -148,166 +136,26 @@ const sspPendingCount = ref(12);
|
|||||||
const currentLocation = ref("");
|
const currentLocation = ref("");
|
||||||
|
|
||||||
// 功能卡片数据
|
// 功能卡片数据
|
||||||
const functionCards = [
|
const functionCards = ref([
|
||||||
{
|
{
|
||||||
icon: "warning",
|
icon: "warning",
|
||||||
label: "路况任务",
|
label: "路况任务",
|
||||||
subtitle: "应急处理数据信息",
|
subtitle: "应急处理数据信息",
|
||||||
count: 236,
|
count: 0,
|
||||||
countLabel: "未执行",
|
countLabel: "未执行",
|
||||||
bgClass: "bg-traffic",
|
bgClass: "bg-traffic",
|
||||||
route: "/traffic-alerts"
|
route: "/traffic-alerts",
|
||||||
|
type: "traffic"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "todo-list",
|
icon: "todo-list",
|
||||||
label: "违规任务",
|
label: "违规任务",
|
||||||
subtitle: "违章车辆数据信息",
|
subtitle: "违章车辆数据信息",
|
||||||
count: 128,
|
count: 0,
|
||||||
countLabel: "未执行",
|
countLabel: "未执行",
|
||||||
bgClass: "bg-violation",
|
bgClass: "bg-violation",
|
||||||
route: "/violation-alerts"
|
route: "/violation-alerts",
|
||||||
}
|
type: "violation"
|
||||||
];
|
|
||||||
|
|
||||||
// 预警列表数据 - 模拟多页数据
|
|
||||||
const allAlerts = ref([
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
alertType: "traffic",
|
|
||||||
type: "交通事故",
|
|
||||||
priority: "一级",
|
|
||||||
time: "03/26 09:15",
|
|
||||||
location: "武汉大道光谷广场",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-high"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
alertType: "violation",
|
|
||||||
type: "违规停车",
|
|
||||||
priority: "一级",
|
|
||||||
plateNumber: "鄂A12345",
|
|
||||||
plateColor: "蓝色",
|
|
||||||
vehicleType: "小型汽车",
|
|
||||||
time: "03/26 10:00",
|
|
||||||
location: "江汉路步行街入口",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-high"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
alertType: "violation",
|
|
||||||
type: "超速行驶",
|
|
||||||
priority: "一级",
|
|
||||||
plateNumber: "鄂C55555",
|
|
||||||
plateColor: "黄色",
|
|
||||||
vehicleType: "中型货车",
|
|
||||||
time: "03/26 09:45",
|
|
||||||
location: "长江大桥北桥头",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-high"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
alertType: "traffic",
|
|
||||||
type: "道路拥堵",
|
|
||||||
priority: "一级",
|
|
||||||
time: "03/26 09:30",
|
|
||||||
location: "中山路与发展大道交叉口",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-high"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
alertType: "traffic",
|
|
||||||
type: "道路施工",
|
|
||||||
priority: "二级",
|
|
||||||
time: "03/26 08:30",
|
|
||||||
location: "解放大道武商广场",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-medium"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
alertType: "violation",
|
|
||||||
type: "违规变道",
|
|
||||||
priority: "二级",
|
|
||||||
plateNumber: "鄂B88888",
|
|
||||||
plateColor: "蓝色",
|
|
||||||
vehicleType: "小型汽车",
|
|
||||||
time: "03/26 08:15",
|
|
||||||
location: "汉口火车站广场",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-medium"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
alertType: "traffic",
|
|
||||||
type: "路面积水",
|
|
||||||
priority: "三级",
|
|
||||||
time: "03/26 07:50",
|
|
||||||
location: "汉口江滩大道",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-low"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
alertType: "violation",
|
|
||||||
type: "闯红灯",
|
|
||||||
priority: "一级",
|
|
||||||
plateNumber: "鄂D66666",
|
|
||||||
plateColor: "蓝色",
|
|
||||||
vehicleType: "小型汽车",
|
|
||||||
time: "03/26 07:30",
|
|
||||||
location: "长江大桥南桥头",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-high"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 9,
|
|
||||||
alertType: "traffic",
|
|
||||||
type: "交通管制",
|
|
||||||
priority: "二级",
|
|
||||||
time: "03/25 22:00",
|
|
||||||
location: "武汉大道CBD",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-medium"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10,
|
|
||||||
alertType: "violation",
|
|
||||||
type: "逆行",
|
|
||||||
priority: "一级",
|
|
||||||
plateNumber: "鄂E77777",
|
|
||||||
plateColor: "蓝色",
|
|
||||||
vehicleType: "小型汽车",
|
|
||||||
time: "03/25 21:30",
|
|
||||||
location: "光谷广场转盘",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-high"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 11,
|
|
||||||
alertType: "traffic",
|
|
||||||
type: "信号灯故障",
|
|
||||||
priority: "二级",
|
|
||||||
time: "03/25 20:00",
|
|
||||||
location: "中山路与发展大道",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-medium"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 12,
|
|
||||||
alertType: "violation",
|
|
||||||
type: "违停",
|
|
||||||
priority: "三级",
|
|
||||||
plateNumber: "鄂F99999",
|
|
||||||
plateColor: "蓝色",
|
|
||||||
vehicleType: "小型汽车",
|
|
||||||
time: "03/25 19:45",
|
|
||||||
location: "江汉路步行街",
|
|
||||||
status: "未执行",
|
|
||||||
priorityColor: "priority-low"
|
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -315,38 +163,67 @@ const allAlerts = ref([
|
|||||||
const alertList = ref([]);
|
const alertList = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const finished = ref(false);
|
const finished = ref(false);
|
||||||
|
const initLoading = ref(false);
|
||||||
const pageSize = 5;
|
const pageSize = 5;
|
||||||
const currentPage = ref(0);
|
const currentPage = ref(0);
|
||||||
|
|
||||||
// 过滤未执行的预警
|
// 过滤未执行的预警(接口直接返回未执行数据,此处无需过滤)
|
||||||
const filteredAlerts = computed(() => {
|
const filteredAlerts = computed(() => {
|
||||||
return allAlerts.value.filter(alert => alert.status === "未执行");
|
return alertList.value;
|
||||||
});
|
});
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
userInfo.value=JSON.parse(localStorage.getItem('userInfo'))
|
userInfo.value = JSON.parse(localStorage.getItem('userInfo')) || {};
|
||||||
|
fetchTaskStats();
|
||||||
})
|
})
|
||||||
// 加载更多数据
|
|
||||||
function onLoad() {
|
|
||||||
// 模拟异步加载
|
|
||||||
setTimeout(() => {
|
|
||||||
const start = currentPage.value * pageSize;
|
|
||||||
const end = start + pageSize;
|
|
||||||
const newData = filteredAlerts.value.slice(start, end);
|
|
||||||
|
|
||||||
if (newData.length > 0) {
|
// 加载拦截预警列表
|
||||||
alertList.value.push(...newData);
|
async function onLoad() {
|
||||||
|
initLoading.value = true;
|
||||||
|
loading.value = true;
|
||||||
|
const userId = userInfo.value?.id;
|
||||||
|
if (!userId) {
|
||||||
|
finished.value = true;
|
||||||
|
loading.value = false;
|
||||||
|
initLoading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await getInterceptWarnList({
|
||||||
|
userId,
|
||||||
|
status: 0,
|
||||||
|
pageSize,
|
||||||
|
page: currentPage.value + 1
|
||||||
|
});
|
||||||
|
console.log('拦截预警列表:', res);
|
||||||
|
if (res && res.content) {
|
||||||
|
const records = res.content || [];
|
||||||
|
if (currentPage.value === 0) {
|
||||||
|
alertList.value = records;
|
||||||
|
} else {
|
||||||
|
alertList.value.push(...records);
|
||||||
|
}
|
||||||
currentPage.value++;
|
currentPage.value++;
|
||||||
|
|
||||||
// 判断是否加载完成
|
const totalPages = res.content.totalPages || res.content.pages || 1;
|
||||||
if (alertList.value.length >= filteredAlerts.value.length) {
|
if (currentPage.value >= totalPages) {
|
||||||
finished.value = true;
|
finished.value = true;
|
||||||
}
|
}
|
||||||
|
} else if (res && Array.isArray(res)) {
|
||||||
|
alertList.value = res;
|
||||||
|
finished.value = true;
|
||||||
} else {
|
} else {
|
||||||
|
alertList.value = [];
|
||||||
finished.value = true;
|
finished.value = true;
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取拦截预警列表失败:", error);
|
||||||
|
alertList.value = [];
|
||||||
|
finished.value = true;
|
||||||
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}, 500);
|
initLoading.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转到随手拍上报页面
|
// 跳转到随手拍上报页面
|
||||||
@ -378,6 +255,32 @@ function handleAlertClick(alert) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取任务统计数据
|
||||||
|
async function fetchTaskStats() {
|
||||||
|
const userId = userInfo.value?.id;
|
||||||
|
if (!userId) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await countByTaskStatus({
|
||||||
|
userId: userId,
|
||||||
|
startTime: "",
|
||||||
|
endTime: ""
|
||||||
|
});
|
||||||
|
if (res && Array.isArray(res)) {
|
||||||
|
res.forEach(item => {
|
||||||
|
const total = item.statusList.reduce((sum, s) => sum + (s.count || 0), 0);
|
||||||
|
if (item.eventCategory === 1) {
|
||||||
|
functionCards.value[0].count = total;
|
||||||
|
} else if (item.eventCategory === 2) {
|
||||||
|
functionCards.value[1].count = total;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取任务统计数据失败:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -510,7 +413,6 @@ function handleAlertClick(alert) {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||||
min-height: 160px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: box-shadow 0.2s;
|
transition: box-shadow 0.2s;
|
||||||
|
|
||||||
@ -554,7 +456,7 @@ function handleAlertClick(alert) {
|
|||||||
.card-subtitle {
|
.card-subtitle {
|
||||||
color: rgba(255, 255, 255, 0.8);
|
color: rgba(255, 255, 255, 0.8);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-count {
|
.card-count {
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
<van-icon name="arrow-left" />
|
<van-icon name="arrow-left" />
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-title">随手拍</div>
|
<div class="nav-title">随手拍</div>
|
||||||
<div class="nav-right" @click="handleSubmit">
|
<div class="nav-right">
|
||||||
提交
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -117,8 +117,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 照片基本信息 -->
|
<!-- 照片基本信息 -->
|
||||||
<van-cell-group :border="false">
|
<van-cell-group :border="false">
|
||||||
<van-field v-model="formData.zpsl" is-link readonly name="照片数量" label="照片数量 *" placeholder="请选择照片数量"
|
<van-field v-model="formData.zpsl" name="照片数量" label="照片数量 *" placeholder="请选择照片数量" />
|
||||||
@click="openPicker({ columns: zpslColumns, title: '选择照片数量', onConfirm: onZpslConfirm })" />
|
|
||||||
<van-field v-model="formData.tpmc" name="图片文件名" label="图片文件名" placeholder="请输入图片文件名" />
|
<van-field v-model="formData.tpmc" name="图片文件名" label="图片文件名" placeholder="请输入图片文件名" />
|
||||||
<van-field v-model="formData.tpfs" is-link readonly name="图片方式" label="图片方式" placeholder="请选择图片方式"
|
<van-field v-model="formData.tpfs" is-link readonly name="图片方式" label="图片方式" placeholder="请选择图片方式"
|
||||||
@click="openPicker({ columns: tpfsColumns, title: '选择图片方式', onConfirm: onTpfsConfirm })" />
|
@click="openPicker({ columns: tpfsColumns, title: '选择图片方式', onConfirm: onTpfsConfirm })" />
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<!-- 顶部导航栏 -->
|
<!-- 顶部导航栏 -->
|
||||||
<div class="nav-bar">
|
<div class="nav-bar">
|
||||||
<van-icon name="arrow-left" class="nav-back" @click="goBack" />
|
<van-icon name="arrow-left" class="nav-back" @click="goBack" />
|
||||||
<h1 class="nav-title">路况预警</h1>
|
<h1 class="nav-title">路况任务</h1>
|
||||||
<van-icon name="filter-o" class="nav-filter" />
|
<van-icon name="filter-o" class="nav-filter" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,77 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 卡口预警折叠面板 -->
|
||||||
|
<van-collapse v-model="activeNames" :border="false" class="alert-collapse">
|
||||||
|
<van-collapse-item name="1" :border="false">
|
||||||
|
<template #title>
|
||||||
|
<div class="collapse-title">卡口预警</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<van-list
|
||||||
|
v-model:loading="alertLoading"
|
||||||
|
:finished="alertFinished"
|
||||||
|
finished-text="没有更多了"
|
||||||
|
@load="onLoadAlerts"
|
||||||
|
:immediate-check="false"
|
||||||
|
>
|
||||||
|
<div class="alert-list">
|
||||||
|
<div v-for="(item, index) in checkinAlerts" :key="item.id" class="alert-item">
|
||||||
|
<!-- 顶部序号和基本信息 -->
|
||||||
|
<div class="item-header">
|
||||||
|
<div class="item-index">{{ index + 1 }}</div>
|
||||||
|
<div class="item-info">
|
||||||
|
<div class="info-row">
|
||||||
|
<van-icon name="location-o" class="info-icon" />
|
||||||
|
<span class="label">检测点位:</span>
|
||||||
|
<span class="value">{{ item.siteName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<van-icon name="clock-o" class="info-icon" />
|
||||||
|
<span class="label">检测时间:</span>
|
||||||
|
<span class="value">{{ item.eventTime }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 抓拍图片区域 -->
|
||||||
|
<div class="capture-section">
|
||||||
|
<div class="section-title">抓拍图片:</div>
|
||||||
|
<van-image :src="item.imgUrl" fit="cover" class="capture-img" radius="12" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 详细网格信息 -->
|
||||||
|
<div class="detail-grid">
|
||||||
|
<div class="grid-item">
|
||||||
|
<span class="label">速度:</span>
|
||||||
|
<span class="value">{{ item.speed }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<span class="label">车道号:</span>
|
||||||
|
<span class="value">{{ item.laneNo }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<span class="label">方向:</span>
|
||||||
|
<span class="value">{{ item.direction }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<van-icon name="user-o" class="grid-icon" />
|
||||||
|
<span class="label">执法人员:</span>
|
||||||
|
<span class="value">{{ item.person }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<span class="label">工号:</span>
|
||||||
|
<span class="value">{{ item.workNo }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 分割线 -->
|
||||||
|
<div v-if="index < checkinAlerts.length - 1" class="item-divider"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-list>
|
||||||
|
</van-collapse-item>
|
||||||
|
</van-collapse>
|
||||||
|
|
||||||
<!-- 底部按钮 - 未执行状态 -->
|
<!-- 底部按钮 - 未执行状态 -->
|
||||||
<div v-if="allDetail.taskStatus == '0'" class="action-bar">
|
<div v-if="allDetail.taskStatus == '0'" class="action-bar">
|
||||||
<van-button block round type="primary" class="action-btn" @click="handleCheckIn">
|
<van-button block round type="primary" class="action-btn" @click="handleCheckIn">
|
||||||
@ -147,6 +218,53 @@ const violationDetail = ref({})
|
|||||||
const allDetail = ref({})
|
const allDetail = ref({})
|
||||||
const taskDetail = ref({})
|
const taskDetail = ref({})
|
||||||
|
|
||||||
|
// 卡口预警模拟数据
|
||||||
|
const checkinAlerts = ref([])
|
||||||
|
const alertLoading = ref(false)
|
||||||
|
const alertFinished = ref(false)
|
||||||
|
const alertPage = ref(1) // 分页当前页码
|
||||||
|
const activeNames = ref(['1']) // 默认展开第一个面板
|
||||||
|
|
||||||
|
// 模拟加载卡口预警数据
|
||||||
|
const onLoadAlerts = () => {
|
||||||
|
// 模拟异步请求
|
||||||
|
setTimeout(() => {
|
||||||
|
const newData = [
|
||||||
|
{
|
||||||
|
id: checkinAlerts.value.length + 1,
|
||||||
|
siteName: '解放大道循礼门路口东',
|
||||||
|
eventTime: '2026-03-27 09:15:32',
|
||||||
|
imgUrl: 'https://img0.baidu.com/it/u=2535738879,1652433069&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
|
||||||
|
speed: '65 km/h',
|
||||||
|
laneNo: '2',
|
||||||
|
direction: '由东向西',
|
||||||
|
person: '张伟',
|
||||||
|
workNo: '210001'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: checkinAlerts.value.length + 2,
|
||||||
|
siteName: '解放大道循礼门路口东',
|
||||||
|
eventTime: '2026-03-27 09:15:35',
|
||||||
|
imgUrl: 'https://img0.baidu.com/it/u=2535738879,1652433069&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
|
||||||
|
speed: '68 km/h',
|
||||||
|
laneNo: '2',
|
||||||
|
direction: '由东向西',
|
||||||
|
person: '张伟',
|
||||||
|
workNo: '210001'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
checkinAlerts.value.push(...newData);
|
||||||
|
alertLoading.value = false;
|
||||||
|
alertPage.value++;
|
||||||
|
|
||||||
|
// 模拟加载 5 页后结束
|
||||||
|
if (alertPage.value > 5) {
|
||||||
|
alertFinished.value = true;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
// 获取详情数据
|
// 获取详情数据
|
||||||
const fetchDetail = async () => {
|
const fetchDetail = async () => {
|
||||||
if (!violationId) return;
|
if (!violationId) return;
|
||||||
@ -238,6 +356,7 @@ function handlePlateMatch(matched) {
|
|||||||
// 页面初始化
|
// 页面初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchDetail();
|
fetchDetail();
|
||||||
|
onLoadAlerts(); // 初始化加载预警数据
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -273,6 +392,7 @@ onMounted(() => {
|
|||||||
.nav-placeholder {
|
.nav-placeholder {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-card {
|
.detail-card {
|
||||||
@ -577,4 +697,139 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert-collapse {
|
||||||
|
margin: 0 16px 16px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
|
||||||
|
:deep(.van-collapse-item__title) {
|
||||||
|
padding: 16px;
|
||||||
|
align-items: center;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-collapse-item__content) {
|
||||||
|
padding: 0 16px 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-list {
|
||||||
|
.alert-item {
|
||||||
|
padding-top: 12px;
|
||||||
|
|
||||||
|
.item-header {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.item-index {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-info {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #94a3b8;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #64748b;
|
||||||
|
min-width: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.capture-section {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #64748b;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.capture-img {
|
||||||
|
width: 120px;
|
||||||
|
height: 80px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 12px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.grid-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.grid-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #94a3b8;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-divider {
|
||||||
|
height: 1px;
|
||||||
|
background: #f1f5f9;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -3,7 +3,7 @@
|
|||||||
<!-- 顶部导航栏 -->
|
<!-- 顶部导航栏 -->
|
||||||
<div class="nav-bar">
|
<div class="nav-bar">
|
||||||
<van-icon name="arrow-left" class="nav-back" @click="goBack" />
|
<van-icon name="arrow-left" class="nav-back" @click="goBack" />
|
||||||
<h1 class="nav-title">违章预警</h1>
|
<h1 class="nav-title">违规任务</h1>
|
||||||
<van-icon name="filter-o" class="nav-filter" />
|
<van-icon name="filter-o" class="nav-filter" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user