This commit is contained in:
给我
2026-04-10 17:10:36 +08:00
parent 368ed7897b
commit ef83eeb5fe
767 changed files with 167713 additions and 0 deletions

View File

@ -0,0 +1,683 @@
<template>
<div class="alert-detail-page">
<!-- 顶部导航栏 -->
<div class="nav-bar">
<van-icon name="arrow-left" class="nav-back" @click="goBack" />
<h1 class="nav-title">路况预警详情</h1>
<div class="nav-placeholder"></div>
</div>
<!-- 预警信息卡片 -->
<div class="detail-card">
<!-- 头部信息 -->
<div class="card-header">
<div class="header-left">
<span class="level-tag" :class="alertDetail.levelClass">
{{ alertDetail.level }}
</span>
<span class="alert-title">{{ alertDetail.title }}</span>
</div>
<span class="status-tag" :class="alertDetail.statusClass">
{{ alertDetail.status }}
</span>
</div>
<!-- 图片 -->
<div class="card-image" v-if="alertDetail.image">
<van-image
:src="alertDetail.image"
fit="cover"
class="alert-img"
/>
</div>
<!-- 详细信息 -->
<div class="card-details">
<div class="detail-item">
<van-icon name="clock" class="detail-icon" />
<span class="label">检测时间</span>
<span class="value">{{ alertDetail.time }}</span>
</div>
<div class="detail-item">
<van-icon name="location" class="detail-icon" />
<span class="label">检测地点</span>
<span class="value">{{ alertDetail.location }}</span>
</div>
<!-- 视频展示按钮 -->
<div class="video-btn-wrapper">
<van-button block round class="video-btn">
<van-icon name="video-o" class="video-icon" />
视频展示
</van-button>
</div>
</div>
</div>
<!-- 执行记录卡片 -->
<div class="record-card">
<div class="card-title">执行记录</div>
<!-- 蓝色边框卡片 -->
<div class="execution-box">
<!-- 绿色边框内层卡片 -->
<div class="info-box">
<div class="info-row">
<span class="info-label">执行时间</span>
<span class="info-value">03/29 09:30</span>
</div>
<div class="info-row">
<span class="info-text">交通指挥中心</span>
<span class="info-divider">|</span>
<span class="info-text">联系电话027-8888-8888</span>
</div>
<div class="info-row">
<span class="info-label">任务地点</span>
<span class="info-value">{{ alertDetail.location }}</span>
</div>
</div>
<!-- 任务描述 -->
<div class="task-desc">
协助疏导交通确保道路畅通维持现场秩序
</div>
<!-- 打卡情况 - 执行中和已完成状态显示 -->
<div v-if="status === '执行中' || status === '已完成'" class="checkin-box">
<div class="checkin-row">
<span class="checkin-date">11-16</span>
<span class="checkin-time">16:20:15</span>
<span class="checkin-type">签到打卡</span>
</div>
<div class="checkin-row">
<span class="checkin-label">打卡账号</span>
<span class="checkin-value">21515800</span>
</div>
<div class="checkin-row checkin-location">
<van-icon name="location" class="location-icon" />
<span>四川省德阳市旌阳区嘉明街道光兴街2号</span>
</div>
</div>
<!-- 按钮区域 -->
<!-- 已完成状态 - 显示三次反馈按钮 -->
<div v-if="status === '已完成'" class="feedback-buttons">
<van-button block round class="feedback-btn" @click="showFeedback(1)">
第一次反馈结果
</van-button>
<van-button block round class="feedback-btn" @click="showFeedback(2)">
第二次反馈结果
</van-button>
<van-button block round class="feedback-btn" @click="showFeedback(3)">
第三次反馈结果
</van-button>
</div>
<!-- 未执行状态 - 显示定位打卡按钮 -->
<div v-else-if="status === '未执行'" class="action-buttons">
<van-button block round type="primary" class="action-btn" @click="handleCheckIn">
定位打卡
</van-button>
</div>
<!-- 执行中状态 - 显示反馈按钮 -->
<div v-else-if="status === '执行中'" class="feedback-buttons">
<van-button block round class="feedback-btn success" @click="showFeedback(1)">
第一次反馈结果
</van-button>
<van-button block round class="feedback-btn success" @click="showFeedback(2)">
第二次反馈结果
</van-button>
<van-button block round type="primary" class="action-btn" @click="handleFeedback">
立即反馈
</van-button>
</div>
</div>
</div>
<!-- 反馈结果弹窗 -->
<van-popup v-model:show="showResultDialog" round position="center" class="feedback-popup">
<div class="popup-content">
<h2 class="popup-title">{{ currentFeedback.title }}</h2>
<div class="popup-info">
<p>反馈时间{{ currentFeedback.time }}</p>
</div>
<!-- 现场照片 -->
<div class="popup-section">
<p class="section-label">现场照片</p>
<div class="image-grid">
<van-image
v-for="(img, idx) in currentFeedback.images"
:key="idx"
:src="img"
fit="cover"
class="feedback-img"
/>
</div>
</div>
<!-- 场地视频 -->
<div class="popup-section">
<p class="section-label">场地视频</p>
<div class="video-item">
<van-icon name="video-o" class="video-icon" />
<span>视频 1</span>
</div>
</div>
<!-- 反馈内容 -->
<div class="popup-section">
<h3 class="content-title">反馈内容</h3>
<p class="content-text">{{ currentFeedback.content }}</p>
</div>
<!-- 关闭按钮 -->
<van-button block round class="close-btn" @click="closePopup">
关闭
</van-button>
</div>
</van-popup>
</div>
</template>
<script setup>
import { ref, computed } from "vue";
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();
// 获取URL参数
const alertId = route.query.id || "1";
const status = route.query.status || "未执行";
// 反馈弹窗状态
const showResultDialog = ref(false);
const selectedFeedbackIndex = ref(1);
// 预警详情数据
const alertDetail = ref({
id: alertId,
level: "一级",
levelClass: "level-red",
title: "交通事故",
status: status,
statusClass: computed(() => {
if (status === "执行中") return "status-blue";
if (status === "已完成") return "status-green";
return "status-orange";
}).value,
image: "https://images.unsplash.com/photo-1772962622823-77778ff7b192?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHx0cmFmZmljJTIwYWNjaWRlbnQlMjBlbWVyZ2VuY3l8ZW58MXx8fHwxNzc0NjA1NzE3fDA&ixlib=rb-4.1.0&q=80&w=1080",
location: "解放大道光谷广场",
time: "03/29 08:00",
issuer: "110指挥中心",
phone: "027-110"
});
// 反馈数据
const feedbackData = {
1: {
title: "第一次反馈结果",
time: "03/29 10:15",
content: "已到达现场,正在疏导交通。现场车流量较大,已设置临时路障引导车辆分流。",
images: [
"https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=800&q=80",
"https://images.unsplash.com/photo-1486006920555-c77dcf18193c?w=800&q=80"
]
},
2: {
title: "第二次反馈结果",
time: "03/29 10:45",
content: "交通疏导进行中拥堵情况有所缓解。已联系拖车处理事故车辆预计15分钟后完全恢复通行。",
images: [
"https://images.unsplash.com/photo-1485833077593-4278bba3f11f?w=800&q=80",
"https://images.unsplash.com/photo-1502444330042-d1a1ddf9bb5b?w=800&q=80"
]
},
3: {
title: "第三次反馈结果",
time: "03/29 11:10",
content: "任务已完成,交通已恢复正常。事故车辆已清离现场,临时路障已撤除,道路完全畅通。",
images: [
"https://images.unsplash.com/photo-1464037866556-6812c9d1c72e?w=800&q=80",
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=800&q=80"
]
}
};
const currentFeedback = computed(() => feedbackData[selectedFeedbackIndex.value] || feedbackData[1]);
// 返回
function goBack() {
router.back();
}
// 定位打卡
function handleCheckIn() {
router.push({
path: "/checkInPage",
query: { id: alertId }
});
}
// 立即反馈
function handleFeedback() {
router.push({
path: "/alert-handle",
query: { id: alertId, status: status }
});
}
// 显示反馈弹窗
function showFeedback(index) {
selectedFeedbackIndex.value = index;
showResultDialog.value = true;
}
// 关闭弹窗
function closePopup() {
showResultDialog.value = false;
}
</script>
<style lang="scss" scoped>
.alert-detail-page {
min-height: 100vh;
background: #f1f5f9;
padding-bottom: 100px;
}
.nav-bar {
position: sticky;
top: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: space-between;
background: white;
border-bottom: 1px solid #e5e5e5;
padding: 12px 16px;
.nav-back {
font-size: 24px;
color: #333;
}
.nav-title {
font-size: 17px;
font-weight: 600;
color: #333;
}
.nav-placeholder {
width: 24px;
}
}
.detail-card,
.record-card {
margin: 16px;
background: white;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.detail-card {
padding: 16px;
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
.header-left {
display: flex;
align-items: center;
gap: 8px;
}
.level-tag {
padding: 4px 8px;
border-radius: 8px;
font-size: 12px;
&.level-red {
background: #fee2e2;
color: #dc2626;
}
&.level-orange {
background: #ffedd5;
color: #ea580c;
}
&.level-blue {
background: #dbeafe;
color: #2563eb;
}
}
.alert-title {
font-size: 15px;
font-weight: 600;
color: #333;
}
.status-tag {
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
&.status-orange {
background: #fff7ed;
color: #ea580c;
border: 1px solid #fed7aa;
}
&.status-blue {
background: #eff6ff;
color: #2563eb;
border: 1px solid #bfdbfe;
}
&.status-green {
background: #f0fdf4;
color: #16a34a;
border: 1px solid #bbf7d0;
}
}
}
.card-image {
margin-bottom: 12px;
.alert-img {
width: 100%;
height: 180px;
border-radius: 12px;
}
}
.card-details {
.detail-item {
display: flex;
align-items: center;
margin-bottom: 8px;
font-size: 14px;
&:last-child {
margin-bottom: 0;
}
.detail-icon {
font-size: 16px;
color: #2563eb;
margin-right: 8px;
}
.label {
color: #94a3b8;
}
.value {
color: #475569;
}
}
.video-btn-wrapper {
margin-top: 12px;
.video-btn {
height: 40px;
background: #2563eb;
border: none;
border-radius: 10px;
font-size: 14px;
font-weight: 500;
color: white;
.video-icon {
margin-right: 6px;
}
}
}
}
.record-card {
padding: 16px;
.card-title {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 12px;
}
}
.execution-box {
background: #eff6ff;
border: 2px solid #2563eb;
border-radius: 16px;
padding: 16px;
}
.info-box {
background: #f0fdf4;
border: 2px solid #16a34a;
border-radius: 12px;
padding: 10px;
.info-row {
display: flex;
flex-wrap: wrap;
margin-bottom: 6px;
font-size: 14px;
&:last-child {
margin-bottom: 0;
}
.info-label {
color: #64748b;
}
.info-value {
color: #333;
font-weight: 500;
}
.info-text {
color: #64748b;
}
.info-divider {
color: #d1d5db;
margin: 0 4px;
}
}
}
.task-desc {
margin-top: 12px;
font-size: 15px;
color: #333;
font-weight: 600;
line-height: 1.5;
padding: 0 4px;
}
.checkin-box {
margin-top: 12px;
background: #f9fafb;
border-radius: 12px;
padding: 12px;
.checkin-row {
display: flex;
flex-wrap: wrap;
margin-bottom: 8px;
font-size: 14px;
&:last-child {
margin-bottom: 0;
}
.checkin-date,
.checkin-time {
color: #64748b;
}
.checkin-type {
color: #475569;
margin-left: 8px;
}
.checkin-label {
color: #64748b;
}
.checkin-value {
color: #333;
}
&.checkin-location {
color: #475569;
.location-icon {
font-size: 14px;
margin-right: 4px;
margin-top: 2px;
}
}
}
}
.feedback-buttons,
.action-buttons {
margin-top: 12px;
display: flex;
flex-direction: column;
gap: 8px;
.feedback-btn {
height: 40px;
background: #2563eb;
border: none;
border-radius: 10px;
font-size: 14px;
font-weight: 500;
color: white;
&.success {
background: #16a34a;
}
}
.action-btn {
height: 40px;
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
border: none;
border-radius: 10px;
font-size: 14px;
font-weight: 500;
}
}
.feedback-popup {
width: 90%;
max-width: 400px;
max-height: 80vh;
overflow-y: auto;
}
.popup-content {
padding: 24px;
}
.popup-title {
font-size: 18px;
font-weight: 600;
color: #333;
margin-bottom: 12px;
}
.popup-info {
margin-bottom: 16px;
font-size: 14px;
color: #64748b;
}
.popup-section {
margin-bottom: 16px;
.section-label {
font-size: 14px;
color: #64748b;
margin-bottom: 8px;
}
.content-title {
font-size: 15px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.content-text {
font-size: 14px;
color: #64748b;
line-height: 1.6;
}
}
.image-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
.feedback-img {
width: 100%;
height: 120px;
border-radius: 8px;
}
}
.video-item {
display: flex;
align-items: center;
gap: 8px;
background: #f9fafb;
padding: 12px;
border-radius: 8px;
.video-icon {
font-size: 20px;
color: #2563eb;
}
span {
font-size: 14px;
color: #64748b;
}
}
.close-btn {
height: 40px;
background: #e5e7eb;
border: none;
border-radius: 10px;
font-size: 14px;
font-weight: 500;
color: #333;
margin-top: 16px;
&:active {
background: #d1d5db;
}
}
</style>