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 } }