修改接口内容

This commit is contained in:
给我
2026-04-21 18:00:09 +08:00
parent 974c82b5df
commit ce0228ef2b
9 changed files with 489 additions and 269 deletions

View File

@ -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
});
}

View File

@ -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');

View File

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

View File

@ -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%" }
},
{
id: 5,
type: "road",
title: "路面积水",
location: "汉口江滩大道",
time: "12:20",
color: "marker-blue",
position: { top: "50%", left: "45%" }
},
{
id: 6,
type: "emergency",
title: "紧急疏导",
location: "光谷转盘",
time: "13:30",
color: "marker-red",
position: { top: "70%", left: "75%" }
} }
]); }
// 根据事件等级获取标记颜色
function getMarkerColor(eventLevel) {
const colorMap = {
1: 'marker-red',
2: 'marker-orange',
3: 'marker-blue',
4: 'marker-purple'
};
return colorMap[eventLevel] || 'marker-blue';
}
// 过滤后的标记点 // 过滤后的标记点
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;
} }

View File

@ -4,7 +4,7 @@
<div class="header-bg"> <div class="header-bg">
<div class="user-section"> <div class="user-section">
<div class="avatar"> <div class="avatar">
{{ userInfo.nickName?userInfo.nickName?.charAt(0):"" }} {{ userInfo.nickName ? userInfo.nickName?.charAt(0) : "" }}
</div> </div>
<div class="user-info"> <div class="user-info">
<div class="user-name">{{ userInfo.nickName }}</div> <div class="user-name">{{ userInfo.nickName }}</div>
@ -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 {

View File

@ -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 })" />

View File

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

View File

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

View File

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