feat: PC灾毁管理
This commit is contained in:
parent
4832facbf9
commit
bb74f03feb
@ -132,7 +132,7 @@
|
||||
<span class="info-value">{{ detailData.event?.needsRecovery ? '是' : '否' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-col :span="16" v-if="detailData.event?.needsRecovery">
|
||||
<div class="info-item">
|
||||
<span class="info-label">恢复重建预估费用:</span>
|
||||
<span class="info-value">{{ detailData.event?.estimatedRecoveryCost ? detailData.event.estimatedRecoveryCost + '万元' : '-' }}</span>
|
||||
@ -195,21 +195,21 @@
|
||||
<LossListDetail :modelValue="report.lossList" :col-span="8" />
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<div class="info-item margin">
|
||||
<span class="info-label">已投入机械:</span>
|
||||
<span class="info-value">{{ report.investedMachinery }}</span>
|
||||
<span class="info-value">{{ report.investedMachinery ? report.investedMachinery + '台/班' : '-'}}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<div class="info-item margin">
|
||||
<span class="info-label">已投入人力:</span>
|
||||
<span class="info-value">{{ report.investedManpower }}</span>
|
||||
<span class="info-value">{{ report.investedManpower ? report.investedManpower + '人次' : '-'}}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="info-item">
|
||||
<div class="info-item margin">
|
||||
<span class="info-label">已投入资金:</span>
|
||||
<span class="info-value">{{ report.investedFunds }}</span>
|
||||
<span class="info-value">{{ report.investedFunds ? report.investedFunds + '万元' : '-'}}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -469,6 +469,10 @@ onMounted(() => {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&.margin {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
|
||||
@ -71,7 +71,6 @@ onMounted(async () => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loss-list-detail {
|
||||
width: 100%;
|
||||
|
||||
.loss-table {
|
||||
margin-bottom: 16px;
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
</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-select v-model="filterForm.type" placeholder="请选择" clearable>
|
||||
<el-option label="水毁事件" value="WATER_DAMAGE" />
|
||||
<el-option label="冰雪灾害" value="ICE_SNOW" />
|
||||
</el-select>
|
||||
@ -37,18 +37,15 @@
|
||||
</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 v-model="filterForm.blocked" placeholder="请选择" clearable>
|
||||
<el-option v-for="(option, idx) in options['yesNoBool']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</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 v-model="filterForm.routeType" placeholder="请选择" clearable>
|
||||
<el-option v-for="(option, idx) in options['roadType']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -69,7 +66,7 @@
|
||||
<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 type="success" @click="handleExport">导出Excel</el-button> -->
|
||||
<el-button @click="resetFilters">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -86,7 +83,11 @@
|
||||
{{ scope.$index + 1 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="district" label="所属区县" min-width="120" />
|
||||
<el-table-column prop="district" label="所属区县" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span>{{ getDistrictName(row.district) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<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="startStakeNo" label="起点桩号" min-width="110" show-overflow-tooltip />
|
||||
@ -120,13 +121,13 @@
|
||||
<el-table-column prop="contactPhone" label="联系电话" width="120" />
|
||||
<el-table-column label="图片" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-icon style="font-size: 18px; cursor: pointer;" v-if="row.images && row.images.length > 0" @click="viewImages(row)"><Picture /></el-icon>
|
||||
<el-icon style="font-size: 18px; cursor: pointer" v-if="row.images && row.images.length > 0" @click="viewImages(row)"><Picture /></el-icon>
|
||||
<span v-else>—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="视频" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-icon v-if="row.videos && row.videos.length > 0" style="font-size: 18px; cursor: pointer;" @click="viewVideos(row)"><VideoPlay /></el-icon>
|
||||
<el-icon v-if="row.videos && row.videos.length > 0" style="font-size: 18px; cursor: pointer" @click="viewVideos(row)"><VideoPlay /></el-icon>
|
||||
<span v-else>—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -165,18 +166,19 @@ import { useRouter } from 'vue-router'
|
||||
import { request } from '@/utils/request'
|
||||
import { Picture, VideoPlay } from '@element-plus/icons-vue'
|
||||
import VideoPreviewDialog from '@/component/VideoPreviewDialog.vue'
|
||||
import { useOptions } from '@shared/composables/useOptions'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const { options, getAreaOptions } = useOptions()
|
||||
// 筛选表单
|
||||
const filterForm = reactive({
|
||||
unit: '', // 所属单位
|
||||
occurLocation: '', // 发生地点
|
||||
routeNo: '', // 路线编号
|
||||
disasterType: '', // 灾害类型/事件类别
|
||||
type: '', // 灾害类型/事件类别
|
||||
eventStatus: '', // 事件状态 (0-未解除, 1-已解除)
|
||||
isBlocked: '', // 是否阻断
|
||||
roadConditionType: '', // 路线类型
|
||||
blocked: '', // 是否阻断
|
||||
routeType: '', // 路线类型
|
||||
pushStatus: '' // 推送状态
|
||||
})
|
||||
|
||||
@ -199,6 +201,11 @@ const pagination = reactive({
|
||||
total: 0
|
||||
})
|
||||
|
||||
const getDistrictName = (districtId) => {
|
||||
if (!options.value.area?.length) return '-'
|
||||
return options.value.area.find((item) => item.value === districtId)?.label || '-'
|
||||
}
|
||||
|
||||
// 构建查询参数
|
||||
const buildQueryParams = () => {
|
||||
const params = {
|
||||
@ -207,15 +214,15 @@ const buildQueryParams = () => {
|
||||
unit: filterForm.unit,
|
||||
occurLocation: filterForm.occurLocation,
|
||||
routeNo: filterForm.routeNo,
|
||||
disasterType: filterForm.disasterType,
|
||||
type: filterForm.type,
|
||||
eventStatus: filterForm.eventStatus,
|
||||
isBlocked: filterForm.isBlocked,
|
||||
roadConditionType: filterForm.roadConditionType
|
||||
blocked: filterForm.blocked,
|
||||
routeType: filterForm.routeType
|
||||
}
|
||||
|
||||
if (dateRange.value && dateRange.value.length === 2) {
|
||||
params.startDate = dateRange.value[0]
|
||||
params.endDate = dateRange.value[1]
|
||||
params.startTime = dateRange.value[0] + " 00:00:00"
|
||||
params.endTime = dateRange.value[1] + " 23:59:59"
|
||||
}
|
||||
|
||||
// 过滤空字符串或null的参数
|
||||
@ -301,10 +308,10 @@ const resetFilters = () => {
|
||||
filterForm.unit = ''
|
||||
filterForm.occurLocation = ''
|
||||
filterForm.routeNo = ''
|
||||
filterForm.disasterType = ''
|
||||
filterForm.type = ''
|
||||
filterForm.eventStatus = ''
|
||||
filterForm.isBlocked = ''
|
||||
filterForm.roadConditionType = ''
|
||||
filterForm.blocked = ''
|
||||
filterForm.routeType = ''
|
||||
filterForm.pushStatus = ''
|
||||
dateRange.value = null
|
||||
handleQuery()
|
||||
@ -353,6 +360,8 @@ const handleCurrentChange = (val) => {
|
||||
|
||||
// 初始化加载数据
|
||||
onMounted(() => {
|
||||
getAreaOptions()
|
||||
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div class="selector-component">
|
||||
<el-input :modelValue="modelValue" :placeholder="placeholder" readonly @click="openDialog">
|
||||
<template #suffix>
|
||||
<el-icon><ArrowDown /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" :width="dialogWidth" :append-to-body="true" :modal="true" @close="handleDialogClose">
|
||||
<div class="dialog-content">
|
||||
<div class="title">已选择地点路线:{{ tempSelectedItem?.routeCode }}</div>
|
||||
|
||||
<el-input v-model="searchKeyword" :placeholder="searchPlaceholder" clearable @input="handleSearch" />
|
||||
|
||||
<el-table :data="dataList" v-loading="loading" height="350" @row-click="handleRowClick" highlight-current-row>
|
||||
<el-table-column prop="routeCode" label="线路编号" />
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-wrapper" v-if="total > 0">
|
||||
<el-pagination
|
||||
v-model:current-page="currentPage"
|
||||
:page-size="pageSize"
|
||||
:total="total"
|
||||
:page-sizes="pageSizes"
|
||||
layout="prev, pager, next, sizes"
|
||||
@current-change="handlePageChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onUnmounted, watch } from 'vue'
|
||||
import { ArrowDown } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { request } from '@shared/utils/request'
|
||||
|
||||
// ==================== Props ====================
|
||||
const props = defineProps({
|
||||
// v-model 绑定的值
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 占位符文本
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
// 弹窗标题
|
||||
dialogTitle: {
|
||||
type: String,
|
||||
default: '选择地点路线'
|
||||
},
|
||||
// 弹窗宽度
|
||||
dialogWidth: {
|
||||
type: String,
|
||||
default: '500px'
|
||||
},
|
||||
// 搜索框占位符
|
||||
searchPlaceholder: {
|
||||
type: String,
|
||||
default: '请输入关键词搜索'
|
||||
},
|
||||
// 请求接口地址
|
||||
apiUrl: {
|
||||
type: String,
|
||||
default: '/snow-ops-platform/infrastructure-asset/routes'
|
||||
},
|
||||
// 每页大小
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
// 每页大小选项
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default: () => [10, 20, 50]
|
||||
},
|
||||
// 额外请求参数
|
||||
extraParams: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
// 搜索防抖延迟时间(ms)
|
||||
searchDelay: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'change'])
|
||||
|
||||
// ==================== 状态 ====================
|
||||
const dialogVisible = ref(false)
|
||||
const searchKeyword = ref('')
|
||||
const dataList = ref([])
|
||||
const loading = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(props.pageSize)
|
||||
const total = ref(0)
|
||||
|
||||
// 临时选中的数据(确定前暂存)
|
||||
const tempSelectedItem = ref(null)
|
||||
|
||||
// 防抖定时器
|
||||
let searchTimer = null
|
||||
|
||||
// 已确认选中的值
|
||||
const selectedValue = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, () => {
|
||||
if(props.modelValue != tempSelectedItem.value?.routeCode) {
|
||||
tempSelectedItem.value = null
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== API 请求 ====================
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const params = {
|
||||
pageNum: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
lxbh: props.modelValue,
|
||||
xzdj: props.extraParams?.xzdj, // 行政等级
|
||||
qxid: props.extraParams?.qxid // 区县编码
|
||||
}
|
||||
|
||||
// 如果有搜索关键词,添加到参数中
|
||||
if (searchKeyword.value) {
|
||||
params.lxbh = searchKeyword.value
|
||||
}
|
||||
|
||||
const response = await request({
|
||||
url: props.apiUrl,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
|
||||
if (response?.code === '00000') {
|
||||
const records = response.data.records || []
|
||||
total.value = response.data.total || 0
|
||||
|
||||
// 统一格式化数据,便于内部使用
|
||||
dataList.value = records
|
||||
} else {
|
||||
ElMessage.error(response.message || '加载失败')
|
||||
dataList.value = []
|
||||
total.value = 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求失败:', error)
|
||||
ElMessage.error('加载失败,请重试')
|
||||
dataList.value = []
|
||||
total.value = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 带防抖的搜索函数
|
||||
const debouncedSearch = () => {
|
||||
// 清除之前的定时器
|
||||
if (searchTimer) {
|
||||
clearTimeout(searchTimer)
|
||||
}
|
||||
|
||||
// 设置新的定时器
|
||||
searchTimer = setTimeout(() => {
|
||||
currentPage.value = 1
|
||||
fetchData()
|
||||
}, props.searchDelay)
|
||||
}
|
||||
|
||||
// ==================== 事件处理 ====================
|
||||
const openDialog = () => {
|
||||
dialogVisible.value = true
|
||||
// 重置状态
|
||||
searchKeyword.value = tempSelectedItem.value?.routeCode || ''
|
||||
currentPage.value = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleDialogClose = () => {
|
||||
dialogVisible.value = false
|
||||
// 关闭弹窗时清除防抖定时器
|
||||
if (searchTimer) {
|
||||
clearTimeout(searchTimer)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
// 使用防抖处理搜索
|
||||
debouncedSearch()
|
||||
}
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
currentPage.value = page
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleSizeChange = (size) => {
|
||||
pageSize.value = size
|
||||
currentPage.value = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleRowClick = (row) => {
|
||||
tempSelectedItem.value = row
|
||||
selectedValue.value = tempSelectedItem.value.routeCode
|
||||
dialogVisible.value = false
|
||||
emit('change', tempSelectedItem.value)
|
||||
}
|
||||
|
||||
// ==================== 清理定时器 ====================
|
||||
onUnmounted(() => {
|
||||
if (searchTimer) {
|
||||
clearTimeout(searchTimer)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.selector-component {
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
cursor: pointer;
|
||||
|
||||
.el-input__inner {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<el-row class="loss-list-pc" :gutter="24">
|
||||
<el-col :span="colSpan" v-for="(item, index) in configs" :key="index">
|
||||
<template v-for="(item, index) in configs" :key="index">
|
||||
<el-col :span="colSpan">
|
||||
<el-form-item :label="item.lossTypeName">
|
||||
<el-input :modelValue="getValue(item)" @update:modelValue="(event) => changeValue(item, event)">
|
||||
<template #suffix>
|
||||
@ -9,6 +10,12 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" v-if="item.lossTypeCode == 'OTHER_LOSS'">
|
||||
<el-form-item label="其它损失描述">
|
||||
<el-input v-model="getValueItem(item).remark" placeholder="请填写"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@ -32,9 +39,17 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const getValue = (config) => {
|
||||
const value = props.modelValue.find((v) => v.lossTypeId === config.lossTypeId)
|
||||
if (value == null) props.modelValue.push({ ...config })
|
||||
return value?.totalAmount || 0
|
||||
const item = getValueItem(config)
|
||||
return item?.totalAmount || 0
|
||||
}
|
||||
|
||||
const getValueItem = (config) => {
|
||||
let item = props.modelValue.find((v) => v.lossTypeId === config.lossTypeId)
|
||||
if (item == null) {
|
||||
item = { ...config }
|
||||
props.modelValue.push(item)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
const configs = ref([])
|
||||
|
||||
@ -37,8 +37,7 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="事件类型">
|
||||
<el-select v-model="eventType" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="水毁事件" value="水毁事件" />
|
||||
<el-option label="冰雪事件" value="冰雪事件" />
|
||||
<el-option v-for="(option, idx) in options['eventType']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -46,12 +45,7 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="路况类别" prop="roadConditionType">
|
||||
<el-select v-model="formData.roadConditionType" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="高速公路" value="高速公路" />
|
||||
<el-option label="国道" value="国道" />
|
||||
<el-option label="省道" value="省道" />
|
||||
<el-option label="县道" value="县道" />
|
||||
<el-option label="乡道" value="乡道" />
|
||||
<el-option label="村道" value="村道" />
|
||||
<el-option v-for="(option, idx) in options['roadConditionType']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -59,8 +53,7 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="是否阻断" prop="event.isBlocked">
|
||||
<el-select v-model="formData.event.isBlocked" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="是" :value="true" />
|
||||
<el-option label="否" :value="false" />
|
||||
<el-option v-for="(option, idx) in options['yesNoBool']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -70,19 +63,15 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="抢险进度" prop="event.repairProgress">
|
||||
<el-select v-model="formData.event.repairProgress" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="未抢险" value="未抢险" />
|
||||
<el-option label="抢险中" value="抢险中" />
|
||||
<el-option v-for="(option, idx) in options['repairProgress']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 处理措施-->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="处理措施" prop="event.disposalMeasures">
|
||||
<el-select v-model="formData.event.disposalMeasures" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="全幅封闭" value="全幅封闭" />
|
||||
<el-option label="半幅封闭" value="半幅封闭" />
|
||||
<el-option label="正常通行" value="正常通行" />
|
||||
<el-option label="限制通行" value="限制通行" />
|
||||
<el-form-item label="处理措施" prop="report.disposalMeasures">
|
||||
<el-select v-model="formData.report.disposalMeasures" placeholder="请选择" style="width: 100%">
|
||||
<el-option v-for="(option, idx) in options['disposalMeasures']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -126,7 +115,7 @@
|
||||
<el-row :gutter="24">
|
||||
<!-- 现场描述 -->
|
||||
<el-col :span="16">
|
||||
<el-form-item label="现场描述" prop="report.siteDescription">
|
||||
<el-form-item label="现场描述(绕行方案)" prop="report.siteDescription">
|
||||
<el-input v-model="formData.report.siteDescription" type="textarea" :rows="2" placeholder="请填写" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -135,20 +124,19 @@
|
||||
|
||||
<BlockItem title="位置信息">
|
||||
<el-row :gutter="24">
|
||||
<!-- 线路编号 -->
|
||||
<!-- 路线类型 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="路线类型" prop="routeNo">
|
||||
<el-input v-model="formData.routeNo" placeholder="请填写" />
|
||||
<el-form-item label="路线类型">
|
||||
<el-select v-model="filterForm.routeType" placeholder="请选择" style="width: 100%">
|
||||
<el-option v-for="(option, idx) in options['roadType']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 所属区县 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="所属区县" prop="event.district">
|
||||
<el-select v-model="formData.event.district" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="万州区" value="万州区" />
|
||||
<el-option label="开州区" value="开州区" />
|
||||
<el-option label="黔江区" value="黔江区" />
|
||||
<el-option label="涪陵区" value="涪陵区" />
|
||||
<el-select v-model="formData.event.district" placeholder="请选择" style="width: 100%" @change="handleDistrictChange">
|
||||
<el-option v-for="(option, idx) in options['area']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -156,7 +144,7 @@
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="地点路线" prop="routeNo">
|
||||
<el-input v-model="formData.routeNo" placeholder="请填写" />
|
||||
<RoadRoutesSelect v-model="formData.routeNo" @change="handleRouteNoChange" :extra-params="{ xzdj: filterForm.routeType, qxid: formData.event.district }" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 起点桩号 -->
|
||||
@ -193,15 +181,15 @@
|
||||
<el-row :gutter="24">
|
||||
<!-- 经度 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="经度" prop="event.startStakeLng">
|
||||
<el-input v-model="formData.event.startStakeLng" placeholder="经度"> </el-input>
|
||||
<el-form-item label="经度" prop="event.longitude">
|
||||
<el-input v-model="formData.event.longitude" placeholder="经度"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 纬度 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="纬度" prop="event.startStakeLat">
|
||||
<el-input v-model="formData.event.startStakeLat" placeholder="纬度"> </el-input>
|
||||
<el-form-item label="纬度" prop="event.latitude">
|
||||
<el-input v-model="formData.event.latitude" placeholder="纬度"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -315,13 +303,6 @@
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 其他损失描述 -->
|
||||
<el-col :span="24">
|
||||
<el-form-item label="其他损失描述" prop="report.siteDescription">
|
||||
<el-input v-model="formData.report.siteDescription" type="textarea" :rows="2" placeholder="请填写" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</BlockItem>
|
||||
<BlockItem title="恢复重建预估费用">
|
||||
@ -330,14 +311,13 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="是否需要恢复重建" prop="event.needsRecovery">
|
||||
<el-select v-model="formData.event.needsRecovery" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="是" :value="true" />
|
||||
<el-option label="否" :value="false" />
|
||||
<el-option v-for="(option, idx) in options['yesNoBool']" :label="option.label" :value="option.value" :key="idx" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 恢复重建预估费用 -->
|
||||
<el-col :span="8" v-if="!isContinue">
|
||||
<el-col :span="8" v-if="formData?.event.needsRecovery">
|
||||
<el-form-item label="恢复重建预估费用" prop="event.estimatedRecoveryCost">
|
||||
<el-input-number v-model="formData.event.estimatedRecoveryCost" :min="0" :precision="2" style="width: 100%" placeholder="请填写">
|
||||
<template #suffix>
|
||||
@ -374,9 +354,12 @@ import { request } from '@/utils/request'
|
||||
import LossList from './WaterDisasterLossListPC.vue'
|
||||
import BlockItem from '@/component/BlockItem.vue'
|
||||
import FileUpload from '@/component/FileUpload/FileUpload.vue'
|
||||
import { useOptions } from '@shared/composables/useOptions'
|
||||
import RoadRoutesSelect from './RoadRoutesSelect.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { options, getAreaOptions } = useOptions()
|
||||
const formRef = ref(null)
|
||||
const submitting = ref(false)
|
||||
|
||||
@ -392,6 +375,10 @@ const videoFileList = ref([])
|
||||
|
||||
const eventType = ref('水毁事件')
|
||||
|
||||
const filterForm = reactive({
|
||||
routeType: ''
|
||||
})
|
||||
|
||||
const formData = reactive({
|
||||
// 顶层字段
|
||||
occurLocation: null, // 发生地点/路况位置
|
||||
@ -502,14 +489,29 @@ watch(
|
||||
|
||||
// 表单校验规则
|
||||
const formRules = {
|
||||
roadConditionType: [{ required: true, message: '请选择路况类别', trigger: 'change' }],
|
||||
"event.isBlocked": [{ required: true, message: '请选择是否阻断', trigger: 'change' }],
|
||||
"event.repairProgress": [{ required: true, message: '请选择抢险进度', trigger: 'change' }],
|
||||
"report.disposalMeasures": [{ required: true, message: '请选择处置措施', trigger: 'change' }],
|
||||
"event.damageCount": [{ required: true, message: '请输入水毁处数', trigger: 'blur' }],
|
||||
"event.blockedMileage": [{ required: true, message: '请输入阻断里程', trigger: 'blur' }],
|
||||
occurTime: [{ required: true, message: '请选择发生时间', trigger: 'change' }],
|
||||
routeNo: [{ required: true, message: '请输入线路编号', trigger: 'blur' }],
|
||||
'event.reporterUnit': [{ required: true, message: '请输入填报单位', trigger: 'blur' }],
|
||||
'event.contactPerson': [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
||||
'event.contactPhone': [
|
||||
{ required: true, message: '请输入联系电话', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
||||
]
|
||||
"report.expectRecoverTime": [{ required: true, message: '请输入预计恢复时间', trigger: 'blur' }],
|
||||
"routeNo": [{ required: true, message: '请输入线路编号', trigger: 'blur' }],
|
||||
"event.startStakeNo": [{ required: true, message: '请输入起点桩号', trigger: 'blur' }],
|
||||
"event.endStakeNo": [{ required: true, message: '请输入止点桩号', trigger: 'blur' }],
|
||||
"occurLocation": [{ required: true, message: '请输入路况位置', trigger: 'blur' }],
|
||||
"event.blockedPointName": [{ required: true, message: '请输入阻断点小地名', trigger: 'blur' }],
|
||||
"event.longitude": [{ required: true, message: '请输入经度', trigger: 'blur' }],
|
||||
"event.latitude": [{ required: true, message: '请输入纬度', trigger: 'blur' }],
|
||||
"event.needsRecovery": [{ required: true, message: '请选择是否需要恢复重建', trigger: 'change' }],
|
||||
"event.estimatedRecoveryCost": [{ required: true, message: '请输入恢复重建预估费用', trigger: 'blur' }],
|
||||
// 'event.reporterUnit': [{ required: true, message: '请输入填报单位', trigger: 'blur' }],
|
||||
// 'event.contactPerson': [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
||||
// 'event.contactPhone': [
|
||||
// { required: true, message: '请输入联系电话', trigger: 'blur' },
|
||||
// { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
||||
// ]
|
||||
}
|
||||
|
||||
// 图片上传前校验
|
||||
@ -561,6 +563,16 @@ const initFormData = (data) => {
|
||||
Object.assign(formData, data)
|
||||
}
|
||||
|
||||
|
||||
const handleDistrictChange = () => {
|
||||
formData.routeNo = null
|
||||
}
|
||||
|
||||
const handleRouteNoChange = (item) => {
|
||||
formData.event.startStakeNo = item.startStakeNo
|
||||
formData.event.endStakeNo = item.endStakeNo
|
||||
}
|
||||
|
||||
// 获取表单数据
|
||||
const getFormData = () => {
|
||||
return { ...formData }
|
||||
@ -621,7 +633,6 @@ const handleSubmit = async () => {
|
||||
|
||||
// 加载编辑数据
|
||||
const loadEditData = async () => {
|
||||
|
||||
if (route.query.mock) {
|
||||
initFormData(mockData)
|
||||
} else {
|
||||
@ -630,6 +641,9 @@ const loadEditData = async () => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取区县下拉列表
|
||||
getAreaOptions()
|
||||
|
||||
loadEditData()
|
||||
})
|
||||
|
||||
|
||||
94
packages/shared/composables/useOptions.js
Normal file
94
packages/shared/composables/useOptions.js
Normal file
@ -0,0 +1,94 @@
|
||||
import { ref } from 'vue'
|
||||
import { request } from '@shared/utils/request'
|
||||
|
||||
// 通用调用接口方法
|
||||
const getOptionsByApi = async ({ url, params }) => {
|
||||
const res = await request({
|
||||
url,
|
||||
method: 'get',
|
||||
params,
|
||||
timeout: 60000
|
||||
})
|
||||
|
||||
if (res?.code === '00000') return res.data
|
||||
else {
|
||||
console.error('接口调用失败', res)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 公用下拉选项
|
||||
|
||||
export function useOptions() {
|
||||
const options = ref({})
|
||||
|
||||
// 是否 布尔类型
|
||||
options.value['yesNoBool'] = [
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false }
|
||||
]
|
||||
|
||||
// 事件类型
|
||||
options.value['eventType'] = [
|
||||
{ label: '水毁事件', value: '水毁事件' },
|
||||
{ label: '冰雪事件', value: '冰雪事件' }
|
||||
]
|
||||
|
||||
// 抢险进度
|
||||
options.value['repairProgress'] = [
|
||||
{ label: '未抢险', value: '未抢险' },
|
||||
{ label: '抢险中', value: '抢险中' }
|
||||
]
|
||||
|
||||
// 处理措施
|
||||
options.value['disposalMeasures'] = [
|
||||
{ label: '全幅封闭', value: '全幅封闭' },
|
||||
{ label: '半幅封闭', value: '半幅封闭' },
|
||||
{ label: '正常通行', value: '正常通行' },
|
||||
{ label: '限制通行', value: '限制通行' }
|
||||
]
|
||||
|
||||
// 路线类型
|
||||
options.value['roadType'] = [
|
||||
{ label: '国道', value: 'G' },
|
||||
{ label: '省道', value: 'S' },
|
||||
{ label: '县道', value: 'X' },
|
||||
{ label: '乡道', value: 'Y' },
|
||||
{ label: '村道', value: 'C' }
|
||||
]
|
||||
|
||||
// 路况类型
|
||||
options.value['roadConditionType'] = [
|
||||
{ label: '山体滑坡', value: '山体滑坡' },
|
||||
{ label: '泥石流', value: '泥石流' },
|
||||
{ label: '边坡坍塌(上、下)', value: '边坡坍塌(上、下)' },
|
||||
{ label: '路基沉降(垮塌)', value: '路基沉降(垮塌)' },
|
||||
{ label: '行道树倒塌', value: '行道树倒塌' },
|
||||
{ label: '积水', value: '积水' },
|
||||
{ label: '其他', value: '其他' }
|
||||
]
|
||||
|
||||
// 获取区县
|
||||
const getAreaOptions = async (params) => {
|
||||
let list = await getOptionsByApi({
|
||||
url: '/snow-ops-platform/infrastructure-asset/counties',
|
||||
params: {
|
||||
xzdm: params?.xzdm // 区县代码 可选
|
||||
}
|
||||
})
|
||||
list = list.filter((item) => {
|
||||
return !!item.qxmc
|
||||
})
|
||||
options.value['area'] = list.map((item) => {
|
||||
return {
|
||||
label: item.qxmc,
|
||||
value: item.xzdm
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
options,
|
||||
getAreaOptions,
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user