2026-04-17 09:21:59 +08:00

337 lines
9.3 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: {
contactPerson: '',
contactPhone: '',
disasterMileage: null,
district: '',
endStakeLatitude: null,
endStakeLongitude: null,
endStakeNo: '',
occurLocation: '',
reporterUnit: DEFAULT_REPORTER_UNIT,
serviceStationId: '',
startStakeLatitude: null,
startStakeLongitude: null,
startStakeNo: ''
},
material: {
inputEquipment: null,
inputFunds: null,
inputManpower: null
},
report: {
actualRecoverTime: '',
disposalMeasures: '',
expectRecoverTime: '',
siteDescription: ''
},
traffic: {
hasStrandedVehicles: null,
strandedVehicleCount: null
},
fileList: []
})
const mergeFormData = (source = {}) => {
const defaults = createDefaultFormData()
const merged = {
...defaults,
...source,
event: {
...defaults.event,
...(source.event || {})
},
material: {
...defaults.material,
...(source.material || {})
},
report: {
...defaults.report,
...(source.report || {})
},
traffic: {
...defaults.traffic,
...(source.traffic || {})
}
}
merged.fileList = Array.isArray(source.fileList) ? source.fileList : defaults.fileList
if (!merged.event.reporterUnit) {
merged.event.reporterUnit = 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.contactPerson': [{ required: true, message: '请输入联系人员', trigger: 'blur' }],
'event.contactPhone': [
{ 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.startStakeLongitude': [{ required: true, message: '请输入起点桩经度', trigger: 'blur' }],
'event.startStakeLatitude': [{ required: true, message: '请输入起点桩纬度', trigger: 'blur' }],
'event.endStakeNo': [{ required: true, message: '请输入止点桩号', trigger: 'blur' }],
'event.endStakeLongitude': [{ required: true, message: '请输入止点桩经度', trigger: 'blur' }],
'event.endStakeLatitude': [{ 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.startStakeLongitude = null
formData.event.startStakeLatitude = null
formData.event.endStakeLongitude = null
formData.event.endStakeLatitude = 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.startStakeLongitude = startPoint.longitude
formData.event.startStakeLatitude = startPoint.latitude
formData.event.endStakeLongitude = endPoint.longitude
formData.event.endStakeLatitude = endPoint.latitude
}
const handleHasStrandedVehiclesChange = (value) => {
if (value !== 1) {
formData.traffic.strandedVehicleCount = null
}
}
const buildSubmitData = () => {
const payload = mergeFormData(formData)
payload.event.routeNo = payload.routeNo
payload.event.occurTime = payload.occurTime
payload.event.eventType = eventType.value
payload.event.roadType = filterForm.routeType
payload.event.roadConditionLocation = payload.occurLocation
if (payload.traffic.hasStrandedVehicles !== 1) {
payload.traffic.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
initFormData({
occurLocation: data.occurLocation || data.event?.roadConditionLocation || '',
occurTime: data.occurTime || data.event?.occurTime || '',
routeNo: data.routeNo || data.event?.routeNo || '',
event: {
...(data.event || {})
},
material: {
...(data.material || {})
},
report: {
...(data.report || {})
},
traffic: {
...(data.traffic || {})
}
})
} 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
}
}