bxztApp/packages/mobile/src/views/Equipment/EquipmentManagement.vue

719 lines
19 KiB
Vue
Raw Normal View History

2025-10-16 15:04:54 +08:00
<template>
<div class="home">
<van-nav-bar title="设备管理" fixed left-arrow @click-left="onClickLeft">
</van-nav-bar>
<van-search
shape="round"
2025-11-04 17:29:45 +08:00
v-model="searchValue"
2025-10-16 15:04:54 +08:00
:show-action="false"
placeholder="请输入设备名称"
/>
<van-cell-group>
2025-11-04 17:29:45 +08:00
<van-cell title="当前站点" :value="detailData.mc || detailData.sbwz" />
2025-10-16 15:04:54 +08:00
</van-cell-group>
2025-10-27 10:50:08 +08:00
<van-notice-bar mode="link">20台设备待确认</van-notice-bar>
2025-10-16 15:04:54 +08:00
<div class="content">
<van-cell-group>
<van-cell
2025-10-24 14:46:42 +08:00
v-for="(item, index) in equipmentList"
:key="index"
2025-11-04 17:29:45 +08:00
:title="item.sbmc"
2025-10-16 15:04:54 +08:00
is-link
2025-11-04 17:29:45 +08:00
:label="`设备类型: ` + item.sblx"
2025-10-24 10:12:16 +08:00
:to="{
name: 'EquipDetail',
2025-10-24 14:46:42 +08:00
params: { data: encodeURIComponent(JSON.stringify(item)) },
2025-10-24 10:12:16 +08:00
}"
2025-10-16 15:04:54 +08:00
>
<template #value>
2025-11-04 17:29:45 +08:00
<span
:class="[
'status-tag',
`status-` +
(item.sbzt === '完好'
? 'good'
: item.sbzt === '损坏'
? 'warning'
: 'danger'),
]"
>{{ item.sbzt }}</span
>
2025-10-16 15:04:54 +08:00
</template>
</van-cell>
</van-cell-group>
</div>
<van-button
type="primary"
class="add-btn"
icon="plus"
@click="handleAddDevice"
>
添加设备
</van-button>
2025-10-16 16:44:08 +08:00
2025-10-17 15:53:41 +08:00
<!-- 添加设备弹窗 -->
2025-10-16 16:44:08 +08:00
<van-popup
:show="showPopup"
position="bottom"
closeable
close-on-click-overlay
:style="{ height: '80%' }"
@close="onPopupClose"
>
2025-10-17 15:53:41 +08:00
<!-- 表单部分 -->
2025-11-04 18:12:08 +08:00
<van-form
class="device-form"
2025-11-05 15:10:15 +08:00
label-align="left"
colon
2025-11-04 18:12:08 +08:00
>
2025-10-17 15:53:41 +08:00
<h3>设备信息</h3>
<!-- 设备名称 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.sbmc"
2025-10-17 15:53:41 +08:00
label="设备名称"
placeholder="请输入设备名称"
:rules="[{ required: true, message: '请填写设备名称' }]"
>
<template #button>
2025-11-04 18:12:08 +08:00
<span class="counter">{{ form.sbmc.length }}/20</span>
2025-10-17 15:53:41 +08:00
</template>
</van-field>
<!-- 设备大类 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.sbdl"
2025-10-17 15:53:41 +08:00
is-link
arrow-direction="down"
label="设备大类"
placeholder="请选择设备大类"
@click="showCategoryPicker = true"
2025-11-05 15:10:15 +08:00
ref="categoryField"
2025-10-17 15:53:41 +08:00
/>
<!-- 设备类型 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.sblx"
2025-10-17 15:53:41 +08:00
is-link
arrow-direction="down"
label="设备类型"
placeholder="请选择设备类型"
@click="showTypePicker = true"
2025-11-05 15:10:15 +08:00
ref="typeField"
/>
<!-- 设备编号 -->
<van-field
v-model="form.sbbh"
label="设备编号"
placeholder="请输入设备编号"
:rules="[{ required: true, message: '请填写设备编号' }]"
2025-10-17 15:53:41 +08:00
/>
<!-- 设备型号 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.sbxh"
2025-10-17 15:53:41 +08:00
label="设备型号"
placeholder="请输入设备型号"
:rules="[{ required: true, message: '请填写设备型号' }]"
/>
<!-- 设备经度 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.jd"
2025-10-17 15:53:41 +08:00
label="设备经度"
placeholder="请输入设备经度"
/>
<!-- 设备纬度 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.wd"
2025-10-17 15:53:41 +08:00
label="设备纬度"
placeholder="请输入设备纬度"
/>
<!-- 设备管理员 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.glry"
2025-10-17 15:53:41 +08:00
is-link
arrow-direction="down"
readonly
2025-11-04 18:12:08 +08:00
label="管理人员"
placeholder="请选择设备管理人员"
2025-10-17 15:53:41 +08:00
@click="showAdminPicker = true"
/>
<!-- 操作员 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.czy"
2025-10-17 15:53:41 +08:00
is-link
arrow-direction="down"
readonly
label="操作员"
placeholder="请选择操作员"
@click="showOperatorPicker = true"
/>
2025-11-05 15:10:15 +08:00
<!-- 购买费用 -->
<van-field
v-model="form.gmfy"
type="number"
label="购买费用(万元)"
placeholder="请输入购买费用"
/>
2025-10-17 15:53:41 +08:00
<!-- 购置日期 -->
<van-field
2025-11-04 18:12:08 +08:00
v-model="form.gzrq"
2025-10-17 15:53:41 +08:00
is-link
arrow-direction="down"
readonly
label="购置日期"
placeholder="请选择日期"
@click="showTimePicker = true"
/>
2025-11-04 18:12:08 +08:00
<!-- 设备状态 -->
<van-field
v-model="form.sbzt"
is-link
arrow-direction="down"
readonly
label="设备状态"
placeholder="请选择设备状态"
@click="showStatusPicker = true"
/>
<!-- 生产厂家 -->
<van-field
v-model="form.sccj"
label="生产厂家"
placeholder="请输入生产厂家"
/>
<!-- 是否应急设备 -->
<van-field
v-model="form.sfyjsb"
is-link
arrow-direction="down"
readonly
label="是否应急设备"
placeholder="请选择"
@click="showEmergencyPicker = true"
/>
<!-- 是否纳入市级补助范围 -->
<van-field
v-model="form.sfnrsjbz"
is-link
arrow-direction="down"
readonly
label="是否纳入市级补助范围"
placeholder="请选择"
@click="showSubsidyPicker = true"
/>
2025-11-05 15:10:15 +08:00
<!-- 辐射范围 -->
<van-field
v-model="form.fsfw"
label="辐射范围"
placeholder="请输入辐射范围"
/>
2025-10-17 15:53:41 +08:00
<!-- 选择器弹窗 -->
<!-- 设备大类弹窗 -->
<van-popup
:show="showCategoryPicker"
round
position="bottom"
close-on-click-overlay
@close="showCategoryPicker = false"
>
<van-picker
title="选择设备大类"
:columns="categoryOptions"
@confirm="onCategoryConfirm"
@cancel="showCategoryPicker = false"
/>
</van-popup>
<!-- 设备类型弹窗 -->
<van-popup
:show="showTypePicker"
round
position="bottom"
close-on-click-overlay
@close="showTypePicker = false"
>
<van-picker
title="选择设备类型"
:columns="typeOptions"
@confirm="onTypeConfirm"
@cancel="showTypePicker = false"
/>
</van-popup>
<!-- 设备管理员弹窗 -->
<van-popup
:show="showAdminPicker"
round
position="bottom"
close-on-click-overlay
@close="showAdminPicker = false"
>
<van-picker
title="选择设备管理员"
:columns="adminOptions"
@confirm="onAdminConfirm"
@cancel="showAdminPicker = false"
/>
</van-popup>
<!-- 操作员弹窗 -->
<van-popup
:show="showOperatorPicker"
round
position="bottom"
close-on-click-overlay
@close="showOperatorPicker = false"
>
<van-picker
title="选择操作员"
:columns="operatorOptions"
@confirm="operatorConfirm"
@cancel="showOperatorPicker = false"
/>
</van-popup>
<!-- 购置日期弹窗 -->
<van-popup
:show="showTimePicker"
round
position="bottom"
close-on-click-overlay
@close="showTimePicker = false"
>
<van-date-picker
v-model="currentDate"
title="选择购置日期"
@confirm="onDateConfirm"
@cancel="showTimePicker = false"
/>
</van-popup>
2025-11-04 18:12:08 +08:00
<!-- 设备状态弹窗 -->
<van-popup
:show="showStatusPicker"
round
position="bottom"
close-on-click-overlay
@close="showStatusPicker = false"
>
<van-picker
title="选择设备状态"
:columns="statusOptions"
@confirm="onStatusConfirm"
@cancel="showStatusPicker = false"
/>
</van-popup>
<!-- 是否应急设备弹窗 -->
<van-popup
:show="showEmergencyPicker"
round
position="bottom"
close-on-click-overlay
@close="showEmergencyPicker = false"
>
<van-picker
title="是否应急设备"
:columns="emergencyOptions"
@confirm="onEmergencyConfirm"
@cancel="showEmergencyPicker = false"
/>
</van-popup>
<!-- 是否纳入市级补助范围弹窗 -->
<van-popup
:show="showSubsidyPicker"
round
position="bottom"
close-on-click-overlay
@close="showSubsidyPicker = false"
>
<van-picker
title="是否纳入市级补助"
:columns="subsidyOptions"
@confirm="onSubsidyConfirm"
@cancel="showSubsidyPicker = false"
/>
</van-popup>
2025-10-17 15:53:41 +08:00
</van-form>
2025-11-04 18:12:08 +08:00
<div
style="
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 16px;
background: white;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
z-index: 100;
"
>
2025-11-05 15:10:15 +08:00
<van-button
round
block
type="primary"
native-type="submit"
@click="handleSubmit"
>
2025-11-04 18:12:08 +08:00
保存
</van-button>
</div>
2025-10-16 16:44:08 +08:00
</van-popup>
2025-10-16 15:04:54 +08:00
</div>
</template>
2025-11-05 15:10:15 +08:00
<script setup>
import "vant/es/toast/style";
import "vant/es/popup/style";
2025-11-04 17:29:45 +08:00
import { ref, onMounted, reactive, toRaw, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
2025-11-05 15:10:15 +08:00
import { showToast, showLoadingToast } from "vant";
import { request } from "../../../../shared/utils/request";
2025-10-16 15:04:54 +08:00
const router = useRouter();
2025-11-04 17:29:45 +08:00
const route = useRoute();
const detailData = ref({}); // 养护站详情数据
2025-10-16 16:44:08 +08:00
const searchValue = ref(""); // 搜索框输入值
2025-11-04 17:29:45 +08:00
const equipmentList = ref([]);
2025-11-04 18:12:08 +08:00
const INIT_FORM = {
qxmc: "",
sbbh: "",
sbdl: "",
sbmc: "",
sblx: "",
sbxh: "",
sbwz: "",
jd: "",
wd: "",
glry: "",
glryid: "",
czy: "",
czyid: "",
gzrq: "",
gmfy: "",
sbzt: "",
sccj: "",
sfyjsb: "",
sfnrsjbz: "",
fsfw: "",
yhzid: "",
}; // 表单初始值
const form = reactive({ ...INIT_FORM }); // 表单
2025-11-04 17:29:45 +08:00
// 获取养护站详情数据
onMounted(() => {
detailData.value = JSON.parse(decodeURIComponent(route.params.data));
getEquipmentList();
2025-11-05 15:10:15 +08:00
form.yhzid = detailData.value.id || detailData.value.yhzid;
form.qxmc = detailData.value.qxmc;
2025-11-04 17:29:45 +08:00
});
watch(
() => searchValue.value,
(newVal, oldVal) => {
if (newVal !== oldVal) {
getEquipmentList(newVal);
}
}
);
// 获取养护站设备列表
const getEquipmentList = async (sbmc) => {
try {
2025-11-05 15:10:15 +08:00
const yhzid = detailData.value.id || detailData.value.yhzid;
if (!yhzid) {
return;
}
2025-11-04 17:29:45 +08:00
const data = {
yhzid: detailData.value.id || detailData.value.yhzid,
sbmc: sbmc,
pageNum: 1,
pageSize: 9999,
};
const res = await request({
2025-11-05 15:10:15 +08:00
url: "/snow-ops-platform/yjsb/list",
2025-11-04 17:29:45 +08:00
method: "get",
params: data,
});
if (res.code && res.code === "00000") {
equipmentList.value = res.data.records;
} else {
throw new Error(res.message);
}
} catch (error) {
console.log(error);
2025-11-05 15:10:15 +08:00
showToast({
type: "error",
message: error.message || "获取设备列表失败",
});
2025-11-04 17:29:45 +08:00
}
};
2025-10-16 16:44:08 +08:00
const showPopup = ref(false); // 控制弹出层显示隐藏
2025-10-16 15:04:54 +08:00
const onClickLeft = () => {
2025-11-04 14:24:06 +08:00
router.push("/");
2025-10-16 15:04:54 +08:00
};
2025-10-16 16:44:08 +08:00
const handleAddDevice = () => {
showPopup.value = true;
};
const onPopupClose = () => {
showPopup.value = false;
};
2025-10-17 15:53:41 +08:00
const showCategoryPicker = ref(false);
const showTypePicker = ref(false);
2025-11-05 15:10:15 +08:00
const categoryField = ref(null);
const typeField = ref(null);
2025-10-17 15:53:41 +08:00
const categoryOptions = [
2025-11-05 15:10:15 +08:00
{ text: "自定义", value: "自定义" },
{ text: "大中修工程设备", value: "大中修工程设备" },
{ text: "小修保养设备", value: "小修保养设备" },
{ text: "交通工具", value: "交通工具" },
2025-10-17 15:53:41 +08:00
];
const typeOptions = [
2025-11-05 15:10:15 +08:00
{ text: "自定义", value: "自定义" },
{ text: "装载机", value: "装载机" },
{ text: "路面修补设备", value: "路面修补设备" },
{ text: "清扫车", value: "清扫车" },
{ text: "压路机", value: "压路机" },
{ text: "洒水车", value: "洒水车" },
{ text: "挖掘机", value: "挖掘机" },
{ text: "运输货车", value: "运输货车" },
{ text: "灌缝设备", value: "灌缝设备" },
{ text: "应急抢险车", value: "应急抢险车" },
{ text: "应急巡查车", value: "应急巡查车" },
{ text: "高空作业车", value: "高空作业车" },
{ text: "除雪设备", value: "除雪设备" },
{ text: "照明设备", value: "照明设备" },
{ text: "护栏维修设备", value: "护栏维修设备" },
{ text: "标线设备", value: "标线设备" },
{ text: "绿化修剪设备", value: "绿化修剪设备" },
{ text: "桥梁维护设备", value: "桥梁维护设备" },
{ text: "发电机", value: "发电机" },
{ text: "沥青洒布车", value: "沥青洒布车" },
{ text: "拖车", value: "拖车" },
{ text: "摊铺机", value: "摊铺机" },
{ text: "抽水设备", value: "抽水设备" },
{ text: "沥青拌和站", value: "沥青拌和站" },
{ text: "水泥拌和机", value: "水泥拌和机" },
{ text: "平地机", value: "平地机" },
{ text: "除雾设备", value: "除雾设备" },
{ text: "无人机", value: "无人机" },
{ text: "推土机", value: "推土机" },
{ text: "稀浆封层设备", value: "稀浆封层设备" },
2025-10-17 15:53:41 +08:00
];
const onCategoryConfirm = (value) => {
2025-11-05 15:10:15 +08:00
if (value.selectedValues[0] === "自定义") {
showCategoryPicker.value = false;
categoryField.value.focus();
} else {
form.sbdl = value.selectedValues[0];
showCategoryPicker.value = false;
}
2025-10-17 15:53:41 +08:00
};
const onTypeConfirm = (value) => {
2025-11-05 15:10:15 +08:00
if (value.selectedValues[0] === "自定义") {
showTypePicker.value = false;
typeField.value.focus();
} else {
form.sblx = value.selectedValues[0];
showTypePicker.value = false;
}
2025-10-17 15:53:41 +08:00
};
2025-11-05 15:10:15 +08:00
2025-10-17 15:53:41 +08:00
// 设备管理员
const showAdminPicker = ref(false);
const adminOptions = [
{ text: "管理员1", value: "管理员1" },
{ text: "管理员2", value: "管理员2" },
{ text: "管理员3", value: "管理员3" },
];
const onAdminConfirm = (value) => {
2025-11-05 15:10:15 +08:00
form.glry = value.selectedValues[0];
2025-10-17 15:53:41 +08:00
showAdminPicker.value = false;
};
2025-11-05 15:10:15 +08:00
2025-10-17 15:53:41 +08:00
// 操作员
const showOperatorPicker = ref(false);
const operatorOptions = [
{ text: "操作员1", value: "操作员1" },
{ text: "操作员2", value: "操作员2" },
{ text: "操作员3", value: "操作员3" },
];
const operatorConfirm = (value) => {
2025-11-05 15:10:15 +08:00
form.czy = value.selectedValues[0];
2025-10-17 15:53:41 +08:00
showOperatorPicker.value = false;
};
// 购置日期
const showTimePicker = ref(false);
const currentDate = ref([
new Date().getFullYear(),
new Date().getMonth() + 1,
new Date().getDate(),
]);
const onDateConfirm = ({ selectedValues }) => {
2025-11-05 15:10:15 +08:00
form.gzrq = selectedValues.join("-");
2025-10-17 15:53:41 +08:00
showTimePicker.value = false;
};
2025-11-04 18:12:08 +08:00
// 设备状态相关
const showStatusPicker = ref(false);
const statusOptions = [
{ text: "完好", value: "完好" },
{ text: "损坏", value: "损坏" },
2025-11-05 15:10:15 +08:00
{ text: "报废", value: "报废" },
2025-11-04 18:12:08 +08:00
];
const onStatusConfirm = (value) => {
form.sbzt = value.selectedValues[0];
showStatusPicker.value = false;
};
// 是否应急设备相关
const showEmergencyPicker = ref(false);
const emergencyOptions = [
{ text: "是", value: "是" },
{ text: "否", value: "否" },
];
const onEmergencyConfirm = (value) => {
form.sfyjsb = value.selectedValues[0];
showEmergencyPicker.value = false;
};
2025-11-05 15:10:15 +08:00
2025-11-04 18:12:08 +08:00
// 是否纳入市级补助相关
const showSubsidyPicker = ref(false);
const subsidyOptions = [
{ text: "是", value: "是" },
{ text: "否", value: "否" },
];
const onSubsidyConfirm = (value) => {
form.sfnrsjbz = value.selectedValues[0];
showSubsidyPicker.value = false;
};
2025-11-05 15:10:15 +08:00
const handleSubmit = async () => {
try {
showLoadingToast({
message: "正在保存",
forbidClick: true,
loadingType: "spinner",
});
console.log("form", toRaw(form));
const res = await request({
url: "/snow-ops-platform/yjsb/add",
method: "post",
data: toRaw(form),
});
if (res.code && res.code === "00000") {
showToast({
type: "success",
message: "新增成功",
});
// 保留需要的数据
const keepData = {
yhzid: form.yhzid,
qxmc: form.qxmc,
};
// 重置表单数据
Object.keys(INIT_FORM).forEach((key) => {
if (!["yhzid", "qxmc"].includes(key)) {
form[key] = INIT_FORM[key];
}
});
// 恢复保留的数据
Object.assign(form, keepData);
onPopupClose();
getEquipmentList(searchValue.value);
} else {
throw new Error(res.message);
}
} catch (error) {
console.log(error);
showToast({
type: "error",
message: error.message || "新增失败",
});
}
2025-10-17 15:53:41 +08:00
};
2025-11-05 15:10:15 +08:00
</script>
<style scoped>
2025-10-16 15:04:54 +08:00
.home {
padding-top: var(--van-nav-bar-height); /* 自动匹配导航栏高度 */
}
.content {
padding: 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;
}
2025-10-17 15:53:41 +08:00
.device-form {
2025-11-05 15:10:15 +08:00
padding: 16px 16px 80px 16px;
2025-10-17 15:53:41 +08:00
}
2025-10-16 15:04:54 +08:00
</style>