feat: 灾毁管理
This commit is contained in:
parent
6203cf9ab9
commit
210128041e
@ -17,7 +17,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['back'])
|
const emit = defineEmits(['click-back'])
|
||||||
|
|
||||||
const onClickLeft = () => {
|
const onClickLeft = () => {
|
||||||
emit('click-back')
|
emit('click-back')
|
||||||
|
|||||||
@ -105,6 +105,11 @@ const routes = [
|
|||||||
path: '/disasterReport',
|
path: '/disasterReport',
|
||||||
name: 'DisasterReport',
|
name: 'DisasterReport',
|
||||||
component: () => import('../views/DisasterManagement/DisasterReport.vue')
|
component: () => import('../views/DisasterManagement/DisasterReport.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/disasterDetail',
|
||||||
|
name: 'DisasterDetail',
|
||||||
|
component: () => import('../views/DisasterManagement/DisasterDetail.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
565
packages/mobile/src/views/DisasterManagement/DisasterDetail.vue
Normal file
565
packages/mobile/src/views/DisasterManagement/DisasterDetail.vue
Normal file
@ -0,0 +1,565 @@
|
|||||||
|
<template>
|
||||||
|
<PageContainer title="灾毁详情" @click-back="handleClickBack" class="page-container">
|
||||||
|
<!-- 当前站点信息 -->
|
||||||
|
<CurrentSite />
|
||||||
|
|
||||||
|
<!-- 基本信息 -->
|
||||||
|
<PanelItem title="基本信息">
|
||||||
|
<template #headerExtra>
|
||||||
|
<!-- 状态标签(需要从续报中判断是否已解除,或接口增加 eventStatus 字段) -->
|
||||||
|
<div class="status-wrapper">
|
||||||
|
<van-tag :type="getEventStatusType()" size="medium" plain>
|
||||||
|
{{ getEventStatusText() }}
|
||||||
|
</van-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 事件类型 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">事件类型:</span>
|
||||||
|
<span class="info-value">水毁事件</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 路况类别 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">路况类别:</span>
|
||||||
|
<span class="info-value">{{ detailData.roadConditionType || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 是否阻断 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">是否阻断:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.isBlocked ? '是' : '否' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 抢修进度 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">抢修进度:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.repairProgress || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 处理措施(从首报中获取) -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">处理措施:</span>
|
||||||
|
<span class="info-value">{{ formatDisposalMeasures(firstReport?.disposalMeasures) || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 水毁处数 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">水毁处数:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.damageCount || 0 }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 阻断里程 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">阻断里程:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.blockedMileage ? detailData.event.blockedMileage + '公里' : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 发生时间 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">发生时间:</span>
|
||||||
|
<span class="info-value">{{ detailData.occurTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 线路编号 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">线路编号:</span>
|
||||||
|
<span class="info-value">{{ detailData.routeNo || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 地点路线 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">地点路线:</span>
|
||||||
|
<span class="info-value">{{ detailData.occurLocation || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 起点桩号及经纬度 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">起点桩号:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.startStakeNo || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row sub-row">
|
||||||
|
<span class="info-label">起点桩经度:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.startStakeLng || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row sub-row">
|
||||||
|
<span class="info-label">起点桩纬度:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.startStakeLat || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 止点桩号及经纬度 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">止点桩号:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.endStakeNo || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row sub-row">
|
||||||
|
<span class="info-label">止点桩经度:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.endStakeLng || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row sub-row">
|
||||||
|
<span class="info-label">止点桩纬度:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.endStakeLat || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 路况位置(使用阻断点小地名或发生地点) -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">路况位置:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.blockedPointName || detailData.occurLocation || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 阻断点小地名 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">阻断点小地名:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.blockedPointName || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 上报区县 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">上报区县:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.district || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 巡查里程 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">巡查里程:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.inspectionMileage ? detailData.event.inspectionMileage + '公里' : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 是否恢复重建 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">是否恢复重建:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.needsRecovery ? '是' : '否' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 恢复重建预估费用 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">恢复重建预估费用:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.estimatedRecoveryCost ? detailData.event.estimatedRecoveryCost + '万元' : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 联系人 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">联系人:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.contactPerson || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 联系电话 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">联系电话:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.contactPhone || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 填报单位 -->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">填报单位:</span>
|
||||||
|
<span class="info-value">{{ detailData.event?.reporterUnit || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</PanelItem>
|
||||||
|
|
||||||
|
<!-- 填报信息 -->
|
||||||
|
<PanelItem title="填报信息">
|
||||||
|
<!-- 首报信息 -->
|
||||||
|
<div class="report-section" v-if="firstReport">
|
||||||
|
<div class="report-header">
|
||||||
|
<span class="report-title">首报</span>
|
||||||
|
<span class="report-meta">{{ firstReport.reporterName || '-' }} {{ firstReport.reportTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="report-content">
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">处置情况:</span>
|
||||||
|
<span class="info-value">{{ formatDisposalMeasures(firstReport.disposalMeasures) || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">塌方及损失:</span>
|
||||||
|
<span class="info-value">{{ getLossDescription(firstReport) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">路产损失:</span>
|
||||||
|
<span class="info-value">{{ firstReport.totalLossAmount ? firstReport.totalLossAmount + '万元' : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">有无车辆滞留:</span>
|
||||||
|
<span class="info-value">{{ getVehicleStrandedText(firstReport) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">滞留车辆:</span>
|
||||||
|
<span class="info-value">{{ firstReport.strandedVehicleCount || 0 }}辆</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">预计恢复时间:</span>
|
||||||
|
<span class="info-value">{{ firstReport.expectRecoverTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">实际恢复时间:</span>
|
||||||
|
<span class="info-value">{{ firstReport.actualRecoverTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">现场描述:</span>
|
||||||
|
<span class="info-value">{{ firstReport.siteDescription || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- 附件 -->
|
||||||
|
<div class="info-row" v-if="firstReport.fileList && firstReport.fileList.length > 0">
|
||||||
|
<span class="info-label">附件:</span>
|
||||||
|
<div class="attachment-list">
|
||||||
|
<div v-for="(file, index) in firstReport.fileList" :key="index" class="attachment-item">
|
||||||
|
<van-icon :name="file.fileType === 1 ? 'photo-o' : 'video-o'" />
|
||||||
|
<span class="file-name">{{ file.fileName }}</span>
|
||||||
|
<van-button size="mini" type="primary" plain @click="previewFile(file)">预览</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 续报列表 -->
|
||||||
|
<div v-for="(report, index) in continueReports" :key="index" class="report-section">
|
||||||
|
<div class="report-header">
|
||||||
|
<span class="report-title">续报{{ index + 1 }}</span>
|
||||||
|
<span class="report-meta">{{ report.reporterName || '-' }} {{ report.reportTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="report-content">
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">处置情况:</span>
|
||||||
|
<span class="info-value">{{ formatDisposalMeasures(report.disposalMeasures) || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">塌方及损失:</span>
|
||||||
|
<span class="info-value">{{ getLossDescription(report) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">路产损失:</span>
|
||||||
|
<span class="info-value">{{ report.totalLossAmount ? report.totalLossAmount + '万元' : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">有无车辆滞留:</span>
|
||||||
|
<span class="info-value">{{ getVehicleStrandedText(report) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">滞留车辆:</span>
|
||||||
|
<span class="info-value">{{ report.strandedVehicleCount || 0 }}辆</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">预计恢复时间:</span>
|
||||||
|
<span class="info-value">{{ report.expectRecoverTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">实际恢复时间:</span>
|
||||||
|
<span class="info-value">{{ report.actualRecoverTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">现场描述:</span>
|
||||||
|
<span class="info-value">{{ report.siteDescription || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- 附件 -->
|
||||||
|
<div class="info-row" v-if="report.fileList && report.fileList.length > 0">
|
||||||
|
<span class="info-label">附件:</span>
|
||||||
|
<div class="attachment-list">
|
||||||
|
<div v-for="(file, fileIndex) in report.fileList" :key="fileIndex" class="attachment-item">
|
||||||
|
<van-icon :name="file.fileType === 1 ? 'photo-o' : 'video-o'" />
|
||||||
|
<span class="file-name">{{ file.fileName }}</span>
|
||||||
|
<van-button size="mini" type="primary" plain @click="previewFile(file)">预览</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 无填报信息时显示 -->
|
||||||
|
<EmptyBox v-if="!hasReportData" placeholder="暂无填报信息" />
|
||||||
|
</PanelItem>
|
||||||
|
|
||||||
|
<!-- 底部按钮:未解除状态显示续报按钮 -->
|
||||||
|
<div class="footer-buttons" v-if="!isEventResolved">
|
||||||
|
<van-button type="primary" class="footer-btn" @click="handleContinueReport">续报</van-button>
|
||||||
|
</div>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, computed } from 'vue'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { showToast } from 'vant'
|
||||||
|
import PageContainer from '@/components/PageContainer.vue'
|
||||||
|
import PanelItem from '@/components/PanelItem.vue'
|
||||||
|
import CurrentSite from '@/components/CurrentSite.vue'
|
||||||
|
import EmptyBox from '@/components/EmptyBox.vue'
|
||||||
|
import { request } from '@shared/utils/request'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
// 详情数据(对应 Data 接口)
|
||||||
|
const detailData = ref({
|
||||||
|
event: null, // Event 对象
|
||||||
|
report: null, // Report 对象(首报)
|
||||||
|
reportList: [], // 续报列表(可选,如果接口返回)
|
||||||
|
fileList: [], // 附件列表
|
||||||
|
lossList: [], // 损失列表
|
||||||
|
occurLocation: '',
|
||||||
|
occurTime: '',
|
||||||
|
roadConditionType: '',
|
||||||
|
routeNo: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 首报(优先使用 report,如果没有则从 reportList 中找 reportType === 1)
|
||||||
|
const firstReport = computed(() => {
|
||||||
|
if (detailData.value.report) {
|
||||||
|
return detailData.value.report
|
||||||
|
}
|
||||||
|
return detailData.value.reportList?.find(r => r.reportType === 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 续报列表(reportType === 2)
|
||||||
|
const continueReports = computed(() => {
|
||||||
|
return detailData.value.reportList?.filter(r => r.reportType === 2) || []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 是否有填报数据
|
||||||
|
const hasReportData = computed(() => {
|
||||||
|
return firstReport.value || continueReports.value.length > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 判断事件是否已解除(根据实际恢复时间或续报状态判断)
|
||||||
|
const isEventResolved = computed(() => {
|
||||||
|
// 如果首报有实际恢复时间且不为空,则认为已解除
|
||||||
|
// if (firstReport.value?.actualRecoverTime) {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// // 检查续报中是否有实际恢复时间
|
||||||
|
// return continueReports.value.some(r => r.actualRecoverTime)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取事件状态文本
|
||||||
|
const getEventStatusText = () => {
|
||||||
|
return isEventResolved.value ? '已解除' : '未解除'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取事件状态类型
|
||||||
|
const getEventStatusType = () => {
|
||||||
|
return isEventResolved.value ? 'success' : 'danger'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化处置措施(逗号分隔转中文)
|
||||||
|
const formatDisposalMeasures = (measures) => {
|
||||||
|
if (!measures) return ''
|
||||||
|
const measureMap = {
|
||||||
|
halfClose: '半幅封闭',
|
||||||
|
fullClose: '全副封闭',
|
||||||
|
bypass: '便道通行',
|
||||||
|
normal: '正常通行'
|
||||||
|
}
|
||||||
|
return measures
|
||||||
|
.split(',')
|
||||||
|
.map((m) => measureMap[m.trim()] || m.trim())
|
||||||
|
.join('、')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取损失描述(从 lossList 计算塌方体积和总损失)
|
||||||
|
const getLossDescription = (report) => {
|
||||||
|
const lossList = report?.lossList
|
||||||
|
if (!lossList || lossList.length === 0) return '-'
|
||||||
|
|
||||||
|
const totalVolume = lossList.reduce((sum, loss) => {
|
||||||
|
const volume = (loss.length || 0) * (loss.width || 0) * (loss.height || 0)
|
||||||
|
return sum + volume
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
const totalAmount = lossList.reduce((sum, loss) => sum + (loss.totalAmount || 0), 0)
|
||||||
|
|
||||||
|
return `${totalVolume}方,共损失${totalAmount}万元`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取车辆滞留文本
|
||||||
|
const getVehicleStrandedText = (report) => {
|
||||||
|
const count = report?.strandedVehicleCount || 0
|
||||||
|
return count > 0 ? `有车滞留,共${count}辆` : '无车滞留'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取灾毁详情
|
||||||
|
const getDisasterDetail = async () => {
|
||||||
|
const id = route.query.id
|
||||||
|
if (!id) {
|
||||||
|
showToast('缺少灾毁ID')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await request({
|
||||||
|
url: `/snow-ops-platform/water-damage/getById`,
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result?.data) {
|
||||||
|
// 接口返回 Data 结构
|
||||||
|
const data = result.data
|
||||||
|
detailData.value = {
|
||||||
|
event: data.event || null,
|
||||||
|
report: data.report || null,
|
||||||
|
reportList: data.reportList || [],
|
||||||
|
fileList: data.fileList || [],
|
||||||
|
lossList: data.lossList || [],
|
||||||
|
occurLocation: data.occurLocation || '',
|
||||||
|
occurTime: data.occurTime || '',
|
||||||
|
roadConditionType: data.roadConditionType || '',
|
||||||
|
routeNo: data.routeNo || ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showToast(result.message || '获取详情失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取灾毁详情失败:', error)
|
||||||
|
showToast('获取详情失败,请稍后重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击返回
|
||||||
|
const handleClickBack = () => {
|
||||||
|
router.push('/disasterManagement')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 续报
|
||||||
|
const handleContinueReport = () => {
|
||||||
|
router.push({
|
||||||
|
path: '/disasterReport',
|
||||||
|
query: {
|
||||||
|
id: route.query.id,
|
||||||
|
eventId: detailData.value.event?.id,
|
||||||
|
isContinue: 'true'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预览附件
|
||||||
|
const previewFile = (file) => {
|
||||||
|
if (file.fileUrl) {
|
||||||
|
window.open(file.fileUrl, '_blank')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDisasterDetail()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.page-container {
|
||||||
|
padding-bottom: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-wrapper {
|
||||||
|
border-bottom: 1px solid #ebedf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
|
||||||
|
&.sub-row {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-top: -8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
width: 110px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: #969799;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
flex: 1;
|
||||||
|
color: #323233;
|
||||||
|
font-size: 14px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-bottom: 1px solid #ebedf0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px dashed #ebedf0;
|
||||||
|
|
||||||
|
.report-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1989fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-meta {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #969799;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-content {
|
||||||
|
.info-row {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-list {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.attachment-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
background: #f7f8fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
.van-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #1989fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #323233;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-buttons {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
.footer-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -3,24 +3,24 @@
|
|||||||
<CurrentSite />
|
<CurrentSite />
|
||||||
|
|
||||||
<div class="list-panel">
|
<div class="list-panel">
|
||||||
<CardItem v-for="(item, index) in list" :key="index" :title="item.title" @click="handleClickItem(item)">
|
<CardItem v-for="(item, index) in list" :key="index" :title="getEventTitle(item)" @click="handleClickItem(item)">
|
||||||
<template #headerExtra>
|
<template #headerExtra>
|
||||||
<van-tag :type="item.status === '未解除' ? 'danger' : 'success'" plain size="medium">
|
<van-tag :type="getEventStatusType(item.eventStatus)" plain size="medium">
|
||||||
{{ item.status }}
|
{{ getEventStatusText(item.eventStatus) }}
|
||||||
</van-tag>
|
</van-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<div class="time-box">
|
<div class="time-box">
|
||||||
<span class="info-label">发生时间:</span>
|
<span class="info-label">发生时间:</span>
|
||||||
<span class="info-value">{{ item.occurTime }}</span>
|
<span class="info-value">{{ item.occurTime || '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="time-box">
|
<div class="time-box">
|
||||||
<span class="info-label">预计恢复时间:</span>
|
<span class="info-label">预计恢复时间:</span>
|
||||||
<span class="info-value">{{ item.estimateRecoverTime }}</span>
|
<span class="info-value">{{ item.expectRecoverTime || '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="disaster-type-wrapper">
|
<div class="disaster-type-wrapper">
|
||||||
<van-tag type="primary" size="medium" plain>{{ item.disasterType }}</van-tag>
|
<van-tag class="tag" type="primary" size="medium" plain>{{ getDisasterTypeText(item) }}</van-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<EmptyBox v-if="!loading && list.length === 0" :placeholder="emptyText" />
|
<EmptyBox v-if="!loading && list.length === 0" :placeholder="emptyText" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<van-button type="primary" class="footer-btn" @click="handleAdd"> 灾害填报 </van-button>
|
<van-button type="primary" class="footer-btn" @click="handleAdd">灾害填报</van-button>
|
||||||
|
|
||||||
<!-- 筛选组件:v-model 绑定选中的值,visible 控制显示隐藏 -->
|
<!-- 筛选组件:v-model 绑定选中的值,visible 控制显示隐藏 -->
|
||||||
<TagFilter
|
<TagFilter
|
||||||
@ -78,7 +78,7 @@ const showFilter = ref(false)
|
|||||||
// 当前选中的灾毁类型(通过 v-model 传给 TagFilter)
|
// 当前选中的灾毁类型(通过 v-model 传给 TagFilter)
|
||||||
const selectedDisasterType = ref('all')
|
const selectedDisasterType = ref('all')
|
||||||
|
|
||||||
// 灾毁类型列表
|
// 灾毁类型列表(根据实际数据中的路况类别或其他字段定义)
|
||||||
const disasterTypes = [
|
const disasterTypes = [
|
||||||
{ label: '全部', value: 'all' },
|
{ label: '全部', value: 'all' },
|
||||||
{ label: '边坡坍塌', value: '边坡坍塌' },
|
{ label: '边坡坍塌', value: '边坡坍塌' },
|
||||||
@ -91,6 +91,53 @@ const disasterTypes = [
|
|||||||
{ label: '其他', value: '其他' }
|
{ label: '其他', value: '其他' }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// 获取事件标题
|
||||||
|
const getEventTitle = (item) => {
|
||||||
|
// 优先使用 eventName,其次使用发生地点+线路编号组合
|
||||||
|
if (item.eventName) {
|
||||||
|
return item.eventName
|
||||||
|
}
|
||||||
|
const parts = []
|
||||||
|
if (item.routeNo) parts.push(item.routeNo)
|
||||||
|
if (item.occurLocation) parts.push(item.occurLocation)
|
||||||
|
if (item.startStakeNo) parts.push(item.startStakeNo)
|
||||||
|
|
||||||
|
if (parts.length > 0) {
|
||||||
|
return parts.join(' ')
|
||||||
|
}
|
||||||
|
return '未命名事件'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取事件状态文本
|
||||||
|
const getEventStatusText = (status) => {
|
||||||
|
// eventStatus: 0-未解除 1-已解除
|
||||||
|
return status === 1 ? '已解除' : '未解除'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取事件状态类型(用于标签颜色)
|
||||||
|
const getEventStatusType = (status) => {
|
||||||
|
return status === 1 ? 'success' : 'danger'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取灾毁类型文本(根据实际情况映射)
|
||||||
|
const getDisasterTypeText = (item) => {
|
||||||
|
// 可以根据 roadConditionType、repairProgress 或其他字段来生成类型标签
|
||||||
|
// 这里提供几种可能的映射方式
|
||||||
|
|
||||||
|
// 方式1:根据抢修进度
|
||||||
|
if (item.repairProgress) {
|
||||||
|
return item.repairProgress
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方式2:根据路况类别
|
||||||
|
if (item.roadConditionType) {
|
||||||
|
return item.roadConditionType
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方式3:默认返回"水毁灾害"
|
||||||
|
return '水毁灾害'
|
||||||
|
}
|
||||||
|
|
||||||
// 获取简短类型名称
|
// 获取简短类型名称
|
||||||
const getShortTypeName = (type) => {
|
const getShortTypeName = (type) => {
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
@ -101,9 +148,15 @@ const getShortTypeName = (type) => {
|
|||||||
'行道树倒塌': '树倒',
|
'行道树倒塌': '树倒',
|
||||||
'积水': '积水',
|
'积水': '积水',
|
||||||
'积雪': '积雪',
|
'积雪': '积雪',
|
||||||
'其他': '其他'
|
'其他': '其他',
|
||||||
|
'未抢修': '待抢修',
|
||||||
|
'抢修中': '抢修中',
|
||||||
|
'已完成': '已完成',
|
||||||
|
'高速公路': '高速',
|
||||||
|
'国道': '国道',
|
||||||
|
'省道': '省道'
|
||||||
}
|
}
|
||||||
return typeMap[type] || type.substring(0, 2)
|
return typeMap[type] || (type ? type.substring(0, 2) : '灾害')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取灾毁列表数据
|
// 获取灾毁列表数据
|
||||||
@ -120,7 +173,15 @@ const getDisasterList = async (keyword = '', disasterType = 'all') => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (result?.data?.records) {
|
if (result?.data?.records) {
|
||||||
list.value = result.data.records
|
list.value = result.data.records.map(item => ({
|
||||||
|
...item,
|
||||||
|
// 数据转换,确保前端使用的字段存在
|
||||||
|
title: getEventTitle(item),
|
||||||
|
status: getEventStatusText(item.eventStatus),
|
||||||
|
occurTime: item.occurTime,
|
||||||
|
estimateRecoverTime: item.expectRecoverTime,
|
||||||
|
disasterType: getDisasterTypeText(item)
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
showToast(result.message || '获取数据失败')
|
showToast(result.message || '获取数据失败')
|
||||||
list.value = []
|
list.value = []
|
||||||
@ -162,14 +223,9 @@ const handleClickBack = () => {
|
|||||||
// 点击列表项
|
// 点击列表项
|
||||||
const handleClickItem = (item) => {
|
const handleClickItem = (item) => {
|
||||||
router.push({
|
router.push({
|
||||||
path: '/disaster-detail',
|
path: '/disasterDetail',
|
||||||
query: {
|
query: {
|
||||||
id: item.id,
|
id: item.id
|
||||||
title: item.title,
|
|
||||||
status: item.status,
|
|
||||||
occurTime: item.occurTime,
|
|
||||||
estimateRecoverTime: item.estimateRecoverTime,
|
|
||||||
disasterType: item.disasterType
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -271,4 +327,7 @@ onMounted(() => {
|
|||||||
border-color: #1989fa;
|
border-color: #1989fa;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
:deep(.van-tag) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<PageContainer title="灾毁填报" @click-back="handleClickBack" class="page-container">
|
<PageContainer :title="title" @click-back="handleClickBack" class="page-container">
|
||||||
<!-- 当前站点信息 -->
|
<!-- 当前站点信息 -->
|
||||||
<CurrentSite />
|
<CurrentSite />
|
||||||
|
|
||||||
<!-- 事件类型 -->
|
<!-- 事件类型 -->
|
||||||
<PanelItem title="事件类型">
|
<PanelItem title="事件类型" style="margin-bottom: 10px;" v-if="!isContinue">
|
||||||
<van-radio-group v-model="eventType" direction="horizontal" class="event-type-group">
|
<van-radio-group v-model="eventType" direction="horizontal" class="event-type-group">
|
||||||
<van-radio name="water">水毁灾害</van-radio>
|
<van-radio name="water">水毁灾害</van-radio>
|
||||||
<van-radio name="ice">冰雪灾害</van-radio>
|
<van-radio name="ice">冰雪灾害</van-radio>
|
||||||
@ -30,8 +30,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { showToast, showSuccessToast, showFailToast } from 'vant'
|
import { showToast, showSuccessToast, showFailToast } from 'vant'
|
||||||
import PageContainer from '@/components/PageContainer.vue'
|
import PageContainer from '@/components/PageContainer.vue'
|
||||||
import CurrentSite from '@/components/CurrentSite.vue'
|
import CurrentSite from '@/components/CurrentSite.vue'
|
||||||
@ -41,6 +41,12 @@ import { request } from "@shared/utils/request";
|
|||||||
import mockFormData from './waterDisasterFormData.json'
|
import mockFormData from './waterDisasterFormData.json'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
// 是否为续报
|
||||||
|
const isContinue = computed(() => route.query.isContinue)
|
||||||
|
|
||||||
|
const title = ref(!isContinue ? '灾毁填报' : '灾毁续报')
|
||||||
|
|
||||||
// 事件类型
|
// 事件类型
|
||||||
const eventType = ref('water')
|
const eventType = ref('water')
|
||||||
@ -84,15 +90,16 @@ const handleSubmit = async () => {
|
|||||||
data: submitData
|
data: submitData
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if(res?.code === '00000') {
|
||||||
// 模拟提交接口
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
||||||
showSuccessToast('提交成功')
|
showSuccessToast('提交成功')
|
||||||
|
} else {
|
||||||
|
showFailToast(res.message)
|
||||||
|
}
|
||||||
|
|
||||||
// 提交成功后返回列表页
|
// 提交成功后返回列表页
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.replace('/disasterManagement')
|
router.replace('/disasterManagement')
|
||||||
}, 1500)
|
}, 1000)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showFailToast('提交失败,请重试')
|
showFailToast('提交失败,请重试')
|
||||||
console.error('提交失败:', error)
|
console.error('提交失败:', error)
|
||||||
@ -101,8 +108,45 @@ const handleSubmit = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取灾毁详情
|
||||||
|
const getDisasterDetail = async () => {
|
||||||
|
const id = route.query.id
|
||||||
|
if (!id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await request({
|
||||||
|
url: `/snow-ops-platform/water-damage/getById`,
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result?.data) {
|
||||||
|
// 接口返回 Data 结构
|
||||||
|
const data = result.data
|
||||||
|
const newFormData = {
|
||||||
|
...data,
|
||||||
|
lossList: null,
|
||||||
|
report: formData.value.report,
|
||||||
|
fileList: null
|
||||||
|
}
|
||||||
|
waterDisasterRef.value.initFormData(newFormData)
|
||||||
|
} else {
|
||||||
|
showToast(result.message || '获取详情失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取灾毁详情失败:', error)
|
||||||
|
showToast('获取详情失败,请稍后重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
if(route.query?.id) {
|
||||||
|
getDisasterDetail()
|
||||||
|
} else {
|
||||||
waterDisasterRef.value.initFormData(formData.value)
|
waterDisasterRef.value.initFormData(formData.value)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<!-- 损失计算弹窗 -->
|
<!-- 损失计算弹窗 -->
|
||||||
<van-dialog
|
<van-dialog
|
||||||
v-model:show="visible"
|
v-model:show="visible"
|
||||||
title="塌方损失信息"
|
:title="itemName + '损失信息'"
|
||||||
show-cancel-button
|
show-cancel-button
|
||||||
@confirm="confirm"
|
@confirm="confirm"
|
||||||
@cancel="cancelLoss"
|
@cancel="cancelLoss"
|
||||||
@ -11,21 +11,21 @@
|
|||||||
>
|
>
|
||||||
<div class="loss-dialog-content">
|
<div class="loss-dialog-content">
|
||||||
<!-- 塌方长 -->
|
<!-- 塌方长 -->
|
||||||
<van-field v-model="formData.length" label="塌方长" placeholder="请填写长度" type="digit" clearable>
|
<van-field v-model="formData.length" :label="itemName + '长'" placeholder="请填写长度" type="digit" clearable>
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">米</span>
|
<span class="field-unit">米</span>
|
||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
|
|
||||||
<!-- 塌方宽 -->
|
<!-- 塌方宽 -->
|
||||||
<van-field v-model="formData.width" label="塌方宽" placeholder="请填写宽度" type="digit" clearable>
|
<van-field v-model="formData.width" :label="itemName + '宽'" placeholder="请填写宽度" type="digit" clearable>
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">米</span>
|
<span class="field-unit">米</span>
|
||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
|
|
||||||
<!-- 塌方高 -->
|
<!-- 塌方高 -->
|
||||||
<van-field v-model="formData.height" label="塌方高" placeholder="请填写高度" type="digit" clearable>
|
<van-field v-model="formData.height" :label="itemName + '高'" placeholder="请填写高度" type="digit" clearable>
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">米</span>
|
<span class="field-unit">米</span>
|
||||||
</template>
|
</template>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
|
|
||||||
<van-field v-model="formData.totalPrice" label="塌方损失金额" placeholder="请填写金额" type="digit" clearable>
|
<van-field v-model="formData.totalAmount" :label="itemName + '损失金额'" placeholder="请填写金额" type="digit" clearable>
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">元</span>
|
<span class="field-unit">元</span>
|
||||||
</template>
|
</template>
|
||||||
@ -61,7 +61,9 @@ const formData = ref({
|
|||||||
unitPrice: ''
|
unitPrice: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const totalPrice = computed(() => {
|
const itemName = ref('')
|
||||||
|
|
||||||
|
const totalAmount = computed(() => {
|
||||||
const l = parseFloat(formData.value.length)
|
const l = parseFloat(formData.value.length)
|
||||||
const w = parseFloat(formData.value.width)
|
const w = parseFloat(formData.value.width)
|
||||||
const h = parseFloat(formData.value.height)
|
const h = parseFloat(formData.value.height)
|
||||||
@ -84,14 +86,25 @@ const totalPrice = computed(() => {
|
|||||||
return (l * w * h * price)
|
return (l * w * h * price)
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(totalPrice, ()=>{
|
watch(totalAmount, ()=>{
|
||||||
formData.value.totalPrice = totalPrice.value
|
formData.value.totalAmount = totalAmount.value
|
||||||
})
|
})
|
||||||
// 显示弹窗
|
// 显示弹窗
|
||||||
const show = () => {
|
const show = (item) => {
|
||||||
|
console.log("🚀 ~ show ~ item:", item)
|
||||||
|
formData.value.length = item.length
|
||||||
|
formData.value.width = item.width
|
||||||
|
formData.value.height = item.height
|
||||||
|
formData.value.unitPrice = item.unitPrice
|
||||||
|
formData.value.totalAmount = item.totalAmount
|
||||||
|
itemName.value = getItemName(item)
|
||||||
visible.value = true
|
visible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getItemName = (item) => {
|
||||||
|
return item.lossTypeName
|
||||||
|
}
|
||||||
|
|
||||||
// 验证表单数据
|
// 验证表单数据
|
||||||
const validateForm = () => {
|
const validateForm = () => {
|
||||||
const l = parseFloat(formData.length)
|
const l = parseFloat(formData.length)
|
||||||
@ -125,11 +138,11 @@ const validateForm = () => {
|
|||||||
|
|
||||||
// 确认损失计算
|
// 确认损失计算
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
if(!formData.value.totalPrice) {
|
if(!formData.value.totalAmount) {
|
||||||
showToast('请填写损失金额')
|
showToast('请填写损失金额')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
emit('confirm', formData.value.totalPrice)
|
emit('confirm', formData.value)
|
||||||
// 重置表单
|
// 重置表单
|
||||||
resetForm()
|
resetForm()
|
||||||
visible.value = false
|
visible.value = false
|
||||||
@ -147,7 +160,7 @@ const resetForm = () => {
|
|||||||
formData.value.width = ''
|
formData.value.width = ''
|
||||||
formData.value.height = ''
|
formData.value.height = ''
|
||||||
formData.value.unitPrice = ''
|
formData.value.unitPrice = ''
|
||||||
formData.value.totalPrice
|
formData.value.totalAmount
|
||||||
}
|
}
|
||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits(['confirm'])
|
const emit = defineEmits(['confirm'])
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="loss-list">
|
<div class="loss-list">
|
||||||
<template v-for="item in modelValue">
|
<template v-for="(item, index) in modelValue">
|
||||||
<van-field v-model="item.totalAmount" :label="getItemLabel(item)" placeholder="请填写" type="digit" @click="cubeCalculateDialog.show()">
|
<van-field v-model="item.totalAmount" :label="getItemLabel(item)" placeholder="请填写" type="digit" @click="showCalculateDialog(item, index)">
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">方/万元</span>
|
<span class="field-unit">{{ item.unit }}</span>
|
||||||
|
<van-icon @click.stop="removeItem(index)" class="remove-icon" name="delete-o" />
|
||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
</template>
|
</template>
|
||||||
<van-button size="small" block type="primary" plain @click="addLoss">添加损失</van-button>
|
<van-button size="small" block type="primary" plain @click="addLoss">添加损失</van-button>
|
||||||
<CubeCalculateDialog ref="cubeCalculateDialog" />
|
<CubeCalculateDialog ref="cubeCalculateDialog" @confirm="confirmCalculate" />
|
||||||
<LossPicker ref="lossPicker" :options="options" @confirm="confirmAddLoss" />
|
<LossPicker ref="lossPicker" :options="options" @confirm="confirmAddLoss" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -31,6 +32,9 @@ const props = defineProps({
|
|||||||
const lossPicker = ref(null)
|
const lossPicker = ref(null)
|
||||||
|
|
||||||
const options = ref({})
|
const options = ref({})
|
||||||
|
|
||||||
|
const dialogItemIndex = ref(null)
|
||||||
|
|
||||||
// 添加损失项
|
// 添加损失项
|
||||||
const addLoss = () => {
|
const addLoss = () => {
|
||||||
lossPicker.value?.show()
|
lossPicker.value?.show()
|
||||||
@ -40,6 +44,10 @@ const confirmAddLoss = (item) => {
|
|||||||
emit('update:modelValue', [...props.modelValue, item])
|
emit('update:modelValue', [...props.modelValue, item])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeItem = (index) => {
|
||||||
|
emit('update:modelValue', [...props.modelValue.slice(0, index), ...props.modelValue.slice(index + 1)])
|
||||||
|
}
|
||||||
|
|
||||||
const cubeCalculateDialog = ref(null)
|
const cubeCalculateDialog = ref(null)
|
||||||
|
|
||||||
const getItemLabel = (item) => {
|
const getItemLabel = (item) => {
|
||||||
@ -62,6 +70,18 @@ const getLossDict = async (params) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showCalculateDialog = (item, index) => {
|
||||||
|
if(item.unit?.indexOf('方') > -1) {
|
||||||
|
dialogItemIndex.value = index
|
||||||
|
cubeCalculateDialog.value?.show(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmCalculate = (newValue) => {
|
||||||
|
const oldItem = props.modelValue[dialogItemIndex.value]
|
||||||
|
props.modelValue[dialogItemIndex.value] = { ...oldItem, ...newValue }
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getLossDict()
|
await getLossDict()
|
||||||
})
|
})
|
||||||
@ -109,4 +129,10 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remove-icon {
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #ee0a24;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="water-disaster">
|
<div class="water-disaster">
|
||||||
<!-- 基本信息 -->
|
<!-- 基本信息 -->
|
||||||
<PanelItem title="基本信息">
|
<PanelItem title="基本信息" v-if="!isContinue">
|
||||||
<van-form>
|
<van-form>
|
||||||
<!-- 路况类别 -->
|
<!-- 路况类别 -->
|
||||||
<BasePicker v-model="formData.roadConditionType" :options="roadConditionOptions" label="路况类别" placeholder="请选择" />
|
<BasePicker v-model="formData.roadConditionType" :options="roadConditionOptions" label="路况类别" placeholder="请选择" />
|
||||||
@ -175,7 +175,7 @@
|
|||||||
<!-- 是否需要恢复重建 (event.needsRecovery) -->
|
<!-- 是否需要恢复重建 (event.needsRecovery) -->
|
||||||
<BasePicker v-model="formData.event.needsRecovery" :options="needsRecoveryOptions" label="是否需要恢复重建" placeholder="请选择" />
|
<BasePicker v-model="formData.event.needsRecovery" :options="needsRecoveryOptions" label="是否需要恢复重建" placeholder="请选择" />
|
||||||
<!-- 恢复重建预估费用 (event.estimatedRecoveryCost) -->
|
<!-- 恢复重建预估费用 (event.estimatedRecoveryCost) -->
|
||||||
<van-field v-model="formData.event.estimatedRecoveryCost" label="恢复重建预估费用" placeholder="请填写" type="digit">
|
<van-field v-model="formData.event.estimatedRecoveryCost" v-if="!isContinue" label="恢复重建预估费用" placeholder="请填写" type="digit">
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">万元</span>
|
<span class="field-unit">万元</span>
|
||||||
</template>
|
</template>
|
||||||
@ -191,7 +191,12 @@ import PanelItem from '@/components/PanelItem.vue'
|
|||||||
import BasePicker from '@/components/BasePicker.vue'
|
import BasePicker from '@/components/BasePicker.vue'
|
||||||
import BaseDatePicker from '@/components/BaseDatePicker.vue'
|
import BaseDatePicker from '@/components/BaseDatePicker.vue'
|
||||||
import LossList from './LossList.vue'
|
import LossList from './LossList.vue'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
// 是否为续报
|
||||||
|
const isContinue = computed(() => route.query.isContinue)
|
||||||
|
|
||||||
// 处置措施数组(用于多选框组,需要转换为逗号分隔的字符串)
|
// 处置措施数组(用于多选框组,需要转换为逗号分隔的字符串)
|
||||||
const disposalMeasuresArray = ref([])
|
const disposalMeasuresArray = ref([])
|
||||||
|
|||||||
@ -40,24 +40,6 @@
|
|||||||
"totalLossAmount": 85.6
|
"totalLossAmount": 85.6
|
||||||
},
|
},
|
||||||
"lossList": [
|
"lossList": [
|
||||||
{
|
|
||||||
"length": 50,
|
|
||||||
"width": 8.5,
|
|
||||||
"height": 2.5,
|
|
||||||
"unitPrice": 380,
|
|
||||||
"totalAmount": 38.9,
|
|
||||||
"lossCategory": "路面损毁",
|
|
||||||
"remark": "沥青路面严重损坏"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"length": 30,
|
|
||||||
"width": 2.5,
|
|
||||||
"height": 6,
|
|
||||||
"unitPrice": 520,
|
|
||||||
"totalAmount": 23.4,
|
|
||||||
"lossCategory": "挡墙损毁",
|
|
||||||
"remark": "浆砌片石挡墙垮塌"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"fileList": []
|
"fileList": []
|
||||||
}
|
}
|
||||||
@ -66,7 +66,6 @@ const routes = [
|
|||||||
breadcrumb: true
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/airSkyLand/AirSkyLand.vue')
|
component: () => import('../views/airSkyLand/AirSkyLand.vue')
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/3DSituationalAwareness',
|
path: '/3DSituationalAwareness',
|
||||||
@ -149,6 +148,24 @@ const routes = [
|
|||||||
title: '项目管理',
|
title: '项目管理',
|
||||||
breadcrumb: true
|
breadcrumb: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/disasterManagement',
|
||||||
|
name: 'disasterManagement',
|
||||||
|
component: () => import('../views/DisasterManagement/DisasterManagement.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '灾害巡检事件',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/disasterReport',
|
||||||
|
name: 'DisasterReport',
|
||||||
|
component: () => import('../views/DisasterManagement/DisasterReport/DisasterReport.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '水毁事件填报',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,403 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-container">
|
||||||
|
<!-- 筛选栏 -->
|
||||||
|
<el-card class="filter-card" shadow="never">
|
||||||
|
<el-form :model="filterForm" label-width="100px" @submit.prevent>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="所属单位">
|
||||||
|
<el-input v-model="filterForm.unit" placeholder="请输入" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="发生地点">
|
||||||
|
<el-input v-model="filterForm.occurLocation" placeholder="请输入" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="路线编号">
|
||||||
|
<el-input v-model="filterForm.routeNo" placeholder="请输入" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="事件类别">
|
||||||
|
<el-select v-model="filterForm.disasterType" placeholder="请选择" clearable>
|
||||||
|
<el-option label="水毁事件" value="水毁事件" />
|
||||||
|
<el-option label="塌方事件" value="塌方事件" />
|
||||||
|
<el-option label="泥石流" value="泥石流" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="事件状态">
|
||||||
|
<el-select v-model="filterForm.eventStatus" placeholder="请选择" clearable>
|
||||||
|
<el-option label="未解除" :value="0" />
|
||||||
|
<el-option label="已解除" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="是否阻断">
|
||||||
|
<el-select v-model="filterForm.isBlocked" placeholder="请选择" clearable>
|
||||||
|
<el-option label="是" value="是" />
|
||||||
|
<el-option label="否" value="否" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="路线类型">
|
||||||
|
<el-select v-model="filterForm.roadConditionType" placeholder="请选择" clearable>
|
||||||
|
<el-option label="国省道" value="国省道" />
|
||||||
|
<el-option label="县乡道" value="县乡道" />
|
||||||
|
<el-option label="高速" value="高速" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6">
|
||||||
|
<el-form-item label="日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="24" :lg="24">
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button @click="toReport">新增</el-button>
|
||||||
|
<el-button type="success" @click="handleExport">导出Excel</el-button>
|
||||||
|
<el-button @click="resetFilters">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 数据表格卡片 -->
|
||||||
|
<el-card class="table-card" shadow="never">
|
||||||
|
<div class="table-container">
|
||||||
|
<el-table :data="tableData" border stripe v-loading="loading" style="width: 100%" height="100%">
|
||||||
|
<el-table-column label="序号" width="60">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.$index + 1 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="routeNo" label="所属区县" min-width="120" />
|
||||||
|
<el-table-column prop="routeNo" label="路线编号" min-width="120" />
|
||||||
|
<el-table-column prop="routeName" label="路线名称" min-width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="startPile" label="起点桩号" min-width="110" />
|
||||||
|
<el-table-column prop="endPile" label="终点桩号" min-width="110" />
|
||||||
|
<el-table-column prop="occurLocation" label="发生地点" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="isBlocked" label="是否阻断" width="90" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="row.isBlocked === '是' ? 'danger' : 'success'" size="small">
|
||||||
|
{{ row.isBlocked || '—' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="disasterType" label="灾害类型" min-width="120" />
|
||||||
|
<el-table-column prop="roadConditionType" label="路线类别" min-width="110" />
|
||||||
|
<el-table-column prop="eventStatus" label="事件状态" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="row.eventStatus === 1 ? 'success' : 'danger'" size="small">
|
||||||
|
{{ row.eventStatus === 1 ? '已解除' : '未解除' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="measure" label="处理措施" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="occurTime" label="发生时间" width="170" />
|
||||||
|
<el-table-column prop="expectRecoverTime" label="预计恢复时间" width="170" />
|
||||||
|
<el-table-column prop="contactPerson" label="联系人" width="110" />
|
||||||
|
<el-table-column prop="contactPhone" label="联系电话" width="120" />
|
||||||
|
<el-table-column label="图片" width="80" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-if="row.hasImage" link type="primary" size="small" @click="viewImages(row)">查看</el-button>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="视频" width="80" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-if="row.hasVideo" link type="primary" size="small" @click="viewVideos(row)">播放</el-button>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="100" fixed="right" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button link type="primary" size="small" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button link type="warning" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="pagination.currentPage"
|
||||||
|
v-model:page-size="pagination.pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:total="pagination.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { request } from '@/utils/request'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
// 筛选表单
|
||||||
|
const filterForm = reactive({
|
||||||
|
unit: '', // 所属单位
|
||||||
|
occurLocation: '', // 发生地点
|
||||||
|
routeNo: '', // 路线编号
|
||||||
|
disasterType: '', // 灾害类型/事件类别
|
||||||
|
eventStatus: '', // 事件状态 (0-未解除, 1-已解除)
|
||||||
|
isBlocked: '', // 是否阻断
|
||||||
|
roadConditionType: '', // 路线类型
|
||||||
|
pushStatus: '' // 推送状态
|
||||||
|
})
|
||||||
|
|
||||||
|
// 日期范围
|
||||||
|
const dateRange = ref(null)
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 分页参数
|
||||||
|
const pagination = reactive({
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 构建查询参数
|
||||||
|
const buildQueryParams = () => {
|
||||||
|
const params = {
|
||||||
|
pageNum: pagination.currentPage,
|
||||||
|
pageSize: pagination.pageSize,
|
||||||
|
unit: filterForm.unit,
|
||||||
|
occurLocation: filterForm.occurLocation,
|
||||||
|
routeNo: filterForm.routeNo,
|
||||||
|
disasterType: filterForm.disasterType,
|
||||||
|
eventStatus: filterForm.eventStatus,
|
||||||
|
isBlocked: filterForm.isBlocked,
|
||||||
|
roadConditionType: filterForm.roadConditionType
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dateRange.value && dateRange.value.length === 2) {
|
||||||
|
params.startDate = dateRange.value[0]
|
||||||
|
params.endDate = dateRange.value[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤空字符串或null的参数
|
||||||
|
Object.keys(params).forEach((key) => {
|
||||||
|
if (params[key] === '' || params[key] === null || params[key] === undefined) {
|
||||||
|
delete params[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
const fetchData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const params = buildQueryParams()
|
||||||
|
|
||||||
|
// 实际接口调用
|
||||||
|
const response = await request({
|
||||||
|
url: '/snow-ops-platform/unified-disaster/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.code === '00000') {
|
||||||
|
const records = response.data.records || response.data || []
|
||||||
|
tableData.value = records.map((item) => ({
|
||||||
|
...item,
|
||||||
|
// 转换状态显示
|
||||||
|
eventStatusText: item.eventStatus === 1 ? '已解除' : '未解除',
|
||||||
|
// 保留原始数据
|
||||||
|
...item
|
||||||
|
}))
|
||||||
|
pagination.total = response.data.total || records.length
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.message || '查询失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('数据加载失败')
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询按钮
|
||||||
|
const handleQuery = () => {
|
||||||
|
pagination.currentPage = 1
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出Excel
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
const params = buildQueryParams()
|
||||||
|
const response = await request({
|
||||||
|
url: '/api/disaster/record/export',
|
||||||
|
method: 'post',
|
||||||
|
data: params,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 创建下载链接
|
||||||
|
const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||||
|
const link = document.createElement('a')
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
link.href = url
|
||||||
|
link.download = `水毁事件列表_${new Date().getTime()}.xlsx`
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
|
||||||
|
ElMessage.success('导出成功')
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('导出失败')
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置筛选条件
|
||||||
|
const resetFilters = () => {
|
||||||
|
filterForm.unit = ''
|
||||||
|
filterForm.occurLocation = ''
|
||||||
|
filterForm.routeNo = ''
|
||||||
|
filterForm.disasterType = ''
|
||||||
|
filterForm.eventStatus = ''
|
||||||
|
filterForm.isBlocked = ''
|
||||||
|
filterForm.roadConditionType = ''
|
||||||
|
filterForm.pushStatus = ''
|
||||||
|
dateRange.value = null
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情
|
||||||
|
const handleDetail = (row) => {
|
||||||
|
router.push({ path: '/disasterDetail', query: { id: row.id } })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
router.push({ path: '/disasterReport', query: { id: row.id, mode: 'edit' } })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增跳转
|
||||||
|
const toReport = () => {
|
||||||
|
router.push('/disasterReport')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看图片
|
||||||
|
const viewImages = (row) => {
|
||||||
|
if (row.images && row.images.length) {
|
||||||
|
// 打开图片预览
|
||||||
|
ElMessage.info('图片预览功能开发中')
|
||||||
|
} else {
|
||||||
|
ElMessage.info('暂无图片')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看视频
|
||||||
|
const viewVideos = (row) => {
|
||||||
|
if (row.videos && row.videos.length) {
|
||||||
|
ElMessage.info('视频播放功能开发中')
|
||||||
|
} else {
|
||||||
|
ElMessage.info('暂无视频')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页大小改变
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
pagination.pageSize = val
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页码改变
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
pagination.currentPage = val
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化加载数据
|
||||||
|
onMounted(() => {
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.page-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.filter-card {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-card {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
:deep(.el-table) {
|
||||||
|
--el-table-border-color: #ebeef5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 16px 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
border-top: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
<template>
|
||||||
|
<div class="disaster-report">
|
||||||
|
<el-page-header @back="handleBack" class="page-header">
|
||||||
|
<template #content>
|
||||||
|
<span class="title">{{ isEdit ? '灾毁填报' : '灾毁填报' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-page-header>
|
||||||
|
|
||||||
|
<WaterDisasterReport />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { Plus, Upload } from '@element-plus/icons-vue'
|
||||||
|
import { request } from '@/utils/request'
|
||||||
|
import WaterDisasterReport from './WaterDisasterReport.vue'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const isEdit = computed(() => !!route.query.id)
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.disaster-report {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 0 0 16px 0;
|
||||||
|
border-bottom: 1px solid #e4e7ed;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.disaster-form {
|
||||||
|
.form-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
:deep(.el-card__header) {
|
||||||
|
padding: 12px 20px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
.section-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 3px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: #409eff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-section-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #606266;
|
||||||
|
margin: 8px 0 16px 0;
|
||||||
|
padding-left: 8px;
|
||||||
|
border-left: 3px solid #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unit-suffix {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 20px 0 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,735 @@
|
|||||||
|
<template>
|
||||||
|
<div class="disaster-form-page">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px" class="disaster-form" @submit.prevent>
|
||||||
|
<!-- 基础信息区块 -->
|
||||||
|
<el-card class="form-section" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">基础信息</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<!-- 填报人员信息 -->
|
||||||
|
<el-col :span="24">
|
||||||
|
<div class="sub-section-title">填报人员信息</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="填报单位" prop="reportUnit">
|
||||||
|
<el-input v-model="formData.reportUnit" placeholder="请输入填报单位" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系人" prop="contactPerson">
|
||||||
|
<el-input v-model="formData.contactPerson" placeholder="请输入联系人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系电话" prop="contactPhone">
|
||||||
|
<el-input v-model="formData.contactPhone" placeholder="请输入联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 路况事件信息 -->
|
||||||
|
<el-col :span="24">
|
||||||
|
<div class="sub-section-title">路况事件信息</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="事件类型" prop="eventType">
|
||||||
|
<el-select v-model="formData.eventType" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="水毁灾害" value="水毁灾害" />
|
||||||
|
<el-option label="冰雪灾害" value="冰雪灾害" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="路况类别" prop="blockedMileage">
|
||||||
|
<el-input-number v-model="formData.blockedMileage" :min="0" :precision="3" style="width: 100%" placeholder="请填写" />
|
||||||
|
<span class="unit-suffix">公里</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="是否阻断" prop="isBlocked">
|
||||||
|
<el-select v-model="formData.isBlocked" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="是" value="是" />
|
||||||
|
<el-option label="否" value="否" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="抢险进度" prop="isBlocked">
|
||||||
|
<el-select v-model="formData.isBlocked" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="是" value="是" />
|
||||||
|
<el-option label="否" value="否" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="处理措施" prop="measure">
|
||||||
|
<el-select v-model="formData.measure" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="正常通行" value="正常通行" />
|
||||||
|
<el-option label="交通管制" value="交通管制" />
|
||||||
|
<el-option label="封闭施工" value="封闭施工" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="水毁处数" prop="waterDamageCount">
|
||||||
|
<el-input-number v-model="formData.waterDamageCount" :min="0" :step="1" style="width: 100%" placeholder="请填写" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="阻断里程" prop="blockedMileage">
|
||||||
|
<el-input-number v-model="formData.blockedMileage" :min="0" :precision="3" style="width: 100%" placeholder="请填写" />
|
||||||
|
<span class="unit-suffix">公里</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="发现时间" prop="discoverTime">
|
||||||
|
<el-date-picker v-model="formData.discoverTime" type="datetime" placeholder="请选择日期时间" style="width: 100%" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="预计恢复" prop="predictRecoverTime">
|
||||||
|
<el-date-picker v-model="formData.predictRecoverTime" type="datetime" placeholder="请选择日期时间" style="width: 100%" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="现场描述" prop="siteDescription">
|
||||||
|
<el-input v-model="formData.siteDescription" type="textarea" :rows="3" placeholder="请输入现场描述及续行方案" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 位置信息区块 -->
|
||||||
|
<el-card class="form-section" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">位置信息</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="路线类型" prop="routeType">
|
||||||
|
<el-select v-model="formData.routeType" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="国省道" value="国省道" />
|
||||||
|
<el-option label="县乡道" value="县乡道" />
|
||||||
|
<el-option label="高速" value="高速" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="所属区县" prop="district">
|
||||||
|
<el-select v-model="formData.district" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="万州区" value="万州区" />
|
||||||
|
<el-option label="开州区" value="开州区" />
|
||||||
|
<el-option label="黔江区" value="黔江区" />
|
||||||
|
<el-option label="涪陵区" value="涪陵区" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="地点路线" prop="routeCode">
|
||||||
|
<el-input v-model="formData.routeCode" placeholder="请输入地点路线" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="起点桩号" prop="startPile">
|
||||||
|
<el-input v-model="formData.startPile" placeholder="K_请填写" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="止点桩号" prop="endPile">
|
||||||
|
<el-input v-model="formData.endPile" placeholder="K_请填写" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="路况位置" prop="locationPath">
|
||||||
|
<el-cascader v-model="formData.locationPath" :options="locationOptions" placeholder="请选择" style="width: 100%" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="阻断点小地名" prop="smallPlaceName">
|
||||||
|
<el-input v-model="formData.smallPlaceName" placeholder="请填写" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="经度" prop="longitude">
|
||||||
|
<el-input v-model="formData.longitude" placeholder="请输入经度" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="纬度" prop="latitude">
|
||||||
|
<el-input v-model="formData.latitude" placeholder="请输入纬度" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 附件上传区块 -->
|
||||||
|
<el-card class="form-section" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">附件上传</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="图片上传" prop="images">
|
||||||
|
<el-upload
|
||||||
|
v-model:file-list="formData.images"
|
||||||
|
action="#"
|
||||||
|
list-type="picture-card"
|
||||||
|
:auto-upload="false"
|
||||||
|
:limit="9"
|
||||||
|
:on-preview="handlePicturePreview"
|
||||||
|
:on-remove="handlePictureRemove"
|
||||||
|
:before-upload="beforeImageUpload"
|
||||||
|
accept="image/jpeg,image/png"
|
||||||
|
>
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
</el-upload>
|
||||||
|
<div class="upload-tip">只能上传jpg/png格式,且不超过500kb</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="视频上传" prop="videos">
|
||||||
|
<el-upload v-model:file-list="formData.videos" action="#" :auto-upload="false" :limit="3" :before-upload="beforeVideoUpload" accept="video/*">
|
||||||
|
<el-button type="primary"
|
||||||
|
><el-icon><Upload /></el-icon> 选择文件</el-button
|
||||||
|
>
|
||||||
|
</el-upload>
|
||||||
|
<div class="upload-tip">仅支持3M以内的视频</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 灾毁损失区块 -->
|
||||||
|
<el-card class="form-section" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">灾毁损失</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="24">
|
||||||
|
<div class="sub-section-title">路况事件信息</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="受伤人员" prop="injuredCount">
|
||||||
|
<el-input-number v-model="formData.injuredCount" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">个</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="死亡人员" prop="deathCount">
|
||||||
|
<el-input-number v-model="formData.deathCount" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">个</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="滞留人员" prop="deathCount">
|
||||||
|
<el-input-number v-model="formData.deathCount" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">个</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="滞留车辆" prop="strandedVehicles">
|
||||||
|
<el-input-number v-model="formData.strandedVehicles" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">辆</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="损坏车辆" prop="damagedVehicles">
|
||||||
|
<el-input-number v-model="formData.damagedVehicles" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">辆</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24">
|
||||||
|
<div class="sub-section-title">道路损失及其他</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="清理方量" prop="clearVolume">
|
||||||
|
<el-input-number v-model="formData.clearVolume" :min="0" :precision="2" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">立方米</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="填方及损失" prop="fillLoss">
|
||||||
|
<el-input v-model="formData.fillLoss" placeholder="填方及损失" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="路面及损失" prop="roadLoss">
|
||||||
|
<el-input v-model="formData.roadLoss" placeholder="路面及损失" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="护坡及损失" prop="slopeLoss">
|
||||||
|
<el-input v-model="formData.slopeLoss" placeholder="护坡及损失" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="桥梁及损失" prop="bridgeLoss">
|
||||||
|
<el-input v-model="formData.bridgeLoss" placeholder="桥梁及损失" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="隧道及损失" prop="tunnelLoss">
|
||||||
|
<el-input v-model="formData.tunnelLoss" placeholder="隧道及损失" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="涵洞及损失" prop="culvertLoss">
|
||||||
|
<el-input v-model="formData.culvertLoss" placeholder="涵洞及损失" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="护栏" prop="guardrailLength">
|
||||||
|
<el-input-number v-model="formData.guardrailLength" :min="0" :precision="3" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">公里</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="行道树" prop="roadsideTrees">
|
||||||
|
<el-input-number v-model="formData.roadsideTrees" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">棵</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="其他损失" prop="otherLossAmount">
|
||||||
|
<el-input-number v-model="formData.otherLossAmount" :min="0" :precision="2" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">万元</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="其他损失描述" prop="otherLossDesc">
|
||||||
|
<el-input v-model="formData.otherLossDesc" type="textarea" :rows="2" placeholder="请输入" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24">
|
||||||
|
<div class="sub-section-title">已投入机械</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="投入机械" prop="inputMachinery">
|
||||||
|
<el-input-number v-model="formData.inputMachinery" :min="0" :precision="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">台/班</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="投入人力" prop="inputLabor">
|
||||||
|
<el-input-number v-model="formData.inputLabor" :min="0" :step="1" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">人</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="投入资金" prop="inputFunds">
|
||||||
|
<el-input-number v-model="formData.inputFunds" :min="0" :precision="2" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">万元</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 恢复重建预估费用区块 -->
|
||||||
|
<el-card class="form-section" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">恢复重建预估费用</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="是否需要恢复重建" prop="needReconstruction">
|
||||||
|
<el-radio-group v-model="formData.needReconstruction">
|
||||||
|
<el-radio label="是">是</el-radio>
|
||||||
|
<el-radio label="否">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="恢复重建预估费用" prop="reconstructionCost">
|
||||||
|
<el-input-number v-model="formData.reconstructionCost" :min="0" :precision="2" style="width: 100%" />
|
||||||
|
<span class="unit-suffix">万元</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<div class="form-actions">
|
||||||
|
<el-button @click="handleBack">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" :loading="submitting">提交</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 图片预览对话框 -->
|
||||||
|
<el-dialog v-model="previewDialogVisible" title="图片预览" width="600px">
|
||||||
|
<img :src="previewImageUrl" style="width: 100%" alt="预览图片" />
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { Plus, Upload } from '@element-plus/icons-vue'
|
||||||
|
import { request } from '@/utils/request'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const formRef = ref(null)
|
||||||
|
const submitting = ref(false)
|
||||||
|
|
||||||
|
// 是否为编辑模式
|
||||||
|
const isEdit = computed(() => !!route.query.id)
|
||||||
|
|
||||||
|
// 图片预览
|
||||||
|
const previewDialogVisible = ref(false)
|
||||||
|
const previewImageUrl = ref('')
|
||||||
|
|
||||||
|
// 地点级联选择器选项(示例数据)
|
||||||
|
const locationOptions = [
|
||||||
|
{
|
||||||
|
value: 'chongqing',
|
||||||
|
label: '重庆市',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
value: 'wanzhou',
|
||||||
|
label: '万州区',
|
||||||
|
children: [
|
||||||
|
{ value: 'shuanghekou', label: '双河口街道' },
|
||||||
|
{ value: 'zhoujiaba', label: '周家坝街道' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'kaizhou',
|
||||||
|
label: '开州区',
|
||||||
|
children: [
|
||||||
|
{ value: 'hanfeng', label: '汉丰街道' },
|
||||||
|
{ value: 'wenfeng', label: '文峰街道' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive({
|
||||||
|
// 填报人员信息
|
||||||
|
reportUnit: '',
|
||||||
|
contactPerson: '',
|
||||||
|
contactPhone: '',
|
||||||
|
// 路况事件信息
|
||||||
|
eventType: '',
|
||||||
|
dangerDesc: '',
|
||||||
|
measure: '',
|
||||||
|
isBlocked: '',
|
||||||
|
waterDamageCount: 0,
|
||||||
|
blockedMileage: 0,
|
||||||
|
discoverTime: '',
|
||||||
|
predictRecoverTime: '',
|
||||||
|
siteDescription: '',
|
||||||
|
// 位置信息
|
||||||
|
routeType: '国省道',
|
||||||
|
district: '',
|
||||||
|
routeCode: '',
|
||||||
|
routeName: '',
|
||||||
|
startPile: '',
|
||||||
|
endPile: '',
|
||||||
|
locationPath: [],
|
||||||
|
smallPlaceName: '',
|
||||||
|
longitude: '',
|
||||||
|
latitude: '',
|
||||||
|
// 附件
|
||||||
|
images: [],
|
||||||
|
videos: [],
|
||||||
|
// 灾毁损失
|
||||||
|
injuredCount: 0,
|
||||||
|
deathCount: 0,
|
||||||
|
strandedVehicles: 0,
|
||||||
|
damagedVehicles: 0,
|
||||||
|
clearVolume: 0,
|
||||||
|
fillLoss: '',
|
||||||
|
roadLoss: '',
|
||||||
|
slopeLoss: '',
|
||||||
|
bridgeLoss: '',
|
||||||
|
tunnelLoss: '',
|
||||||
|
culvertLoss: '',
|
||||||
|
guardrailLength: 0,
|
||||||
|
roadsideTrees: 0,
|
||||||
|
otherLossAmount: 0,
|
||||||
|
otherLossDesc: '',
|
||||||
|
inputMachinery: 0,
|
||||||
|
inputLabor: 0,
|
||||||
|
inputFunds: 0,
|
||||||
|
// 恢复重建
|
||||||
|
needReconstruction: '是',
|
||||||
|
reconstructionCost: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单校验规则
|
||||||
|
const formRules = {
|
||||||
|
reportUnit: [{ required: true, message: '请输入填报单位', trigger: 'blur' }],
|
||||||
|
contactPerson: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
||||||
|
contactPhone: [
|
||||||
|
{ required: true, message: '请输入联系电话', trigger: 'blur' },
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
eventType: [{ required: true, message: '请选择事件类型', trigger: 'change' }],
|
||||||
|
isBlocked: [{ required: true, message: '请选择是否阻断', trigger: 'change' }],
|
||||||
|
discoverTime: [{ required: true, message: '请选择发现时间', trigger: 'change' }],
|
||||||
|
routeType: [{ required: true, message: '请选择路线类型', trigger: 'change' }],
|
||||||
|
district: [{ required: true, message: '请选择所属区县', trigger: 'change' }],
|
||||||
|
routeCode: [{ required: true, message: '请输入路线编号', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片上传前校验
|
||||||
|
const beforeImageUpload = (file) => {
|
||||||
|
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
|
||||||
|
const isLt500k = file.size / 1024 < 500
|
||||||
|
|
||||||
|
if (!isJpgOrPng) {
|
||||||
|
ElMessage.error('只能上传 JPG/PNG 格式的图片!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!isLt500k) {
|
||||||
|
ElMessage.error('图片大小不能超过 500KB!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false // 返回false阻止自动上传,由提交时统一处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频上传前校验
|
||||||
|
const beforeVideoUpload = (file) => {
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 3
|
||||||
|
if (!isLt3M) {
|
||||||
|
ElMessage.error('视频大小不能超过 3MB!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false // 返回false阻止自动上传,由提交时统一处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片预览
|
||||||
|
const handlePicturePreview = (file) => {
|
||||||
|
previewImageUrl.value = file.url
|
||||||
|
previewDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片移除
|
||||||
|
const handlePictureRemove = (file, fileList) => {
|
||||||
|
formData.images = fileList
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回上一页
|
||||||
|
const handleBack = () => {
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!formRef.value) return
|
||||||
|
|
||||||
|
await formRef.value.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
ElMessage.warning('请完善表单信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
// 构建提交数据
|
||||||
|
const submitData = {
|
||||||
|
...formData,
|
||||||
|
// 处理级联选择器值
|
||||||
|
locationPath: formData.locationPath.join('/'),
|
||||||
|
// 处理附件列表
|
||||||
|
imageList: formData.images.map((item) => item.raw),
|
||||||
|
videoList: formData.videos.map((item) => item.raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟提交,实际使用时取消注释
|
||||||
|
// if (isEdit.value) {
|
||||||
|
// await request({ url: `/api/water-damage/events/${route.query.id}`, method: 'put', data: submitData })
|
||||||
|
// ElMessage.success('编辑成功')
|
||||||
|
// } else {
|
||||||
|
// await request({ url: '/api/water-damage/events', method: 'post', data: submitData })
|
||||||
|
// ElMessage.success('新增成功')
|
||||||
|
// }
|
||||||
|
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
|
ElMessage.success(isEdit.value ? '编辑成功' : '新增成功')
|
||||||
|
router.back()
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('提交失败,请重试')
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载编辑数据
|
||||||
|
const loadEditData = async () => {
|
||||||
|
if (!isEdit.value) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 模拟获取详情数据,实际使用时取消注释
|
||||||
|
// const response = await request({ url: `/api/water-damage/events/${route.query.id}`, method: 'get' })
|
||||||
|
// const data = response.data
|
||||||
|
// Object.assign(formData, data)
|
||||||
|
|
||||||
|
// 模拟数据
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 300))
|
||||||
|
Object.assign(formData, {
|
||||||
|
reportUnit: '万州区公路中心',
|
||||||
|
contactPerson: '王强',
|
||||||
|
contactPhone: '15978906789',
|
||||||
|
eventType: '水毁事件',
|
||||||
|
dangerDesc: '抢险中',
|
||||||
|
measure: '交通管制',
|
||||||
|
isBlocked: '是',
|
||||||
|
waterDamageCount: 3,
|
||||||
|
blockedMileage: 1.25,
|
||||||
|
discoverTime: '2024-07-11 16:00:00',
|
||||||
|
predictRecoverTime: '2024-08-12 16:30:00',
|
||||||
|
siteDescription: '边坡塌方导致道路中断,正在组织抢通',
|
||||||
|
routeType: '国省道',
|
||||||
|
district: '万州区',
|
||||||
|
routeCode: 'S202',
|
||||||
|
routeName: '开云路',
|
||||||
|
startPile: 'K17.200',
|
||||||
|
endPile: 'K17.350',
|
||||||
|
locationPath: ['chongqing', 'wanzhou', 'shuanghekou'],
|
||||||
|
smallPlaceName: '三汇口',
|
||||||
|
longitude: '108.408',
|
||||||
|
latitude: '30.808',
|
||||||
|
injuredCount: 0,
|
||||||
|
deathCount: 0,
|
||||||
|
strandedVehicles: 5,
|
||||||
|
damagedVehicles: 1,
|
||||||
|
clearVolume: 1200,
|
||||||
|
guardrailLength: 0.15,
|
||||||
|
roadsideTrees: 8,
|
||||||
|
otherLossAmount: 10,
|
||||||
|
otherLossDesc: '部分边沟损毁',
|
||||||
|
inputMachinery: 6,
|
||||||
|
inputLabor: 25,
|
||||||
|
inputFunds: 8,
|
||||||
|
needReconstruction: '是',
|
||||||
|
reconstructionCost: 50
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('加载数据失败')
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadEditData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.disaster-form-page {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
|
||||||
|
.disaster-form {
|
||||||
|
.form-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
:deep(.el-card__header) {
|
||||||
|
padding: 12px 20px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
.section-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 3px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: #409eff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-section-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #606266;
|
||||||
|
margin: 8px 0 16px 0;
|
||||||
|
padding-left: 8px;
|
||||||
|
border-left: 3px solid #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unit-suffix {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 20px 0 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
202
packages/screen/src/views/DisasterManagement/mockDataList.json
Normal file
202
packages/screen/src/views/DisasterManagement/mockDataList.json
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"reportUnit": "开州区交通建设发展中心",
|
||||||
|
"routeCode": "S202",
|
||||||
|
"routeName": "开云路",
|
||||||
|
"startPile": "17.200",
|
||||||
|
"endPile": "17.350",
|
||||||
|
"locationDesc": "三汇口",
|
||||||
|
"isBlocked": "是",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2024-07-11",
|
||||||
|
"predictRecoverTime": "2024-08-12",
|
||||||
|
"contactPerson": "郭玲雅",
|
||||||
|
"contactPhone": "18223732276",
|
||||||
|
"hasImage": true,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"reportUnit": "彭水苗族土家族自治县...",
|
||||||
|
"routeCode": "G319",
|
||||||
|
"routeName": "高雄-成都",
|
||||||
|
"startPile": "2272",
|
||||||
|
"endPile": "2273",
|
||||||
|
"locationDesc": "高谷",
|
||||||
|
"isBlocked": "否",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2025-06-04",
|
||||||
|
"predictRecoverTime": "2025-06-04",
|
||||||
|
"contactPerson": "朱小明",
|
||||||
|
"contactPhone": "18996180931",
|
||||||
|
"hasImage": false,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"reportUnit": "巫溪县交通局",
|
||||||
|
"routeCode": "S301",
|
||||||
|
"routeName": "溪城路",
|
||||||
|
"startPile": "40.970",
|
||||||
|
"endPile": "40.990",
|
||||||
|
"locationDesc": "重庆市巫溪县通城镇通江街",
|
||||||
|
"isBlocked": "否",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2025-07-04",
|
||||||
|
"predictRecoverTime": "2025-08-20",
|
||||||
|
"contactPerson": "宁阳",
|
||||||
|
"contactPhone": "18182310829",
|
||||||
|
"hasImage": true,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"reportUnit": "綦江区公路事务中心",
|
||||||
|
"routeCode": "S534",
|
||||||
|
"routeName": "一赶路",
|
||||||
|
"startPile": "132.550",
|
||||||
|
"endPile": "132.600",
|
||||||
|
"locationDesc": "重庆市綦江区赶水镇280县道..",
|
||||||
|
"isBlocked": "否",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2025-07-22",
|
||||||
|
"predictRecoverTime": "2025-07-22",
|
||||||
|
"contactPerson": "沈伟",
|
||||||
|
"contactPhone": "13637759650",
|
||||||
|
"hasImage": false,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"reportUnit": "酉阳土家族苗族自治县...",
|
||||||
|
"routeCode": "G211",
|
||||||
|
"routeName": "银川一榕江",
|
||||||
|
"startPile": "1828.8",
|
||||||
|
"endPile": "1828.81",
|
||||||
|
"locationDesc": "重庆市酉阳土家族苗族自治县.",
|
||||||
|
"isBlocked": "否",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2025-10-20",
|
||||||
|
"predictRecoverTime": "2025-10-21",
|
||||||
|
"contactPerson": "陈建琼",
|
||||||
|
"contactPhone": "",
|
||||||
|
"hasImage": false,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"reportUnit": "黔江区公路事务中心",
|
||||||
|
"routeCode": "S203",
|
||||||
|
"routeName": "黔彭路",
|
||||||
|
"startPile": "48.720",
|
||||||
|
"endPile": "48.750",
|
||||||
|
"locationDesc": "重庆市黔江区小南海镇209省道",
|
||||||
|
"isBlocked": "是",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2023-09-25",
|
||||||
|
"predictRecoverTime": "2023-09-25",
|
||||||
|
"contactPerson": "刘昭君",
|
||||||
|
"contactPhone": "13594943712",
|
||||||
|
"hasImage": true,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"reportUnit": "武隆区公路养护公司",
|
||||||
|
"routeCode": "S521",
|
||||||
|
"routeName": "后沧路",
|
||||||
|
"startPile": "7.050",
|
||||||
|
"endPile": "7.070",
|
||||||
|
"locationDesc": "代家窑脚",
|
||||||
|
"isBlocked": "是",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2020-06-21",
|
||||||
|
"predictRecoverTime": "2020-07-11",
|
||||||
|
"contactPerson": "向显凤",
|
||||||
|
"contactPhone": "18696935340",
|
||||||
|
"hasImage": false,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"reportUnit": "石柱县公路局",
|
||||||
|
"routeCode": "G350",
|
||||||
|
"routeName": "利川一炉霍",
|
||||||
|
"startPile": "87.850",
|
||||||
|
"endPile": "87.900",
|
||||||
|
"locationDesc": "三块石",
|
||||||
|
"isBlocked": "是",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2020-07-12",
|
||||||
|
"predictRecoverTime": "2020-07-12",
|
||||||
|
"contactPerson": "陈世良",
|
||||||
|
"contactPhone": "13609484536",
|
||||||
|
"hasImage": true,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"reportUnit": "梁平区公路局",
|
||||||
|
"routeCode": "G243",
|
||||||
|
"routeName": "开县一凭祥",
|
||||||
|
"startPile": "67.88",
|
||||||
|
"endPile": "67.885",
|
||||||
|
"locationDesc": "合兴街道老拱桥",
|
||||||
|
"isBlocked": "否",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2021-05-15",
|
||||||
|
"predictRecoverTime": "2021-05-15",
|
||||||
|
"contactPerson": "江勇",
|
||||||
|
"contactPhone": "13628409515",
|
||||||
|
"hasImage": false,
|
||||||
|
"hasVideo": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"reportUnit": "奉节公路事务中心",
|
||||||
|
"routeCode": "G348",
|
||||||
|
"routeName": "武汉一大理",
|
||||||
|
"startPile": "806.8",
|
||||||
|
"endPile": "806.86",
|
||||||
|
"locationDesc": "麻牛坨",
|
||||||
|
"isBlocked": "是",
|
||||||
|
"eventType": "水毁事件",
|
||||||
|
"routeCategory": "国省道",
|
||||||
|
"eventStatus": "已解除",
|
||||||
|
"measure": "正常通行",
|
||||||
|
"discoverTime": "2021-07-08",
|
||||||
|
"predictRecoverTime": "2021-07-10",
|
||||||
|
"contactPerson": "王大平",
|
||||||
|
"contactPhone": "13983502063",
|
||||||
|
"hasImage": true,
|
||||||
|
"hasVideo": false
|
||||||
|
}
|
||||||
|
]
|
||||||
Loading…
x
Reference in New Issue
Block a user