517 lines
14 KiB
Vue
Raw Normal View History

2025-11-07 17:27:41 +08:00
<template>
<div class="home">
<van-nav-bar title="冰雪填报" fixed left-arrow @click-left="onClickLeft">
</van-nav-bar>
<van-cell-group>
<van-cell title="当前站点" :value="yhzDetail.mc" />
</van-cell-group>
<div class="content">
<h3>基本信息</h3>
<van-form class="IceEventAddForm" label-align="left" colon>
<van-field v-model="form.event.occurTime" label="发生时间" center>
<template #button>
<van-button
plain
round
type="primary"
size="mini"
@click="getCurrentTime"
>校准时间</van-button
>
</template>
</van-field>
<van-field
v-model="form.event.occurLocation"
label="发生地点"
center
placeholder="请填写"
/>
<van-field
v-model="form.event.routeNo"
label="线路编号"
center
placeholder="请填写"
/>
<van-field
v-model="form.event.startStakeNo"
label="起点桩号"
center
placeholder="请填写"
/>
<van-field
v-model="form.event.endStakeNo"
label="止点桩号"
center
placeholder="请填写"
/>
<van-field
v-model="form.event.disasterMileage"
label="受灾里程"
center
placeholder="请填写"
/>
</van-form>
<h3>处置情况</h3>
<van-form class="IceEventAddForm" label-align="left" colon>
<van-field label="处置措施" center>
<template #input>
<div class="disposal-buttons">
<van-button
plain
:type="
form.event.disposalMeasures === '限速通行'
? 'primary'
: 'default'
"
size="small"
@click="toggleDisposal('限速通行')"
>
限速通行
</van-button>
<van-button
plain
:type="
form.event.disposalMeasures === '封闭交通'
? 'primary'
: 'default'
"
size="small"
@click="toggleDisposal('封闭交通')"
class="last-button"
>
封闭交通
</van-button>
</div>
</template>
</van-field>
<van-field
v-model="form.event.expectRecoverTime"
label="预计恢复时间"
center
placeholder="请选择"
readonly
clickable
@click="showExpectPicker = true"
/>
<van-popup
:show="showExpectPicker"
round
position="bottom"
close-on-click-overlay
@close="showExpectPicker = false"
>
<van-date-picker
type="datetime"
:min-date="minDate"
:max-date="maxDate"
@confirm="handleConfirmExpectTime"
@cancel="showExpectPicker = false"
/>
</van-popup>
</van-form>
<h3>实施情况</h3>
<van-form class="IceEventAddForm" label-align="left" colon>
<van-field
v-model="form.material.snowMeltingAgent"
type="number"
label="融雪剂"
center
placeholder="请填写"
>
<template #extra> </template>
</van-field>
<van-field
v-model="form.material.antiSlipSand"
type="number"
label="防滑沙"
center
placeholder="请填写"
>
<template #extra> </template>
</van-field>
<van-field
v-model="form.material.antiSlipChains"
type="number"
label="防滑链"
center
placeholder="请填写"
>
<template #extra> </template>
</van-field>
<van-field
v-model="form.material.sandbags"
type="number"
label="麻袋"
center
placeholder="请填写"
>
<template #extra> </template>
</van-field>
<van-field
v-model="form.material.inputManpower"
type="number"
label="投入人力"
center
placeholder="请填写"
>
<template #extra> 人次 </template>
</van-field>
<van-field
v-model="form.material.inputFunds"
type="number"
label="投入资金"
center
placeholder="请填写"
>
<template #extra> 万元 </template>
</van-field>
<van-field
v-model="form.material.inputEquipment"
type="number"
label="投入设备"
center
placeholder="请填写"
>
<template #extra> 台班 </template>
</van-field>
<van-field label="当前通行情况" center>
<template #input>
<div class="disposal-buttons">
<van-button
plain
:type="form.traffic.currentStatus === 1 ? 'primary' : 'default'"
size="small"
@click="form.traffic.currentStatus = 1"
>
正常通行
</van-button>
<van-button
plain
:type="form.traffic.currentStatus === 2 ? 'primary' : 'default'"
size="small"
@click="form.traffic.currentStatus = 2"
>
限速通行
</van-button>
<van-button
plain
:type="form.traffic.currentStatus === 3 ? 'primary' : 'default'"
size="small"
@click="form.traffic.currentStatus = 3"
class="last-button"
>
封闭交通
</van-button>
</div>
</template>
</van-field>
<van-field label="有无车辆滞留" center>
<template #input>
<div class="disposal-buttons">
<van-button
plain
:type="
form.traffic.hasStrandedVehicles === 1 ? 'primary' : 'default'
"
size="small"
@click="form.traffic.hasStrandedVehicles = 1"
>
有滞留
</van-button>
<van-button
plain
:type="
form.traffic.hasStrandedVehicles === 0 ? 'primary' : 'default'
"
size="small"
@click="form.traffic.hasStrandedVehicles = 0"
class="last-button"
>
无滞留
</van-button>
</div>
</template>
</van-field>
<van-field
v-model="form.traffic.strandedVehicleCount"
type="number"
label="滞留车辆数"
center
placeholder="请填写"
/>
<van-field
v-model="form.traffic.actualRecoverTime"
label="实际恢复时间"
center
placeholder="请选择"
readonly
clickable
@click="showActualPicker = true"
/>
<van-popup
:show="showActualPicker"
round
position="bottom"
close-on-click-overlay
@close="showActualPicker = false"
>
<van-date-picker
type="datetime"
:min-date="minDate"
:max-date="maxDate"
@confirm="handleConfirmActualTime"
@cancel="showActualPicker = false"
/>
</van-popup>
<van-field label="附件" center>
<template #input>
<van-uploader
v-model="fileList"
@delete="handleDelete"
name="photos"
:file-list="fileList"
:file-type="['image/jpeg', 'image/png']"
:after-read="afterRead"
multiple
:max-count="6"
/>
</template>
</van-field>
</van-form>
</div>
<van-button type="primary" class="add-btn" icon="plus" @click="handleAdd">
填报
</van-button>
</div>
</template>
<script setup>
import "vant/es/toast/style";
import "vant/es/popup/style";
import { ref, onMounted, reactive, toRaw, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import { showToast, showLoadingToast } from "vant";
import { request } from "../../../../shared/utils/request";
const router = useRouter();
const route = useRoute();
const yhzDetail = ref({}); // 养护站详情数据
const INIT_FORM = reactive({
event: {
occurLocation: "", // 发生地点
routeNo: "", // 线路编号
occurTime: "", // 发生时间
startStakeNo: "", // 起点桩号
endStakeNo: "", // 止点桩号
disasterMileage: "", // 受灾里程
expectRecoverTime: "", // 预计恢复时间
actualRecoverTime: "", // 实际恢复时间
serviceStationId: "", // 养护站ID
district: "", // 所属区县
reportTime: "", // 填报时间
reporterPhone: "", // 填报人手机号
disposalMeasures: "", // 处置措施
createTime: "", // 创建时间
updateTime: "", // 更新时间
isDeleted: "", // 是否删除 0-未删除 1-已删除
},
material: {
inputManpower: null, // 投入人力
inputFunds: null, // 投入资金
inputEquipment: null, // 投入设备
snowMeltingAgent: null, // 融雪剂
sandbags: null, // 麻袋
antiSlipSand: null, // 防滑沙
antiSlipChains: null, // 防滑链
createTime: "", // 创建时间
updateTime: "", // 更新时间
},
traffic: {
currentStatus: 0, // 当前通行情况 1-正常通行 2-限速通行 3-封闭交通
hasStrandedVehicles: 0, // 是否有车辆滞留 0-无 1-有
strandedVehicleCount: null, // 车辆滞留数量
actualRecoverTime: "", // 实际恢复时间
createTime: "", // 创建时间
updateTime: "", // 更新时间
},
photos: [],
});
const form = reactive({ ...INIT_FORM });
const fileList = ref([]);
// 日期格式化
const formatTime = (date = new Date()) => {
const pad = (n) => n.toString().padStart(2, "0");
return (
`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
date.getDate()
)} ` +
`${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
date.getSeconds()
)}`
);
};
const getCurrentTime = () => {
form.event.occurTime = formatTime();
};
const toggleDisposal = (type) => {
form.event.disposalMeasures =
form.event.disposalMeasures === type ? "" : type;
};
// 组件挂载时获取数据
onMounted(() => {
yhzDetail.value = JSON.parse(decodeURIComponent(route.params.data));
console.log("yhzDetail", toRaw(yhzDetail.value));
form.event.occurTime = formatTime(); // 初始化为当前时间
});
const onClickLeft = () => {
router.push({
name: "IceEventManage",
params: { data: encodeURIComponent(JSON.stringify(yhzDetail.value)) },
});
};
const handleAdd = () => {
console.log("form", toRaw(form));
};
// 预计恢复时间相关
const showExpectPicker = ref(false);
const minDate = new Date();
const maxDate = new Date(2050, 11, 31);
const handleConfirmExpectTime = ({ selectedValues }) => {
form.event.expectRecoverTime = selectedValues.join("-");
showExpectPicker.value = false;
};
// 实际恢复时间相关
const showActualPicker = ref(false);
const handleConfirmActualTime = ({ selectedValues }) => {
form.traffic.actualRecoverTime = selectedValues.join("-");
showActualPicker.value = false;
};
// 文件上传
const afterRead = async (file) => {
try {
const toast = showLoadingToast({
message: "上传中...",
forbidClick: true,
duration: 0, // 设置为0表示不会自动关闭
});
const formData = new FormData();
formData.append("file", file.file);
const res = await request({
url: "/snow-ops-platform/file/upload",
method: "post",
data: formData,
});
toast.close();
if (res.code === "00000") {
form.photos.push({ photoUrl: res.data });
const index = fileList.value.findIndex((f) => f.file === file.file);
if (index !== -1) {
fileList.value[index].serverUrl = res.data;
}
console.log("form.photos", toRaw(form.photos));
console.log("fileList.value", fileList.value);
} else {
throw new Error(res.message);
}
} catch (error) {
toast.close();
showToast({
type: "fail",
message: error.message,
});
}
};
// 文件删除
const handleDelete = (file) => {
if (file.serverUrl) {
const index = form.photos.findIndex((p) => p.photoUrl === file.serverUrl);
if (index !== -1) {
form.photos.splice(index, 1);
}
}
};
</script>
<style scoped>
.home {
padding-top: var(--van-nav-bar-height); /* 自动匹配导航栏高度 */
}
.content {
padding: 16px 16px 80px 16px;
}
.content .van-cell-group .van-cell {
margin-bottom: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.add-btn {
position: fixed;
bottom: 20px;
left: 16px;
right: 16px;
width: calc(100% - 32px);
margin: 0 auto;
border-radius: 24px;
font-size: 16px;
height: 44px;
z-index: 999;
}
.grid {
margin-top: 16px;
}
.btn {
margin-top: 24px;
}
.status-tag {
display: inline-block;
padding: 3px 8px;
border-radius: 4px;
color: white;
font-size: 12px;
}
.status-good {
background-color: #07c160;
}
.status-warning {
background-color: #ff976a;
}
.status-danger {
background-color: #ee0a24;
}
.IceEventAddForm {
padding: 16px 16px 16px 16px;
}
.disposal-buttons {
display: flex;
gap: 10px;
padding: 8px 0;
}
.disposal-buttons .van-button {
flex: 1;
}
.last-button {
margin-right: 16px;
}
</style>