feat: 气象预警响应
This commit is contained in:
parent
285bc95b91
commit
7eef4cfd92
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="card-item">
|
<div class="card-item">
|
||||||
<slot name="header">
|
<slot name="header" v-if="title">
|
||||||
<div class="header" :style="{marginBottom: titleGap + 'px'}">
|
<div class="header" :style="{marginBottom: titleGap + 'px'}">
|
||||||
<div class="header-title">{{ title }}</div>
|
<div class="header-title">{{ title }}</div>
|
||||||
<div class="header-extra" v-if="$slots.headerExtra">
|
<div class="header-extra" v-if="$slots.headerExtra">
|
||||||
|
|||||||
@ -52,7 +52,7 @@ const eventTypeOptions = [
|
|||||||
|
|
||||||
// 返回上一页
|
// 返回上一页
|
||||||
const handleClickBack = () => {
|
const handleClickBack = () => {
|
||||||
router.replace('/disasterManagement')
|
router.go(-1)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<PageContainer title="气象预警" @click-back="handleClickBack">
|
<PageContainer title="气象预警" @click-back="handleClickBack">
|
||||||
<SearchInput v-model="searchValue" />
|
<SearchInput v-model="searchValue" @update:modelValue="handleSearch" />
|
||||||
|
|
||||||
<CurrentSite />
|
<CurrentSite />
|
||||||
|
|
||||||
<div class="list-panel">
|
<div class="list-panel">
|
||||||
<CardItem v-for="(item, index) in list" :key="index" :title="item.area" @click="handleClickItem(item)">
|
<CardItem
|
||||||
|
v-for="(item, index) in list"
|
||||||
|
:key="index"
|
||||||
|
:class="['card-item', item.status]"
|
||||||
|
:title="item.title"
|
||||||
|
@click="handleClickItem(item)"
|
||||||
|
>
|
||||||
<template #headerExtra>
|
<template #headerExtra>
|
||||||
<span class="red-ball"></span>
|
<span v-if="item.status === 'unread'" class="red-ball"></span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 发布时间 block -->
|
<!-- 发布时间 block -->
|
||||||
<div class="time-block">
|
<div class="time-block">
|
||||||
<div class="time-box">
|
<div class="time-box">
|
||||||
<span class="time-label-text">发布时间:</span>
|
<span class="time-label-text">发布时间:</span>
|
||||||
<span class="time-value-text">{{ item.publishTime }}</span>
|
<span class="time-value-text">{{ item.onset }}</span>
|
||||||
</div>
|
</div>
|
||||||
<van-icon class="jump-icon" name="arrow" />
|
<van-icon class="jump-icon" name="arrow" />
|
||||||
</div>
|
</div>
|
||||||
@ -27,67 +33,89 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch } from 'vue'
|
import { ref, onMounted } from 'vue';
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
import PageContainer from '@/components/PageContainer.vue'
|
import PageContainer from '@/components/PageContainer.vue';
|
||||||
import SearchInput from '@/components/SearchInput.vue'
|
import SearchInput from '@/components/SearchInput.vue';
|
||||||
import CurrentSite from '@/components/CurrentSite.vue'
|
import CurrentSite from '@/components/CurrentSite.vue';
|
||||||
import CardItem from '@/components/CardItem.vue'
|
import CardItem from '@/components/CardItem.vue';
|
||||||
import EmptyBox from '@/components/EmptyBox.vue'
|
import EmptyBox from '@/components/EmptyBox.vue';
|
||||||
|
import warningMessageMock from './mock.json';
|
||||||
|
import { request } from '@shared/utils/request';
|
||||||
|
import { showToast } from 'vant';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getData()
|
getData();
|
||||||
})
|
});
|
||||||
|
|
||||||
// 搜索关键词
|
// 搜索关键词
|
||||||
const searchValue = ref('')
|
const searchValue = ref('');
|
||||||
|
|
||||||
watch(
|
|
||||||
() => searchValue.value,
|
|
||||||
(newVal, oldVal) => {
|
|
||||||
if (newVal !== oldVal) {
|
|
||||||
getData(newVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleSearch = value => {
|
||||||
|
getData(value);
|
||||||
|
};
|
||||||
|
|
||||||
// 预警列表数据
|
// 预警列表数据
|
||||||
const list = ref([
|
const list = ref([]);
|
||||||
{
|
|
||||||
area: '合川区',
|
const getData = async (keyword = '') => {
|
||||||
level: '红色气象预警',
|
const normalizedKeyword = keyword.trim();
|
||||||
publishTime: '2026/01/10 20:29'
|
|
||||||
},
|
if (route.query.mock) {
|
||||||
{
|
list.value = warningMessageMock.filter(item => {
|
||||||
area: '万州区',
|
if (!normalizedKeyword) return true;
|
||||||
level: '红色气象预警',
|
return item.title.includes(normalizedKeyword);
|
||||||
publishTime: '2025/10/10 20:29'
|
});
|
||||||
},
|
return;
|
||||||
{
|
|
||||||
area: '涪陵区',
|
|
||||||
level: '红色气象预警',
|
|
||||||
publishTime: '2025/10/10 20:29'
|
|
||||||
}
|
}
|
||||||
])
|
|
||||||
|
|
||||||
const getData = async () => {
|
try {
|
||||||
|
const result = await request({
|
||||||
|
url: '/snow-ops-platform/weather-warning/notice',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
pageSize: 999,
|
||||||
|
keyword: normalizedKeyword,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
list.value = result.data.records;
|
||||||
|
} catch (_error) {
|
||||||
|
showToast('获取数据失败,请稍后重试');
|
||||||
|
list.value = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
const markNoticeRead = async id => {
|
||||||
|
await request({
|
||||||
|
url: `/snow-ops-platform/weather-warning/notice/${id}/_read`,
|
||||||
|
method: 'put',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleClickItem = (item) => {
|
const handleClickItem = async item => {
|
||||||
|
try {
|
||||||
|
await markNoticeRead(item.id);
|
||||||
|
item.status = 'read';
|
||||||
|
} catch (_error) {
|
||||||
|
showToast('更新已读状态失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
window.warningMessageDetail = item;
|
||||||
router.push({
|
router.push({
|
||||||
path: '/warningMessage-detail',
|
name: 'WarningMessageDetail',
|
||||||
|
query: {
|
||||||
})
|
id: item.id,
|
||||||
}
|
mock: route.query.mock,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleClickBack = () => {
|
const handleClickBack = () => {
|
||||||
router.push('/')
|
router.push('/');
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -98,10 +126,6 @@ const handleClickBack = () => {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-item {
|
|
||||||
padding-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==================== Block 层级 ==================== */
|
/* ==================== Block 层级 ==================== */
|
||||||
.time-block {
|
.time-block {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -126,9 +150,13 @@ const handleClickBack = () => {
|
|||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-item {
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.jump-icon {
|
.jump-icon {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgb(102, 102, 102, .4);
|
color: rgb(102, 102, 102, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-label-text {
|
.time-label-text {
|
||||||
|
|||||||
@ -4,92 +4,151 @@
|
|||||||
|
|
||||||
<PanelHeader title="气象预警" />
|
<PanelHeader title="气象预警" />
|
||||||
<div class="list-panel margin">
|
<div class="list-panel margin">
|
||||||
<CardItem class="card-item" v-for="(item, index) in list" :key="index" :title="item.area" titleGap="10">
|
<CardItem class="card-item" :title="detail?.title">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="time-block">
|
<div class="time-block">
|
||||||
<div class="time-box">
|
<div class="time-box">
|
||||||
<span class="time-label-text">发布时间:</span>
|
<span class="time-label-text">发布时间:</span>
|
||||||
<span class="time-value-text">{{ item.publishTime }}</span>
|
<span class="time-value-text">{{ detail?.onset }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="desc-block">
|
<div class="desc-block">
|
||||||
<div class="desc-text">{{ item.content }}</div>
|
<div class="desc-text">{{ detail?.warningContent }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<van-icon class="jump-icon" name="arrow" />
|
|
||||||
</template>
|
</template>
|
||||||
</CardItem>
|
</CardItem>
|
||||||
|
|
||||||
<!-- 空状态提示 -->
|
<!-- 空状态提示 -->
|
||||||
<EmptyBox v-if="list.length === 0" placeholder="暂无相关预警信息" />
|
<EmptyBox v-if="!detail?.warningContent" placeholder="暂无相关预警信息" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PanelHeader title="防御措施" />
|
<PanelHeader title="工作建议" />
|
||||||
<div class="list-panel">
|
<div class="list-panel margin">
|
||||||
<CardItem v-for="(item, index) in list" :key="index" :title="item.area">
|
<CardItem class="card-item">
|
||||||
<div class="method-block">
|
<template #content>{{ detail?.workSuggestion }}</template>
|
||||||
<div class="method-text">{{ item.method }}</div>
|
|
||||||
</div>
|
|
||||||
<van-icon class="jump-icon" name="arrow" />
|
|
||||||
</CardItem>
|
</CardItem>
|
||||||
|
|
||||||
<!-- 空状态提示 -->
|
<!-- 空状态提示 -->
|
||||||
<EmptyBox v-if="list.length === 0" placeholder="暂无相关防御措施" />
|
<EmptyBox v-if="!detail?.workSuggestion" placeholder="暂无相关防御措施" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<PanelHeader title="影响范围" />
|
||||||
|
<CardItem class="card-item impact-card">
|
||||||
|
<template #content>
|
||||||
|
<div class="impact-tab-block">
|
||||||
|
<div
|
||||||
|
class="impact-tab-item"
|
||||||
|
:class="{ active: activeImpactTab === item.value }"
|
||||||
|
v-for="item in impactTabs"
|
||||||
|
:key="item.value"
|
||||||
|
@click="activeImpactTab = item.value"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="impact-table" v-if="currentImpactList.length">
|
||||||
|
<div class="impact-table-header" :class="`cols-${currentImpactColumns.length}`">
|
||||||
|
<div class="impact-table-cell" v-for="column in currentImpactColumns" :key="column.key">
|
||||||
|
{{ column.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="impact-table-body">
|
||||||
|
<div class="impact-table-row" :class="`cols-${currentImpactColumns.length}`" v-for="(item, index) in currentImpactList" :key="index">
|
||||||
|
<div class="impact-table-cell" v-for="column in currentImpactColumns" :key="column.key">
|
||||||
|
{{ item[column.key] }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<EmptyBox v-else placeholder="暂无相关影响范围" />
|
||||||
|
</template>
|
||||||
|
</CardItem>
|
||||||
|
|
||||||
<div class="footer-panel">
|
<div class="footer-panel">
|
||||||
<van-button block type="primary" @click="handleClickBack()">我已知晓</van-button>
|
<!-- <van-button block type="primary" @click="handleClickBack()">我已知晓</van-button> -->
|
||||||
<van-button block type="primary" @click="goToHandle()">我要响应</van-button>
|
<van-button block type="primary" @click="goToHandle()">我要响应</van-button>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter } from 'vue-router';
|
||||||
import PageContainer from '@/components/PageContainer.vue'
|
import PageContainer from '@/components/PageContainer.vue';
|
||||||
import CurrentSite from '@/components/CurrentSite.vue'
|
import CurrentSite from '@/components/CurrentSite.vue';
|
||||||
import PanelHeader from '@/components/PanelHeader.vue'
|
import PanelHeader from '@/components/PanelHeader.vue';
|
||||||
import CardItem from '@/components/CardItem.vue'
|
import CardItem from '@/components/CardItem.vue';
|
||||||
import EmptyBox from '@/components/EmptyBox.vue'
|
import EmptyBox from '@/components/EmptyBox.vue';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter();
|
||||||
|
|
||||||
|
const detail = ref({
|
||||||
|
id: null,
|
||||||
|
status: '',
|
||||||
|
title: '',
|
||||||
|
onset: '',
|
||||||
|
warningContent: '',
|
||||||
|
workSuggestion: '',
|
||||||
|
affectedPoints: [],
|
||||||
|
affectedProjects: [],
|
||||||
|
});
|
||||||
|
const activeImpactTab = ref('point');
|
||||||
|
const impactTabs = [
|
||||||
|
{ label: '影响点', value: 'point' },
|
||||||
|
{ label: '影响项目', value: 'project' },
|
||||||
|
];
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getData()
|
getData();
|
||||||
})
|
});
|
||||||
|
|
||||||
// 列表数据
|
const impactColumnsMap = {
|
||||||
const list = ref([
|
point: [
|
||||||
{
|
{ label: '序号', key: 'index' },
|
||||||
area: '合川区',
|
{ label: '影响区域', key: 'affectedCounty' },
|
||||||
level: '红色气象预警',
|
{ label: '线路编号', key: 'roadCode' },
|
||||||
content: '今天,北京将进入大雪,请做好',
|
{ label: '类型', key: 'type' },
|
||||||
publishTime: '2026/01/10 20:29',
|
{ label: '桩号', key: 'station' },
|
||||||
method: '立即启动防汛Ⅰ级应急响应,立即转移危险区'
|
],
|
||||||
},
|
project: [
|
||||||
{
|
{ label: '序号', key: 'index' },
|
||||||
area: '万州区',
|
{ label: '影响区域', key: 'affectedCounty' },
|
||||||
level: '红色气象预警',
|
{ label: '项目名称', key: 'projectName' },
|
||||||
publishTime: '2025/10/10 20:29',
|
{ label: '驻地名称', key: 'siteName' },
|
||||||
method: '立即启动防汛Ⅰ级应急响应,立即转移危险区'
|
{ label: '线路编号', key: 'roadCode' },
|
||||||
},
|
],
|
||||||
{
|
};
|
||||||
area: '涪陵区',
|
|
||||||
level: '红色气象预警',
|
const currentImpactColumns = computed(() => impactColumnsMap[activeImpactTab.value] || []);
|
||||||
publishTime: '2025/10/10 20:29',
|
const impactListMap = computed(() => ({
|
||||||
method: '立即启动防汛Ⅰ级应急响应,立即转移危险区'
|
point: detail.value.affectedPoints,
|
||||||
|
project: detail.value.affectedProjects,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const currentImpactList = computed(() => {
|
||||||
|
return impactListMap.value[activeImpactTab.value].map((item, index) => ({
|
||||||
|
index: index + 1,
|
||||||
|
...item,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
if (!window.warningMessageDetail) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
])
|
|
||||||
|
|
||||||
const getData = async () => {}
|
detail.value = window.warningMessageDetail;
|
||||||
|
};
|
||||||
|
|
||||||
const handleClickBack = () => {
|
const handleClickBack = () => {
|
||||||
router.go(-1)
|
router.go(-1);
|
||||||
}
|
};
|
||||||
const goToHandle = () => {
|
const goToHandle = () => {
|
||||||
router.push({path: '/warningMessageHandle'})
|
router.push({ path: '/disasterReport' });
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -164,7 +223,7 @@ const goToHandle = () => {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #666666;
|
color: #666666;
|
||||||
line-height: 13px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
.method-text {
|
.method-text {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@ -172,4 +231,75 @@ const goToHandle = () => {
|
|||||||
color: #4a4a4a;
|
color: #4a4a4a;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.impact-card {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-tab-block {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-tab-item {
|
||||||
|
height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #4a4a4a;
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
& + .impact-tab-item {
|
||||||
|
border-left: 1px solid #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #ffffff;
|
||||||
|
background: linear-gradient(180deg, #2f79f6 0%, #1f66e0 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-table {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-table-header,
|
||||||
|
.impact-table-row {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cols-5 {
|
||||||
|
grid-template-columns: 52px 1fr 1fr 1fr 1.2fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-table-header {
|
||||||
|
background: linear-gradient(180deg, #e5e5e5 0%, #d8d8d8 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-table-row {
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
& + .impact-table-row {
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-table-cell {
|
||||||
|
min-height: 52px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px 6px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #4a4a4a;
|
||||||
|
line-height: 20px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
62
packages/mobile/src/views/WarningMessage/mock.json
Normal file
62
packages/mobile/src/views/WarningMessage/mock.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"status": "unread",
|
||||||
|
"title": "潼南区气象台发布暴雨蓝色预警[Ⅳ级/一般]",
|
||||||
|
"onset": "2026/01/10 20:29",
|
||||||
|
"warningContent": "区气象台发布暴雨红色预警,按照相关要求,启动I级防御响应,并请及时关注地质、水文等风险提示信息,落实主动封闭管控/“关停撤转”措施。",
|
||||||
|
"workSuggestion": "立即启动防汛Ⅰ级应急响应,立即转移危险区,加强沿线桥梁、隧道及在建项目巡查。",
|
||||||
|
"affectedPoints": [
|
||||||
|
{
|
||||||
|
"affectedCounty": "巫溪县",
|
||||||
|
"roadCode": "G242",
|
||||||
|
"type": "桥梁",
|
||||||
|
"station": "336.800-336.850"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"affectedCounty": "万州区",
|
||||||
|
"roadCode": "G242",
|
||||||
|
"type": "隧道",
|
||||||
|
"station": "336.800-336.850"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"affectedProjects": [
|
||||||
|
{
|
||||||
|
"affectedCounty": "巫溪县",
|
||||||
|
"projectName": "G242灾害防治工程",
|
||||||
|
"siteName": "巫溪驻地",
|
||||||
|
"roadCode": "G242"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"affectedCounty": "万州区",
|
||||||
|
"projectName": "G242改扩建工程",
|
||||||
|
"siteName": "万州驻地",
|
||||||
|
"roadCode": "G242"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"status": "read",
|
||||||
|
"title": "潼南区气象台发布暴雨蓝色预警[Ⅳ级/一般]",
|
||||||
|
"onset": "2026/01/09 07:10",
|
||||||
|
"warningContent": "预计未来12小时局地将出现能见度小于500米的大雾天气,请注意行车安全并做好道路巡查。",
|
||||||
|
"workSuggestion": "加强重点路段值守,及时发布诱导信息,视情采取限速、分流等措施。",
|
||||||
|
"affectedPoints": [
|
||||||
|
{
|
||||||
|
"affectedCounty": "涪陵区",
|
||||||
|
"roadCode": "S105",
|
||||||
|
"type": "高边坡",
|
||||||
|
"station": "K12+300-K13+100"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"affectedProjects": [
|
||||||
|
{
|
||||||
|
"affectedCounty": "涪陵区",
|
||||||
|
"projectName": "S105养护提升工程",
|
||||||
|
"siteName": "涪陵驻地",
|
||||||
|
"roadCode": "S105"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
Loading…
x
Reference in New Issue
Block a user