feat: 水毁接口联调
This commit is contained in:
parent
922e2b0c09
commit
5a20821e32
@ -34,7 +34,7 @@ import { Field, Popup, Picker } from 'vant'
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 双向绑定值 (v-model)
|
// 双向绑定值 (v-model)
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: [String, Number],
|
type: [String, Number, Boolean],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
// 选项数据,默认格式 [{ label: '显示名', value: '值' }]
|
// 选项数据,默认格式 [{ label: '显示名', value: '值' }]
|
||||||
|
|||||||
@ -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" icon="plus" @click="handleAdd"> 冰雪填报 </van-button>
|
<van-button type="primary" class="footer-btn" @click="handleAdd"> 灾害填报 </van-button>
|
||||||
|
|
||||||
<!-- 筛选组件:v-model 绑定选中的值,visible 控制显示隐藏 -->
|
<!-- 筛选组件:v-model 绑定选中的值,visible 控制显示隐藏 -->
|
||||||
<TagFilter
|
<TagFilter
|
||||||
@ -56,7 +56,7 @@ import CardItem from '@/components/CardItem.vue'
|
|||||||
import EmptyBox from '@/components/EmptyBox.vue'
|
import EmptyBox from '@/components/EmptyBox.vue'
|
||||||
import CurrentSite from '@/components/CurrentSite.vue'
|
import CurrentSite from '@/components/CurrentSite.vue'
|
||||||
import TagFilter from '@/components/TagFilter.vue'
|
import TagFilter from '@/components/TagFilter.vue'
|
||||||
import mockDataJSON from './mockData.json'
|
import { request } from "@shared/utils/request";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -111,54 +111,21 @@ const getDisasterList = async (keyword = '', disasterType = 'all') => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: 替换为实际的后端接口地址
|
const result = await request({
|
||||||
// const response = await fetch('/api/disaster/list', {
|
url: '/snow-ops-platform/water-damage/list',
|
||||||
// method: 'POST',
|
method: 'get',
|
||||||
// headers: {
|
params: {
|
||||||
// 'Content-Type': 'application/json'
|
keyword: keyword.trim(),
|
||||||
// },
|
disasterType: disasterType === 'all' ? '' : disasterType
|
||||||
// body: JSON.stringify({
|
|
||||||
// keyword: keyword.trim(),
|
|
||||||
// disasterType: disasterType === 'all' ? '' : disasterType
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// const result = await response.json()
|
|
||||||
// if (result.code === 200) {
|
|
||||||
// list.value = result.data
|
|
||||||
// } else {
|
|
||||||
// showToast(result.message || '获取数据失败')
|
|
||||||
// list.value = []
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ========== 模拟数据 ==========
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
|
||||||
const mockData = mockDataJSON
|
|
||||||
|
|
||||||
let filteredData = [...mockData]
|
|
||||||
|
|
||||||
if (keyword) {
|
|
||||||
filteredData = filteredData.filter((item) =>
|
|
||||||
item.title.toLowerCase().includes(keyword.toLowerCase())
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
if (disasterType !== 'all') {
|
if (result?.data?.records) {
|
||||||
filteredData = filteredData.filter((item) =>
|
list.value = result.data.records
|
||||||
item.disasterType === disasterType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
list.value = filteredData
|
|
||||||
|
|
||||||
if (keyword && filteredData.length === 0) {
|
|
||||||
emptyText.value = '未搜索到相关灾毁信息'
|
|
||||||
} else if (disasterType !== 'all' && filteredData.length === 0) {
|
|
||||||
const typeLabel = disasterTypes.find(t => t.value === disasterType)?.label || disasterType
|
|
||||||
emptyText.value = `暂无${typeLabel}类型灾毁信息`
|
|
||||||
} else {
|
} else {
|
||||||
emptyText.value = '暂无相关灾毁信息'
|
showToast(result.message || '获取数据失败')
|
||||||
|
list.value = []
|
||||||
}
|
}
|
||||||
// ========== 模拟数据结束 ==========
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取灾毁列表失败:', error)
|
console.error('获取灾毁列表失败:', error)
|
||||||
showToast('获取数据失败,请稍后重试')
|
showToast('获取数据失败,请稍后重试')
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
<WaterDisaster
|
<WaterDisaster
|
||||||
v-if="eventType === 'water'"
|
v-if="eventType === 'water'"
|
||||||
ref="waterDisasterRef"
|
ref="waterDisasterRef"
|
||||||
v-model="waterDisasterData"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 冰雪灾害表单(待实现) -->
|
<!-- 冰雪灾害表单(待实现) -->
|
||||||
@ -31,13 +30,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } 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'
|
||||||
import PanelItem from '@/components/PanelItem.vue'
|
import PanelItem from '@/components/PanelItem.vue'
|
||||||
import WaterDisaster from './WaterDisaster/WaterDisaster.vue'
|
import WaterDisaster from './WaterDisaster/WaterDisaster.vue'
|
||||||
|
import { request } from "@shared/utils/request";
|
||||||
|
import mockFormData from './waterDisasterFormData.json'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ const router = useRouter()
|
|||||||
const eventType = ref('water')
|
const eventType = ref('water')
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const waterDisasterData = ref({})
|
const formData = ref(mockFormData)
|
||||||
const waterDisasterRef = ref(null)
|
const waterDisasterRef = ref(null)
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
|
|
||||||
@ -73,12 +74,16 @@ const handleSubmit = async () => {
|
|||||||
|
|
||||||
// 添加事件类型和站点信息
|
// 添加事件类型和站点信息
|
||||||
const submitData = {
|
const submitData = {
|
||||||
eventType: eventType.value,
|
|
||||||
...formData,
|
...formData,
|
||||||
// 可以在这里添加站点信息等其他数据
|
// 可以在这里添加站点信息等其他数据
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('提交数据:', submitData)
|
const res = await request({
|
||||||
|
url: '/snow-ops-platform/water-damage/addOrUpdate',
|
||||||
|
method: 'post',
|
||||||
|
data: submitData
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// 模拟提交接口
|
// 模拟提交接口
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
@ -95,6 +100,10 @@ const handleSubmit = async () => {
|
|||||||
submitting.value = false
|
submitting.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
waterDisasterRef.value.initFormData(formData.value)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,20 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="loss-list">
|
<div class="loss-list">
|
||||||
<template v-for="item in modelValue">
|
<template v-for="item in modelValue">
|
||||||
<van-field v-model="item.value" label="塌方及损失" placeholder="请填写" type="digit" @click="cubeCalculateDialog.show()">
|
<van-field v-model="item.totalAmount" :label="getItemLabel(item)" placeholder="请填写" type="digit" @click="cubeCalculateDialog.show()">
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">方/万元</span>
|
<span class="field-unit">方/万元</span>
|
||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
</template>
|
</template>
|
||||||
|
<van-button size="small" block type="primary" plain @click="addLoss">添加损失</van-button>
|
||||||
<CubeCalculateDialog ref="cubeCalculateDialog" />
|
<CubeCalculateDialog ref="cubeCalculateDialog" />
|
||||||
|
<LossPicker ref="lossPicker" :options="options" @confirm="confirmAddLoss" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import CubeCalculateDialog from './CubeCalculateDialog.vue';
|
import CubeCalculateDialog from './CubeCalculateDialog.vue'
|
||||||
|
import { request } from '@shared/utils/request'
|
||||||
|
import LossPicker from './LossPicker.vue'
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@ -23,8 +28,43 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const lossPicker = ref(null)
|
||||||
|
|
||||||
|
const options = ref({})
|
||||||
|
// 添加损失项
|
||||||
|
const addLoss = () => {
|
||||||
|
lossPicker.value?.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmAddLoss = (item) => {
|
||||||
|
emit('update:modelValue', [...props.modelValue, item])
|
||||||
|
}
|
||||||
|
|
||||||
const cubeCalculateDialog = ref(null)
|
const cubeCalculateDialog = ref(null)
|
||||||
|
|
||||||
|
const getItemLabel = (item) => {
|
||||||
|
const loss = options.value.loss?.find((loss) => loss.value === item.lossTypeId)
|
||||||
|
return loss?.text
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLossDict = async (params) => {
|
||||||
|
const res = await request({
|
||||||
|
url: '/snow-ops-platform/water-damage/loss/typeAndInfo',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
options.value.loss = res.data.records.map((item)=>{
|
||||||
|
return {
|
||||||
|
text: item.lossTypeName,
|
||||||
|
value: item.lossTypeId,
|
||||||
|
item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getLossDict()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<van-popup v-model:show="showPicker" position="bottom" round>
|
||||||
|
<van-picker :columns="columns" :title="pickerTitle" show-toolbar @confirm="onConfirm" @cancel="showPicker = false" />
|
||||||
|
</van-popup>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, computed } from 'vue'
|
||||||
|
|
||||||
|
const emit = defineEmits(['confirm'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const pickerTitle = ref("请选择损失类型")
|
||||||
|
|
||||||
|
|
||||||
|
const columns = computed(() => {
|
||||||
|
return props.options.loss || []
|
||||||
|
})
|
||||||
|
|
||||||
|
const showPicker = ref(false)
|
||||||
|
|
||||||
|
const show = () => {
|
||||||
|
showPicker.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const clsoe = () => {
|
||||||
|
showPicker.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const onConfirm = ({ selectedValues, selectedOptions }) => {
|
||||||
|
|
||||||
|
emit('confirm', selectedOptions[0].item)
|
||||||
|
showPicker.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
clsoe
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@ -4,74 +4,74 @@
|
|||||||
<PanelItem title="基本信息">
|
<PanelItem title="基本信息">
|
||||||
<van-form>
|
<van-form>
|
||||||
<!-- 路况类别 -->
|
<!-- 路况类别 -->
|
||||||
<BasePicker v-model="formData.roadCondition" :options="roadConditionOptions" label="路况类别" placeholder="请选择" />
|
<BasePicker v-model="formData.roadConditionType" :options="roadConditionOptions" label="路况类别" placeholder="请选择" />
|
||||||
|
|
||||||
<!-- 是否阻断 -->
|
<!-- 是否阻断 (event.isBlocked) -->
|
||||||
<BasePicker v-model="formData.isBlocked" :options="blockedOptions" label="是否阻断" placeholder="请选择" />
|
<BasePicker v-model="formData.event.isBlocked" :options="blockedOptions" label="是否阻断" placeholder="请选择" />
|
||||||
|
|
||||||
<!-- 抢修进度 -->
|
<!-- 抢修进度 (event.repairProgress) -->
|
||||||
<BasePicker v-model="formData.repairProgress" :options="repairProgressOptions" label="抢修进度" placeholder="请选择" />
|
<BasePicker v-model="formData.event.repairProgress" :options="repairProgressOptions" label="抢修进度" placeholder="请选择" />
|
||||||
|
|
||||||
<!-- 水毁处数 -->
|
<!-- 水毁处数 (event.damageCount) -->
|
||||||
<van-field v-model="formData.waterDamageCount" label="水毁处数" placeholder="请填写" type="number" />
|
<van-field v-model="formData.event.damageCount" label="水毁处数" placeholder="请填写" type="number" />
|
||||||
|
|
||||||
<!-- 阻断里程 -->
|
<!-- 阻断里程 (event.blockedMileage) -->
|
||||||
<van-field v-model="formData.blockedMileage" label="阻断里程" placeholder="请填写" type="digit">
|
<van-field v-model="formData.event.blockedMileage" label="阻断里程" placeholder="请填写" type="digit">
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">公里</span>
|
<span class="field-unit">公里</span>
|
||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
|
|
||||||
<!-- 发生时间 -->
|
<!-- 发生时间 (顶层 occurTime) -->
|
||||||
<BaseDatePicker v-model="formData.occurTime" label="发生时间" placeholder="请选择时间" :columnsType="['year', 'month', 'day', 'hour', 'minute']" />
|
<BaseDatePicker v-model="formData.occurTime" label="发生时间" placeholder="请选择时间" :columnsType="['year', 'month', 'day', 'hour', 'minute']" />
|
||||||
<div class="calibrate-time-btn" @click="calibrateTime">
|
<div class="calibrate-time-btn" @click="calibrateTime">
|
||||||
<van-icon name="replay" />
|
<van-icon name="replay" />
|
||||||
<span>校准时间</span>
|
<span>校准时间</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 线路编号 -->
|
<!-- 线路编号 (顶层 routeNo) -->
|
||||||
<van-field v-model="formData.lineCode" label="线路编号" placeholder="请填写" />
|
<van-field v-model="formData.routeNo" label="线路编号" placeholder="请填写" />
|
||||||
|
|
||||||
<!-- 起点桩号 -->
|
<!-- 起点桩号 (event.startStakeNo) -->
|
||||||
<van-field v-model="formData.startPileNo" label="起点桩号(K)" placeholder="请填写" />
|
<van-field v-model="formData.event.startStakeNo" label="起点桩号(K)" placeholder="请填写" />
|
||||||
|
|
||||||
<!-- 起点桩经纬度 -->
|
<!-- 起点桩经纬度 (event.startStakeLng / startStakeLat) -->
|
||||||
<div class="coordinate-row">
|
<div class="coordinate-row">
|
||||||
<van-field v-model="formData.startLongitude" label="起点桩经度" placeholder="经度" class="coordinate-field" />
|
<van-field v-model="formData.event.startStakeLng" label="起点桩经度" placeholder="经度" class="coordinate-field" />
|
||||||
<van-field v-model="formData.startLatitude" label="起点桩纬度" placeholder="纬度" class="coordinate-field" />
|
<van-field v-model="formData.event.startStakeLat" label="起点桩纬度" placeholder="纬度" class="coordinate-field" />
|
||||||
</div>
|
</div>
|
||||||
<div class="calibrate-coord-btn" @click="calibrateStartCoord">
|
<div class="calibrate-coord-btn" @click="calibrateStartCoord">
|
||||||
<van-icon name="location-o" />
|
<van-icon name="location-o" />
|
||||||
<span>校准经纬度</span>
|
<span>校准经纬度</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 止点桩号 -->
|
<!-- 止点桩号 (event.endStakeNo) -->
|
||||||
<van-field v-model="formData.endPileNo" label="止点桩号(K)" placeholder="请填写" />
|
<van-field v-model="formData.event.endStakeNo" label="止点桩号(K)" placeholder="请填写" />
|
||||||
|
|
||||||
<!-- 止点桩经纬度 -->
|
<!-- 止点桩经纬度 (event.endStakeLng / endStakeLat) -->
|
||||||
<div class="coordinate-row">
|
<div class="coordinate-row">
|
||||||
<van-field v-model="formData.endLongitude" label="止点桩经度" placeholder="经度" class="coordinate-field" />
|
<van-field v-model="formData.event.endStakeLng" label="止点桩经度" placeholder="经度" class="coordinate-field" />
|
||||||
<van-field v-model="formData.endLatitude" label="止点桩纬度" placeholder="纬度" class="coordinate-field" />
|
<van-field v-model="formData.event.endStakeLat" label="止点桩纬度" placeholder="纬度" class="coordinate-field" />
|
||||||
</div>
|
</div>
|
||||||
<div class="calibrate-coord-btn" @click="calibrateEndCoord">
|
<div class="calibrate-coord-btn" @click="calibrateEndCoord">
|
||||||
<van-icon name="location-o" />
|
<van-icon name="location-o" />
|
||||||
<span>校准经纬度</span>
|
<span>校准经纬度</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 路况位置 -->
|
<!-- 路况位置 (event.endStakeNo) -->
|
||||||
<van-field v-model="formData.roadLocation" label="路况位置" placeholder="请填写" />
|
<van-field v-model="formData.occurLocation" label="路况位置" placeholder="请填写" />
|
||||||
|
|
||||||
<!-- 阻断点小地名 -->
|
<!-- 阻断点小地名 (event.blockedPointName) -->
|
||||||
<van-field v-model="formData.smallPlaceName" label="阻断点小地名" placeholder="请填写" />
|
<van-field v-model="formData.event.blockedPointName" label="阻断点小地名" placeholder="请填写" />
|
||||||
</van-form>
|
</van-form>
|
||||||
</PanelItem>
|
</PanelItem>
|
||||||
|
|
||||||
<!-- 处置情况 -->
|
<!-- 处置情况 (report) -->
|
||||||
<PanelItem title="处置情况">
|
<PanelItem title="处置情况">
|
||||||
<div class="disposal-measures">
|
<div class="disposal-measures">
|
||||||
<span class="measures-label">处置措施</span>
|
<span class="measures-label">处置措施</span>
|
||||||
<div class="measures-options">
|
<div class="measures-options">
|
||||||
<van-checkbox-group v-model="formData.disposalMeasures" direction="horizontal">
|
<van-checkbox-group v-model="disposalMeasuresArray" direction="horizontal">
|
||||||
<van-checkbox name="halfClose">半幅封闭</van-checkbox>
|
<van-checkbox name="halfClose">半幅封闭</van-checkbox>
|
||||||
<van-checkbox name="fullClose">全副封闭</van-checkbox>
|
<van-checkbox name="fullClose">全副封闭</van-checkbox>
|
||||||
<van-checkbox name="bypass">便道通行</van-checkbox>
|
<van-checkbox name="bypass">便道通行</van-checkbox>
|
||||||
@ -80,37 +80,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 预计恢复时间 -->
|
<!-- 预计恢复时间 (report.expectRecoverTime) -->
|
||||||
<BaseDatePicker v-model="formData.estimatedRecoverTime" label="预计恢复时间" placeholder="请选择时间" :min-date="minDate" :max-date="maxDate" type="datetime" />
|
<BaseDatePicker v-model="formData.report.expectRecoverTime" label="预计恢复时间" placeholder="请选择时间" :min-date="minDate" :max-date="maxDate" type="datetime" />
|
||||||
|
|
||||||
<!-- 实际恢复时间 -->
|
<!-- 实际恢复时间 (report.actualRecoverTime) -->
|
||||||
<BaseDatePicker v-model="formData.actualRecoverTime" label="实际恢复时间" placeholder="请选择时间" :min-date="minDate" :max-date="maxDate" type="datetime" />
|
<BaseDatePicker v-model="formData.report.actualRecoverTime" label="实际恢复时间" placeholder="请选择时间" :min-date="minDate" :max-date="maxDate" type="datetime" />
|
||||||
</PanelItem>
|
</PanelItem>
|
||||||
|
|
||||||
<!-- 人员车辆 -->
|
<!-- 人员车辆 (report) -->
|
||||||
<PanelItem title="人员车辆">
|
<PanelItem title="人员车辆">
|
||||||
<van-form>
|
<van-form>
|
||||||
<van-field v-model="formData.injuredCount" label="受伤人员" placeholder="请填写" type="number">
|
<van-field v-model="formData.report.injuredCount" label="受伤人员" placeholder="请填写" type="number">
|
||||||
<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.deathCount" label="死亡人员" placeholder="请填写" type="number">
|
<van-field v-model="formData.report.deadCount" label="死亡人员" placeholder="请填写" type="number">
|
||||||
<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.strandedPeople" label="滞留人员" placeholder="请填写" type="number">
|
<van-field v-model="formData.report.strandedPersonCount" label="滞留人员" placeholder="请填写" type="number">
|
||||||
<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.damagedVehicles" label="损坏车辆" placeholder="请填写" type="number">
|
<van-field v-model="formData.report.damagedVehicleCount" label="损坏车辆" placeholder="请填写" type="number">
|
||||||
<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.strandedVehicles" label="滞留车辆" placeholder="请填写" type="number">
|
<van-field v-model="formData.report.strandedVehicleCount" label="滞留车辆" placeholder="请填写" type="number">
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">辆</span>
|
<span class="field-unit">辆</span>
|
||||||
</template>
|
</template>
|
||||||
@ -118,70 +118,69 @@
|
|||||||
</van-form>
|
</van-form>
|
||||||
</PanelItem>
|
</PanelItem>
|
||||||
|
|
||||||
<!-- 灾毁损失 -->
|
<!-- 灾毁损失 (lossList) -->
|
||||||
<PanelItem title="灾毁损失">
|
<PanelItem title="灾毁损失">
|
||||||
<LossList v-model="formData.lossList" />
|
<LossList v-model="formData.lossList" />
|
||||||
<van-button size="small" block type="primary" plain>添加损失</van-button>
|
<van-field v-model="formData.report.remark" label="处理情况" placeholder="请填写(选填)" />
|
||||||
<van-field v-model="formData.handlingSituation" label="处理情况" placeholder="请填写(选填)" />
|
<van-field v-model="formData.report.totalLossAmount" label="损失总金额" placeholder="请填写(选填)" type="digit">
|
||||||
<van-field v-model="formData.totalLossAmount" label="损失总金额" placeholder="请填写(选填)" type="digit">
|
|
||||||
<template #button>
|
<template #button>
|
||||||
<span class="field-unit">万元</span>
|
<span class="field-unit">万元</span>
|
||||||
</template>
|
</template>
|
||||||
</van-field>
|
</van-field>
|
||||||
</PanelItem>
|
</PanelItem>
|
||||||
|
|
||||||
|
<!-- 投入资源 (report) -->
|
||||||
<PanelItem>
|
<PanelItem>
|
||||||
<van-field v-model="formData.machineryInput" label="已投机械" placeholder="请填写" type="digit">
|
<van-field v-model="formData.report.investedMachinery" label="已投机械" placeholder="请填写" type="digit">
|
||||||
<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.laborInput" label="已投入力" placeholder="请填写" type="number">
|
<van-field v-model="formData.report.investedManpower" label="已投入力" placeholder="请填写" type="number">
|
||||||
<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.fundsInput" label="已投资金" placeholder="请填写" type="digit">
|
<van-field v-model="formData.report.investedFunds" label="已投资金" placeholder="请填写" type="digit">
|
||||||
<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.siteDescription" label="现场描述" placeholder="请填写" type="textarea" rows="2" autosize />
|
<van-field v-model="formData.report.siteDescription" label="现场描述" placeholder="请填写" type="textarea" rows="2" autosize />
|
||||||
|
|
||||||
<van-field label="附件">
|
|
||||||
<template #input> </template>
|
|
||||||
</van-field>
|
|
||||||
</PanelItem>
|
</PanelItem>
|
||||||
|
|
||||||
<!-- 附件 -->
|
<!-- 附件 (fileList) -->
|
||||||
<!-- <PanelItem title="附件">
|
<!-- <PanelItem title="附件">
|
||||||
<div class="attachment-tip">图片只能上传jpg/png文件,且不超过500kb;视频仅支持20s内的视频</div>
|
<div class="attachment-tip">图片只能上传jpg/png文件,且不超过500kb;视频仅支持20s内的视频</div>
|
||||||
<div class="upload-area">
|
<div class="upload-area">
|
||||||
<van-uploader
|
<van-uploader v-model="imageFileList" :after-read="afterImageRead" accept="image/jpeg,image/png" :max-size="500 * 1024" @oversize="onOversize" multiple :max-count="9">
|
||||||
v-model="formData.imageFiles"
|
|
||||||
:after-read="afterImageRead"
|
|
||||||
accept="image/jpeg,image/png"
|
|
||||||
:max-size="500 * 1024"
|
|
||||||
@oversize="onOversize"
|
|
||||||
multiple
|
|
||||||
:max-count="9"
|
|
||||||
>
|
|
||||||
<div class="upload-btn">
|
<div class="upload-btn">
|
||||||
<van-icon name="photo-o" size="24" />
|
<van-icon name="photo-o" size="24" />
|
||||||
<span>上传图片</span>
|
<span>上传图片</span>
|
||||||
</div>
|
</div>
|
||||||
</van-uploader>
|
</van-uploader>
|
||||||
<van-uploader v-model="formData.videoFile" :after-read="afterVideoRead" accept="video/*" :max-size="20 * 1024 * 1024" @oversize="onVideoOversize">
|
<van-uploader v-model="videoFileList" :after-read="afterVideoRead" accept="video/*" :max-size="20 * 1024 * 1024" @oversize="onVideoOversize">
|
||||||
<div class="upload-btn">
|
<div class="upload-btn">
|
||||||
<van-icon name="video-o" size="24" />
|
<van-icon name="video-o" size="24" />
|
||||||
<span>上传视频</span>
|
<span>上传视频</span>
|
||||||
</div>
|
</div>
|
||||||
</van-uploader>
|
</van-uploader>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="formData.videoFile.length > 0 && formData.videoFile[0].content" class="video-preview">
|
<div v-if="videoFileList.length > 0 && videoFileList[0].content" class="video-preview">
|
||||||
<video :src="formData.videoFile[0].content" controls style="width: 100%; max-height: 200px"></video>
|
<video :src="videoFileList[0].content" controls style="width: 100%; max-height: 200px"></video>
|
||||||
</div>
|
</div>
|
||||||
</PanelItem> -->
|
</PanelItem> -->
|
||||||
|
|
||||||
|
<PanelItem>
|
||||||
|
<!-- 是否需要恢复重建 (event.needsRecovery) -->
|
||||||
|
<BasePicker v-model="formData.event.needsRecovery" :options="needsRecoveryOptions" label="是否需要恢复重建" placeholder="请选择" />
|
||||||
|
<!-- 恢复重建预估费用 (event.estimatedRecoveryCost) -->
|
||||||
|
<van-field v-model="formData.event.estimatedRecoveryCost" label="恢复重建预估费用" placeholder="请填写" type="digit">
|
||||||
|
<template #button>
|
||||||
|
<span class="field-unit">万元</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
</PanelItem>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -193,54 +192,133 @@ 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'
|
||||||
|
|
||||||
// 定义 props
|
|
||||||
const props = defineProps({
|
|
||||||
modelValue: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 定义 emits
|
// 处置措施数组(用于多选框组,需要转换为逗号分隔的字符串)
|
||||||
const emit = defineEmits(['update:modelValue', 'submit'])
|
const disposalMeasuresArray = ref([])
|
||||||
|
|
||||||
// 表单数据
|
// 附件列表
|
||||||
|
const imageFileList = ref([])
|
||||||
|
const videoFileList = ref([])
|
||||||
|
|
||||||
|
// 表单数据 - 按 Request 接口结构定义
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
roadCondition: '',
|
// 顶层字段
|
||||||
isBlocked: '',
|
occurLocation: '', // 发生地点
|
||||||
repairProgress: '',
|
occurTime: '', // 发生时间
|
||||||
waterDamageCount: '',
|
roadConditionType: '', // 路况类别
|
||||||
blockedMileage: '',
|
routeNo: '', // 线路编号
|
||||||
occurTime: '',
|
|
||||||
lineCode: '',
|
// event 对象
|
||||||
startPileNo: '',
|
event: {
|
||||||
startLongitude: '',
|
blockedMileage: '', // 阻断里程
|
||||||
startLatitude: '',
|
blockedPointName: '', // 阻断点小地名
|
||||||
endPileNo: '',
|
contactPerson: '', // 联系人
|
||||||
endLongitude: '',
|
contactPhone: '', // 联系电话
|
||||||
endLatitude: '',
|
damageCount: '', // 水毁处数
|
||||||
roadLocation: '',
|
district: '', // 上报区县
|
||||||
smallPlaceName: '',
|
endStakeLat: '', // 止点纬度
|
||||||
disposalMeasures: [],
|
endStakeLng: '', // 止点经度
|
||||||
estimatedRecoverTime: '',
|
endStakeNo: '', // 止点桩号
|
||||||
actualRecoverTime: '',
|
estimatedRecoveryCost: '', // 恢复重建预估费用
|
||||||
injuredCount: '',
|
inspectionMileage: '', // 巡查里程
|
||||||
deathCount: '',
|
isBlocked: '', // 是否阻断
|
||||||
strandedPeople: '',
|
needsRecovery: '', // 是否需要恢复重建
|
||||||
damagedVehicles: '',
|
repairProgress: '', // 抢修进度
|
||||||
strandedVehicles: '',
|
reporterUnit: '', // 填报单位
|
||||||
collapseLoss: [],
|
startStakeLat: '', // 起点纬度
|
||||||
handlingSituation: '',
|
startStakeLng: '', // 起点经度
|
||||||
totalLossAmount: '',
|
startStakeNo: '' // 起点桩号
|
||||||
machineryInput: '',
|
},
|
||||||
laborInput: '',
|
|
||||||
fundsInput: '',
|
// report 对象
|
||||||
siteDescription: '',
|
report: {
|
||||||
imageFiles: [],
|
actualRecoverTime: '', // 实际恢复时间
|
||||||
videoFile: [],
|
damagedVehicleCount: '', // 损坏车辆
|
||||||
lossList: [{ value: '' }]
|
deadCount: '', // 死亡人员
|
||||||
|
disposalMeasures: '', // 处置措施(逗号分隔)
|
||||||
|
expectRecoverTime: '', // 预计恢复时间
|
||||||
|
injuredCount: '', // 受伤人员
|
||||||
|
investedFunds: '', // 已投资金
|
||||||
|
investedMachinery: '', // 已投机械
|
||||||
|
investedManpower: '', // 已投人力
|
||||||
|
remark: '', // 处理情况/备注
|
||||||
|
siteDescription: '', // 现场描述
|
||||||
|
strandedPersonCount: '', // 滞留人员
|
||||||
|
strandedVehicleCount: '', // 滞留车辆
|
||||||
|
totalLossAmount: '' // 损失总金额
|
||||||
|
},
|
||||||
|
|
||||||
|
// lossList 数组
|
||||||
|
lossList: [],
|
||||||
|
|
||||||
|
// fileList 数组
|
||||||
|
fileList: []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听处置措施数组变化,转换为逗号分隔的字符串存到 report.disposalMeasures
|
||||||
|
watch(
|
||||||
|
disposalMeasuresArray,
|
||||||
|
(newVal) => {
|
||||||
|
formData.report.disposalMeasures = newVal.join(',')
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听附件变化,同步到 fileList
|
||||||
|
watch(
|
||||||
|
imageFileList,
|
||||||
|
(newVal) => {
|
||||||
|
// 转换为接口需要的格式
|
||||||
|
formData.fileList = [
|
||||||
|
...imageFileList.value.map((f) => ({
|
||||||
|
fileName: f.file?.name || '',
|
||||||
|
fileSize: f.file?.size || 0,
|
||||||
|
fileType: 1, // 1-图片
|
||||||
|
fileUrl: f.content || ''
|
||||||
|
})),
|
||||||
|
...videoFileList.value.map((f) => ({
|
||||||
|
fileName: f.file?.name || '',
|
||||||
|
fileSize: f.file?.size || 0,
|
||||||
|
fileType: 2, // 2-视频
|
||||||
|
fileUrl: f.content || ''
|
||||||
|
}))
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
videoFileList,
|
||||||
|
(newVal) => {
|
||||||
|
formData.fileList = [
|
||||||
|
...imageFileList.value.map((f) => ({
|
||||||
|
fileName: f.file?.name || '',
|
||||||
|
fileSize: f.file?.size || 0,
|
||||||
|
fileType: 1,
|
||||||
|
fileUrl: f.content || ''
|
||||||
|
})),
|
||||||
|
...newVal.map((f) => ({
|
||||||
|
fileName: f.file?.name || '',
|
||||||
|
fileSize: f.file?.size || 0,
|
||||||
|
fileType: 2,
|
||||||
|
fileUrl: f.content || ''
|
||||||
|
}))
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 从 report.disposalMeasures 初始化处置措施数组
|
||||||
|
watch(
|
||||||
|
() => formData.report.disposalMeasures,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal && typeof newVal === 'string') {
|
||||||
|
disposalMeasuresArray.value = newVal.split(',').filter(Boolean)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
// BasePicker 选项数据
|
// BasePicker 选项数据
|
||||||
const roadConditionOptions = [
|
const roadConditionOptions = [
|
||||||
{ label: '高速公路', value: '高速公路' },
|
{ label: '高速公路', value: '高速公路' },
|
||||||
@ -252,40 +330,45 @@ const roadConditionOptions = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const blockedOptions = [
|
const blockedOptions = [
|
||||||
{ label: '是', value: '是' },
|
{ label: '是', value: true },
|
||||||
{ label: '否', value: '否' }
|
{ label: '否', value: false }
|
||||||
]
|
]
|
||||||
|
|
||||||
const repairProgressOptions = [
|
const repairProgressOptions = [
|
||||||
{ label: '未开始', value: '未开始' },
|
{ label: '未抢修', value: '未抢修' },
|
||||||
{ label: '进行中', value: '进行中' },
|
{ label: '抢修中', value: '抢修中' },
|
||||||
{ label: '已抢通', value: '已抢通' },
|
{ label: '已完成', value: '已完成' },
|
||||||
{ label: '已修复', value: '已修复' }
|
]
|
||||||
|
|
||||||
|
const needsRecoveryOptions = [
|
||||||
|
{ label: '是', value: true },
|
||||||
|
{ label: '否', value: false }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 时间选择器范围
|
// 时间选择器范围
|
||||||
const minDate = new Date(2020, 0, 1)
|
const minDate = new Date(2020, 0, 1)
|
||||||
const maxDate = new Date(2030, 11, 31)
|
const maxDate = new Date(2030, 11, 31)
|
||||||
|
|
||||||
// 监听父组件传入的数据
|
const initFormData = (newVal) => {
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal && Object.keys(newVal).length > 0) {
|
if (newVal && Object.keys(newVal).length > 0) {
|
||||||
Object.assign(formData, newVal)
|
// 深度合并数据
|
||||||
}
|
Object.assign(formData, {
|
||||||
},
|
occurLocation: newVal.occurLocation || '',
|
||||||
{ immediate: true, deep: true }
|
occurTime: newVal.occurTime || '',
|
||||||
)
|
roadConditionType: newVal.roadConditionType || '',
|
||||||
|
routeNo: newVal.routeNo || '',
|
||||||
|
event: { ...formData.event, ...(newVal.event || {}) },
|
||||||
|
report: { ...formData.report, ...(newVal.report || {}) },
|
||||||
|
lossList: newVal.lossList || [],
|
||||||
|
fileList: newVal.fileList || []
|
||||||
|
})
|
||||||
|
|
||||||
// 监听表单数据变化,同步到父组件
|
// 初始化处置措施数组
|
||||||
watch(
|
if (newVal.report?.disposalMeasures) {
|
||||||
formData,
|
disposalMeasuresArray.value = newVal.report.disposalMeasures.split(',').filter(Boolean)
|
||||||
() => {
|
}
|
||||||
emit('update:modelValue', { ...formData })
|
}
|
||||||
},
|
}
|
||||||
{ deep: true }
|
|
||||||
)
|
|
||||||
|
|
||||||
// 校准时间
|
// 校准时间
|
||||||
const calibrateTime = () => {
|
const calibrateTime = () => {
|
||||||
@ -297,15 +380,15 @@ const calibrateTime = () => {
|
|||||||
|
|
||||||
// 校准起点经纬度
|
// 校准起点经纬度
|
||||||
const calibrateStartCoord = () => {
|
const calibrateStartCoord = () => {
|
||||||
formData.startLongitude = '108.41763025'
|
formData.event.startStakeLng = '108.41763025'
|
||||||
formData.startLatitude = '108.41763025'
|
formData.event.startStakeLat = '108.41763025'
|
||||||
showToast('起点经纬度已校准')
|
showToast('起点经纬度已校准')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校准止点经纬度
|
// 校准止点经纬度
|
||||||
const calibrateEndCoord = () => {
|
const calibrateEndCoord = () => {
|
||||||
formData.endLongitude = '108.41763025'
|
formData.event.endStakeLng = '108.41763025'
|
||||||
formData.endLatitude = '108.41763025'
|
formData.event.endStakeLat = '108.41763025'
|
||||||
showToast('止点经纬度已校准')
|
showToast('止点经纬度已校准')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +415,7 @@ const validate = () => {
|
|||||||
showToast('请填写发生时间')
|
showToast('请填写发生时间')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (!formData.lineCode) {
|
if (!formData.routeNo) {
|
||||||
showToast('请填写线路编号')
|
showToast('请填写线路编号')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -347,6 +430,7 @@ const getFormData = () => {
|
|||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
validate,
|
validate,
|
||||||
|
initFormData,
|
||||||
getFormData
|
getFormData
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -433,18 +517,8 @@ defineExpose({
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loss-dialog-content {
|
|
||||||
padding: 8px 16px 16px;
|
|
||||||
.loss-calc-result {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #1989fa;
|
|
||||||
margin-top: 12px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-field__label) {
|
:deep(.van-field__label) {
|
||||||
width: 90px;
|
width: 110px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"occurLocation": "G108国道 K2250+300处",
|
||||||
|
"occurTime": "2024-07-15 14:30:00",
|
||||||
|
"roadConditionType": "国道",
|
||||||
|
"routeNo": "G108",
|
||||||
|
"event": {
|
||||||
|
"blockedMileage": 1.5,
|
||||||
|
"blockedPointName": "磨盘山隧道口",
|
||||||
|
"contactPerson": "张明",
|
||||||
|
"contactPhone": "13812345678",
|
||||||
|
"damageCount": 3,
|
||||||
|
"district": "武侯区",
|
||||||
|
"endStakeLat": "30.658712",
|
||||||
|
"endStakeLng": "104.082356",
|
||||||
|
"endStakeNo": "K2251+200",
|
||||||
|
"estimatedRecoveryCost": 120.5,
|
||||||
|
"inspectionMileage": 25.6,
|
||||||
|
"isBlocked": true,
|
||||||
|
"needsRecovery": true,
|
||||||
|
"repairProgress": "抢修中",
|
||||||
|
"reporterUnit": "武侯区交通运输局",
|
||||||
|
"startStakeLat": "30.652145",
|
||||||
|
"startStakeLng": "104.075632",
|
||||||
|
"startStakeNo": "K2250+300"
|
||||||
|
},
|
||||||
|
"report": {
|
||||||
|
"damagedVehicleCount": 2,
|
||||||
|
"strandedPersonCount": 12,
|
||||||
|
"deadCount": 0,
|
||||||
|
"strandedVehicleCount": 12,
|
||||||
|
"disposalMeasures": "halfClose,bypass",
|
||||||
|
"actualRecoverTime": "2024-07-17 12:00:00",
|
||||||
|
"expectRecoverTime": "2024-07-18 18:00:00",
|
||||||
|
"injuredCount": 1,
|
||||||
|
"investedFunds": 35.8,
|
||||||
|
"investedMachinery": 6,
|
||||||
|
"investedManpower": 45,
|
||||||
|
"remark": "已组织抢险队伍进行抢通,便道已修建完成",
|
||||||
|
"siteDescription": "因持续强降雨导致山体滑坡,掩埋路面约50米,边坡垮塌严重",
|
||||||
|
"totalLossAmount": 85.6
|
||||||
|
},
|
||||||
|
"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": []
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user