2026-04-17 18:16:31 +08:00

389 lines
13 KiB
JavaScript

import { computed, onMounted, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { request } from '@/utils/request'
import { useOptions } from '@shared/composables/useOptions'
const DEFAULT_REPORTER_UNIT = '万州区公路中心'
const createDefaultFormData = () => ({
occurLocation: '',
occurTime: '',
routeNo: '',
event: {
actualRecoverTime: '',
disasterMileage: null,
disposalMeasures: '',
district: '',
endStakeLat: null,
endStakeLng: null,
endStakeNo: '',
expectRecoverTime: '',
id: null,
occurLocation: '',
occurTime: '',
reporterName: '',
reporterPhone: '',
reportTime: '',
reportUnit: DEFAULT_REPORTER_UNIT,
roadConditionLocation: '',
routeNo: '',
routeType: '',
serviceStationId: '',
startStakeLat: null,
startStakeLng: null,
startStakeNo: ''
},
report: {
actualRecoverTime: '',
antiSlipSand: null,
disposalMeasures: '',
expectRecoverTime: '',
hasStrandedVehicles: null,
industrialSalt: null,
inputEquipment: null,
inputFunds: null,
inputManpower: null,
reporterName: '',
reporterPhone: '',
reportTime: '',
sandbags: null,
siteDescription: '',
strandedVehicleCount: null
},
fileList: [],
lossList: [],
yhzMaterialList: []
})
const mergeFormData = (source = {}) => {
const defaults = createDefaultFormData()
const merged = {
...defaults,
...source,
event: {
...defaults.event,
...(source.event || {})
},
report: {
...defaults.report,
...(source.report || {})
}
}
merged.fileList = Array.isArray(source.fileList) ? source.fileList : defaults.fileList
merged.lossList = Array.isArray(source.lossList) ? source.lossList : defaults.lossList
merged.yhzMaterialList = Array.isArray(source.yhzMaterialList) ? source.yhzMaterialList : defaults.yhzMaterialList
if (!merged.event.reportUnit) {
merged.event.reportUnit = DEFAULT_REPORTER_UNIT
}
return merged
}
const parsePointValue = (point) => {
if (!point) {
return { longitude: null, latitude: null }
}
if (Array.isArray(point) && point.length >= 2) {
return {
longitude: point[0] ?? null,
latitude: point[1] ?? null
}
}
if (typeof point === 'string') {
try {
const parsed = JSON.parse(point)
if (Array.isArray(parsed) && parsed.length >= 2) {
return {
longitude: parsed[0] ?? null,
latitude: parsed[1] ?? null
}
}
} catch (_error) {
return { longitude: null, latitude: null }
}
}
return { longitude: null, latitude: null }
}
export const useIceDisasterReport = () => {
const router = useRouter()
const route = useRoute()
const { options, getAreaOptions } = useOptions()
const formRef = ref(null)
const submitting = ref(false)
const eventType = ref('冰雪事件')
const filterForm = reactive({
routeType: ''
})
const formData = reactive(createDefaultFormData())
const strandedVehicleOptions = [
{ label: '有', value: 1 },
{ label: '无', value: 0 }
]
const routeTypeLabel = computed(() => {
const matched = options.value.roadType?.find((item) => item.value === filterForm.routeType)
return matched?.label || '国省道'
})
const formRules = {
'event.reporterName': [{ required: true, message: '请输入联系人员', trigger: 'blur' }],
'event.reporterPhone': [
{ required: true, message: '请输入联系电话', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的联系电话', trigger: 'blur' }
],
'event.serviceStationId': [{ required: true, message: '请选择填报站点', trigger: 'change' }],
occurTime: [{ required: true, message: '请选择发生时间', trigger: 'change' }],
'event.district': [{ required: true, message: '请选择所属区县', trigger: 'change' }],
routeNo: [{ required: true, message: '请选择线路编号', trigger: 'change' }],
'event.occurLocation': [{ required: true, message: '请输入发生地点', trigger: 'blur' }],
occurLocation: [{ required: true, message: '请选择路况位置', trigger: 'blur' }],
'event.startStakeNo': [{ required: true, message: '请输入起点桩号', trigger: 'blur' }],
'event.startStakeLng': [{ required: true, message: '请输入起点桩经度', trigger: 'blur' }],
'event.startStakeLat': [{ required: true, message: '请输入起点桩纬度', trigger: 'blur' }],
'event.endStakeNo': [{ required: true, message: '请输入止点桩号', trigger: 'blur' }],
'event.endStakeLng': [{ required: true, message: '请输入止点桩经度', trigger: 'blur' }],
'event.endStakeLat': [{ required: true, message: '请输入止点桩纬度', trigger: 'blur' }],
'event.disasterMileage': [{ required: true, message: '请输入受灾里程', trigger: 'blur' }],
'report.disposalMeasures': [{ required: true, message: '请选择处理措施', trigger: 'change' }],
'report.siteDescription': [{ required: true, message: '请输入现场情况描述', trigger: 'blur' }],
fileList: [
{
validator: (_rule, value, callback) => {
if (!Array.isArray(value) || value.length === 0) {
callback(new Error('请上传附件'))
return
}
callback()
},
trigger: 'change'
}
]
}
const initFormData = (data = {}) => {
Object.assign(formData, mergeFormData(data))
}
const handleEventTypeChange = (value) => {
if (value === '水毁事件') {
router.replace({ path: '/waterDisasterReport' })
}
}
const handleDistrictChange = () => {
// 暂时不处理区县变化
// formData.routeNo = ''
// formData.event.startStakeNo = ''
// formData.event.endStakeNo = ''
// formData.event.startStakeLng = null
// formData.event.startStakeLat = null
// formData.event.endStakeLng = null
// formData.event.endStakeLat = null
}
const handleRouteNoChange = (item = {}) => {
formData.routeNo = item.routeCode || formData.routeNo
formData.event.startStakeNo = item.startStakeNo
formData.event.endStakeNo = item.endStakeNo
const startPoint = parsePointValue(item.startPoint ?? item.startpoint)
const endPoint = parsePointValue(item.endPoint ?? item.endpoint)
formData.event.startStakeLng = startPoint.longitude
formData.event.startStakeLat = startPoint.latitude
formData.event.endStakeLng = endPoint.longitude
formData.event.endStakeLat = endPoint.latitude
}
const handleHasStrandedVehiclesChange = (value) => {
if (value !== 1) {
formData.report.strandedVehicleCount = null
}
}
const getCurrentTime = () => {
const currentDate = new Date()
const year = currentDate.getFullYear()
const month = String(currentDate.getMonth() + 1).padStart(2, '0')
const day = String(currentDate.getDate()).padStart(2, '0')
const hours = String(currentDate.getHours()).padStart(2, '0')
const minutes = String(currentDate.getMinutes()).padStart(2, '0')
const seconds = String(currentDate.getSeconds()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
const buildSubmitData = () => {
const payload = mergeFormData(formData)
const reportTime = payload.report.reportTime || payload.event.reportTime || getCurrentTime()
payload.event.routeNo = payload.routeNo
payload.event.occurTime = payload.occurTime
payload.event.reportTime = reportTime
payload.event.reportUnit = payload.event.reportUnit || DEFAULT_REPORTER_UNIT
payload.event.disposalMeasures = payload.report.disposalMeasures
payload.event.expectRecoverTime = payload.report.expectRecoverTime
payload.event.actualRecoverTime = payload.report.actualRecoverTime || null
payload.event.roadConditionLocation = payload.occurLocation
payload.event.routeType = filterForm.routeType
payload.event.eventType = eventType.value
payload.report.reporterName = payload.report.reporterName || payload.event.reporterName
payload.report.reporterPhone = payload.report.reporterPhone || payload.event.reporterPhone
payload.report.reportTime = reportTime
if (payload.report.hasStrandedVehicles !== 1) {
payload.report.strandedVehicleCount = null
}
return payload
}
const getFormData = () => buildSubmitData()
const validate = async () => {
if (!formRef.value) {
return false
}
try {
await formRef.value.validate()
return true
} catch (_error) {
ElMessage.warning('请完善表单信息')
return false
}
}
const handleSubmit = async () => {
if (!(await validate())) {
return
}
submitting.value = true
try {
const res = await request({
url: '/snow-ops-platform/event/addOrUpdate',
method: 'post',
data: buildSubmitData()
})
if (res?.code === '00000') {
ElMessage.success('提交成功')
setTimeout(() => {
router.replace('/disasterManagement')
}, 500)
} else {
ElMessage.error(res?.message || '提交失败')
}
} catch (error) {
console.error('提交失败:', error)
ElMessage.error('提交失败,请重试')
} finally {
submitting.value = false
}
}
const getDisasterDetail = async () => {
if (!route.query.id) {
return
}
try {
const result = await request({
url: `/snow-ops-platform/event/getById?id=${route.query.id}`,
method: 'get'
})
if (result?.data) {
const data = result.data
const baseReport = data.report || data.reportList?.[data.reportList.length - 1] || {}
filterForm.routeType = data.event?.routeType || data.event?.roadType || filterForm.routeType
initFormData({
occurLocation: data.occurLocation || data.event?.roadConditionLocation || '',
occurTime: data.occurTime || data.event?.occurTime || '',
routeNo: data.routeNo || data.event?.routeNo || '',
event: {
...(data.event || {}),
reporterName: data.event?.reporterName || data.event?.contactPerson || '',
reporterPhone: data.event?.reporterPhone || data.event?.contactPhone || '',
reportUnit: data.event?.reportUnit || data.event?.reporterUnit || DEFAULT_REPORTER_UNIT,
startStakeLat: data.event?.startStakeLat ?? data.event?.startStakeLatitude ?? null,
startStakeLng: data.event?.startStakeLng ?? data.event?.startStakeLongitude ?? null,
endStakeLat: data.event?.endStakeLat ?? data.event?.endStakeLatitude ?? null,
endStakeLng: data.event?.endStakeLng ?? data.event?.endStakeLongitude ?? null
},
report: {
...baseReport,
disposalMeasures: baseReport.disposalMeasures || data.event?.disposalMeasures || '',
expectRecoverTime: baseReport.expectRecoverTime || data.event?.expectRecoverTime || '',
actualRecoverTime: baseReport.actualRecoverTime || data.event?.actualRecoverTime || '',
inputEquipment: baseReport.inputEquipment ?? data.material?.inputEquipment ?? baseReport.investedMachinery ?? null,
inputFunds: baseReport.inputFunds ?? data.material?.inputFunds ?? baseReport.investedFunds ?? null,
inputManpower: baseReport.inputManpower ?? data.material?.inputManpower ?? baseReport.investedManpower ?? null,
hasStrandedVehicles: baseReport.hasStrandedVehicles ?? data.traffic?.hasStrandedVehicles ?? null,
strandedVehicleCount: baseReport.strandedVehicleCount ?? data.traffic?.strandedVehicleCount ?? null,
industrialSalt: baseReport.industrialSalt ?? null,
antiSlipSand: baseReport.antiSlipSand ?? null,
sandbags: baseReport.sandbags ?? null,
reporterName: baseReport.reporterName || data.event?.reporterName || data.event?.contactPerson || '',
reporterPhone: baseReport.reporterPhone || data.event?.reporterPhone || data.event?.contactPhone || '',
reportTime: baseReport.reportTime || data.event?.reportTime || ''
},
fileList: data.fileList || [],
lossList: data.lossList || [],
yhzMaterialList: data.yhzMaterialList || baseReport.yhzMaterialList || []
})
} else {
ElMessage.warning(result?.message || '获取详情失败')
}
} catch (error) {
console.error('获取冰雪详情失败:', error)
ElMessage.error('获取详情失败,请稍后重试')
}
}
const handleBack = () => {
router.back()
}
onMounted(async () => {
await getAreaOptions()
if (route.query.id) {
await getDisasterDetail()
return
}
initFormData({})
})
return {
eventType,
filterForm,
formData,
formRef,
formRules,
handleBack,
handleDistrictChange,
handleEventTypeChange,
handleHasStrandedVehiclesChange,
handleRouteNoChange,
handleSubmit,
initFormData,
getFormData,
options,
routeTypeLabel,
strandedVehicleOptions,
submitting,
validate
}
}