Compare commits
No commits in common. "c4b5e700ccd87e737f1cb8c3147f4ce5c546c9dc" and "08d54009695db33fb390dffb0f610796b9de3849" have entirely different histories.
c4b5e700cc
...
08d5400969
@ -66,16 +66,6 @@ const routes = [
|
||||
name: 'IceEventDetail',
|
||||
component: () => import('../views/IceEvent/IceEventDetails.vue')
|
||||
},
|
||||
{
|
||||
path: '/warningMessage/:data',
|
||||
name: 'WarningMessage',
|
||||
component: () => import('../views/WarningMessage/WarningMessage.vue')
|
||||
},
|
||||
{
|
||||
path: '/warningMessage-detail/:data',
|
||||
name: 'WarningMessageDetail',
|
||||
component: () => import('../views/WarningMessage/WarningMessageDetail.vue')
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@ -40,14 +40,6 @@
|
||||
params: { data: encodeURIComponent(JSON.stringify(yhzinfo)) },
|
||||
}"
|
||||
/>
|
||||
<van-grid-item
|
||||
icon="warning-o"
|
||||
text="气象预警"
|
||||
:to="{
|
||||
name: 'WarningMessage',
|
||||
params: { data: encodeURIComponent(JSON.stringify(yhzinfo)) },
|
||||
}"
|
||||
/>
|
||||
</van-grid>
|
||||
</div>
|
||||
<van-popup
|
||||
|
||||
@ -1,362 +0,0 @@
|
||||
<template>
|
||||
<div class="warning-message-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<div class="nav-bar">
|
||||
<div class="back-btn" @click="goBack">
|
||||
<van-icon name="arrow-left" />
|
||||
</div>
|
||||
<div class="title">气象预警</div>
|
||||
<div class="placeholder"></div>
|
||||
</div>
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<div class="search-section">
|
||||
<div class="search-box">
|
||||
<span class="search-text">关键词</span>
|
||||
<van-icon name="search" class="search-icon" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 当前站点 -->
|
||||
<div class="current-site">
|
||||
<span class="site-label">当前站点:</span>
|
||||
<span class="site-name">{{ currentSite }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 预警列表 -->
|
||||
<div class="warning-list">
|
||||
<div
|
||||
v-for="(item, index) in warningList"
|
||||
:key="index"
|
||||
class="warning-item"
|
||||
:class="{ unread: !item.isRead }"
|
||||
@click="viewDetail(item)"
|
||||
>
|
||||
<div class="item-content">
|
||||
<div class="warning-title">{{ item.title }}</div>
|
||||
<div class="warning-time">
|
||||
<span class="time-label">发布时间:</span>
|
||||
<span class="time-value">{{ item.publishTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-right">
|
||||
<div v-if="!item.isRead" class="unread-dot"></div>
|
||||
<van-icon name="arrow" class="arrow-icon" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div v-if="warningList.length === 0" class="empty-state">
|
||||
<van-icon name="warning-o" class="empty-icon" />
|
||||
<div class="empty-text">暂无预警消息</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
// 当前站点
|
||||
const currentSite = ref("李家坝仓库");
|
||||
|
||||
// 解析传递的站点信息
|
||||
const initSiteInfo = () => {
|
||||
const { data } = route.params;
|
||||
if (data) {
|
||||
try {
|
||||
const yhzinfo = JSON.parse(decodeURIComponent(data));
|
||||
currentSite.value = yhzinfo.mc || "李家坝仓库";
|
||||
} catch (e) {
|
||||
console.error("解析站点信息失败", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
initSiteInfo();
|
||||
|
||||
// 预警列表数据
|
||||
const warningList = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: "合川区暴雨红色预警",
|
||||
publishTime: "2025/10/10 20:29",
|
||||
isRead: false,
|
||||
level: "red",
|
||||
type: "rain",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "合川区红色气象预警",
|
||||
publishTime: "2025/10/09 20:29",
|
||||
isRead: true,
|
||||
level: "red",
|
||||
type: "weather",
|
||||
},
|
||||
]);
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
console.log("返回上一页");
|
||||
// 实际项目中使用:
|
||||
// router.back()
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const viewDetail = (item) => {
|
||||
// 标记为已读
|
||||
item.isRead = true;
|
||||
// 跳转到详情页
|
||||
router.push({
|
||||
name: "WarningMessageDetail",
|
||||
params: {
|
||||
id: item.id,
|
||||
data: route.params.data,
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 移动端适配变量
|
||||
$primary-color: #409eff;
|
||||
$text-color: #333;
|
||||
$text-secondary: #666;
|
||||
$text-tertiary: #999;
|
||||
$bg-color: #f5f5f5;
|
||||
$border-color: #e0e0e0;
|
||||
$unread-color: #f56c6c;
|
||||
|
||||
.warning-message-page {
|
||||
min-height: 100vh;
|
||||
background-color: $bg-color;
|
||||
padding-bottom: 20px;
|
||||
|
||||
// 顶部导航栏
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 44px;
|
||||
background-color: #fff;
|
||||
padding: 0 15px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
|
||||
.back-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: $text-color;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索栏
|
||||
.search-section {
|
||||
padding: 12px 15px;
|
||||
background-color: #fff;
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 36px;
|
||||
background-color: #e8e8e8;
|
||||
border-radius: 18px;
|
||||
padding: 0 15px;
|
||||
|
||||
.search-text {
|
||||
font-size: 14px;
|
||||
color: $text-tertiary;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
font-size: 18px;
|
||||
color: $text-tertiary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 当前站点
|
||||
.current-site {
|
||||
padding: 10px 15px;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
.site-label {
|
||||
color: $text-secondary;
|
||||
}
|
||||
|
||||
.site-name {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 预警列表
|
||||
.warning-list {
|
||||
padding: 10px 15px;
|
||||
|
||||
.warning-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:active {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
.warning-title {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: $text-color;
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.warning-time {
|
||||
font-size: 12px;
|
||||
color: $text-tertiary;
|
||||
|
||||
.time-label {
|
||||
color: $text-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-left: 10px;
|
||||
|
||||
.unread-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: $unread-color;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 16px;
|
||||
color: $text-tertiary;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 未读状态样式
|
||||
&.unread {
|
||||
.warning-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 20px;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 48px;
|
||||
color: $text-tertiary;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 14px;
|
||||
color: $text-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适配 iPhone 刘海屏
|
||||
@supports (padding-top: env(safe-area-inset-top)) {
|
||||
.warning-message-page {
|
||||
.nav-bar {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
height: calc(44px + env(safe-area-inset-top));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适配不同屏幕尺寸
|
||||
@media screen and (max-width: 320px) {
|
||||
.warning-message-page {
|
||||
.warning-list {
|
||||
.warning-item {
|
||||
.item-content {
|
||||
.warning-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 414px) {
|
||||
.warning-message-page {
|
||||
.nav-bar {
|
||||
height: 48px;
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.warning-list {
|
||||
.warning-item {
|
||||
padding: 18px;
|
||||
|
||||
.item-content {
|
||||
.warning-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.warning-time {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,395 +0,0 @@
|
||||
<template>
|
||||
<div class="warning-detail-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<div class="nav-bar">
|
||||
<div class="back-btn" @click="goBack">
|
||||
<van-icon name="arrow-left" />
|
||||
</div>
|
||||
<div class="title">气象预警</div>
|
||||
<div class="placeholder"></div>
|
||||
</div>
|
||||
|
||||
<!-- 当前站点 -->
|
||||
<div class="current-site">
|
||||
<span class="site-label">当前站点:</span>
|
||||
<span class="site-name">{{ currentSite }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 预警详情内容 -->
|
||||
<div class="detail-content" v-if="warningDetail">
|
||||
<!-- 预警标题区域 -->
|
||||
<div class="warning-header">
|
||||
<div class="header-title">气象预警</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警信息卡片 -->
|
||||
<div class="info-card">
|
||||
<div class="warning-name">{{ warningDetail.title }}</div>
|
||||
<div class="publish-time">
|
||||
<span class="time-label">发布时间:</span>
|
||||
<span class="time-value">{{ warningDetail.publishTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警描述 -->
|
||||
<div class="description-card">
|
||||
<div class="desc-text">{{ warningDetail.description }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 防御措施 -->
|
||||
<div class="measures-section">
|
||||
<div class="section-title">防御措施</div>
|
||||
<div class="measures-card">
|
||||
<div class="measures-text">{{ warningDetail.measures }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div class="bottom-action">
|
||||
<van-button type="primary" block round @click="handleResponse">
|
||||
立即响应
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { showToast } from "vant";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
// 当前站点
|
||||
const currentSite = ref("李家坝仓库");
|
||||
|
||||
// 预警详情数据
|
||||
const warningDetail = ref({
|
||||
id: 1,
|
||||
title: "合川区暴雨红色预警",
|
||||
publishTime: "2025/10/10 20:29",
|
||||
description:
|
||||
"区气象台发布暴雨红色预警,按照相关要求,启动I级防御响应,并请及时关注地质、水文等风险提示信息,落实主动封闭管控/“关停撤转”措施",
|
||||
measures:
|
||||
"请立即按照2小时一次频率对你管养的重点路段/重点部位进行巡查,重点巡查较高及以上风险路段、涉灾隐患点、地质条件复杂路段、临河临崖路段/两区三厂、大型设施设备、取弃土(渣)场、砂石料场、涉水桥梁、富水隧道、围堰、支架脚手架、高切坡、滑坡处置等部位,重点关注涉水桥梁基础及墩台、不良地质隧道、隧道洞口边仰坡及侧切结构、高陡边坡支挡防护以及防排水设施,发现异常情况,立即向上报告,采取紧急排危、告警阻拦、吹哨撤转等措施,并及时报送工作开展情况。",
|
||||
level: "red",
|
||||
type: "rain",
|
||||
});
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
// 立即响应
|
||||
const handleResponse = () => {
|
||||
showToast({
|
||||
message: "响应成功",
|
||||
type: "success",
|
||||
});
|
||||
// 实际项目中调用API提交响应
|
||||
console.log("立即响应", warningDetail.value);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 从路由参数获取预警ID,然后请求详情数据
|
||||
const { id } = route.params;
|
||||
if (id) {
|
||||
console.log("获取预警详情 ID:", id);
|
||||
// 实际项目中调用API获取详情
|
||||
// fetchWarningDetail(id);
|
||||
}
|
||||
|
||||
// 解析传递的站点信息
|
||||
const { data } = route.params;
|
||||
if (data) {
|
||||
try {
|
||||
const yhzinfo = JSON.parse(decodeURIComponent(data));
|
||||
currentSite.value = yhzinfo.mc || "李家坝仓库";
|
||||
} catch (e) {
|
||||
console.error("解析站点信息失败", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 移动端适配变量
|
||||
$primary-color: #1989fa;
|
||||
$text-color: #333;
|
||||
$text-secondary: #666;
|
||||
$text-tertiary: #999;
|
||||
$bg-color: #f5f5f5;
|
||||
$border-color: #e0e0e0;
|
||||
$card-bg: #fff;
|
||||
$section-title-color: #666;
|
||||
|
||||
.warning-detail-page {
|
||||
min-height: 100vh;
|
||||
background-color: $bg-color;
|
||||
padding-bottom: 80px;
|
||||
|
||||
// 顶部导航栏
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 44px;
|
||||
background-color: #fff;
|
||||
padding: 0 15px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
|
||||
.back-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: $text-color;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// 当前站点
|
||||
.current-site {
|
||||
padding: 10px 15px;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
.site-label {
|
||||
color: $text-secondary;
|
||||
}
|
||||
|
||||
.site-name {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 详情内容
|
||||
.detail-content {
|
||||
padding: 15px;
|
||||
|
||||
// 预警标题区域
|
||||
.warning-header {
|
||||
margin-bottom: 12px;
|
||||
|
||||
.header-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: $text-color;
|
||||
position: relative;
|
||||
padding-left: 12px;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background-color: $primary-color;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 信息卡片
|
||||
.info-card {
|
||||
background-color: $card-bg;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.warning-name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: $text-color;
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.publish-time {
|
||||
font-size: 13px;
|
||||
color: $text-tertiary;
|
||||
|
||||
.time-label {
|
||||
color: $text-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 描述卡片
|
||||
.description-card {
|
||||
background-color: $card-bg;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.desc-text {
|
||||
font-size: 14px;
|
||||
color: $text-secondary;
|
||||
line-height: 1.8;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
|
||||
// 防御措施区域
|
||||
.measures-section {
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: $text-color;
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
padding-left: 12px;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background-color: $primary-color;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.measures-card {
|
||||
background-color: $card-bg;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.measures-text {
|
||||
font-size: 14px;
|
||||
color: $text-secondary;
|
||||
line-height: 1.8;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 底部按钮
|
||||
.bottom-action {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 10px 15px 20px;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid $border-color;
|
||||
|
||||
.van-button {
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适配 iPhone 刘海屏
|
||||
@supports (padding-top: env(safe-area-inset-top)) {
|
||||
.warning-detail-page {
|
||||
.nav-bar {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
height: calc(44px + env(safe-area-inset-top));
|
||||
}
|
||||
|
||||
.bottom-action {
|
||||
padding-bottom: calc(20px + env(safe-area-inset-bottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适配不同屏幕尺寸
|
||||
@media screen and (max-width: 320px) {
|
||||
.warning-detail-page {
|
||||
.detail-content {
|
||||
.info-card {
|
||||
.warning-name {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.description-card,
|
||||
.measures-section {
|
||||
.desc-text,
|
||||
.measures-text {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 414px) {
|
||||
.warning-detail-page {
|
||||
.nav-bar {
|
||||
height: 48px;
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
.warning-header {
|
||||
.header-title {
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-card {
|
||||
padding: 18px;
|
||||
|
||||
.warning-name {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.publish-time {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.description-card,
|
||||
.measures-card {
|
||||
padding: 18px;
|
||||
|
||||
.desc-text,
|
||||
.measures-text {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.measures-section {
|
||||
.section-title {
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 655 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 112 KiB |
@ -61,30 +61,6 @@ const routes = [
|
||||
},
|
||||
component: () => import('../views/RiskWarning/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/regulationsDivision',
|
||||
name: 'RegulationsDivision',
|
||||
meta: {
|
||||
screen: true
|
||||
},
|
||||
component: () => import('../views/RegulationsDivision/RegulationsDivision.vue')
|
||||
},
|
||||
{
|
||||
path: '/warningCounty',
|
||||
name: 'WarningCounty',
|
||||
meta: {
|
||||
screen: true
|
||||
},
|
||||
component: () => import('../views/warningCounty/warningCounty.vue')
|
||||
},
|
||||
{
|
||||
path: '/constructionDepartment',
|
||||
name: 'ConstructionDepartment',
|
||||
meta: {
|
||||
screen: true
|
||||
},
|
||||
component: () => import('../views/ConstructionDepartment/ConstructionDepartment.vue')
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@ -1,548 +0,0 @@
|
||||
<template>
|
||||
<div class="construction-department-page">
|
||||
<!-- 左侧树形菜单 -->
|
||||
<div class="left-sidebar">
|
||||
<el-tree
|
||||
:data="treeData"
|
||||
:props="defaultProps"
|
||||
node-key="id"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick"
|
||||
class="department-tree"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="tree-node">
|
||||
<el-icon v-if="data.children && data.children.length" class="tree-icon">
|
||||
<FolderOpened v-if="node.expanded" />
|
||||
<Folder v-else />
|
||||
</el-icon>
|
||||
<el-icon v-else class="tree-icon"><Document /></el-icon>
|
||||
<span class="tree-label">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
|
||||
<!-- 右侧内容区域 -->
|
||||
<div class="right-content">
|
||||
<!-- 搜索筛选区域 -->
|
||||
<div class="search-area">
|
||||
<div class="search-row">
|
||||
<div class="search-item">
|
||||
<span class="search-label">项目名称</span>
|
||||
<el-input v-model="searchForm.projectName" placeholder="" clearable style="width: 140px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">驻地名称</span>
|
||||
<el-input v-model="searchForm.stationName" placeholder="" clearable style="width: 140px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">建设单位</span>
|
||||
<el-input v-model="searchForm.constructionUnit" placeholder="" clearable style="width: 140px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">施工单位</span>
|
||||
<el-input v-model="searchForm.builderUnit" placeholder="" clearable style="width: 140px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">项目类型</span>
|
||||
<el-select v-model="searchForm.projectType" placeholder="全部" clearable style="width: 100px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="新建" value="new" />
|
||||
<el-option label="改扩建" value="rebuild" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-row">
|
||||
<div class="search-item">
|
||||
<span class="search-label">驻地类型</span>
|
||||
<el-select v-model="searchForm.stationType" placeholder="全部" clearable style="width: 100px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="类型1" value="type1" />
|
||||
<el-option label="类型2" value="type2" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">驻地风险等级</span>
|
||||
<el-select v-model="searchForm.riskLevel" placeholder="全部" clearable style="width: 100px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="高" value="high" />
|
||||
<el-option label="中" value="medium" />
|
||||
<el-option label="低" value="low" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">所属区县</span>
|
||||
<el-select v-model="searchForm.district" placeholder="全部" clearable style="width: 100px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="万州区" value="wanzhou" />
|
||||
<el-option label="沙坪坝区" value="shapingba" />
|
||||
<el-option label="涪陵区" value="fuling" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">吹哨人姓名</span>
|
||||
<el-input v-model="searchForm.whistleblowerName" placeholder="" clearable style="width: 100px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">建设单位责任人姓名</span>
|
||||
<el-input v-model="searchForm.constructorResponsible" placeholder="" clearable style="width: 100px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-row">
|
||||
<div class="search-item">
|
||||
<span class="search-label">区县级责任人姓名</span>
|
||||
<el-input v-model="searchForm.countyResponsible" placeholder="" clearable style="width: 100px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">市级责任人姓名</span>
|
||||
<el-input v-model="searchForm.cityResponsible" placeholder="" clearable style="width: 100px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">施工单位责任人姓名</span>
|
||||
<el-input v-model="searchForm.builderResponsible" placeholder="" clearable style="width: 100px" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="search-label">驻地责任人姓名</span>
|
||||
<el-input v-model="searchForm.stationResponsible" placeholder="" clearable style="width: 100px" />
|
||||
</div>
|
||||
<div class="search-item search-buttons">
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<!-- <el-button link type="primary" @click="handleReset">收起</el-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="action-area">
|
||||
<el-button type="primary" class="export-btn" @click="handleExport">
|
||||
<el-icon><Download /></el-icon>
|
||||
导出
|
||||
</el-button>
|
||||
<el-button type="primary" class="import-btn" @click="handleImport">
|
||||
<el-icon><Upload /></el-icon>
|
||||
导入
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-area">
|
||||
<el-table
|
||||
:data="filteredTableData"
|
||||
stripe
|
||||
style="width: 100%"
|
||||
:header-cell-style="headerCellStyle"
|
||||
:row-class-name="rowClassName"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="district" label="所属区县" width="100" align="center" />
|
||||
<el-table-column prop="projectName" label="项目名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="stationName" label="驻地名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="stationType" label="驻地类型" width="100" align="center" />
|
||||
<el-table-column prop="coordinate" label="坐标点位" width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="parentProject" label="所属项目名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="projectType" label="项目类型" width="120" align="center" />
|
||||
<el-table-column prop="constructionUnit" label="建设单位" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="builderUnit" label="施工单位" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="stationAddress" label="驻地地址" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="adminArea" label="行政区域" width="100" align="center" />
|
||||
<el-table-column prop="stationPeople" label="驻地人数" width="90" align="center" />
|
||||
<el-table-column prop="riskLevel" label="驻地风险等级" width="110" align="center" />
|
||||
<el-table-column prop="buildingType" label="房建类型" width="100" align="center" />
|
||||
<el-table-column prop="relocationStatus" label="搬迁状态" width="90" align="center" />
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button link type="danger" size="small" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-area">
|
||||
<el-pagination
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="prev, pager, next, jumper"
|
||||
prev-text="上一个"
|
||||
next-text="下一个"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { Folder, FolderOpened, Document, Download, Upload } from "@element-plus/icons-vue";
|
||||
|
||||
// 树形菜单数据
|
||||
const treeData = ref([
|
||||
{
|
||||
id: 1,
|
||||
label: "2026",
|
||||
children: [
|
||||
{ id: 11, label: "2026.3" },
|
||||
{ id: 12, label: "2026.2" },
|
||||
{ id: 13, label: "2026.1" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: "2025",
|
||||
children: [
|
||||
{ id: 21, label: "2025.12" },
|
||||
{ id: 22, label: "2025.11" },
|
||||
{ id: 23, label: "2025.10" },
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const defaultProps = {
|
||||
children: "children",
|
||||
label: "label",
|
||||
};
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
projectName: "",
|
||||
stationName: "",
|
||||
constructionUnit: "",
|
||||
builderUnit: "",
|
||||
projectType: "",
|
||||
stationType: "",
|
||||
riskLevel: "",
|
||||
district: "",
|
||||
whistleblowerName: "",
|
||||
constructorResponsible: "",
|
||||
countyResponsible: "",
|
||||
cityResponsible: "",
|
||||
builderResponsible: "",
|
||||
stationResponsible: "",
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
district: "沙坪坝区",
|
||||
projectName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)",
|
||||
stationName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)项目经理部",
|
||||
stationType: "项目部驻地",
|
||||
coordinate: "经度:106.44E;纬度29.62N",
|
||||
parentProject: "中铁十七局集团第五工程有限公司",
|
||||
projectType: "普通国省干线(新建/改扩建)",
|
||||
constructionUnit: "成渝铁路客运专线有限公司",
|
||||
builderUnit: "中铁十七局集团",
|
||||
stationAddress: "沙坪坝区井口街道南溪村茅山峡公路跨线桥处",
|
||||
adminArea: "沙坪坝区",
|
||||
stationPeople: "16",
|
||||
riskLevel: "高",
|
||||
buildingType: "板房",
|
||||
relocationStatus: "否",
|
||||
},
|
||||
{
|
||||
district: "沙坪坝区",
|
||||
projectName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)",
|
||||
stationName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)项目经理部",
|
||||
stationType: "项目部驻地",
|
||||
coordinate: "经度:106.44E;纬度29.62N",
|
||||
parentProject: "中铁十七局集团第五工程有限公司",
|
||||
projectType: "普通国省干线(新建/改扩建)",
|
||||
constructionUnit: "成渝铁路客运专线有限公司",
|
||||
builderUnit: "中铁十七局集团",
|
||||
stationAddress: "沙坪坝区井口街道南溪村茅山峡公路跨线桥处",
|
||||
adminArea: "沙坪坝区",
|
||||
stationPeople: "16",
|
||||
riskLevel: "高",
|
||||
buildingType: "板房",
|
||||
relocationStatus: "否",
|
||||
},
|
||||
]);
|
||||
|
||||
// 过滤后的表格数据
|
||||
const filteredTableData = computed(() => {
|
||||
return tableData.value.filter((item) => {
|
||||
const matchProjectName = !searchForm.projectName || item.projectName.includes(searchForm.projectName);
|
||||
const matchStationName = !searchForm.stationName || item.stationName.includes(searchForm.stationName);
|
||||
const matchConstructionUnit = !searchForm.constructionUnit || item.constructionUnit.includes(searchForm.constructionUnit);
|
||||
const matchBuilderUnit = !searchForm.builderUnit || item.builderUnit.includes(searchForm.builderUnit);
|
||||
const matchDistrict = !searchForm.district || item.district.includes(searchForm.district === 'wanzhou' ? '万州' : searchForm.district === 'shapingba' ? '沙坪坝' : '涪陵');
|
||||
return matchProjectName && matchStationName && matchConstructionUnit && matchBuilderUnit && matchDistrict;
|
||||
});
|
||||
});
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(2);
|
||||
|
||||
// 表头样式
|
||||
const headerCellStyle = () => ({
|
||||
background: "#e6f0ff",
|
||||
color: "#303133",
|
||||
fontWeight: "bold",
|
||||
fontSize: "13px",
|
||||
padding: "10px 0",
|
||||
});
|
||||
|
||||
// 行样式
|
||||
const rowClassName = ({ rowIndex }) => {
|
||||
return rowIndex % 2 === 0 ? "even-row" : "odd-row";
|
||||
};
|
||||
|
||||
// 树节点点击
|
||||
const handleNodeClick = (data) => {
|
||||
console.log("点击节点:", data);
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleSearch = () => {
|
||||
currentPage.value = 1;
|
||||
ElMessage.success("查询成功");
|
||||
};
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
Object.keys(searchForm).forEach((key) => {
|
||||
searchForm[key] = "";
|
||||
});
|
||||
currentPage.value = 1;
|
||||
ElMessage.success("已重置");
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
ElMessage.success("导出成功");
|
||||
};
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
ElMessage.info("请选择要导入的文件");
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row) => {
|
||||
ElMessage.info(`编辑 ${row.projectName}`);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm(`确定删除 ${row.projectName} 吗?`, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const handleCurrentChange = (val) => {
|
||||
currentPage.value = val;
|
||||
};
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.construction-department-page {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
background: #f5f7fa;
|
||||
|
||||
// 左侧树形菜单
|
||||
.left-sidebar {
|
||||
width: 200px;
|
||||
background: #fff;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
padding: 15px;
|
||||
overflow-y: auto;
|
||||
|
||||
.department-tree {
|
||||
.tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
|
||||
.tree-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 16px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.tree-label {
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-tree-node__content) {
|
||||
height: 32px;
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node__children) {
|
||||
.el-tree-node__content {
|
||||
padding-left: 24px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧内容区域
|
||||
.right-content {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
|
||||
// 搜索区域
|
||||
.search-area {
|
||||
background: #fff;
|
||||
padding: 15px 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-bottom: 12px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.search-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.search-label {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.search-buttons {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作区域
|
||||
.action-area {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.export-btn,
|
||||
.import-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-area {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
:deep(.el-table) {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-table__header-wrapper {
|
||||
th {
|
||||
background: #e6f0ff !important;
|
||||
}
|
||||
}
|
||||
|
||||
.even-row {
|
||||
background: #f5f9ff;
|
||||
}
|
||||
|
||||
.odd-row {
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页区域
|
||||
.pagination-area {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
|
||||
:deep(.el-pagination) {
|
||||
.btn-prev,
|
||||
.btn-next {
|
||||
padding: 0 15px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
color: #606266;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #c0c4cc;
|
||||
border-color: #e4e7ed;
|
||||
}
|
||||
}
|
||||
|
||||
.el-pager {
|
||||
li {
|
||||
min-width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
margin: 0 4px;
|
||||
background: #fff;
|
||||
color: #606266;
|
||||
|
||||
&.active {
|
||||
background: #409eff;
|
||||
border-color: #409eff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
&.active:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-pagination__jump {
|
||||
margin-left: 15px;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="bottom-panel">
|
||||
<div class="main-box display p_10" style="box-sizing: border-box">
|
||||
<div class="nav-menu">
|
||||
<div
|
||||
v-for="(item, index) in menuItems"
|
||||
@ -8,7 +8,7 @@
|
||||
:class="{ active: activeIndex === index }"
|
||||
@click="activeIndex = index"
|
||||
>
|
||||
<div class="nav-icon-box">
|
||||
<div class="nav-icon">
|
||||
<!-- <i :class="item.icon"></i> -->
|
||||
<img :src="activeIndex === index ? item.icon1 : item.icon" alt="" />
|
||||
</div>
|
||||
@ -86,7 +86,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { ElTable } from "element-plus";
|
||||
import orangeIcon from "../../assets/RiskWarning_img/橙色@2x.png";
|
||||
import yellowIcon from "../../assets/RiskWarning_img/黄色@2x.png";
|
||||
@ -216,145 +216,25 @@ const cellStyle = () => ({
|
||||
background: "transparent",
|
||||
color: "rgba(255, 255, 255, 0.9)",
|
||||
borderBottom: "1px solid rgba(64, 169, 255, 0.1)",
|
||||
padding: "5px 5px",
|
||||
padding: "12px 8px",
|
||||
});
|
||||
|
||||
const rowClassName = ({ rowIndex }) => {
|
||||
return rowIndex % 2 === 0 ? "even-row" : "odd-row";
|
||||
};
|
||||
|
||||
// 表格自动滚动相关
|
||||
const tableRef = ref(null);
|
||||
const isScrolling = ref(true);
|
||||
const scrollTimer = ref(null);
|
||||
const scrollSpeed = 50; // 滚动间隔(毫秒)
|
||||
const scrollStep = 1; // 每次滚动像素
|
||||
|
||||
// 检查是否有筛选条件
|
||||
const hasFilter = computed(() => {
|
||||
return filters.value.red || filters.value.blue || filters.value.orange || filters.value.yellow;
|
||||
});
|
||||
|
||||
// 开始自动滚动
|
||||
const startAutoScroll = () => {
|
||||
if (scrollTimer.value) {
|
||||
clearInterval(scrollTimer.value);
|
||||
}
|
||||
if (!isScrolling.value || hasFilter.value) return;
|
||||
|
||||
const tableBody = document.querySelector('.weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap');
|
||||
if (!tableBody) return;
|
||||
|
||||
scrollTimer.value = setInterval(() => {
|
||||
if (tableBody) {
|
||||
tableBody.scrollTop += scrollStep;
|
||||
// 滚动到底部后回到顶部(使用 >= 判断,并留出一点余量确保准确触发)
|
||||
const maxScroll = tableBody.scrollHeight - tableBody.clientHeight;
|
||||
if (tableBody.scrollTop >= maxScroll - 2) {
|
||||
tableBody.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
}, scrollSpeed);
|
||||
};
|
||||
|
||||
// 停止自动滚动
|
||||
const stopAutoScroll = () => {
|
||||
if (scrollTimer.value) {
|
||||
clearInterval(scrollTimer.value);
|
||||
scrollTimer.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
// 重置滚动到顶部
|
||||
const resetScrollToTop = () => {
|
||||
const tableBody = document.querySelector('.weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap');
|
||||
if (tableBody) {
|
||||
tableBody.scrollTop = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 鼠标移入停止滚动
|
||||
const handleMouseEnter = () => {
|
||||
stopAutoScroll();
|
||||
};
|
||||
|
||||
// 鼠标移出开始滚动
|
||||
const handleMouseLeave = () => {
|
||||
if (!hasFilter.value) {
|
||||
isScrolling.value = true;
|
||||
startAutoScroll();
|
||||
}
|
||||
};
|
||||
|
||||
// 监听筛选条件变化
|
||||
watch(hasFilter, (newVal) => {
|
||||
if (newVal) {
|
||||
// 有筛选条件时停止滚动并回到顶部
|
||||
stopAutoScroll();
|
||||
resetScrollToTop();
|
||||
} else {
|
||||
// 取消筛选后开始滚动
|
||||
isScrolling.value = true;
|
||||
nextTick(() => {
|
||||
startAutoScroll();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
startAutoScroll();
|
||||
// 添加鼠标事件监听
|
||||
const tableContainer = document.querySelector('.weather-warning-panel .table-container');
|
||||
if (tableContainer) {
|
||||
tableContainer.addEventListener('mouseenter', handleMouseEnter);
|
||||
tableContainer.addEventListener('mouseleave', handleMouseLeave);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopAutoScroll();
|
||||
const tableContainer = document.querySelector('.weather-warning-panel .table-container');
|
||||
if (tableContainer) {
|
||||
tableContainer.removeEventListener('mouseenter', handleMouseEnter);
|
||||
tableContainer.removeEventListener('mouseleave', handleMouseLeave);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 视频屏幕自适应 - 基于视口宽度动态调整
|
||||
// 基准宽度 1920px,使用 vw 单位实现自适应
|
||||
@function vw($px) {
|
||||
@return calc($px / 1920 * 100vw);
|
||||
}
|
||||
|
||||
.bottom-panel {
|
||||
.main-box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: vw(10);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
||||
// 小屏幕适配
|
||||
@media (max-width: 1366px) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding: 6px;
|
||||
}
|
||||
}
|
||||
.nav-menu {
|
||||
width: vw(50);
|
||||
min-width: 40px;
|
||||
width: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
gap: vw(5);
|
||||
gap: 5px;
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
@ -365,7 +245,7 @@ onUnmounted(() => {
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
.nav-icon-box {
|
||||
.nav-icon {
|
||||
background: rgba(64, 169, 255, 0.3);
|
||||
border-color: rgba(64, 169, 255, 0.6);
|
||||
}
|
||||
@ -375,12 +255,10 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.nav-icon-box {
|
||||
width: vw(50);
|
||||
height: vw(50);
|
||||
min-width: 36px;
|
||||
min-height: 36px;
|
||||
margin-bottom: vw(5);
|
||||
.nav-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-bottom: 5px;
|
||||
background: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
@ -389,41 +267,39 @@ onUnmounted(() => {
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
img {
|
||||
width: vw(50);
|
||||
height: vw(50);
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
width: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
color: #40a9ff;
|
||||
}
|
||||
|
||||
// 使用 emoji 作为图标占位
|
||||
&.warning::before {
|
||||
content: "📍";
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
&.tunnel::before {
|
||||
content: "🚇";
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
&.slope::before {
|
||||
content: "⛰️";
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
&.bridge::before {
|
||||
content: "🌉";
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
&.road::before {
|
||||
content: "🛣️";
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,7 +307,7 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: vw(12);
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
@ -449,36 +325,38 @@ onUnmounted(() => {
|
||||
|
||||
// 气象预警监测面板样式
|
||||
.weather-warning-panel {
|
||||
height: 50%;
|
||||
background: rgba(64, 169, 255, 0.1);
|
||||
height: 60%;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(21, 41, 59, 0.95) 0%,
|
||||
rgba(13, 28, 42, 0.95) 100%
|
||||
);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: vw(15);
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
.clear-icon {
|
||||
position: absolute;
|
||||
top: vw(-50);
|
||||
top: -50px;
|
||||
right: 0px;
|
||||
width: vw(40) !important;
|
||||
height: vw(40) !important;
|
||||
min-width: 28px;
|
||||
min-height: 28px;
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: vw(15);
|
||||
margin-bottom: 15px;
|
||||
|
||||
.header-title {
|
||||
font-size: vw(18);
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
position: relative;
|
||||
padding-left: vw(12);
|
||||
padding-left: 12px;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
@ -486,8 +364,8 @@ onUnmounted(() => {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: vw(4);
|
||||
height: vw(16);
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 2px;
|
||||
}
|
||||
@ -495,24 +373,22 @@ onUnmounted(() => {
|
||||
|
||||
.filter-tags {
|
||||
display: flex;
|
||||
gap: vw(15);
|
||||
gap: 15px;
|
||||
|
||||
.tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(5);
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
|
||||
input {
|
||||
width: vw(14);
|
||||
height: vw(14);
|
||||
min-width: 12px;
|
||||
min-height: 12px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
accent-color: #40a9ff;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: vw(12);
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
|
||||
&.tag-red {
|
||||
@ -602,10 +478,8 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
img {
|
||||
width: vw(15);
|
||||
height: vw(15);
|
||||
min-width: 10px;
|
||||
min-height: 10px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
// .level-icon {
|
||||
|
||||
@ -1,370 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="ai-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="ai-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">AI预警处理结果</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<div class="content-wrapper">
|
||||
<!-- AI处理前预警 -->
|
||||
<div class="panel before-panel" style="background: linear-gradient(135deg, rgba(30, 80, 140, 0.6) 0%, rgba(20, 60, 110, 0.8) 100%);">
|
||||
<div class="panel-title">AI处理前预警</div>
|
||||
<div class="panel-content">
|
||||
<div class="info-item">
|
||||
<span class="info-label">发布单位:</span>
|
||||
<span class="info-value">{{ beforeData.publishOrg }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">发布内容:</span>
|
||||
<span class="info-value content-text">{{ beforeData.publishContent }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">生效时间:</span>
|
||||
<span class="info-value">{{ beforeData.effectiveTime }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">失效时间:</span>
|
||||
<span class="info-value">{{ beforeData.expireTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间AI标识 -->
|
||||
<div class="ai-center">
|
||||
<img class="ai-icon-img" src="../../../assets/RiskWarning_img/AI1@2x.png" alt="AI" />
|
||||
<div class="ai-arrow">
|
||||
<el-icon><DArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- AI处理后预警 -->
|
||||
<div class="panel after-panel panel1" style="background: #2699FF">
|
||||
<div class="panel-title" style="color:#fff">AI处理后预警</div>
|
||||
<div class="panel-content">
|
||||
<!-- 标签页 -->
|
||||
<div class="tab-header">
|
||||
<div
|
||||
v-for="tab in tabs"
|
||||
:key="tab.key"
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === tab.key }"
|
||||
@click="activeTab = tab.key"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- 标签内容 -->
|
||||
<div class="tab-content">
|
||||
<div class="info-item">
|
||||
<span class="info-label">预警等级:</span>
|
||||
<span class="info-value">{{ afterData.warningLevel }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">预警信息:</span>
|
||||
<span class="info-value content-text">{{ afterData.warningInfo }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">预警详情:</span>
|
||||
<span class="info-value content-text">{{ afterData.warningDetail }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { Close, DArrowRight } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
aiData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close"]);
|
||||
|
||||
// 标签页
|
||||
const tabs = ref([
|
||||
{ key: "frontline", label: "一线人员" },
|
||||
{ key: "district", label: "区县人员" },
|
||||
{ key: "handler", label: "处室人员" },
|
||||
{ key: "leader", label: "中心领导" },
|
||||
]);
|
||||
|
||||
const activeTab = ref("frontline");
|
||||
|
||||
// AI处理前数据
|
||||
const beforeData = ref({
|
||||
publishOrg: "潼南区预警中心",
|
||||
publishContent: '潼南区气象台2025年11月13日0时40分发布"暴雨蓝色预警信号",预计23日0:40-6:40,龙形、宝龙、上和、大佛、桂林、玉溪、米心、花岩、双江、古溪、群力、柏梓、崇龛、梓潼、太安等15个乡镇(街道)强降水趋于减弱,未来6小时累计雨量将达50~100毫米,最大小时雨强将达20~40毫米,局地伴有雷电、阵性大风,请各地注意防范。',
|
||||
effectiveTime: "2025-11-13 00:31:30.0",
|
||||
expireTime: "2025-11-13 00:31:30.0",
|
||||
});
|
||||
|
||||
// AI处理后数据
|
||||
const afterData = ref({
|
||||
warningLevel: "重庆市潼南气象台发布大雾黄色预警[III级/较重]",
|
||||
warningInfo: '潼南区区气象台发布暴雨红色预警,按照相关要求,启动I级防御响应,并请及时关注地质、水文等风险提示信息,落实主动封闭管控/"关停撒转"措施',
|
||||
warningDetail: "请立即按照2小时一次频率对你管养的重点路段/重点部位进行巡查,重点巡查较高及以上风险路段、涉灾隐患点、地质条件复杂路段、临河临崖路段/两区三厂、大型设施设备、取弃土(渣)场、砂石料场、涉水桥梁、富水隧道、围堰、支架脚手架、高切坡、滑坡处置等部位,重点关注涉水桥梁基础及墩台、不良地质隧道、隧道洞口边仰坡及侧切结构、高陡边坡支挡防护以及防排水设施,发现异常情况,立即向上报告,采取紧急排危、告警阻拦、吹哨撒转等措施,并及时报送工作开展情况。",
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal && props.aiData) {
|
||||
Object.assign(beforeData.value, props.aiData.before);
|
||||
Object.assign(afterData.value, props.aiData.after);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ai-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.ai-dialog {
|
||||
width: 1000px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 内容区域
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
// 面板
|
||||
.panel {
|
||||
flex: 1;
|
||||
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border-radius: 12px;
|
||||
padding: 1px;
|
||||
background: linear-gradient(135deg, rgba(64, 169, 255, 0.5) 0%, transparent 50%, rgba(64, 169, 255, 0.5) 100%);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #40a9ff;
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid rgba(64, 169, 255, 0.2);
|
||||
}
|
||||
|
||||
.panel-content {
|
||||
.info-item {
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.6;
|
||||
|
||||
&.content-text {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 中间AI标识
|
||||
.ai-center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
padding: 0 10px;
|
||||
.ai-icon-img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.ai-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 20px rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
.ai-arrow {
|
||||
font-size: 32px;
|
||||
color: #40a9ff;
|
||||
animation: pulse 1.5s infinite;
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
transform: translateX(5px);
|
||||
}
|
||||
}
|
||||
|
||||
// 标签页
|
||||
.tab-header {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid rgba(64, 169, 255, 0.2);
|
||||
|
||||
.tab-item {
|
||||
padding: 6px 14px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
// background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
background: #163B6C;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
.info-item {
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,590 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="clearance-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="clearance-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">抢通情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">行政区域</span>
|
||||
<el-select v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in regionOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">类型</span>
|
||||
<el-select v-model="filterForm.type" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">管控措施</span>
|
||||
<el-select v-model="filterForm.controlMeasure" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in controlMeasureOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 50px">序号</div>
|
||||
<div class="th" style="width: 80px">行政区域</div>
|
||||
<div class="th" style="width: 80px">线路编号</div>
|
||||
<div class="th" style="width: 100px">起止桩号</div>
|
||||
<div class="th" style="width: 100px">路况位置</div>
|
||||
<div class="th" style="width: 140px">发生时间</div>
|
||||
<div class="th" style="width: 80px">线路编号</div>
|
||||
<div class="th" style="width: 80px">类型</div>
|
||||
<div class="th" style="width: 100px">管控措施</div>
|
||||
<div class="th" style="flex: 1">操作</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 50px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.routeNo }}</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<el-tooltip :content="item.stakeNo" placement="top" :show-after="500">
|
||||
<span class="ellipsis-text">{{ item.stakeNo }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<el-tooltip :content="item.location" placement="top" :show-after="500">
|
||||
<span class="ellipsis-text">{{ item.location }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="td" style="width: 140px">{{ item.occurrenceTime }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.routeNo2 }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.type }}</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<span :class="['control-tag', getControlClass(item.controlMeasure)]">{{ item.controlMeasure }}</span>
|
||||
</div>
|
||||
<div class="td" style="flex: 1">
|
||||
<span class="detail-link" @click="handleDetail(item)">详情</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
上一个
|
||||
</div>
|
||||
<div class="page-numbers">
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-num"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
下一个
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "detail"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
region: "",
|
||||
type: "",
|
||||
controlMeasure: "",
|
||||
});
|
||||
|
||||
// 行政区域选项
|
||||
const regionOptions = ref([
|
||||
{ label: "巫溪县", value: "巫溪县" },
|
||||
{ label: "万州区", value: "万州区" },
|
||||
{ label: "沙坪坝区", value: "沙坪坝区" },
|
||||
{ label: "渝中区", value: "渝中区" },
|
||||
]);
|
||||
|
||||
// 类型选项
|
||||
const typeOptions = ref([
|
||||
{ label: "边坡坍塌", value: "边坡坍塌" },
|
||||
{ label: "路面塌陷", value: "路面塌陷" },
|
||||
{ label: "桥梁损坏", value: "桥梁损坏" },
|
||||
{ label: "隧道事故", value: "隧道事故" },
|
||||
]);
|
||||
|
||||
// 管控措施选项
|
||||
const controlMeasureOptions = ref([
|
||||
{ label: "全幅封闭", value: "全幅封闭" },
|
||||
{ label: "半幅封闭", value: "半幅封闭" },
|
||||
{ label: "正常通行", value: "正常通行" },
|
||||
{ label: "限制通行", value: "限制通行" },
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "巫溪县",
|
||||
routeNo: "G242",
|
||||
stakeNo: "336.800-338.850",
|
||||
location: "三星乡五斗村",
|
||||
occurrenceTime: "2025-08-11 04:53:42",
|
||||
routeNo2: "G242",
|
||||
type: "边坡坍塌",
|
||||
controlMeasure: "全幅封闭",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "万州区",
|
||||
routeNo: "G242",
|
||||
stakeNo: "338.800-338.850",
|
||||
location: "三星乡五斗村",
|
||||
occurrenceTime: "2025-08-11 04:53:42",
|
||||
routeNo2: "G242",
|
||||
type: "边坡坍塌",
|
||||
controlMeasure: "正常通行",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "沙坪坝区",
|
||||
routeNo: "G319",
|
||||
stakeNo: "120.500-122.000",
|
||||
location: "沙坪坝镇",
|
||||
occurrenceTime: "2025-08-10 14:30:00",
|
||||
routeNo2: "G319",
|
||||
type: "路面塌陷",
|
||||
controlMeasure: "半幅封闭",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
region: "渝中区",
|
||||
routeNo: "G212",
|
||||
stakeNo: "88.200-89.100",
|
||||
location: "渝中大道",
|
||||
occurrenceTime: "2025-08-09 09:15:30",
|
||||
routeNo2: "G212",
|
||||
type: "桥梁损坏",
|
||||
controlMeasure: "限制通行",
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 获取管控措施样式类
|
||||
const getControlClass = (measure) => {
|
||||
const classMap = {
|
||||
"全幅封闭": "control-close",
|
||||
"半幅封闭": "control-half",
|
||||
"正常通行": "control-normal",
|
||||
"限制通行": "control-limit",
|
||||
};
|
||||
return classMap[measure] || "";
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleDetail = (item) => {
|
||||
emit("detail", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.clearance-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.clearance-dialog {
|
||||
width: 1000px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.filter-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
width: 120px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
.ellipsis-text {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 管控措施标签
|
||||
.control-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.control-close {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
|
||||
&.control-half {
|
||||
background-color: rgba(255, 122, 0, 0.2);
|
||||
color: #ff7a00;
|
||||
border: 1px solid rgba(255, 122, 0, 0.4);
|
||||
}
|
||||
|
||||
&.control-normal {
|
||||
background-color: rgba(82, 196, 26, 0.2);
|
||||
color: #52c41a;
|
||||
border: 1px solid rgba(82, 196, 26, 0.4);
|
||||
}
|
||||
|
||||
&.control-limit {
|
||||
background-color: rgba(250, 219, 20, 0.2);
|
||||
color: #fadb14;
|
||||
border: 1px solid rgba(250, 219, 20, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
// 详情链接
|
||||
.detail-link {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-num {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,183 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="confirm-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="confirm-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">{{ title }}</div>
|
||||
<div class="close-btn" @click="handleCancel">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 提示内容 -->
|
||||
<div class="dialog-content">
|
||||
<p class="confirm-message">{{ message }}</p>
|
||||
</div>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<div class="dialog-footer">
|
||||
<el-button class="btn-cancel" @click="handleCancel">
|
||||
{{ cancelText }}
|
||||
</el-button>
|
||||
<el-button type="primary" class="btn-confirm" @click="handleConfirm">
|
||||
{{ confirmText }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "提示",
|
||||
},
|
||||
message: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
confirmText: {
|
||||
type: String,
|
||||
default: "确定",
|
||||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: "取消",
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "confirm", "cancel"]);
|
||||
|
||||
// 确认
|
||||
const handleConfirm = () => {
|
||||
emit("confirm");
|
||||
emit("update:visible", false);
|
||||
};
|
||||
|
||||
// 取消
|
||||
const handleCancel = () => {
|
||||
emit("cancel");
|
||||
emit("update:visible", false);
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleCancel();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.confirm-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2200;
|
||||
}
|
||||
|
||||
.confirm-dialog {
|
||||
width: 360px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
background: linear-gradient(90deg, rgba(64, 169, 255, 0.15) 0%, rgba(64, 169, 255, 0.05) 100%);
|
||||
border-bottom: 1px solid rgba(64, 169, 255, 0.2);
|
||||
|
||||
.header-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 内容区域
|
||||
.dialog-content {
|
||||
padding: 24px 20px;
|
||||
text-align: center;
|
||||
|
||||
.confirm-message {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮区域
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
padding: 0 20px 20px;
|
||||
|
||||
.btn-cancel {
|
||||
min-width: 80px;
|
||||
height: 32px;
|
||||
background-color: transparent;
|
||||
border: 1px solid rgba(64, 169, 255, 0.4);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 13px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border-color: rgba(64, 169, 255, 0.6);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-confirm {
|
||||
min-width: 80px;
|
||||
height: 32px;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,530 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="control-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="control-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">管控情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">行政区域</span>
|
||||
<el-select v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in regionOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">驻地风险等级</span>
|
||||
<el-select v-model="filterForm.riskLevel" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in riskLevelOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 100px">行政区域</div>
|
||||
<div class="th" style="width: 200px">驻地名称</div>
|
||||
<div class="th" style="width: 200px">所属项目</div>
|
||||
<div class="th" style="width: 80px">驻地人数</div>
|
||||
<div class="th" style="flex: 1">驻地风险等级</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 200px">
|
||||
<el-tooltip :content="item.stationName" placement="top" :show-after="500">
|
||||
<span class="ellipsis-text">{{ item.stationName }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="td" style="width: 200px">
|
||||
<el-tooltip :content="item.project" placement="top" :show-after="500">
|
||||
<span class="ellipsis-text">{{ item.project }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="td" style="width: 80px">{{ item.peopleCount }}</div>
|
||||
<div class="td" style="flex: 1">
|
||||
<span :class="['risk-tag', getRiskClass(item.riskLevel)]">{{ item.riskLevel }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
上一个
|
||||
</div>
|
||||
<div class="page-numbers">
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-num"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
下一个
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
region: "",
|
||||
riskLevel: "",
|
||||
});
|
||||
|
||||
// 行政区域选项
|
||||
const regionOptions = ref([
|
||||
{ label: "沙坪坝区", value: "沙坪坝区" },
|
||||
{ label: "万州区", value: "万州区" },
|
||||
{ label: "渝中区", value: "渝中区" },
|
||||
{ label: "江北区", value: "江北区" },
|
||||
]);
|
||||
|
||||
// 风险等级选项
|
||||
const riskLevelOptions = ref([
|
||||
{ label: "Ⅰ级", value: "Ⅰ级" },
|
||||
{ label: "Ⅱ级", value: "Ⅱ级" },
|
||||
{ label: "Ⅲ级", value: "Ⅲ级" },
|
||||
{ label: "Ⅳ级", value: "Ⅳ级" },
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "沙坪坝区",
|
||||
stationName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)项目经理部",
|
||||
project: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)",
|
||||
peopleCount: 21,
|
||||
riskLevel: "Ⅳ级",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "万州区",
|
||||
stationName: "万州区项目经理部",
|
||||
project: "万州区公路改造项目",
|
||||
peopleCount: 15,
|
||||
riskLevel: "Ⅲ级",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "渝中区",
|
||||
stationName: "渝中区桥梁维护项目部",
|
||||
project: "渝中区桥梁维护工程",
|
||||
peopleCount: 8,
|
||||
riskLevel: "Ⅱ级",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
region: "江北区",
|
||||
stationName: "江北区道路施工项目部",
|
||||
project: "江北区道路施工项目",
|
||||
peopleCount: 32,
|
||||
riskLevel: "Ⅰ级",
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 获取风险等级样式类
|
||||
const getRiskClass = (level) => {
|
||||
const classMap = {
|
||||
"Ⅰ级": "risk-level-1",
|
||||
"Ⅱ级": "risk-level-2",
|
||||
"Ⅲ级": "risk-level-3",
|
||||
"Ⅳ级": "risk-level-4",
|
||||
};
|
||||
return classMap[level] || "";
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.control-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.control-dialog {
|
||||
width: 900px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.filter-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
width: 140px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
.ellipsis-text {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 风险等级标签
|
||||
.risk-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.risk-level-1 {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
|
||||
&.risk-level-2 {
|
||||
background-color: rgba(255, 122, 0, 0.2);
|
||||
color: #ff7a00;
|
||||
border: 1px solid rgba(255, 122, 0, 0.4);
|
||||
}
|
||||
|
||||
&.risk-level-3 {
|
||||
background-color: rgba(250, 219, 20, 0.2);
|
||||
color: #fadb14;
|
||||
border: 1px solid rgba(250, 219, 20, 0.4);
|
||||
}
|
||||
|
||||
&.risk-level-4 {
|
||||
background-color: rgba(82, 196, 26, 0.2);
|
||||
color: #52c41a;
|
||||
border: 1px solid rgba(82, 196, 26, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-num {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,473 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="dispatch-detail-overlay" @click="handleOverlayClick">
|
||||
<div class="dispatch-detail-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">调度区县情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">行政区域</span>
|
||||
<el-select v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in regionOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">类型</span>
|
||||
<el-select v-model="filterForm.type" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 50px">序号</div>
|
||||
<div class="th" style="width: 100px">区县/镇街</div>
|
||||
<div class="th" style="width: 80px">姓名</div>
|
||||
<div class="th" style="width: 120px">电话</div>
|
||||
<div class="th" style="width: 100px">类型</div>
|
||||
<div class="th" style="width: 140px">角色</div>
|
||||
<div class="th" style="flex: 1">调度时间</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 50px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.district }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.name }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.phone }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.type }}</div>
|
||||
<div class="td" style="width: 140px">{{ item.role }}</div>
|
||||
<div class="td" style="flex: 1">{{ item.dispatchTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
上一个
|
||||
</div>
|
||||
<div class="page-numbers">
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-num"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
下一个
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
region: "",
|
||||
type: "",
|
||||
});
|
||||
|
||||
// 行政区域选项
|
||||
const regionOptions = ref([
|
||||
{ label: "柏梓镇", value: "柏梓镇" },
|
||||
{ label: "万州区", value: "万州区" },
|
||||
{ label: "沙坪坝区", value: "沙坪坝区" },
|
||||
{ label: "渝中区", value: "渝中区" },
|
||||
]);
|
||||
|
||||
// 类型选项
|
||||
const typeOptions = ref([
|
||||
{ label: "交通主管部门", value: "交通主管部门" },
|
||||
{ label: "公路机构", value: "公路机构" },
|
||||
{ label: "养护站", value: "养护站" },
|
||||
{ label: "护路员", value: "护路员" },
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
district: "柏梓镇",
|
||||
name: "赵海浪",
|
||||
phone: "18623520681",
|
||||
type: "交通主管部门",
|
||||
role: "一般人员(路长履职)",
|
||||
dispatchTime: "2025-08-11 04:53:42",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
district: "柏梓镇",
|
||||
name: "赵海浪",
|
||||
phone: "18623520681",
|
||||
type: "公路机构",
|
||||
role: "一般人员(路长履职)",
|
||||
dispatchTime: "2025-08-11 04:53:42",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
district: "万州区",
|
||||
name: "王鑫",
|
||||
phone: "18623520682",
|
||||
type: "养护站",
|
||||
role: "站长",
|
||||
dispatchTime: "2025-08-10 14:30:00",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
district: "沙坪坝区",
|
||||
name: "李华",
|
||||
phone: "18623520683",
|
||||
type: "护路员",
|
||||
role: "一般人员",
|
||||
dispatchTime: "2025-08-09 09:15:30",
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dispatch-detail-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2100;
|
||||
}
|
||||
|
||||
.dispatch-detail-dialog {
|
||||
width: 900px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.filter-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
width: 140px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-num {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,455 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="dispatch-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="dispatch-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">调度区县情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">行政区域</span>
|
||||
<el-select v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in regionOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 120px">行政区域</div>
|
||||
<div class="th" style="width: 100px">调度数</div>
|
||||
<div class="th" style="flex: 1">最近调度时间</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<span class="dispatch-count" @click="handleDispatchClick(item)">{{ item.dispatchCount }}</span>
|
||||
</div>
|
||||
<div class="td" style="flex: 1">{{ item.lastDispatchTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
上一个
|
||||
</div>
|
||||
<div class="page-numbers">
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-num"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
下一个
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "dispatchClick"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
region: "",
|
||||
});
|
||||
|
||||
// 行政区域选项
|
||||
const regionOptions = ref([
|
||||
{ label: "重庆市", value: "重庆市" },
|
||||
{ label: "万州区", value: "万州区" },
|
||||
{ label: "沙坪坝区", value: "沙坪坝区" },
|
||||
{ label: "渝中区", value: "渝中区" },
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "重庆市",
|
||||
dispatchCount: 1,
|
||||
lastDispatchTime: "2025-08-11 04:53:42",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "万州区",
|
||||
dispatchCount: 1,
|
||||
lastDispatchTime: "2025-08-11 04:53:42",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "沙坪坝区",
|
||||
dispatchCount: 3,
|
||||
lastDispatchTime: "2025-08-10 16:20:15",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
region: "渝中区",
|
||||
dispatchCount: 2,
|
||||
lastDispatchTime: "2025-08-09 11:45:30",
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 点击调度数
|
||||
const handleDispatchClick = (item) => {
|
||||
emit("dispatchClick", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dispatch-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.dispatch-dialog {
|
||||
width: 700px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.filter-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
width: 140px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
// 调度数字
|
||||
.dispatch-count {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-num {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,542 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="event-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="event-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">详情</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 事件基本信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
事件基本信息
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-label">事件编号:</span>
|
||||
<span class="info-value">{{ eventInfo.eventNo }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">发生时间:</span>
|
||||
<span class="info-value">{{ eventInfo.occurTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-label">事件类型:</span>
|
||||
<span class="info-value">{{ eventInfo.eventType }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">事件等级:</span>
|
||||
<span class="info-value level-tag" :class="eventInfo.levelClass">{{ eventInfo.eventLevel }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-label">所属区域:</span>
|
||||
<span class="info-value">{{ eventInfo.region }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">上报人:</span>
|
||||
<span class="info-value">{{ eventInfo.reporter }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-label">详细地址:</span>
|
||||
<span class="info-value">{{ eventInfo.address }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">上报时间:</span>
|
||||
<span class="info-value">{{ eventInfo.reportTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item full-width">
|
||||
<span class="info-label">事件描述:</span>
|
||||
<span class="info-value">{{ eventInfo.description }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 处置反馈信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
处置反馈信息
|
||||
</div>
|
||||
<div class="feedback-list">
|
||||
<div v-for="(item, index) in feedbackList" :key="item.id" class="feedback-item">
|
||||
<div class="feedback-header">
|
||||
<div class="feedback-num">{{ index + 1 }}</div>
|
||||
<div class="feedback-info">
|
||||
<div class="feedback-row">
|
||||
<span class="feedback-label">处置时间:</span>
|
||||
<span class="feedback-value">{{ item.handleTime }}</span>
|
||||
</div>
|
||||
<div class="feedback-row">
|
||||
<span class="feedback-label">处置人:</span>
|
||||
<span class="feedback-value">{{ item.handler }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-image" @click="previewImage(item.image)">
|
||||
<img :src="item.image" alt="处置图片" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-detail">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">预计开始时间:</span>
|
||||
<span class="detail-value">{{ item.estimatedStartTime }}</span>
|
||||
<span class="detail-label" style="margin-left: 40px">预计结束时间:</span>
|
||||
<span class="detail-value">{{ item.estimatedEndTime }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">实际开始时间:</span>
|
||||
<span class="detail-value">{{ item.actualStartTime }}</span>
|
||||
<span class="detail-label" style="margin-left: 40px">实际结束时间:</span>
|
||||
<span class="detail-value">{{ item.actualEndTime }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">处置人:</span>
|
||||
<span class="detail-value">{{ item.handlerName }}</span>
|
||||
<span class="detail-label" style="margin-left: 40px">联系电话:</span>
|
||||
<span class="detail-value">{{ item.contactPhone }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">处置情况描述:</span>
|
||||
<span class="detail-value">{{ item.handleDesc }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<div v-if="previewVisible" class="image-preview-overlay" @click="closePreview">
|
||||
<div class="image-preview-container" @click.stop>
|
||||
<img :src="previewImageUrl" alt="预览" />
|
||||
<div class="close-preview-btn" @click="closePreview">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
eventData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close"]);
|
||||
|
||||
// 事件基本信息
|
||||
const eventInfo = ref({
|
||||
eventNo: "202310120001",
|
||||
occurTime: "2023-10-12 14:30:00",
|
||||
eventType: "路面塌陷",
|
||||
eventLevel: "一般事件",
|
||||
levelClass: "level-normal",
|
||||
region: "万州区",
|
||||
reporter: "张三",
|
||||
address: "万州区太白路123号附近",
|
||||
reportTime: "2023-10-12 14:35:00",
|
||||
description: "路面出现塌陷,面积约2平方米,深度约0.5米,已设置警示标志,请尽快处理。",
|
||||
});
|
||||
|
||||
// 处置反馈信息
|
||||
const feedbackList = ref([
|
||||
{
|
||||
id: 1,
|
||||
handleTime: "2023-10-12 14:45:26",
|
||||
handler: "李四",
|
||||
image: "https://via.placeholder.com/80x60/40a9ff/ffffff?text=图片1",
|
||||
estimatedStartTime: "2023-10-12 14:30:00",
|
||||
estimatedEndTime: "2023-10-12 16:30:00",
|
||||
actualStartTime: "2023-10-12 14:45:00",
|
||||
actualEndTime: "2023-10-12 16:20:00",
|
||||
handlerName: "王五",
|
||||
contactPhone: "13800138000",
|
||||
handleDesc: "已到达现场,正在设置围挡,准备进行修复作业。",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
handleTime: "2023-10-12 16:20:45",
|
||||
handler: "李四",
|
||||
image: "https://via.placeholder.com/80x60/40a9ff/ffffff?text=图片2",
|
||||
estimatedStartTime: "2023-10-12 14:30:00",
|
||||
estimatedEndTime: "2023-10-12 16:30:00",
|
||||
actualStartTime: "2023-10-12 14:45:00",
|
||||
actualEndTime: "2023-10-12 16:20:00",
|
||||
handlerName: "王五",
|
||||
contactPhone: "13800138000",
|
||||
handleDesc: "修复作业已完成,路面已恢复平整,围挡已拆除,交通恢复正常。",
|
||||
},
|
||||
]);
|
||||
|
||||
// 图片预览
|
||||
const previewVisible = ref(false);
|
||||
const previewImageUrl = ref("");
|
||||
|
||||
const previewImage = (url) => {
|
||||
previewImageUrl.value = url;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false;
|
||||
previewImageUrl.value = "";
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal && props.eventData) {
|
||||
// 如果有传入数据,更新显示
|
||||
Object.assign(eventInfo.value, props.eventData);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.event-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2100;
|
||||
}
|
||||
|
||||
.event-dialog {
|
||||
width: 700px;
|
||||
max-height: 85vh;
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 区块
|
||||
.section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 区块标题
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-icon {
|
||||
color: #40a9ff;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// 信息网格
|
||||
.info-grid {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.info-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
&.full-width {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
white-space: nowrap;
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
|
||||
&.level-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.level-urgent {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
|
||||
&.level-normal {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
color: #40a9ff;
|
||||
border: 1px solid rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.level-low {
|
||||
background-color: rgba(82, 196, 26, 0.2);
|
||||
color: #52c41a;
|
||||
border: 1px solid rgba(82, 196, 26, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 反馈列表
|
||||
.feedback-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.feedback-item {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
border-left: 3px solid #40a9ff;
|
||||
}
|
||||
|
||||
.feedback-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.feedback-num {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.feedback-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feedback-row {
|
||||
margin-bottom: 6px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.feedback-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.feedback-value {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.feedback-image {
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 反馈详情
|
||||
.feedback-detail {
|
||||
padding-left: 36px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
.image-preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
.image-preview-container {
|
||||
position: relative;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.close-preview-btn {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏滚动条
|
||||
.event-dialog {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,567 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="impact-detail-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="impact-detail-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">影响点详情</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 隐患点基本信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
隐患点基本信息
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">所属区县</span>
|
||||
<span class="info-value">{{ basicInfo.district }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">影响点等级</span>
|
||||
<span class="info-value level-tag" :class="basicInfo.levelClass">{{ basicInfo.level }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">公路编号</span>
|
||||
<span class="info-value">{{ basicInfo.roadCode }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">位置</span>
|
||||
<span class="info-value">{{ basicInfo.location }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">风险点描述</span>
|
||||
<span class="info-value" :class="getStatusClass(basicInfo.riskDesc)">{{ basicInfo.riskDesc }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">发现时间</span>
|
||||
<span class="info-value">{{ basicInfo.discoverTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 照片 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
照片
|
||||
</div>
|
||||
<div class="photo-list">
|
||||
<div
|
||||
v-for="(photo, index) in photoList"
|
||||
:key="index"
|
||||
class="photo-item"
|
||||
@click="previewImage(photo)"
|
||||
>
|
||||
<img :src="photo" alt="照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 填报动态信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
填报动态信息
|
||||
</div>
|
||||
<div class="timeline-list">
|
||||
<div v-for="(record, index) in dynamicRecords" :key="index" class="timeline-item">
|
||||
<div class="timeline-marker">{{ index + 1 }}</div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">{{ record.type }}</span>
|
||||
</div>
|
||||
<div class="timeline-detail">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">巡查时间:</span>
|
||||
<span class="detail-value">{{ record.patrolTime }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">巡查人:</span>
|
||||
<span class="detail-value">{{ record.patrolPerson }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">现场情况描述:</span>
|
||||
<span class="detail-value">{{ record.description }}</span>
|
||||
<div v-if="record.image" class="detail-image" @click="previewImage(record.image)">
|
||||
<img :src="record.image" alt="现场照片" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">是否发现问题:</span>
|
||||
<span class="detail-value" :class="record.hasProblem ? 'status-yes' : 'status-no'">{{ record.hasProblem ? '是' : '否' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<div v-if="previewVisible" class="image-preview-overlay" @click="closePreview">
|
||||
<div class="image-preview-container" @click.stop>
|
||||
<img :src="previewImageUrl" alt="预览" />
|
||||
<div class="close-preview-btn" @click="closePreview">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
pointData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close"]);
|
||||
|
||||
// 基本信息
|
||||
const basicInfo = ref({
|
||||
district: "合川区",
|
||||
level: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
roadCode: "G348",
|
||||
location: "丁吴路(K116+656至K116+739)",
|
||||
riskDesc: "未回应",
|
||||
discoverTime: "立即启动防汛Ⅰ级应急响应,立即转移危险区群众,医疗机构做好应急准备",
|
||||
});
|
||||
|
||||
// 照片列表
|
||||
const photoList = ref([
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片",
|
||||
]);
|
||||
|
||||
// 动态记录
|
||||
const dynamicRecords = ref([
|
||||
{
|
||||
type: "隐患",
|
||||
patrolTime: "2026-03-28 14:30:00",
|
||||
patrolPerson: "刘伟",
|
||||
description: "设置警示标识,半幅通行",
|
||||
hasProblem: true,
|
||||
image: "https://via.placeholder.com/80x60/40a9ff/ffffff?text=现场",
|
||||
},
|
||||
{
|
||||
type: "隐患",
|
||||
patrolTime: "2026-03-28 14:30:00",
|
||||
patrolPerson: "刘伟",
|
||||
description: "设置警示标识,半幅通行",
|
||||
hasProblem: false,
|
||||
image: null,
|
||||
},
|
||||
]);
|
||||
|
||||
// 状态样式
|
||||
const getStatusClass = (status) => {
|
||||
if (status === "未回应") return "status-unresponse";
|
||||
if (status === "已回应") return "status-response";
|
||||
return "";
|
||||
};
|
||||
|
||||
// 图片预览
|
||||
const previewVisible = ref(false);
|
||||
const previewImageUrl = ref("");
|
||||
|
||||
const previewImage = (url) => {
|
||||
previewImageUrl.value = url;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false;
|
||||
previewImageUrl.value = "";
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal && props.pointData) {
|
||||
Object.assign(basicInfo.value, props.pointData);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.impact-detail-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2500;
|
||||
}
|
||||
|
||||
.impact-detail-dialog {
|
||||
width: 650px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 区块
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 区块标题
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-icon {
|
||||
color: #40a9ff;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 基本信息
|
||||
.basic-info {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.info-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.info-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
border-radius: 50%;
|
||||
margin-top: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.4;
|
||||
flex: 1;
|
||||
|
||||
&.level-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
width: fit-content;
|
||||
|
||||
&.level-normal {
|
||||
background-color: rgba(250, 219, 95, 0.2);
|
||||
color: #fadb5f;
|
||||
border: 1px solid rgba(250, 219, 95, 0.4);
|
||||
}
|
||||
|
||||
&.level-serious {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
&.status-unresponse {
|
||||
color: #ff7a45;
|
||||
}
|
||||
|
||||
&.status-response {
|
||||
color: #52c41a;
|
||||
}
|
||||
}
|
||||
|
||||
// 照片列表
|
||||
.photo-list {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 时间轴列表
|
||||
.timeline-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline-marker {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.timeline-type {
|
||||
font-size: 14px;
|
||||
color: #40a9ff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// 详情内容
|
||||
.timeline-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
min-width: 90px;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
|
||||
&.status-yes {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-no {
|
||||
color: #ff7a45;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-image {
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
margin-left: 12px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
.image-preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2600;
|
||||
}
|
||||
|
||||
.image-preview-container {
|
||||
position: relative;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.close-preview-btn {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏滚动条
|
||||
.impact-detail-dialog {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,569 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="impact-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="impact-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">影响点情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.pointType" placeholder="影响点类型" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="边坡" value="slope" />
|
||||
<el-option label="桥梁" value="bridge" />
|
||||
<el-option label="隧道" value="tunnel" />
|
||||
<el-option label="路面" value="road" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.pointLevel" placeholder="影响点等级" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="一般隐患" value="normal" />
|
||||
<el-option label="重大隐患" value="serious" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.region" placeholder="行政区域" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="万州区" value="wanzhou" />
|
||||
<el-option label="涪陵区" value="fuling" />
|
||||
<el-option label="合川区" value="hechuan" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">
|
||||
查询
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 50px">序号</div>
|
||||
<div class="th" style="width: 80px">行政区域</div>
|
||||
<div class="th" style="width: 80px">影响点类型</div>
|
||||
<div class="th" style="width: 180px">影响点位置</div>
|
||||
<div class="th" style="width: 90px">影响点等级</div>
|
||||
<div class="th" style="width: 130px">交通主管部门负责人</div>
|
||||
<div class="th" style="width: 110px">公路机构责任人</div>
|
||||
<div class="th" style="width: 110px">养护站负责人</div>
|
||||
<div class="th" style="width: 100px">护路员</div>
|
||||
<div class="th" style="width: 60px">操作</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 50px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.pointType }}</div>
|
||||
<div class="td" style="width: 180px">{{ item.pointLocation }}</div>
|
||||
<div class="td" style="width: 90px">
|
||||
<span class="level-tag" :class="item.levelClass">{{ item.pointLevel }}</span>
|
||||
</div>
|
||||
<div class="td" style="width: 130px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.trafficDept.name }}</span>
|
||||
<span class="person-phone">{{ item.trafficDept.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 110px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.roadOrg.name }}</span>
|
||||
<span class="person-phone">{{ item.roadOrg.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 110px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.maintenance.name }}</span>
|
||||
<span class="person-phone">{{ item.maintenance.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.roadKeeper.name }}</span>
|
||||
<span class="person-phone">{{ item.roadKeeper.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 60px">
|
||||
<span class="detail-link" @click="handleDetail(item)">详情</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共{{ total }}条数据</span>
|
||||
<div class="page-btns">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-btn"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "detail"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
pointType: "",
|
||||
pointLevel: "",
|
||||
region: "",
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "重庆市",
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "13708320801" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "重庆市",
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "13708320801" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "重庆市",
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "13708320801" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 4;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleSearch = () => {
|
||||
console.log("查询条件:", filterForm.value);
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleDetail = (item) => {
|
||||
emit("detail", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.impact-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.impact-dialog {
|
||||
width: 1050px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
.filter-select {
|
||||
width: 150px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 0 24px;
|
||||
height: 32px;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 12px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
min-height: 60px;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
padding: 0 4px;
|
||||
|
||||
.level-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
|
||||
&.level-normal {
|
||||
background-color: rgba(250, 219, 95, 0.2);
|
||||
color: #fadb5f;
|
||||
border: 1px solid rgba(250, 219, 95, 0.4);
|
||||
}
|
||||
|
||||
&.level-serious {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.person-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
|
||||
.person-name {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.person-phone {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
.total {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.page-btns {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled):not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
|
||||
// 下拉菜单样式
|
||||
:deep(.el-select-dropdown) {
|
||||
background-color: rgba(20, 50, 90, 0.98);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
|
||||
.el-select-dropdown__item {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,677 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="response-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="response-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">响应点详情</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 隐患点基本信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
隐患点基本信息
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<div class="info-row three-col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">所属区县</span>
|
||||
<span class="info-value">{{ basicInfo.district }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">影响点等级</span>
|
||||
<span class="info-value level-tag" :class="basicInfo.levelClass">{{ basicInfo.level }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">公路编号</span>
|
||||
<span class="info-value">{{ basicInfo.roadCode }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row three-col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">位置</span>
|
||||
<span class="info-value">{{ basicInfo.location }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">风险点描述</span>
|
||||
<span class="info-value" :class="getStatusClass(basicInfo.riskDesc)">{{ basicInfo.riskDesc }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">发现时间</span>
|
||||
<span class="info-value">{{ basicInfo.discoverTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 照片 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
照片
|
||||
</div>
|
||||
<div class="photo-list">
|
||||
<div
|
||||
v-for="(photo, index) in photoList"
|
||||
:key="index"
|
||||
class="photo-item"
|
||||
@click="previewImage(photo)"
|
||||
>
|
||||
<img :src="photo" alt="照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 巡查记录 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
巡查记录
|
||||
</div>
|
||||
<div class="timeline-list">
|
||||
<!-- 巡查记录详情 -->
|
||||
<div class="timeline-item patrol-item">
|
||||
<div class="timeline-marker patrol"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">巡查记录:</span>
|
||||
<span class="timeline-person">{{ patrolRecord.person }}</span>
|
||||
<span class="timeline-time">{{ patrolRecord.time }}</span>
|
||||
</div>
|
||||
<div class="timeline-detail">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">巡查轨迹:</span>
|
||||
<span class="detail-link" @click="viewTrack">查看轨迹</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">现场情况:</span>
|
||||
<span class="detail-text">{{ patrolRecord.situation }}</span>
|
||||
<div v-if="patrolRecord.image" class="detail-image" @click="previewImage(patrolRecord.image)">
|
||||
<img :src="patrolRecord.image" alt="现场照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 动态记录列表 -->
|
||||
<div v-for="(record, index) in dynamicRecords" :key="index" class="timeline-item">
|
||||
<div class="timeline-marker" :class="record.type"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">{{ record.typeName }}:</span>
|
||||
<span class="timeline-person">{{ record.person }}</span>
|
||||
<span class="timeline-time">{{ record.time }}</span>
|
||||
<span v-if="record.status" class="timeline-status" :class="record.statusClass">{{ record.status }}</span>
|
||||
<span v-if="record.target" class="timeline-target">
|
||||
到 <span class="target-name">{{ record.target }}</span> {{ record.targetPhone }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<div v-if="previewVisible" class="image-preview-overlay" @click="closePreview">
|
||||
<div class="image-preview-container" @click.stop>
|
||||
<img :src="previewImageUrl" alt="预览" />
|
||||
<div class="close-preview-btn" @click="closePreview">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
pointData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "viewTrack"]);
|
||||
|
||||
// 基本信息
|
||||
const basicInfo = ref({
|
||||
district: "合川区",
|
||||
level: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
roadCode: "G348",
|
||||
location: "丁吴路(K116+656至K116+739)",
|
||||
riskDesc: "未回应",
|
||||
discoverTime: "立即启动防汛Ⅰ级应急响应,立即转移危险区群众,医疗机构做好应急准备",
|
||||
});
|
||||
|
||||
// 照片列表
|
||||
const photoList = ref([
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片1",
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片2",
|
||||
]);
|
||||
|
||||
// 巡查记录
|
||||
const patrolRecord = ref({
|
||||
person: "蒋汉成 18702307964",
|
||||
time: "2025-10-14 15:43:24",
|
||||
situation: "收到暴雨黄色预警信息,开展公路夜间巡查排查,道路滑坡涉灾点,无明显变化",
|
||||
image: "https://via.placeholder.com/80x60/40a9ff/ffffff?text=现场",
|
||||
});
|
||||
|
||||
// 动态记录
|
||||
const dynamicRecords = ref([
|
||||
{
|
||||
type: "dispatch",
|
||||
typeName: "调度记录",
|
||||
person: "蒋汉成",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "【已接通语音】",
|
||||
statusClass: "status-success",
|
||||
target: "养护站负责人",
|
||||
targetPhone: "刘孝万(13609403931)",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "审核驳回",
|
||||
statusClass: "status-reject",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "审核通过",
|
||||
statusClass: "status-success",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "响应预警",
|
||||
statusClass: "status-success",
|
||||
},
|
||||
]);
|
||||
|
||||
// 状态样式
|
||||
const getStatusClass = (status) => {
|
||||
if (status === "未回应") return "status-unresponse";
|
||||
if (status === "已回应") return "status-response";
|
||||
return "";
|
||||
};
|
||||
|
||||
// 图片预览
|
||||
const previewVisible = ref(false);
|
||||
const previewImageUrl = ref("");
|
||||
|
||||
const previewImage = (url) => {
|
||||
previewImageUrl.value = url;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false;
|
||||
previewImageUrl.value = "";
|
||||
};
|
||||
|
||||
// 查看轨迹
|
||||
const viewTrack = () => {
|
||||
emit("viewTrack", patrolRecord.value);
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal && props.pointData) {
|
||||
Object.assign(basicInfo.value, props.pointData);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.response-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.response-dialog {
|
||||
width: 700px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 区块
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 区块标题
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-icon {
|
||||
color: #40a9ff;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 基本信息
|
||||
.basic-info {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.three-col {
|
||||
.info-item {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.4;
|
||||
|
||||
&.level-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
width: fit-content;
|
||||
|
||||
&.level-normal {
|
||||
background-color: rgba(250, 219, 95, 0.2);
|
||||
color: #fadb5f;
|
||||
border: 1px solid rgba(250, 219, 95, 0.4);
|
||||
}
|
||||
|
||||
&.level-serious {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
&.status-unresponse {
|
||||
color: #ff7a45;
|
||||
}
|
||||
|
||||
&.status-response {
|
||||
color: #52c41a;
|
||||
}
|
||||
}
|
||||
|
||||
// 照片列表
|
||||
.photo-list {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 时间轴列表
|
||||
.timeline-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
|
||||
&.patrol-item {
|
||||
.timeline-content {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-marker {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: #40a9ff;
|
||||
flex-shrink: 0;
|
||||
margin-top: 4px;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 2px;
|
||||
height: calc(100% + 12px);
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
}
|
||||
|
||||
&.patrol {
|
||||
background-color: #40a9ff;
|
||||
}
|
||||
|
||||
&.dispatch {
|
||||
background-color: #faad14;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-item:last-child .timeline-marker::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-type {
|
||||
font-size: 13px;
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.timeline-person {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.timeline-status {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.status-success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-target {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
|
||||
.target-name {
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// 详情内容
|
||||
.timeline-detail {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-text {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
font-size: 12px;
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-image {
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
margin-left: 12px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
.image-preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
.image-preview-container {
|
||||
position: relative;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.close-preview-btn {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.response-dialog::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.response-dialog::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.response-dialog::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.response-dialog::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,714 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="response-info-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="response-info-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">响应点详情</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
基本信息
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">所属区县</span>
|
||||
<span class="info-value">{{ basicInfo.district }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">公路编号</span>
|
||||
<span class="info-value">{{ basicInfo.roadCode }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">风险点类型</span>
|
||||
<span class="info-value">{{ basicInfo.riskType }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">风险点位置</span>
|
||||
<span class="info-value">{{ basicInfo.riskLocation }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">回应状态</span>
|
||||
<span class="info-value" :class="getStatusClass(basicInfo.responseStatus)">{{ basicInfo.responseStatus }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">审核状态</span>
|
||||
<span class="info-value" :class="getAuditClass(basicInfo.auditStatus)">{{ basicInfo.auditStatus }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">预警等级</span>
|
||||
<span class="info-value level-red">{{ basicInfo.warningLevel }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">起点桩号-止点桩号</span>
|
||||
<span class="info-value">{{ basicInfo.stakeRange }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-dot"></span>
|
||||
<span class="info-label">发现时间</span>
|
||||
<span class="info-value">{{ basicInfo.discoverTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 照片 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
照片
|
||||
</div>
|
||||
<div class="photo-list">
|
||||
<div
|
||||
v-for="(photo, index) in photoList"
|
||||
:key="index"
|
||||
class="photo-item"
|
||||
@click="previewImage(photo)"
|
||||
>
|
||||
<img :src="photo" alt="照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 巡查记录 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
巡查记录
|
||||
</div>
|
||||
<div class="timeline-list">
|
||||
<!-- 巡查记录详情 -->
|
||||
<div class="timeline-item patrol-item">
|
||||
<div class="timeline-marker patrol"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">巡查记录:</span>
|
||||
<span class="timeline-person">{{ patrolRecord.person }}</span>
|
||||
<span class="timeline-time">{{ patrolRecord.time }}</span>
|
||||
</div>
|
||||
<div class="timeline-detail">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">巡查轨迹:</span>
|
||||
<span class="detail-link" @click="viewTrack">查看轨迹</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">现场情况:</span>
|
||||
<span class="detail-text">{{ patrolRecord.situation }}</span>
|
||||
<div v-if="patrolRecord.image" class="detail-image" @click="previewImage(patrolRecord.image)">
|
||||
<img :src="patrolRecord.image" alt="现场照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 动态记录列表 -->
|
||||
<div v-for="(record, index) in dynamicRecords" :key="index" class="timeline-item">
|
||||
<div class="timeline-marker" :class="record.type"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">{{ record.typeName }}:</span>
|
||||
<span class="timeline-person">{{ record.person }}</span>
|
||||
<span class="timeline-time">{{ record.time }}</span>
|
||||
<span v-if="record.status" class="timeline-status" :class="record.statusClass">{{ record.status }}</span>
|
||||
<span v-if="record.target" class="timeline-target">
|
||||
到 <span class="target-name">{{ record.target }}</span> {{ record.targetPhone }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<div v-if="previewVisible" class="image-preview-overlay" @click="closePreview">
|
||||
<div class="image-preview-container" @click.stop>
|
||||
<img :src="previewImageUrl" alt="预览" />
|
||||
<div class="close-preview-btn" @click="closePreview">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
pointData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "viewTrack"]);
|
||||
|
||||
// 基本信息
|
||||
const basicInfo = ref({
|
||||
district: "合川区",
|
||||
roadCode: "G542",
|
||||
riskType: "风险路段",
|
||||
riskLocation: "丁吴路(K116+656至K116+739)",
|
||||
responseStatus: "未回应",
|
||||
auditStatus: "未审核",
|
||||
warningLevel: "红色预警",
|
||||
stakeRange: "三级治理中心发布发布暴雨红色预警信号",
|
||||
discoverTime: "立即启动防汛Ⅰ级应急响应,立即转移危险区群众,医疗机构做好应急准备",
|
||||
});
|
||||
|
||||
// 照片列表
|
||||
const photoList = ref([
|
||||
"https://via.placeholder.com/100x70/40a9ff/ffffff?text=照片1",
|
||||
"https://via.placeholder.com/100x70/40a9ff/ffffff?text=照片2",
|
||||
"https://via.placeholder.com/100x70/40a9ff/ffffff?text=照片3",
|
||||
"https://via.placeholder.com/100x70/40a9ff/ffffff?text=照片4",
|
||||
]);
|
||||
|
||||
// 巡查记录
|
||||
const patrolRecord = ref({
|
||||
person: "蒋汉成 18702307964",
|
||||
time: "2025-10-14 15:43:24",
|
||||
situation: "收到暴雨黄色预警信息,开展公路夜间巡查排查,道路滑坡涉灾点,无明显变化",
|
||||
image: "https://via.placeholder.com/80x60/40a9ff/ffffff?text=现场",
|
||||
});
|
||||
|
||||
// 动态记录
|
||||
const dynamicRecords = ref([
|
||||
{
|
||||
type: "dispatch",
|
||||
typeName: "调度记录",
|
||||
person: "蒋汉成",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "【已接通语音】",
|
||||
statusClass: "status-success",
|
||||
target: "养护站负责人",
|
||||
targetPhone: "刘孝万(13609403931)",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "审核驳回",
|
||||
statusClass: "status-reject",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "审核通过",
|
||||
statusClass: "status-success",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "响应预警",
|
||||
statusClass: "status-success",
|
||||
},
|
||||
]);
|
||||
|
||||
// 状态样式
|
||||
const getStatusClass = (status) => {
|
||||
if (status === "未回应") return "status-unresponse";
|
||||
if (status === "已回应") return "status-response";
|
||||
return "";
|
||||
};
|
||||
|
||||
const getAuditClass = (status) => {
|
||||
if (status === "未审核") return "status-unaudit";
|
||||
if (status === "审核通过") return "status-pass";
|
||||
if (status === "审核驳回") return "status-reject";
|
||||
return "";
|
||||
};
|
||||
|
||||
// 图片预览
|
||||
const previewVisible = ref(false);
|
||||
const previewImageUrl = ref("");
|
||||
|
||||
const previewImage = (url) => {
|
||||
previewImageUrl.value = url;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false;
|
||||
previewImageUrl.value = "";
|
||||
};
|
||||
|
||||
// 查看轨迹
|
||||
const viewTrack = () => {
|
||||
emit("viewTrack", patrolRecord.value);
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal && props.pointData) {
|
||||
Object.assign(basicInfo.value, props.pointData);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.response-info-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.response-info-dialog {
|
||||
width: 750px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 区块
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 区块标题
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-icon {
|
||||
color: #40a9ff;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 基本信息
|
||||
.basic-info {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.info-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.info-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
border-radius: 50%;
|
||||
margin-top: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.4;
|
||||
flex: 1;
|
||||
|
||||
&.level-red {
|
||||
color: #ff4d4f;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.status-unresponse {
|
||||
color: #ff7a45;
|
||||
}
|
||||
|
||||
&.status-response {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-unaudit {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.status-pass {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
// 照片列表
|
||||
.photo-list {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
width: 100px;
|
||||
height: 70px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 时间轴列表
|
||||
.timeline-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
|
||||
&.patrol-item {
|
||||
.timeline-content {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-marker {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: #40a9ff;
|
||||
flex-shrink: 0;
|
||||
margin-top: 4px;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 2px;
|
||||
height: calc(100% + 12px);
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
}
|
||||
|
||||
&.patrol {
|
||||
background-color: #40a9ff;
|
||||
}
|
||||
|
||||
&.dispatch {
|
||||
background-color: #faad14;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-item:last-child .timeline-marker::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-type {
|
||||
font-size: 13px;
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.timeline-person {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.timeline-status {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.status-success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-target {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
|
||||
.target-name {
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// 详情内容
|
||||
.timeline-detail {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-text {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
font-size: 12px;
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-image {
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
margin-left: 12px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
.image-preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
.image-preview-container {
|
||||
position: relative;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.close-preview-btn {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.response-info-dialog::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.response-info-dialog::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.response-info-dialog::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.response-info-dialog::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,502 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="response-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="response-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">潼南三级路长明细</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计数据卡片 -->
|
||||
<div class="stats-cards">
|
||||
<div class="stat-card">
|
||||
<div class="card-icon">
|
||||
<el-icon class="stat-icon"><User /></el-icon>
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<div class="card-label">路长总人数</div>
|
||||
<div class="card-value">
|
||||
<span class="value-num">{{ stats.total }}</span>
|
||||
<span class="value-unit">人</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="card-icon">
|
||||
<el-icon class="stat-icon"><OfficeBuilding /></el-icon>
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<div class="card-label">县级路长</div>
|
||||
<div class="card-value">
|
||||
<span class="value-num">{{ stats.county }}</span>
|
||||
<span class="value-unit">公里</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="card-icon">
|
||||
<el-icon class="stat-icon"><MapLocation /></el-icon>
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<div class="card-label">乡、村路长</div>
|
||||
<div class="card-value">
|
||||
<span class="value-num">{{ stats.village }}</span>
|
||||
<span class="value-unit">次</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 120px">区县/镇街</div>
|
||||
<div class="th" style="width: 100px">姓名</div>
|
||||
<div class="th" style="width: 120px">电话</div>
|
||||
<div class="th" style="flex: 1">角色</div>
|
||||
<div class="th" style="width: 100px">职务</div>
|
||||
<div class="th" style="width: 120px">操作</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ index + 1 }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.district }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.name }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.phone }}</div>
|
||||
<div class="td" style="flex: 1">{{ item.role }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.position }}</div>
|
||||
<div class="td" style="width: 120px">
|
||||
<div class="action-btns">
|
||||
<div class="action-btn" @click="handleView(item)">
|
||||
<el-icon><VideoCamera /></el-icon>
|
||||
</div>
|
||||
<div class="action-btn" @click="handleVoice(item)">
|
||||
<el-icon><Microphone /></el-icon>
|
||||
</div>
|
||||
<div class="action-btn" @click="handleCall(item)">
|
||||
<el-icon><Phone /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共{{ total }}条数据</span>
|
||||
<div class="page-btns">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-btn"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close, VideoCamera, Microphone, Phone, ArrowLeft, ArrowRight, User, OfficeBuilding, MapLocation } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close"]);
|
||||
|
||||
// 统计数据
|
||||
const stats = ref({
|
||||
total: 1127,
|
||||
county: 216,
|
||||
village: 1099,
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{ id: 1, district: "万州区柏梓镇", name: "赵海浪", phone: "1862352068", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 2, district: "万州区柏梓镇", name: "赵海浪", phone: "1862352068", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 3, district: "万州区柏梓镇", name: "赵海浪", phone: "1862352068", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 4, district: "万州区柏梓镇", name: "赵海浪", phone: "1862352068", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 5, district: "万州区李河镇", name: "王建国", phone: "1398324567", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 6, district: "万州区李河镇", name: "王建国", phone: "1398324567", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 7, district: "万州区李河镇", name: "王建国", phone: "1398324567", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 8, district: "万州区李河镇", name: "王建国", phone: "1398324567", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 9, district: "万州区分水镇", name: "刘志强", phone: "1387654321", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 10, district: "万州区分水镇", name: "刘志强", phone: "1387654321", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 11, district: "万州区分水镇", name: "刘志强", phone: "1387654321", role: "一般人员(路长履职)", position: "其他" },
|
||||
{ id: 12, district: "万州区分水镇", name: "刘志强", phone: "1387654321", role: "一般人员(路长履职)", position: "其他" },
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 4;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 操作按钮
|
||||
const handleView = (item) => {
|
||||
console.log("查看视频:", item);
|
||||
};
|
||||
|
||||
const handleVoice = (item) => {
|
||||
console.log("语音通话:", item);
|
||||
};
|
||||
|
||||
const handleCall = (item) => {
|
||||
console.log("拨打电话:", item);
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.response-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.response-dialog {
|
||||
width: 900px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 统计卡片
|
||||
.stats-cards {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.stat-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background: linear-gradient(135deg, rgba(30, 80, 140, 0.6) 0%, rgba(20, 60, 110, 0.8) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
|
||||
.card-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.15);
|
||||
border-radius: 8px;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
|
||||
.card-info {
|
||||
.card-label {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
|
||||
.value-num {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #40a9ff;
|
||||
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
.value-unit {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 12px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
.action-btns {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
|
||||
.action-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.15);
|
||||
border-radius: 4px;
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
.total {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.page-btns {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
min-width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled):not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
|
||||
// 滚动条角落
|
||||
.table-body::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
@ -1,573 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="response-status-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="response-status-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">响应情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.pointType" placeholder="影响点类型" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="边坡" value="slope" />
|
||||
<el-option label="桥梁" value="bridge" />
|
||||
<el-option label="隧道" value="tunnel" />
|
||||
<el-option label="路面" value="road" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.pointLevel" placeholder="影响点等级" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="一般隐患" value="normal" />
|
||||
<el-option label="重大隐患" value="serious" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.isResponded" placeholder="是否回应" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="是" value="yes" />
|
||||
<el-option label="否" value="no" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 50px">序号</div>
|
||||
<div class="th" style="width: 80px">影响点类型</div>
|
||||
<div class="th" style="width: 180px">影响点位置</div>
|
||||
<div class="th" style="width: 90px">影响点等级</div>
|
||||
<div class="th" style="width: 60px">查次数</div>
|
||||
<div class="th" style="width: 120px">交通主管部门负责人</div>
|
||||
<div class="th" style="width: 110px">公路机构责任人</div>
|
||||
<div class="th" style="width: 110px">养护站负责人</div>
|
||||
<div class="th" style="width: 80px">护路员</div>
|
||||
<div class="th" style="width: 70px">回应状态</div>
|
||||
<div class="th" style="width: 110px">最新催告时间</div>
|
||||
<div class="th" style="width: 50px">操作</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 50px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.pointType }}</div>
|
||||
<div class="td" style="width: 180px">{{ item.pointLocation }}</div>
|
||||
<div class="td" style="width: 90px">
|
||||
<span class="level-tag" :class="item.levelClass">{{ item.pointLevel }}</span>
|
||||
</div>
|
||||
<div class="td" style="width: 60px">{{ item.checkCount }}</div>
|
||||
<div class="td" style="width: 120px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.trafficDept.name }}</span>
|
||||
<span class="person-phone">{{ item.trafficDept.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 110px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.roadOrg.name }}</span>
|
||||
<span class="person-phone">{{ item.roadOrg.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 110px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.maintenance.name }}</span>
|
||||
<span class="person-phone">{{ item.maintenance.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 80px">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ item.roadKeeper.name }}</span>
|
||||
<span class="person-phone">{{ item.roadKeeper.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 70px">
|
||||
<span class="response-status" :class="item.responseClass">{{ item.responseStatus }}</span>
|
||||
</div>
|
||||
<div class="td" style="width: 110px">
|
||||
<div class="time-info">
|
||||
<span class="time-date">{{ item.urgeTime.date }}</span>
|
||||
<span class="time-clock">{{ item.urgeTime.time }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td" style="width: 50px">
|
||||
<span class="detail-link" @click="handleDetail(item)">详情</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共{{ total }}条数据</span>
|
||||
<div class="page-btns">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-btn"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "detail"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
pointType: "",
|
||||
pointLevel: "",
|
||||
isResponded: "",
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
checkCount: 2,
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "1372386532" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
responseStatus: "已回应",
|
||||
responseClass: "status-responded",
|
||||
urgeTime: { date: "2026-03-28", time: "12:30:00" },
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
checkCount: 2,
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "1372386532" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
responseStatus: "已回应",
|
||||
responseClass: "status-responded",
|
||||
urgeTime: { date: "2026-03-28", time: "12:30:00" },
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 4;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleDetail = (item) => {
|
||||
emit("detail", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.response-status-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.response-status-dialog {
|
||||
width: 1150px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
.filter-select {
|
||||
width: 150px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 12px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
.level-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
|
||||
&.level-normal {
|
||||
background-color: rgba(250, 219, 95, 0.2);
|
||||
color: #fadb5f;
|
||||
border: 1px solid rgba(250, 219, 95, 0.4);
|
||||
}
|
||||
|
||||
&.level-serious {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.person-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
|
||||
.person-name {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.person-phone {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.response-status {
|
||||
font-size: 12px;
|
||||
|
||||
&.status-responded {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-unresponded {
|
||||
color: #ff7a45;
|
||||
}
|
||||
}
|
||||
|
||||
.time-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
|
||||
.time-date {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.time-clock {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
.total {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.page-btns {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled):not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
|
||||
// 下拉菜单样式
|
||||
:deep(.el-select-dropdown) {
|
||||
background-color: rgba(20, 50, 90, 0.98);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
|
||||
.el-select-dropdown__item {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,784 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="risk-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="risk-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">影响点详情</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
基本信息
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<div class="info-row three-col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">所属区县</span>
|
||||
<span class="info-value">{{ basicInfo.district }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">公路编号</span>
|
||||
<span class="info-value">{{ basicInfo.roadCode }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">风险点类型</span>
|
||||
<span class="info-value">{{ basicInfo.riskType }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row three-col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">风险点位置</span>
|
||||
<span class="info-value">{{ basicInfo.riskLocation }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">回应状态</span>
|
||||
<span class="info-value" :class="getStatusClass(basicInfo.responseStatus)">{{ basicInfo.responseStatus }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">审核状态</span>
|
||||
<span class="info-value" :class="getAuditClass(basicInfo.auditStatus)">{{ basicInfo.auditStatus }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row three-col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">预警等级</span>
|
||||
<span class="info-value level-red">{{ basicInfo.warningLevel }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">起点桩号-止点桩号</span>
|
||||
<span class="info-value">{{ basicInfo.stakeRange }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">发现时间</span>
|
||||
<span class="info-value">{{ basicInfo.discoverTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row full-width">
|
||||
<div class="info-item">
|
||||
<span class="info-label">预警内容</span>
|
||||
<span class="info-value">{{ basicInfo.warningContent }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 照片 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
照片
|
||||
</div>
|
||||
<div class="photo-list">
|
||||
<div
|
||||
v-for="(photo, index) in photoList"
|
||||
:key="index"
|
||||
class="photo-item"
|
||||
@click="previewImage(photo)"
|
||||
>
|
||||
<img :src="photo" alt="照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 三级包保责任人 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
三级包保责任人
|
||||
</div>
|
||||
<div class="responsible-table">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 30%">责任人类型</div>
|
||||
<div class="th" style="width: 40%">责任人</div>
|
||||
<div class="th" style="width: 30%">巡查频率</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in responsibleList"
|
||||
:key="index"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 30%">{{ item.type }}</div>
|
||||
<div class="td" style="width: 40%">{{ item.name }} {{ item.phone }}</div>
|
||||
<div class="td" style="width: 30%">{{ item.frequency }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 填报动态信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">▍</span>
|
||||
填报动态信息
|
||||
</div>
|
||||
<div class="timeline-list">
|
||||
<!-- 巡查记录 -->
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-marker patrol"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">巡查记录:</span>
|
||||
<span class="timeline-person">{{ patrolRecord.person }}</span>
|
||||
<span class="timeline-time">{{ patrolRecord.time }}</span>
|
||||
</div>
|
||||
<div class="timeline-detail">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">巡查轨迹:</span>
|
||||
<span class="detail-link" @click="viewTrack">查看轨迹</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">现场情况:</span>
|
||||
<span class="detail-text">{{ patrolRecord.situation }}</span>
|
||||
<div v-if="patrolRecord.image" class="detail-image" @click="previewImage(patrolRecord.image)">
|
||||
<img :src="patrolRecord.image" alt="现场照片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 动态记录列表 -->
|
||||
<div v-for="(record, index) in dynamicRecords" :key="index" class="timeline-item">
|
||||
<div class="timeline-marker" :class="record.type"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-type">{{ record.typeName }}:</span>
|
||||
<span class="timeline-person">{{ record.person }}</span>
|
||||
<span class="timeline-time">{{ record.time }}</span>
|
||||
<span v-if="record.status" class="timeline-status" :class="record.statusClass">{{ record.status }}</span>
|
||||
<span v-if="record.target" class="timeline-target">
|
||||
到 <span class="target-name">{{ record.target }}</span> {{ record.targetPhone }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<div v-if="previewVisible" class="image-preview-overlay" @click="closePreview">
|
||||
<div class="image-preview-container" @click.stop>
|
||||
<img :src="previewImageUrl" alt="预览" />
|
||||
<div class="close-preview-btn" @click="closePreview">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
riskData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "viewTrack"]);
|
||||
|
||||
// 基本信息
|
||||
const basicInfo = ref({
|
||||
district: "合川区",
|
||||
roadCode: "G542",
|
||||
riskType: "风险路段",
|
||||
riskLocation: "丁吴路(K116+656至K116+739)",
|
||||
responseStatus: "未回应",
|
||||
auditStatus: "未审核",
|
||||
warningLevel: "红色预警",
|
||||
stakeRange: "三级治理中心发布发布暴雨红色预警信号",
|
||||
discoverTime: "立即启动防汛Ⅰ级应急响应,立即转移危险区群众,医疗机构做好应急准备",
|
||||
warningContent: "",
|
||||
});
|
||||
|
||||
// 照片列表
|
||||
const photoList = ref([
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片1",
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片2",
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片3",
|
||||
"https://via.placeholder.com/120x80/40a9ff/ffffff?text=照片4",
|
||||
]);
|
||||
|
||||
// 三级包保责任人
|
||||
const responsibleList = ref([
|
||||
{ type: "交通主管部门负责人", name: "胡雷", phone: "18983923577", frequency: "半年巡查一次" },
|
||||
{ type: "公路机构负责人", name: "刘孝万", phone: "13609403931", frequency: "每月巡查一次" },
|
||||
{ type: "养护站负责人", name: "彭应成", phone: "18323031454", frequency: "每周巡查一次" },
|
||||
{ type: "护路员", name: "蒋汉成", phone: "1870230796", frequency: "每周巡查两次" },
|
||||
]);
|
||||
|
||||
// 巡查记录
|
||||
const patrolRecord = ref({
|
||||
person: "蒋汉成 18702307964",
|
||||
time: "2025-10-14 15:43:24",
|
||||
situation: "收到暴雨黄色预警信息,开展公路夜间巡查排查,道路滑坡涉灾点,无明显变化",
|
||||
image: "https://via.placeholder.com/80x60/40a9ff/ffffff?text=现场",
|
||||
});
|
||||
|
||||
// 动态记录
|
||||
const dynamicRecords = ref([
|
||||
{
|
||||
type: "dispatch",
|
||||
typeName: "调度记录",
|
||||
person: "蒋汉成",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "【已接通语音】",
|
||||
statusClass: "status-success",
|
||||
target: "养护站负责人",
|
||||
targetPhone: "刘孝万(13609403931)",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "审核驳回",
|
||||
statusClass: "status-reject",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "审核通过",
|
||||
statusClass: "status-success",
|
||||
},
|
||||
{
|
||||
type: "warning",
|
||||
typeName: "预警记录",
|
||||
person: "蒋汉成(18702307964)",
|
||||
time: "2025-10-13 15:43:24",
|
||||
status: "响应预警",
|
||||
statusClass: "status-success",
|
||||
},
|
||||
]);
|
||||
|
||||
// 状态样式
|
||||
const getStatusClass = (status) => {
|
||||
if (status === "未回应") return "status-unresponse";
|
||||
if (status === "已回应") return "status-response";
|
||||
return "";
|
||||
};
|
||||
|
||||
const getAuditClass = (status) => {
|
||||
if (status === "未审核") return "status-unaudit";
|
||||
if (status === "审核通过") return "status-pass";
|
||||
if (status === "审核驳回") return "status-reject";
|
||||
return "";
|
||||
};
|
||||
|
||||
// 图片预览
|
||||
const previewVisible = ref(false);
|
||||
const previewImageUrl = ref("");
|
||||
|
||||
const previewImage = (url) => {
|
||||
previewImageUrl.value = url;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false;
|
||||
previewImageUrl.value = "";
|
||||
};
|
||||
|
||||
// 查看轨迹
|
||||
const viewTrack = () => {
|
||||
emit("viewTrack", patrolRecord.value);
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal && props.riskData) {
|
||||
Object.assign(basicInfo.value, props.riskData);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.risk-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.risk-dialog {
|
||||
width: 800px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 区块
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 区块标题
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-icon {
|
||||
color: #40a9ff;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 基本信息
|
||||
.basic-info {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.three-col {
|
||||
.info-item {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.full-width {
|
||||
.info-item {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.4;
|
||||
|
||||
&.level-red {
|
||||
color: #ff4d4f;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.status-unresponse {
|
||||
color: #ff7a45;
|
||||
}
|
||||
|
||||
&.status-response {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-unaudit {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.status-pass {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
// 照片列表
|
||||
.photo-list {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 责任人表格
|
||||
.responsible-table {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 10px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 10px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 时间轴列表
|
||||
.timeline-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline-marker {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: #40a9ff;
|
||||
flex-shrink: 0;
|
||||
margin-top: 4px;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 2px;
|
||||
height: calc(100% + 12px);
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
}
|
||||
|
||||
&.patrol {
|
||||
background-color: #40a9ff;
|
||||
}
|
||||
|
||||
&.dispatch {
|
||||
background-color: #faad14;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-item:last-child .timeline-marker::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-type {
|
||||
font-size: 13px;
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.timeline-person {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.timeline-status {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.status-success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-target {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
|
||||
.target-name {
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// 详情内容
|
||||
.timeline-detail {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-text {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
font-size: 12px;
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-image {
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
margin-left: 12px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
.image-preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
.image-preview-container {
|
||||
position: relative;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.close-preview-btn {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.risk-dialog::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.risk-dialog::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.risk-dialog::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.risk-dialog::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -28,6 +28,7 @@ defineProps({
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
background-image: url(v-bind(bgImg));
|
||||
background-size: cover;
|
||||
background-position: left;
|
||||
@ -38,7 +39,7 @@ defineProps({
|
||||
gap: 8px;
|
||||
|
||||
.title {
|
||||
margin-left: 45px;
|
||||
margin-left: 35px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
|
||||
13
packages/screen/src/views/RiskWarning/component/title.vue
Normal file
13
packages/screen/src/views/RiskWarning/component/title.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@ -1,438 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="tongnan-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="tongnan-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">潼南基本信息表</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 140px">区县/镇街</div>
|
||||
<div class="th" style="width: 100px">姓名</div>
|
||||
<div class="th" style="width: 120px">电话</div>
|
||||
<div class="th" style="width: 180px">驻地名称</div>
|
||||
<div class="th" style="flex: 1">类型</div>
|
||||
<div class="th" style="width: 140px">调度</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 140px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.name }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.phone }}</div>
|
||||
<div class="td" style="width: 180px">
|
||||
<el-tooltip :content="item.stationName" placement="top" :show-after="500">
|
||||
<span class="station-name-text" @click="handleStationNameClick(item)">{{ item.stationName }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="td" style="flex: 1">{{ item.type }}</div>
|
||||
<div class="td" style="width: 140px">
|
||||
<div class="action-btns">
|
||||
<div class="action-btn" @click="handleVideo(item)" title="视频">
|
||||
<el-icon><VideoCamera /></el-icon>
|
||||
</div>
|
||||
<div class="action-btn" @click="handleVoice(item)" title="语音">
|
||||
<el-icon><Microphone /></el-icon>
|
||||
</div>
|
||||
<div class="action-btn" @click="handleCall(item)" title="电话">
|
||||
<el-icon><Phone /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共{{ total }}条数据</span>
|
||||
<div class="page-btns">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-btn"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close, VideoCamera, Microphone, Phone, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "video", "voice", "call", "stationNameClick"]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "沙坪坝区",
|
||||
name: "赵海浪",
|
||||
phone: "1862352068",
|
||||
stationName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)项目经理部",
|
||||
type: "交通主管部门",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "沙坪坝区",
|
||||
name: "府效能",
|
||||
phone: "1862352068",
|
||||
stationName: "沙坪坝区S545茅山峡公路桥新建工程(渝黔铁路扩能改造工程)项目经理部",
|
||||
type: "公路机构",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "万州区柏梓镇",
|
||||
name: "王鑫",
|
||||
phone: "1862352068",
|
||||
stationName: "万州区项目经理部",
|
||||
type: "公路机构",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
region: "万州区柏梓镇",
|
||||
name: "王鑫",
|
||||
phone: "1862352068",
|
||||
stationName: "万州区项目经理部",
|
||||
type: "公路机构",
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 4;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 操作按钮
|
||||
const handleVideo = (item) => {
|
||||
emit("video", item);
|
||||
};
|
||||
|
||||
const handleVoice = (item) => {
|
||||
emit("voice", item);
|
||||
};
|
||||
|
||||
const handleCall = (item) => {
|
||||
emit("call", item);
|
||||
};
|
||||
|
||||
// 点击驻地名称
|
||||
const handleStationNameClick = (item) => {
|
||||
emit("stationNameClick", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tongnan-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2100;
|
||||
}
|
||||
|
||||
.tongnan-dialog {
|
||||
width: 1000px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
.station-name-text {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 180px;
|
||||
color: #40a9ff;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.action-btns {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
|
||||
.action-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
.total {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.page-btns {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled):not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,375 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="responsible-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="responsible-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">潼南建设项目责任人明细</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 100px">区县/镇街</div>
|
||||
<div class="th" style="width: 70px">总人数</div>
|
||||
<div class="th" style="width: 70px">吹哨人</div>
|
||||
<div class="th" style="width: 130px">建设单位包保责任人</div>
|
||||
<div class="th" style="width: 130px">施工单位包保责任人</div>
|
||||
<div class="th" style="width: 120px">驻地包保责任人</div>
|
||||
<div class="th" style="width: 120px">区县级包保责任人</div>
|
||||
<div class="th" style="width: 120px">市级包保责任人</div>
|
||||
<div class="th" style="width: 60px">操作</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 70px">{{ item.totalCount }}</div>
|
||||
<div class="td" style="width: 70px">{{ item.whistleblower }}</div>
|
||||
<div class="td" style="width: 130px">{{ item.constructionUnit }}</div>
|
||||
<div class="td" style="width: 130px">{{ item.contractorUnit }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.stationed }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.districtLevel }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.cityLevel }}</div>
|
||||
<div class="td" style="width: 60px">
|
||||
<span class="detail-link" @click="handleDetail(item)">详情</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共{{ total }}条数据</span>
|
||||
<div class="page-btns">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-btn"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "detail"]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "万州区",
|
||||
totalCount: 6,
|
||||
whistleblower: 2,
|
||||
constructionUnit: 2,
|
||||
contractorUnit: 2,
|
||||
stationed: 2,
|
||||
districtLevel: 2,
|
||||
cityLevel: 2,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "柏梓镇",
|
||||
totalCount: 6,
|
||||
whistleblower: 2,
|
||||
constructionUnit: 2,
|
||||
contractorUnit: 2,
|
||||
stationed: 2,
|
||||
districtLevel: 2,
|
||||
cityLevel: 2,
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 4;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleDetail = (item) => {
|
||||
emit("detail", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.responsible-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.responsible-dialog {
|
||||
width: 1100px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
.detail-link {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
.total {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.page-btns {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled):not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,397 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="team-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="team-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">潼南护路团队成员</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 100px">区县</div>
|
||||
<div class="th" style="width: 80px">总人数</div>
|
||||
<div class="th" style="width: 140px">交通主管部门责任人</div>
|
||||
<div class="th" style="width: 120px">公路机构责任人</div>
|
||||
<div class="th" style="width: 140px">养护站道班责任人</div>
|
||||
<div class="th" style="width: 80px">护路员</div>
|
||||
<div class="th" style="flex: 1">操作</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.district }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.totalCount }}</div>
|
||||
<div class="td" style="width: 140px">{{ item.trafficDept }}</div>
|
||||
<div class="td" style="width: 120px">{{ item.roadOrg }}</div>
|
||||
<div class="td" style="width: 140px">{{ item.maintenance }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.roadKeeper }}</div>
|
||||
<div class="td" style="flex: 1">
|
||||
<span class="view-link" @click="handleView(item)">查看</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
上一个
|
||||
</div>
|
||||
<div class="page-numbers">
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-num"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
下一个
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "view"]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
district: "潼南",
|
||||
totalCount: 128,
|
||||
trafficDept: 2,
|
||||
roadOrg: 3,
|
||||
maintenance: 6,
|
||||
roadKeeper: 117,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
district: "万州",
|
||||
totalCount: 96,
|
||||
trafficDept: 1,
|
||||
roadOrg: 2,
|
||||
maintenance: 4,
|
||||
roadKeeper: 89,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
district: "沙坪坝",
|
||||
totalCount: 156,
|
||||
trafficDept: 3,
|
||||
roadOrg: 4,
|
||||
maintenance: 8,
|
||||
roadKeeper: 141,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
district: "渝中",
|
||||
totalCount: 64,
|
||||
trafficDept: 1,
|
||||
roadOrg: 2,
|
||||
maintenance: 3,
|
||||
roadKeeper: 58,
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleView = (item) => {
|
||||
emit("view", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.team-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.team-dialog {
|
||||
width: 900px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
// 查看链接
|
||||
.view-link {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-num {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,605 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="warning-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="warning-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">响应情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.warningLevel" placeholder="预警等级" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="红色预警" value="red" />
|
||||
<el-option label="橙色预警" value="orange" />
|
||||
<el-option label="黄色预警" value="yellow" />
|
||||
<el-option label="蓝色预警" value="blue" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.region" placeholder="行政区域" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="万州区" value="wanzhou" />
|
||||
<el-option label="涪陵区" value="fuling" />
|
||||
<el-option label="万盛区" value="wansheng" />
|
||||
<el-option label="长寿区" value="changshou" />
|
||||
<el-option label="城口区" value="chengkou" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.isEnded" placeholder="是否结束" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="是" value="yes" />
|
||||
<el-option label="否" value="no" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select v-model="filterForm.isResponded" placeholder="是否回应" class="filter-select">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="是" value="yes" />
|
||||
<el-option label="否" value="no" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">
|
||||
<el-icon><Search /></el-icon>
|
||||
查询
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 60px">序号</div>
|
||||
<div class="th" style="width: 100px">预警等级</div>
|
||||
<div class="th" style="width: 100px">行政区域</div>
|
||||
<div class="th" style="width: 160px">预警时间</div>
|
||||
<div class="th" style="width: 160px">结束时间</div>
|
||||
<div class="th" style="width: 100px">影响点数量</div>
|
||||
<div class="th clickable" style="width: 80px">已叫应</div>
|
||||
<div class="th" style="width: 80px">已回应</div>
|
||||
<div class="th" style="width: 80px">未回应</div>
|
||||
<div class="th" style="width: 80px">已催告</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 60px">{{ index + 1 }}</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<span class="warning-level" :class="item.levelClass">{{ item.warningLevel }}</span>
|
||||
</div>
|
||||
<div class="td" style="width: 100px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 160px">{{ item.warningTime }}</div>
|
||||
<div class="td" style="width: 160px">{{ item.endTime }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.impactPoints }}</div>
|
||||
<div class="td clickable-cell" style="width: 80px" @click.stop="handleCalledClick(item)">{{ item.called }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.responded }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.notResponded }}</div>
|
||||
<div class="td" style="width: 80px">{{ item.urged }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共{{ total }}条数据</span>
|
||||
<div class="page-btns">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-btn"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close, Search, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "openImpactPoint"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
warningLevel: "",
|
||||
region: "",
|
||||
isEnded: "",
|
||||
isResponded: "",
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
warningLevel: "红色预警",
|
||||
levelClass: "level-red",
|
||||
region: "万州区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactPoints: 4,
|
||||
called: 2,
|
||||
responded: 2,
|
||||
notResponded: 2,
|
||||
urged: 22,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
warningLevel: "橙色预警",
|
||||
levelClass: "level-orange",
|
||||
region: "涪陵区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactPoints: 0,
|
||||
called: 0,
|
||||
responded: 0,
|
||||
notResponded: 0,
|
||||
urged: 18,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
warningLevel: "红色预警",
|
||||
levelClass: "level-red",
|
||||
region: "万盛区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactPoints: 0,
|
||||
called: 0,
|
||||
responded: 0,
|
||||
notResponded: 0,
|
||||
urged: 15,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
warningLevel: "黄色预警",
|
||||
levelClass: "level-yellow",
|
||||
region: "长寿区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactPoints: 0,
|
||||
called: 0,
|
||||
responded: 0,
|
||||
notResponded: 0,
|
||||
urged: 20,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
warningLevel: "红色预警",
|
||||
levelClass: "level-red",
|
||||
region: "城口区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactPoints: 0,
|
||||
called: 0,
|
||||
responded: 0,
|
||||
notResponded: 0,
|
||||
urged: 15,
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 4;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 点击已叫应
|
||||
const handleCalledClick = () => {
|
||||
emit("responseStatus");
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleSearch = () => {
|
||||
console.log("查询条件:", filterForm.value);
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.warning-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.warning-dialog {
|
||||
width: 1100px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
.filter-select {
|
||||
width: 140px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 0 20px;
|
||||
height: 32px;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 280px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 12px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
&.clickable-cell {
|
||||
cursor: pointer;
|
||||
color: #40a9ff;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.warning-level {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.level-red {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
|
||||
&.level-orange {
|
||||
background-color: rgba(255, 122, 69, 0.2);
|
||||
color: #ff7a45;
|
||||
border: 1px solid rgba(255, 122, 69, 0.4);
|
||||
}
|
||||
|
||||
&.level-yellow {
|
||||
background-color: rgba(250, 219, 95, 0.2);
|
||||
color: #fadb5f;
|
||||
border: 1px solid rgba(250, 219, 95, 0.4);
|
||||
}
|
||||
|
||||
&.level-blue {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
color: #40a9ff;
|
||||
border: 1px solid rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
.total {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.page-btns {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
min-width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled):not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// 下拉菜单样式
|
||||
:deep(.el-select-dropdown) {
|
||||
background-color: rgba(20, 50, 90, 0.98);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
|
||||
.el-select-dropdown__item {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(64, 169, 255, 0.3);
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,557 +0,0 @@
|
||||
<template>
|
||||
<div v-if="visible" class="warning-dialog-overlay" @click="handleOverlayClick">
|
||||
<div class="warning-dialog" @click.stop>
|
||||
<!-- 标题栏 -->
|
||||
<div class="dialog-header">
|
||||
<div class="header-title">预警情况</div>
|
||||
<div class="close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">预警等级</span>
|
||||
<el-select v-model="filterForm.warningLevel" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in warningLevelOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">行政区域</span>
|
||||
<el-select v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in regionOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">是否结束</span>
|
||||
<el-select v-model="filterForm.isEnded" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-option
|
||||
v-for="item in isEndedOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<div class="table-header">
|
||||
<div class="th" style="width: 50px">序号</div>
|
||||
<div class="th" style="width: 100px">预警等级</div>
|
||||
<div class="th" style="width: 100px">气象类型</div>
|
||||
<div class="th" style="width: 100px">行政区域</div>
|
||||
<div class="th" style="width: 160px">预警时间</div>
|
||||
<div class="th" style="width: 160px">结束时间</div>
|
||||
<div class="th" style="flex: 1">影响点数量</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td" style="width: 50px">{{ item.id }}</div>
|
||||
<div class="td" style="width: 100px">
|
||||
<span :class="['warning-level-tag', getWarningClass(item.warningLevel)]">{{ item.warningLevel }}</span>
|
||||
</div>
|
||||
<div class="td" style="width: 100px">{{ item.weatherType }}</div>
|
||||
<div class="td" style="width: 100px">{{ item.region }}</div>
|
||||
<div class="td" style="width: 160px">{{ item.warningTime }}</div>
|
||||
<div class="td" style="width: 160px">{{ item.endTime }}</div>
|
||||
<div class="td" style="flex: 1">
|
||||
<span class="impact-count" @click="handleImpactClick(item)">{{ item.impactCount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
|
||||
上一个
|
||||
</div>
|
||||
<div class="page-numbers">
|
||||
<div
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-num"
|
||||
:class="{ active: currentPage === page }"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
{{ page }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
|
||||
下一个
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "impactClick"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
warningLevel: "",
|
||||
region: "",
|
||||
isEnded: "",
|
||||
});
|
||||
|
||||
// 预警等级选项
|
||||
const warningLevelOptions = ref([
|
||||
{ label: "红色预警", value: "红色预警" },
|
||||
{ label: "橙色预警", value: "橙色预警" },
|
||||
{ label: "黄色预警", value: "黄色预警" },
|
||||
{ label: "蓝色预警", value: "蓝色预警" },
|
||||
]);
|
||||
|
||||
// 行政区域选项
|
||||
const regionOptions = ref([
|
||||
{ label: "重庆市", value: "重庆市" },
|
||||
{ label: "万州区", value: "万州区" },
|
||||
{ label: "沙坪坝区", value: "沙坪坝区" },
|
||||
{ label: "渝中区", value: "渝中区" },
|
||||
]);
|
||||
|
||||
// 是否结束选项
|
||||
const isEndedOptions = ref([
|
||||
{ label: "是", value: "是" },
|
||||
{ label: "否", value: "否" },
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
warningLevel: "红色预警",
|
||||
weatherType: "暴雨",
|
||||
region: "重庆市",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactCount: 0,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
warningLevel: "橙色预警",
|
||||
weatherType: "暴雨",
|
||||
region: "万州区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactCount: 1,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
warningLevel: "黄色预警",
|
||||
weatherType: "大风",
|
||||
region: "沙坪坝区",
|
||||
warningTime: "2025-08-10 16:20:15",
|
||||
endTime: "2025-08-10 20:30:00",
|
||||
impactCount: 3,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
warningLevel: "蓝色预警",
|
||||
weatherType: "雷电",
|
||||
region: "渝中区",
|
||||
warningTime: "2025-08-09 09:15:30",
|
||||
endTime: "2025-08-09 12:00:00",
|
||||
impactCount: 2,
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = [];
|
||||
const maxVisible = 5;
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1);
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1);
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 获取预警等级样式类
|
||||
const getWarningClass = (level) => {
|
||||
const classMap = {
|
||||
"红色预警": "warning-red",
|
||||
"橙色预警": "warning-orange",
|
||||
"黄色预警": "warning-yellow",
|
||||
"蓝色预警": "warning-blue",
|
||||
};
|
||||
return classMap[level] || "";
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit("update:visible", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 点击遮罩关闭
|
||||
const handleOverlayClick = () => {
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 点击影响点数量
|
||||
const handleImpactClick = (item) => {
|
||||
emit("impactClick", item);
|
||||
};
|
||||
|
||||
// 分页操作
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++;
|
||||
fetchData();
|
||||
}
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
currentPage.value = page;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.warning-dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.warning-dialog {
|
||||
width: 950px;
|
||||
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
padding: 8px 40px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
|
||||
border-bottom: 2px solid #40a9ff;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-section {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.filter-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
width: 120px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
background-color: rgba(30, 70, 120, 0.4);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
.el-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域
|
||||
.table-section {
|
||||
background-color: rgba(30, 70, 120, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
padding: 12px 16px;
|
||||
|
||||
.th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background-color: rgba(30, 70, 120, 0.2);
|
||||
}
|
||||
|
||||
.td {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-align: center;
|
||||
|
||||
// 预警等级标签
|
||||
.warning-level-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.warning-red {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
|
||||
&.warning-orange {
|
||||
background-color: rgba(255, 122, 0, 0.2);
|
||||
color: #ff7a00;
|
||||
border: 1px solid rgba(255, 122, 0, 0.4);
|
||||
}
|
||||
|
||||
&.warning-yellow {
|
||||
background-color: rgba(250, 219, 20, 0.2);
|
||||
color: #fadb14;
|
||||
border: 1px solid rgba(250, 219, 20, 0.4);
|
||||
}
|
||||
|
||||
&.warning-blue {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
color: #40a9ff;
|
||||
border: 1px solid rgba(64, 169, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
// 影响点数量
|
||||
.impact-count {
|
||||
color: #ff4d4f;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #ff7875;
|
||||
text-shadow: 0 0 8px rgba(255, 77, 79, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.disabled) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.page-num {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(.active) {
|
||||
background-color: rgba(64, 169, 255, 0.2);
|
||||
border-color: rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
.table-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.table-body::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
|
||||
}
|
||||
</style>
|
||||
@ -1,320 +1,37 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="top_title">
|
||||
<img
|
||||
class="title_bg"
|
||||
src="../../assets/RiskWarning_img/一级标题栏bg@2x.png"
|
||||
alt=""
|
||||
/>
|
||||
<div class="title_img_box">
|
||||
<img class="title_img1" src="../../assets/RiskWarning_img/位图@2x.png" alt="" />
|
||||
<img
|
||||
class="title_img2"
|
||||
src="../../assets/RiskWarning_img/渝路畅行-风险预警一键响应@2x.png"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 四个角的装饰 -->
|
||||
<div class="corner corner-top-left"></div>
|
||||
<div class="corner corner-top-right"></div>
|
||||
<div class="corner corner-bottom-left"></div>
|
||||
<div class="corner corner-bottom-right"></div>
|
||||
<!-- 中心数据展示卡片 -->
|
||||
<div class="center-info-card-container">
|
||||
<div
|
||||
class="center-info-card"
|
||||
@click="openDialog('tongnanResponsible')"
|
||||
v-if="showCenterCard.type === 'first'"
|
||||
>
|
||||
<div class="card-title">潼南</div>
|
||||
<div class="card-content">
|
||||
<div class="info-item clickable">
|
||||
<span class="info-label">人数</span>
|
||||
<span class="info-value">{{ showCenterCard.value }}</span>
|
||||
<span class="info-unit">人</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">项目</span>
|
||||
<span class="info-value">2</span>
|
||||
<span class="info-unit">处</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="center-info-card"
|
||||
v-if="showCenterCard.type === 'second' || showCenterCard.type === 'third'"
|
||||
>
|
||||
<div
|
||||
class="card-title"
|
||||
@click="
|
||||
showCenterCard.type === 'second'
|
||||
? openDialog('tongnanTeam')
|
||||
: showCenterCard.type === 'third'
|
||||
? openDialog('responseSituation')
|
||||
: ''
|
||||
"
|
||||
>
|
||||
潼南
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="info-item">
|
||||
<span class="info-label">人数</span>
|
||||
<span class="info-value">{{ showCenterCard.value }}</span>
|
||||
<span class="info-unit">人</span>
|
||||
</div>
|
||||
<div class="info-item clickable">
|
||||
<span class="info-label">路段</span>
|
||||
<span class="info-value">117</span>
|
||||
<span class="info-unit">条</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="left">
|
||||
<left
|
||||
@openWarningInfo="openDialog('warningInfo')"
|
||||
@openImpactPoint="openDialog('impactPoint')"
|
||||
@openWarningSituation="openDialog('warningSituation')"
|
||||
@openResponseStatus="openDialog('responseStatus')"
|
||||
@openDispatchDistrict="openDialog('dispatchDistrict')"
|
||||
@showCenterCard="(item) => (showCenterCard = item)"
|
||||
></left>
|
||||
<left></left>
|
||||
</div>
|
||||
<div class="right">
|
||||
<right
|
||||
@openClearanceSituation="openDialog('clearanceSituation')"
|
||||
@openControlSituation="openDialog('controlSituation')"
|
||||
></right>
|
||||
<right></right>
|
||||
</div>
|
||||
<!-- 地图中心 -->
|
||||
<div class="center">
|
||||
<!-- <MapCenter /> -->
|
||||
<MapCenter />
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<bottom></bottom>
|
||||
</div>
|
||||
<top class="top" @openAIResult="openDialog('aiWarningResult')"></top>
|
||||
|
||||
<!-- 响应情况对话框 -->
|
||||
<responseSituationDiaLog
|
||||
v-model:visible="dialogVisible.responseSituation"
|
||||
@close="closeDialog('responseSituation')"
|
||||
/>
|
||||
|
||||
<!-- 预警信息对话框 -->
|
||||
<warningInfoDialog
|
||||
v-model:visible="dialogVisible.warningInfo"
|
||||
@close="closeDialog('warningInfo')"
|
||||
@responseStatus="openDialog('responseStatus')"
|
||||
/>
|
||||
|
||||
<!-- 事件详情对话框 -->
|
||||
<eventDetailDialog
|
||||
v-model:visible="dialogVisible.eventDetail"
|
||||
@close="closeDialog('eventDetail')"
|
||||
/>
|
||||
|
||||
<!-- 确认对话框 -->
|
||||
<confirmDialog
|
||||
v-model:visible="dialogVisible.confirm"
|
||||
:title="confirmConfig.title"
|
||||
:message="confirmConfig.message"
|
||||
:confirm-text="confirmConfig.confirmText"
|
||||
:cancel-text="confirmConfig.cancelText"
|
||||
@confirm="closeDialog('confirm')"
|
||||
@cancel="closeDialog('confirm')"
|
||||
/>
|
||||
|
||||
<!-- 风险点详情对话框 -->
|
||||
<riskPointDetailDialog
|
||||
v-model:visible="dialogVisible.riskPointDetail"
|
||||
@close="closeDialog('riskPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 影响点情况对话框 -->
|
||||
<impactPointDialog
|
||||
v-model:visible="dialogVisible.impactPoint"
|
||||
@close="closeDialog('impactPoint')"
|
||||
@detail="openDialog('impactPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 影响点详情对话框 -->
|
||||
<impactPointDetailDialog
|
||||
v-model:visible="dialogVisible.impactPointDetail"
|
||||
@close="closeDialog('impactPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 响应点详情对话框 -->
|
||||
<responsePointDetailDialog
|
||||
v-model:visible="dialogVisible.responsePointDetail"
|
||||
@close="closeDialog('responsePointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 响应点信息对话框 -->
|
||||
<responsePointInfoDialog
|
||||
v-model:visible="dialogVisible.responsePointInfo"
|
||||
@close="closeDialog('responsePointInfo')"
|
||||
/>
|
||||
|
||||
<!-- 响应状态对话框 -->
|
||||
<responseStatusDialog
|
||||
v-model:visible="dialogVisible.responseStatus"
|
||||
@close="closeDialog('responseStatus')"
|
||||
@detail="openDialog('impactPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- AI预警处理结果对话框 -->
|
||||
<aiWarningResultDialog
|
||||
v-model:visible="dialogVisible.aiWarningResult"
|
||||
@close="closeDialog('aiWarningResult')"
|
||||
/>
|
||||
|
||||
<!-- 潼南基本信息对话框 -->
|
||||
<tongnanInfoDialog
|
||||
v-model:visible="dialogVisible.tongnanInfo"
|
||||
@close="closeDialog('tongnanInfo')"
|
||||
@call="openDialog('confirm')"
|
||||
/>
|
||||
|
||||
<!-- 潼南建设项目责任人明细对话框 -->
|
||||
<tongnanResponsibleDialog
|
||||
v-model:visible="dialogVisible.tongnanResponsible"
|
||||
@close="closeDialog('tongnanResponsible')"
|
||||
@detail="openDialog('tongnanInfo')"
|
||||
/>
|
||||
|
||||
<!-- 抢通情况对话框 -->
|
||||
<clearanceSituationDialog
|
||||
v-model:visible="dialogVisible.clearanceSituation"
|
||||
@close="closeDialog('clearanceSituation')"
|
||||
@detail="openDialog('eventDetail')"
|
||||
/>
|
||||
|
||||
<!-- 管控情况对话框 -->
|
||||
<controlSituationDialog
|
||||
v-model:visible="dialogVisible.controlSituation"
|
||||
@close="closeDialog('controlSituation')"
|
||||
/>
|
||||
|
||||
<!-- 调度详情对话框 -->
|
||||
<dispatchDetailDialog
|
||||
v-model:visible="dialogVisible.dispatchDetail"
|
||||
@close="closeDialog('dispatchDetail')"
|
||||
/>
|
||||
|
||||
<!-- 调度区县情况对话框 -->
|
||||
<dispatchDistrictDialog
|
||||
v-model:visible="dialogVisible.dispatchDistrict"
|
||||
@close="closeDialog('dispatchDistrict')"
|
||||
@dispatchClick="openDialog('dispatchDetail')"
|
||||
/>
|
||||
|
||||
<!-- 潼南护路团队成员对话框 -->
|
||||
<tongnanTeamDialog
|
||||
v-model:visible="dialogVisible.tongnanTeam"
|
||||
@close="closeDialog('tongnanTeam')"
|
||||
@view="openDialog('tongnanInfo')"
|
||||
/>
|
||||
|
||||
<!-- 预警情况对话框 -->
|
||||
<warningSituationDialog
|
||||
v-model:visible="dialogVisible.warningSituation"
|
||||
@close="closeDialog('warningSituation')"
|
||||
@impactClick="openDialog('impactPoint')"
|
||||
/>
|
||||
<top class="top"></top>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import left from "./left.vue";
|
||||
import right from "./right.vue";
|
||||
import bottom from "./bottom.vue";
|
||||
import top from "./top.vue";
|
||||
import MapCenter from "../cockpit/components/MapCenter.vue";
|
||||
|
||||
// 引入所有弹窗组件
|
||||
import responseSituationDiaLog from "./component/responseSituationDiaLog.vue";
|
||||
import warningInfoDialog from "./component/warningInfoDialog.vue";
|
||||
import eventDetailDialog from "./component/eventDetailDialog.vue";
|
||||
import confirmDialog from "./component/confirmDialog.vue";
|
||||
import riskPointDetailDialog from "./component/riskPointDetailDialog.vue";
|
||||
import impactPointDialog from "./component/impactPointDialog.vue";
|
||||
import impactPointDetailDialog from "./component/impactPointDetailDialog.vue";
|
||||
import responsePointDetailDialog from "./component/responsePointDetailDialog.vue";
|
||||
import responsePointInfoDialog from "./component/responsePointInfoDialog.vue";
|
||||
import responseStatusDialog from "./component/responseStatusDialog.vue";
|
||||
import aiWarningResultDialog from "./component/aiWarningResultDialog.vue";
|
||||
import tongnanInfoDialog from "./component/tongnanInfoDialog.vue";
|
||||
import tongnanResponsibleDialog from "./component/tongnanResponsibleDialog.vue";
|
||||
import clearanceSituationDialog from "./component/clearanceSituationDialog.vue";
|
||||
import controlSituationDialog from "./component/controlSituationDialog.vue";
|
||||
import dispatchDetailDialog from "./component/dispatchDetailDialog.vue";
|
||||
import dispatchDistrictDialog from "./component/dispatchDistrictDialog.vue";
|
||||
import tongnanTeamDialog from "./component/tongnanTeamDialog.vue";
|
||||
import warningSituationDialog from "./component/warningSituationDialog.vue";
|
||||
|
||||
// 弹窗显示状态
|
||||
const dialogVisible = ref({
|
||||
responseSituation: false,
|
||||
warningInfo: false,
|
||||
eventDetail: false,
|
||||
confirm: false,
|
||||
riskPointDetail: false,
|
||||
impactPoint: false,
|
||||
impactPointDetail: false,
|
||||
responsePointDetail: false,
|
||||
responsePointInfo: false,
|
||||
responseStatus: false,
|
||||
aiWarningResult: false,
|
||||
tongnanInfo: false,
|
||||
tongnanResponsible: false,
|
||||
clearanceSituation: false,
|
||||
controlSituation: false,
|
||||
dispatchDetail: false,
|
||||
dispatchDistrict: false,
|
||||
tongnanTeam: false,
|
||||
warningSituation: false,
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (dialogName) => {
|
||||
dialogVisible.value[dialogName] = true;
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (dialogName) => {
|
||||
dialogVisible.value[dialogName] = false;
|
||||
};
|
||||
|
||||
// 确认对话框配置
|
||||
const confirmConfig = ref({
|
||||
title: "提示",
|
||||
message: "是否拨打电话?",
|
||||
confirmText: "确定",
|
||||
cancelText: "取消",
|
||||
});
|
||||
|
||||
// 打开确认对话框
|
||||
const openConfirm = (config) => {
|
||||
confirmConfig.value = { ...confirmConfig.value, ...config };
|
||||
dialogVisible.value.confirm = true;
|
||||
};
|
||||
|
||||
// 中心信息卡片显示状态
|
||||
const showCenterCard = ref(false);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 视频屏幕自适应 - 基于视口宽度动态调整
|
||||
// 基准宽度 1920px,使用 vw 单位实现自适应
|
||||
@function vw($px) {
|
||||
@return calc($px / 1920 * 100vw);
|
||||
}
|
||||
|
||||
.main {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@ -323,66 +40,26 @@ const showCenterCard = ref(false);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
.top_title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: vw(100);
|
||||
min-height: 70px;
|
||||
z-index: 100;
|
||||
|
||||
.title_bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.title_img_box {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: vw(10);
|
||||
}
|
||||
|
||||
.title_img1 {
|
||||
width: vw(40);
|
||||
height: vw(40);
|
||||
min-width: 28px;
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
.title_img2 {
|
||||
height: vw(40);
|
||||
min-height: 28px;
|
||||
}
|
||||
}
|
||||
.left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: vw(100);
|
||||
width: 25%;
|
||||
height: calc(100% - #{vw(100)});
|
||||
top: 0;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: vw(100);
|
||||
width: 25%;
|
||||
height: calc(100% - #{vw(100)});
|
||||
top: 0;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
bottom: 10px;
|
||||
left: 30%;
|
||||
width: 40%;
|
||||
height: 50%;
|
||||
@ -390,10 +67,10 @@ const showCenterCard = ref(false);
|
||||
|
||||
.top {
|
||||
position: absolute;
|
||||
top: vw(120);
|
||||
top: 10px;
|
||||
left: 30%;
|
||||
width: 40%;
|
||||
// height: 15%;
|
||||
height: 15%;
|
||||
// background-color: #15293B;
|
||||
}
|
||||
|
||||
@ -409,127 +86,42 @@ const showCenterCard = ref(false);
|
||||
// 四个角的装饰
|
||||
.corner {
|
||||
position: absolute;
|
||||
width: vw(30);
|
||||
height: vw(30);
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 2px solid #40a9ff;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
|
||||
&.corner-top-left {
|
||||
top: vw(110);
|
||||
left: vw(10);
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
|
||||
&.corner-top-right {
|
||||
top: vw(110);
|
||||
right: vw(10);
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
border-left: none;
|
||||
border-bottom: none;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
&.corner-bottom-left {
|
||||
bottom: vw(10);
|
||||
left: vw(10);
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
&.corner-bottom-right {
|
||||
bottom: 0;
|
||||
right: vw(10);
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
border-left: none;
|
||||
border-top: none;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.center-info-card-container {
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
left: 35%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: vw(250);
|
||||
min-width: 180px;
|
||||
z-index: 200;
|
||||
}
|
||||
// 中心数据展示卡片
|
||||
.center-info-card {
|
||||
background: rgba(64, 169, 255, 0.2);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
z-index: 50;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
margin-bottom: vw(10);
|
||||
|
||||
// &:hover {
|
||||
// border-color: rgba(64, 169, 255, 0.6);
|
||||
// box-shadow: 0 6px 30px rgba(64, 169, 255, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
// transform: translate(-50%, -52%);
|
||||
// }
|
||||
|
||||
.card-title {
|
||||
font-size: vw(16);
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: vw(12);
|
||||
background: rgba(64, 169, 255, 0.8);
|
||||
padding: vw(16) vw(20);
|
||||
border-bottom: 1px solid rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 0 vw(20) vw(16) vw(20);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: vw(4);
|
||||
|
||||
.info-label {
|
||||
font-size: vw(13);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: vw(24);
|
||||
font-weight: 700;
|
||||
color: #40a9ff;
|
||||
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
.info-unit {
|
||||
font-size: vw(12);
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
.info-value {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 15px rgba(105, 192, 255, 0.8);
|
||||
}
|
||||
|
||||
.info-label,
|
||||
.info-unit {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
:key="index"
|
||||
class="warning-card"
|
||||
:class="item.class"
|
||||
@click="handleWarningCardClick(item)"
|
||||
>
|
||||
<img
|
||||
class="card-icon"
|
||||
@ -31,9 +30,7 @@
|
||||
<div class="impact-section">
|
||||
<div class="impact-header">
|
||||
<div class="impact-title">影响点概况</div>
|
||||
<div class="impact-detail clickable" @click="handleImpactDetailClick">
|
||||
影响点明细
|
||||
</div>
|
||||
<div class="impact-detail">影响点明细</div>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<div class="chart-y-label">数量</div>
|
||||
@ -90,18 +87,7 @@
|
||||
|
||||
<!-- 6个统计项 -->
|
||||
<div class="stats-grid">
|
||||
<div
|
||||
v-for="(item, index) in responseStats"
|
||||
:key="index"
|
||||
class="stat-item"
|
||||
:class="{
|
||||
clickable:
|
||||
item.label === '叫应总数' ||
|
||||
item.label === '已回应数' ||
|
||||
item.label === '调度区县数',
|
||||
}"
|
||||
@click="handleStatClick(item)"
|
||||
>
|
||||
<div v-for="(item, index) in responseStats" :key="index" class="stat-item">
|
||||
<!-- <div class="stat-icon" :class="item.iconClass"></div> -->
|
||||
<img class="stat-icon" :src="item.img" alt="" />
|
||||
<div class="stat-info">
|
||||
@ -113,18 +99,7 @@
|
||||
|
||||
<!-- 3个调度清单卡片 -->
|
||||
<div class="dispatch-cards">
|
||||
<div
|
||||
v-for="(item, index) in dispatchList"
|
||||
:key="index"
|
||||
class="dispatch-card"
|
||||
:class="{
|
||||
clickable:
|
||||
item.label === '国省道调度清单' ||
|
||||
item.label === '农村公路调度清单' ||
|
||||
item.label === '建设工程调度清单',
|
||||
}"
|
||||
@click="handleDispatchCardClick(item)"
|
||||
>
|
||||
<div v-for="(item, index) in dispatchList" :key="index" class="dispatch-card">
|
||||
<div class="card-num">{{ item.value }}<span class="unit">人</span></div>
|
||||
<div class="card-label">{{ item.label }}</div>
|
||||
</div>
|
||||
@ -138,57 +113,6 @@ import { ref } from "vue";
|
||||
|
||||
import SectionHeader from "./component/sectionHeader.vue";
|
||||
|
||||
const emit = defineEmits([
|
||||
"openWarningInfo",
|
||||
"openImpactPoint",
|
||||
"openWarningSituation",
|
||||
"openResponseStatus",
|
||||
"openDispatchDistrict",
|
||||
"openImpactDetail",
|
||||
"showCenterCard",
|
||||
]);
|
||||
|
||||
// 点击统计项
|
||||
const handleStatClick = (item) => {
|
||||
if (item.label === "叫应总数") {
|
||||
emit("openWarningInfo");
|
||||
} else if (item.label === "已回应数") {
|
||||
emit("openResponseStatus");
|
||||
} else if (item.label === "调度区县数") {
|
||||
emit("openDispatchDistrict");
|
||||
}
|
||||
};
|
||||
|
||||
// 点击气象预警卡片
|
||||
const handleWarningCardClick = (item) => {
|
||||
emit("openWarningSituation", item);
|
||||
};
|
||||
|
||||
// 点击影响点明细
|
||||
const handleImpactDetailClick = () => {
|
||||
emit("openImpactDetail");
|
||||
};
|
||||
|
||||
// 点击调度清单卡片
|
||||
const handleDispatchCardClick = (item) => {
|
||||
if (item.label === "建设工程调度清单") {
|
||||
emit("showCenterCard", {
|
||||
type: "first",
|
||||
value: item.value,
|
||||
});
|
||||
} else if (item.label === "国省道调度清单") {
|
||||
emit("showCenterCard", {
|
||||
type: "second",
|
||||
value: item.value,
|
||||
});
|
||||
} else if (item.label === "农村公路调度清单") {
|
||||
emit("showCenterCard", {
|
||||
type: "third",
|
||||
value: item.value,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 导入图片资源
|
||||
import imgCall from "../../assets/RiskWarning_img/回应icon@2x.png";
|
||||
import imgReply from "../../assets/RiskWarning_img/已回应icon@2x.png";
|
||||
@ -229,11 +153,9 @@ const getBarHeight = (value) => {
|
||||
|
||||
// 区县数据
|
||||
const districtData = [
|
||||
{ name: "江北区", road: 1, bridge: 1, tunnel: 1, slope: 8, project: 11 },
|
||||
{ name: "江北区", road: 1, bridge: 1, tunnel: 1, slope: 8, project: 11 },
|
||||
{ name: "南岸区", road: 1, bridge: 2, tunnel: 2, slope: 6, project: 12 },
|
||||
{ name: "九龙坡区", road: 2, bridge: 1, tunnel: 1, slope: 9, project: 9 },
|
||||
{ name: "九龙坡区", road: 2, bridge: 1, tunnel: 1, slope: 9, project: 9 },
|
||||
{ name: "万州区", road: 1, bridge: 2, tunnel: 2, slope: 11, project: 7 },
|
||||
];
|
||||
|
||||
@ -305,16 +227,10 @@ const cellStyle = () => ({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 视频屏幕自适应 - 基于视口宽度动态调整
|
||||
// 基准宽度 1920px,使用 vw 单位实现自适应
|
||||
@function vw($px) {
|
||||
@return calc($px / 1920 * 100vw);
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: vw(20);
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
@ -324,22 +240,12 @@ const cellStyle = () => ({
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 小屏幕适配
|
||||
@media (max-width: 1366px) {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
height: vw(50);
|
||||
min-height: 40px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: vw(20);
|
||||
margin-bottom: 20px;
|
||||
background-image: url("../../assets/RiskWarning_img/标题bg@2x.png");
|
||||
background-size: cover;
|
||||
background-position: left;
|
||||
@ -347,17 +253,15 @@ const cellStyle = () => ({
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(8);
|
||||
margin-left: vw(35);
|
||||
gap: 8px;
|
||||
margin-left: 35px;
|
||||
color: #fff;
|
||||
font-size: vw(24);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
|
||||
.icon-back {
|
||||
width: vw(20);
|
||||
height: vw(20);
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
@ -367,44 +271,44 @@ const cellStyle = () => ({
|
||||
&::before {
|
||||
content: "←";
|
||||
color: #fff;
|
||||
font-size: vw(12);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: vw(16);
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.header-date {
|
||||
font-size: vw(11);
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
// 气象预警
|
||||
.weather-warning-section {
|
||||
margin-bottom: vw(20);
|
||||
margin-bottom: 20px;
|
||||
|
||||
.section-title {
|
||||
font-size: vw(16);
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: vw(12);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.warning-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: vw(10);
|
||||
gap: 10px;
|
||||
display: flex;
|
||||
|
||||
.warning-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(10);
|
||||
gap: 10px;
|
||||
flex: 1;
|
||||
// padding: 12px;
|
||||
background: rgba(64, 169, 255, 0.1);
|
||||
@ -413,12 +317,12 @@ const cellStyle = () => ({
|
||||
|
||||
.card-icon {
|
||||
width: 100%;
|
||||
max-width: vw(35);
|
||||
max-width: 40px;
|
||||
height: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: vw(24);
|
||||
font-size: 28px;
|
||||
|
||||
// &::before {
|
||||
// content: "⛈️";
|
||||
@ -428,13 +332,13 @@ const cellStyle = () => ({
|
||||
.card-info {
|
||||
flex: 1;
|
||||
.card-num {
|
||||
font-size: vw(24);
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
@ -457,47 +361,37 @@ const cellStyle = () => ({
|
||||
|
||||
// 影响点概况
|
||||
.impact-section {
|
||||
margin-bottom: vw(40);
|
||||
margin-bottom: 40px;
|
||||
|
||||
.impact-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: vw(20);
|
||||
margin-bottom: 20px;
|
||||
|
||||
.impact-title {
|
||||
font-size: vw(16);
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.impact-detail {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
|
||||
&.clickable {
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
position: relative;
|
||||
height: vw(120);
|
||||
min-height: 80px;
|
||||
height: 120px;
|
||||
display: flex;
|
||||
// padding: 10px 0 30px 40px;
|
||||
|
||||
.chart-y-label {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: vw(-10);
|
||||
font-size: vw(11);
|
||||
top: -10px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
@ -531,7 +425,7 @@ const cellStyle = () => ({
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
padding: vw(5) 0;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
@ -557,16 +451,15 @@ const cellStyle = () => ({
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: vw(5);
|
||||
margin-bottom: 5px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.bar {
|
||||
width: vw(30);
|
||||
min-width: 16px;
|
||||
width: 30px;
|
||||
background: linear-gradient(180deg, #40a9ff 0%, rgba(64, 169, 255, 0.3) 100%);
|
||||
border-radius: 2px 2px 0 0;
|
||||
min-height: 20px;
|
||||
@ -574,8 +467,8 @@ const cellStyle = () => ({
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
bottom: vw(-20);
|
||||
font-size: vw(10);
|
||||
bottom: -20px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
transition: all 0.3s ease;
|
||||
position: absolute;
|
||||
@ -585,9 +478,9 @@ const cellStyle = () => ({
|
||||
|
||||
.chart-x-label {
|
||||
position: absolute;
|
||||
right: vw(-15);
|
||||
right: -15px;
|
||||
bottom: 0;
|
||||
font-size: vw(10);
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
@ -637,14 +530,21 @@ const cellStyle = () => ({
|
||||
|
||||
// 响应调度
|
||||
.response-section {
|
||||
padding: vw(15);
|
||||
margin-top: vw(20);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(21, 41, 59, 0.95) 0%,
|
||||
rgba(13, 28, 42, 0.95) 100%
|
||||
);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-top: 20px;
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: vw(15);
|
||||
margin-bottom: 15px;
|
||||
background-image: url("../../assets/RiskWarning_img/标题bg@2x.png") no-repeat;
|
||||
background-size: cover;
|
||||
background-position: left;
|
||||
@ -652,13 +552,11 @@ const cellStyle = () => ({
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(8);
|
||||
gap: 8px;
|
||||
|
||||
.icon-back {
|
||||
width: vw(20);
|
||||
height: vw(20);
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
@ -668,12 +566,12 @@ const cellStyle = () => ({
|
||||
&::before {
|
||||
content: "←";
|
||||
color: #fff;
|
||||
font-size: vw(12);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
@ -682,12 +580,12 @@ const cellStyle = () => ({
|
||||
.header-filters {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(6);
|
||||
font-size: vw(10);
|
||||
gap: 6px;
|
||||
font-size: 11px;
|
||||
|
||||
.filter-item {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
padding: vw(3) vw(8);
|
||||
padding: 3px 8px;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
@ -709,25 +607,25 @@ const cellStyle = () => ({
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: vw(10);
|
||||
margin-bottom: vw(15);
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(8);
|
||||
padding: vw(10);
|
||||
gap: 8px;
|
||||
padding: 10px;
|
||||
background: rgba(64, 169, 255, 0.08);
|
||||
border-radius: 6px;
|
||||
|
||||
.stat-icon {
|
||||
width: 100%;
|
||||
max-width: vw(40);
|
||||
max-width: 45px;
|
||||
height: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: vw(18);
|
||||
font-size: 20px;
|
||||
|
||||
&.icon-call::before {
|
||||
content: "💬";
|
||||
@ -751,32 +649,17 @@ const cellStyle = () => ({
|
||||
|
||||
.stat-info {
|
||||
.stat-num {
|
||||
font-size: vw(24);
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(64, 169, 255, 0.2);
|
||||
transform: translateY(-2px);
|
||||
|
||||
.stat-num {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 10px rgba(105, 192, 255, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,38 +667,23 @@ const cellStyle = () => ({
|
||||
.dispatch-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: vw(10);
|
||||
gap: 10px;
|
||||
|
||||
.dispatch-card {
|
||||
padding: vw(12);
|
||||
padding: 12px;
|
||||
background: rgba(64, 169, 255, 0.1);
|
||||
border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
border-radius: 6px;
|
||||
text-align: center;
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(64, 169, 255, 0.2);
|
||||
transform: translateY(-2px);
|
||||
|
||||
.card-num {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 10px rgba(105, 192, 255, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-num {
|
||||
font-size: vw(20);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
margin-bottom: vw(6);
|
||||
margin-bottom: 6px;
|
||||
|
||||
.unit {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: normal;
|
||||
margin-left: 2px;
|
||||
@ -823,7 +691,7 @@ const cellStyle = () => ({
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-size: vw(10);
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
@ -833,8 +701,7 @@ const cellStyle = () => ({
|
||||
|
||||
.date-range-wrapper {
|
||||
:deep(.el-date-editor) {
|
||||
width: vw(200);
|
||||
min-width: 140px;
|
||||
width: 200px;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
|
||||
@ -21,13 +21,7 @@
|
||||
<div class="control-section">
|
||||
<div class="control-title">管控路段数 <span class="control-num">2</span></div>
|
||||
<div class="control-grid">
|
||||
<div
|
||||
v-for="(item, index) in controlData"
|
||||
:key="index"
|
||||
class="control-item"
|
||||
:class="{ clickable: item.label === '全幅封闭数' || item.label === '关闭驻地数' }"
|
||||
@click="handleControlClick(item)"
|
||||
>
|
||||
<div v-for="(item, index) in controlData" :key="index" class="control-item">
|
||||
<div class="control-value">{{ item.value }}</div>
|
||||
<div class="control-label">{{ item.label }}</div>
|
||||
</div>
|
||||
@ -89,7 +83,7 @@
|
||||
</SectionHeader>
|
||||
|
||||
<!-- 阻断情况 -->
|
||||
<div class="block-section clickable" @click="handleBlockClick">
|
||||
<div class="block-section">
|
||||
<div class="block-title">阻断情况(已抢通/阻断数)</div>
|
||||
<div class="block-grid">
|
||||
<div class="block-item">
|
||||
@ -153,22 +147,6 @@ import { ref, computed } from "vue";
|
||||
import SectionHeader from "./component/sectionHeader.vue";
|
||||
import { Calendar } from "@element-plus/icons-vue";
|
||||
|
||||
const emit = defineEmits(["openClearanceSituation", "openControlSituation"]);
|
||||
|
||||
// 点击管控项
|
||||
const handleControlClick = (item) => {
|
||||
if (item.label === "全幅封闭数") {
|
||||
emit("openClearanceSituation");
|
||||
} else if (item.label === "关闭驻地数") {
|
||||
emit("openControlSituation");
|
||||
}
|
||||
};
|
||||
|
||||
// 点击阻断情况
|
||||
const handleBlockClick = () => {
|
||||
emit("openClearanceSituation");
|
||||
};
|
||||
|
||||
import icon1 from "../../assets/RiskWarning_img/icon1@2x.png";
|
||||
import icon2 from "../../assets/RiskWarning_img/icon2@2x.png";
|
||||
import icon3 from "../../assets/RiskWarning_img/icon3@2x.png";
|
||||
@ -272,16 +250,10 @@ const majorEvent = "0";
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 视频屏幕自适应 - 基于视口宽度动态调整
|
||||
// 基准宽度 1920px,使用 vw 单位实现自适应
|
||||
@function vw($px) {
|
||||
@return calc($px / 1920 * 100vw);
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: vw(20);
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
@ -290,15 +262,6 @@ const majorEvent = "0";
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 小屏幕适配
|
||||
@media (max-width: 1366px) {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.prevention-section {
|
||||
@ -309,6 +272,7 @@ const majorEvent = "0";
|
||||
// );
|
||||
// border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
@ -316,18 +280,16 @@ const majorEvent = "0";
|
||||
justify-content: space-between;
|
||||
background-image: url("../../assets/RiskWarning_img/标题bg@2x.png");
|
||||
align-items: center;
|
||||
margin-bottom: vw(15);
|
||||
margin-bottom: 15px;
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(8);
|
||||
gap: 8px;
|
||||
|
||||
.icon-back {
|
||||
width: vw(20);
|
||||
height: vw(20);
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
@ -337,12 +299,12 @@ const majorEvent = "0";
|
||||
&::before {
|
||||
content: "←";
|
||||
color: #fff;
|
||||
font-size: vw(12);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: vw(16);
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
@ -353,14 +315,14 @@ const majorEvent = "0";
|
||||
.resource-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: vw(10);
|
||||
margin-bottom: vw(10);
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.resource-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(10);
|
||||
padding: vw(8) vw(12);
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
background: linear-gradient(270deg, rgba(18, 84, 97, 0) 0%, #204a55 100%);
|
||||
border: 2px solid transparent;
|
||||
border-image: linear-gradient(270deg, rgba(80, 201, 191, 0), rgba(39, 135, 153, 1)) 2
|
||||
@ -369,14 +331,12 @@ const majorEvent = "0";
|
||||
border-right: 0px;
|
||||
|
||||
.resource-icon {
|
||||
width: vw(32);
|
||||
height: vw(32);
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: vw(20);
|
||||
font-size: 22px;
|
||||
|
||||
&.icon-team::before {
|
||||
content: "👷";
|
||||
@ -399,18 +359,18 @@ const majorEvent = "0";
|
||||
align-items: center;
|
||||
.resource-label {
|
||||
width: 48%;
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: vw(4);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.resource-value {
|
||||
font-size: vw(18);
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
|
||||
.unit {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: normal;
|
||||
margin-left: 2px;
|
||||
@ -422,58 +382,44 @@ const majorEvent = "0";
|
||||
|
||||
// 管控路段
|
||||
.control-section {
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 15px;
|
||||
|
||||
.control-title {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 10px;
|
||||
|
||||
.control-num {
|
||||
font-size: vw(16);
|
||||
font-size: 18px;
|
||||
|
||||
color: #40a9ff;
|
||||
font-weight: bold;
|
||||
margin-left: vw(5);
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
background: rgba(64, 169, 255, 0.1);
|
||||
background: #182f4c;
|
||||
box-shadow: inset 0px 0px 8px 0px #379bff;
|
||||
gap: vw(8);
|
||||
gap: 8px;
|
||||
|
||||
.control-item {
|
||||
text-align: center;
|
||||
padding: vw(6) vw(5);
|
||||
padding: 10px 5px;
|
||||
// background: rgba(64, 169, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 169, 255, 0.15);
|
||||
|
||||
.control-value {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.control-value {
|
||||
font-size: vw(18);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
margin-bottom: vw(4);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.control-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
@ -482,21 +428,21 @@ const majorEvent = "0";
|
||||
|
||||
// 巡查公路里程
|
||||
.patrol-section {
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 15px;
|
||||
|
||||
.patrol-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(10);
|
||||
margin-bottom: vw(10);
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.patrol-title {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.patrol-mileage {
|
||||
font-size: vw(16);
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
}
|
||||
@ -505,11 +451,11 @@ const majorEvent = "0";
|
||||
.patrol-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: vw(8);
|
||||
gap: 8px;
|
||||
|
||||
.patrol-item {
|
||||
text-align: center;
|
||||
padding: vw(6) vw(5);
|
||||
padding: 10px 5px;
|
||||
// background: rgba(64, 169, 255, 0.1);
|
||||
// border-radius: 4px;
|
||||
background-image: url("../../assets/RiskWarning_img/路径62@2x (1).png");
|
||||
@ -517,16 +463,16 @@ const majorEvent = "0";
|
||||
background-position: right;
|
||||
|
||||
.patrol-value {
|
||||
font-size: vw(18);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
margin-bottom: vw(4);
|
||||
margin-bottom: 4px;
|
||||
text-align: left;
|
||||
margin-left: vw(5);
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.patrol-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
@ -536,21 +482,21 @@ const majorEvent = "0";
|
||||
// 抢险投入情况
|
||||
.rescue-section {
|
||||
.rescue-title {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.rescue-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: vw(10);
|
||||
gap: 10px;
|
||||
|
||||
.rescue-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(4);
|
||||
padding: vw(8) 0;
|
||||
gap: 4px;
|
||||
padding: 12px 0;
|
||||
// background: rgba(64, 169, 255, 0.1);
|
||||
// border: 1px solid rgba(64, 169, 255, 0.2);
|
||||
// border-radius: 6px;
|
||||
@ -559,15 +505,13 @@ const majorEvent = "0";
|
||||
background-position: right;
|
||||
|
||||
.rescue-icon {
|
||||
width: vw(36);
|
||||
height: vw(36);
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: vw(22);
|
||||
margin-left: vw(5);
|
||||
font-size: 24px;
|
||||
margin-left: 5px;
|
||||
|
||||
&.icon-rescue-person::before {
|
||||
content: "👷";
|
||||
@ -582,15 +526,15 @@ const majorEvent = "0";
|
||||
|
||||
.rescue-info {
|
||||
.rescue-value {
|
||||
font-size: vw(18);
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
margin-bottom: vw(4);
|
||||
margin-bottom: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.unit {
|
||||
font-size: vw(10);
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: normal;
|
||||
margin-left: 2px;
|
||||
@ -598,7 +542,7 @@ const majorEvent = "0";
|
||||
}
|
||||
|
||||
.rescue-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
@ -608,35 +552,30 @@ const majorEvent = "0";
|
||||
|
||||
// 受灾情况样式
|
||||
.disaster-section {
|
||||
margin-top: vw(15);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(21, 41, 59, 0.95) 0%,
|
||||
rgba(13, 28, 42, 0.95) 100%
|
||||
);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-top: 15px;
|
||||
|
||||
.block-section {
|
||||
margin-bottom: vw(10);
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
|
||||
.block-title {
|
||||
color: #69c0ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-bottom: 15px;
|
||||
|
||||
.block-title {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.block-grid {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
padding: 0 vw(20);
|
||||
padding: 0 20px;
|
||||
// display: grid;
|
||||
// grid-template-columns: repeat(5, 1fr);
|
||||
// gap: 10px;
|
||||
@ -646,7 +585,7 @@ const majorEvent = "0";
|
||||
|
||||
.divider-line {
|
||||
width: 2px;
|
||||
height: vw(40);
|
||||
height: 40px;
|
||||
margin: auto 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
@ -659,7 +598,7 @@ const majorEvent = "0";
|
||||
|
||||
.block-item {
|
||||
text-align: center;
|
||||
padding: vw(8);
|
||||
padding: 12px 8px;
|
||||
// background: rgba(64, 169, 255, 0.1);
|
||||
// border-radius: 6px;
|
||||
// background-image: url("../../assets/RiskWarning_img/路径62@2x (1).png");
|
||||
@ -667,9 +606,9 @@ const majorEvent = "0";
|
||||
// background-position: left;
|
||||
|
||||
.block-num {
|
||||
font-size: vw(18);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: vw(6);
|
||||
margin-bottom: 6px;
|
||||
|
||||
.current {
|
||||
color: #40a9ff;
|
||||
@ -686,20 +625,20 @@ const majorEvent = "0";
|
||||
}
|
||||
|
||||
.block-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
&.death-item {
|
||||
.death-num {
|
||||
font-size: vw(18);
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #40a9ff;
|
||||
margin-bottom: vw(6);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.death-label {
|
||||
font-size: vw(10);
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
@ -708,22 +647,22 @@ const majorEvent = "0";
|
||||
}
|
||||
|
||||
.damage-section {
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 15px;
|
||||
|
||||
.damage-title {
|
||||
font-size: vw(14);
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin-bottom: vw(10);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.damage-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: vw(10);
|
||||
gap: 10px;
|
||||
|
||||
.damage-item {
|
||||
text-align: center;
|
||||
padding: vw(8);
|
||||
padding: 12px 8px;
|
||||
// background: rgba(64, 169, 255, 0.1);
|
||||
// border-radius: 6px;
|
||||
background-image: url("../../assets/RiskWarning_img/路径62@2x.png");
|
||||
@ -731,19 +670,19 @@ const majorEvent = "0";
|
||||
background-position: left;
|
||||
|
||||
.damage-value {
|
||||
font-size: vw(18);
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin-bottom: vw(6);
|
||||
margin-bottom: 6px;
|
||||
|
||||
.unit {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.damage-label {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
@ -766,7 +705,7 @@ const majorEvent = "0";
|
||||
|
||||
.event-section {
|
||||
text-align: center;
|
||||
padding: vw(12);
|
||||
padding: 12px;
|
||||
// background: rgba(64, 169, 255, 0.1);
|
||||
// border-radius: 6px;
|
||||
background-image: url("../../assets/RiskWarning_img/编组5@2x.png");
|
||||
@ -774,12 +713,12 @@ const majorEvent = "0";
|
||||
background-position: left;
|
||||
|
||||
.event-title {
|
||||
font-size: vw(12);
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.event-num {
|
||||
font-size: vw(18);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
@ -788,12 +727,12 @@ const majorEvent = "0";
|
||||
.header-filters {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(6);
|
||||
font-size: vw(10);
|
||||
gap: 6px;
|
||||
font-size: 11px;
|
||||
|
||||
.filter-item {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
padding: vw(3) vw(8);
|
||||
padding: 3px 8px;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<img class="filter-icon-ai" src="../../assets/RiskWarning_img/AI1@2x.png" alt="" @click="handleAIClick" />
|
||||
<img class="filter-icon-ai" src="../../assets/RiskWarning_img/AI1@2x.png" alt="" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -23,51 +23,28 @@
|
||||
import { ref } from "vue";
|
||||
import { Calendar } from "@element-plus/icons-vue";
|
||||
|
||||
const emit = defineEmits(["openAIResult"]);
|
||||
|
||||
const dateRange = ref([]);
|
||||
|
||||
const handleAIClick = () => {
|
||||
emit("openAIResult");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 视频屏幕自适应 - 基于视口宽度动态调整
|
||||
// 基准宽度 1920px,使用 vw 单位实现自适应
|
||||
@function vw($px) {
|
||||
@return calc($px / 1920 * 100vw);
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
padding: vw(10);
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
// align-items: center;
|
||||
|
||||
// 小屏幕适配
|
||||
@media (max-width: 1366px) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: vw(20);
|
||||
min-height: 18px;
|
||||
gap: vw(8);
|
||||
font-size: vw(13);
|
||||
height: 20px;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
|
||||
.filter-item {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
padding: 0 vw(12);
|
||||
height: vw(24);
|
||||
min-height: 20px;
|
||||
padding: 0 12px;
|
||||
height: 24px;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
@ -90,8 +67,7 @@ const handleAIClick = () => {
|
||||
|
||||
.date-range-wrapper {
|
||||
:deep(.el-date-editor) {
|
||||
width: vw(200);
|
||||
min-width: 140px;
|
||||
width: 200px;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
@ -122,10 +98,8 @@ const handleAIClick = () => {
|
||||
}
|
||||
}
|
||||
.filter-icon-ai {
|
||||
width: vw(67);
|
||||
height: vw(67);
|
||||
min-width: 48px;
|
||||
min-height: 48px;
|
||||
width: 67px;
|
||||
height: 67px;
|
||||
cursor: pointer;
|
||||
}
|
||||
// 日期选择器下拉面板样式
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user