<template>
|
<view class="upkeep-add">
|
<!-- 使用通用页面头部组件 -->
|
<PageHeader :title="operationType === 'edit' ? '编辑保养计划' : '新增保养计划'" @back="goBack" />
|
|
<!-- 表单内容 -->
|
<van-form @submit="sendForm" ref="formRef" label-width="110px" input-align="right" error-message-align="right" scroll-to-error scroll-to-error-position="center">
|
<!-- 基本信息 -->
|
<van-cell-group title="基本信息" inset>
|
<van-field
|
v-model="deviceNameText"
|
label="设备名称"
|
placeholder="请选择设备名称"
|
:rules="formRules.deviceLedgerId"
|
required
|
readonly
|
@click="showDevicePicker"
|
clearable
|
>
|
<template #right-icon>
|
<van-icon name="scan" @click.stop="startScan" class="scan-icon" />
|
</template>
|
</van-field>
|
<van-field
|
v-model="form.deviceModel"
|
label="规格型号"
|
placeholder="请输入规格型号"
|
readonly
|
clearable
|
/>
|
<van-field
|
v-model="form.maintenancePlanTime"
|
label="计划保养日期"
|
placeholder="请选择计划保养日期"
|
:rules="formRules.maintenancePlanTime"
|
required
|
readonly
|
@click="showDatePicker"
|
clearable
|
/>
|
</van-cell-group>
|
|
<!-- 提交按钮 -->
|
<view class="footer-btns">
|
<van-button class="cancel-btn" @click="goBack">取消</van-button>
|
<van-button class="save-btn" native-type="submit" form-type="submit" :loading="loading">保存</van-button>
|
</view>
|
</van-form>
|
|
<!-- 设备选择器 -->
|
<van-popup v-model:show="showDevice" position="bottom">
|
<van-picker
|
:model-value="devicePickerValue"
|
:columns="deviceColumns"
|
@confirm="onDeviceConfirm"
|
@cancel="showDevice = false"
|
/>
|
</van-popup>
|
|
<!-- 日期选择器 -->
|
<van-popup v-model:show="showDate" position="bottom">
|
<van-date-picker
|
v-model="currentDate"
|
title="选择日期"
|
@confirm="onDateConfirm"
|
@cancel="showDate = false"
|
/>
|
</van-popup>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
import { onShow } from '@dcloudio/uni-app';
|
import PageHeader from '@/components/PageHeader.vue';
|
import { getDeviceLedger } from '@/api/equipmentManagement/ledger';
|
import { addUpkeep, editUpkeep, getUpkeepById } from '@/api/equipmentManagement/upkeep';
|
import dayjs from "dayjs";
|
|
defineOptions({
|
name: "设备保养计划表单",
|
});
|
|
// 表单引用
|
const formRef = ref(null);
|
const operationType = ref('add');
|
const loading = ref(false);
|
const showDevice = ref(false);
|
const devicePickerValue = ref([]);
|
const showDate = ref(false);
|
const currentDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]);
|
|
// 设备选项
|
const deviceOptions = ref([]);
|
const deviceNameText = ref('');
|
|
// 扫码相关状态
|
const isScanning = ref(false);
|
const scanTimer = ref(null);
|
|
// 表单验证规则
|
const formRules = {
|
deviceLedgerId: [{ required: true, trigger: "change", message: "请选择设备名称" }],
|
maintenancePlanTime: [{ required: true, trigger: "change", message: "请选择计划保养日期" }],
|
};
|
|
// 使用 ref 声明表单数据
|
const form = ref({
|
deviceLedgerId: undefined, // 设备ID
|
deviceModel: undefined, // 规格型号
|
maintenancePlanTime: dayjs().format("YYYY-MM-DD"), // 计划保养日期
|
});
|
|
// 设备选择器列
|
const deviceColumns = computed(() => {
|
return deviceOptions.value.map(item => ({
|
text: item.deviceName,
|
value: item.id
|
}));
|
});
|
|
// 加载设备列表
|
const loadDeviceName = async () => {
|
try {
|
const { data } = await getDeviceLedger();
|
deviceOptions.value = data || [];
|
} catch (e) {
|
showToast('获取设备列表失败');
|
}
|
};
|
|
// 设置设备规格型号
|
const setDeviceModel = (id) => {
|
const option = deviceOptions.value.find((item) => item.id === id);
|
if (option) {
|
form.value.deviceModel = option.deviceModel;
|
deviceNameText.value = option.deviceName;
|
}
|
};
|
|
// 加载表单数据(编辑模式)
|
const loadForm = async (id) => {
|
if (id) {
|
operationType.value = 'edit';
|
try {
|
const { code, data } = await getUpkeepById(id);
|
if (code == 200) {
|
form.value.deviceLedgerId = data.deviceLedgerId;
|
form.value.deviceModel = data.deviceModel;
|
form.value.maintenancePlanTime = dayjs(data.maintenancePlanTime).format("YYYY-MM-DD");
|
// 设置设备名称显示
|
const device = deviceOptions.value.find(item => item.id === data.deviceLedgerId);
|
if (device) {
|
deviceNameText.value = device.deviceName;
|
}
|
}
|
} catch (e) {
|
showToast('获取详情失败');
|
}
|
} else {
|
// 新增模式
|
operationType.value = 'add';
|
}
|
};
|
|
// 清除表单校验状态
|
const clearValidate = () => {
|
formRef.value?.clearValidate();
|
};
|
|
// 重置表单数据和校验状态
|
const resetForm = () => {
|
form.value = {
|
deviceLedgerId: undefined,
|
deviceModel: undefined,
|
maintenancePlanTime: dayjs().format("YYYY-MM-DD"),
|
};
|
deviceNameText.value = '';
|
};
|
|
const resetFormAndValidate = () => {
|
resetForm();
|
clearValidate();
|
};
|
|
// 扫描二维码功能
|
const startScan = () => {
|
if (isScanning.value) {
|
showToast('正在扫描中,请稍候...');
|
return;
|
}
|
|
// 调用uni-app的扫码API
|
uni.scanCode({
|
scanType: ['qrCode', 'barCode'],
|
success: (res) => {
|
handleScanResult(res.result);
|
},
|
fail: (err) => {
|
console.error('扫码失败:', err);
|
showToast('扫码失败,请重试');
|
}
|
});
|
};
|
|
// 处理扫码结果
|
const handleScanResult = (scanResult) => {
|
if (!scanResult) {
|
showToast('扫码结果为空');
|
return;
|
}
|
|
isScanning.value = true;
|
showToast('扫码成功,3秒后自动填充设备信息');
|
|
// 3秒后处理扫码结果
|
scanTimer.value = setTimeout(() => {
|
processScanResult(scanResult);
|
isScanning.value = false;
|
}, 3000);
|
};
|
|
// 处理扫码结果并匹配设备
|
const processScanResult = (scanResult) => {
|
// 在设备列表中查找匹配的设备
|
// 假设二维码内容是设备名称或设备编号
|
const matchedDevice = deviceOptions.value.find(device =>
|
device.deviceName === scanResult ||
|
device.deviceCode === scanResult ||
|
device.id.toString() === scanResult
|
);
|
|
if (matchedDevice) {
|
// 找到匹配的设备,自动填充
|
form.value.deviceLedgerId = matchedDevice.id;
|
deviceNameText.value = matchedDevice.deviceName;
|
form.value.deviceModel = matchedDevice.deviceModel;
|
showToast('设备信息已自动填充');
|
} else {
|
// 未找到匹配的设备
|
showToast('未找到匹配的设备,请手动选择');
|
}
|
};
|
|
// 显示设备选择器
|
const showDevicePicker = () => {
|
showDevice.value = true;
|
};
|
|
// 确认设备选择
|
const onDeviceConfirm = ({ selectedValues, selectedOptions }) => {
|
form.value.deviceLedgerId = selectedOptions[0].value;
|
devicePickerValue.value = selectedValues;
|
showDevice.value = false;
|
setDeviceModel(selectedOptions[0].value);
|
};
|
|
// 显示日期选择器
|
const showDatePicker = () => {
|
showDate.value = true;
|
};
|
|
// 确认日期选择
|
const onDateConfirm = ({ selectedValues }) => {
|
form.value.maintenancePlanTime = selectedValues.join('-');
|
currentDate.value = selectedValues;
|
showDate.value = false;
|
};
|
|
onShow(() => {
|
// 页面显示时获取参数
|
getPageParams();
|
});
|
|
onMounted(() => {
|
// 页面加载时获取设备列表和参数
|
loadDeviceName();
|
getPageParams();
|
});
|
|
// 组件卸载时清理定时器
|
onUnmounted(() => {
|
if (scanTimer.value) {
|
clearTimeout(scanTimer.value);
|
}
|
});
|
|
// 提交表单
|
const sendForm = async () => {
|
try {
|
// 手动验证表单
|
await formRef.value?.validate();
|
|
loading.value = true;
|
const id = getPageId();
|
|
// 准备提交数据
|
const submitData = { ...form.value };
|
// 确保日期格式正确
|
if (submitData.maintenancePlanTime && !submitData.maintenancePlanTime.includes(':')) {
|
submitData.maintenancePlanTime = submitData.maintenancePlanTime + ' 00:00:00';
|
}
|
|
const { code } = id
|
? await editUpkeep({ id: id, ...submitData })
|
: await addUpkeep(submitData);
|
|
if (code == 200) {
|
showToast(`${id ? "编辑" : "新增"}计划成功`);
|
setTimeout(() => {
|
uni.navigateBack();
|
}, 1500);
|
} else {
|
loading.value = false;
|
}
|
} catch (e) {
|
loading.value = false;
|
showToast('表单验证失败');
|
}
|
};
|
|
// 返回上一页
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
// 获取页面参数
|
const getPageParams = () => {
|
const pages = getCurrentPages();
|
const currentPage = pages[pages.length - 1];
|
const options = currentPage.options;
|
|
// 根据是否有id参数来判断是新增还是编辑
|
if (options.id) {
|
// 编辑模式,获取详情
|
loadForm(options.id);
|
} else {
|
// 新增模式
|
loadForm();
|
}
|
};
|
|
// 获取页面ID
|
const getPageId = () => {
|
const pages = getCurrentPages();
|
const currentPage = pages[pages.length - 1];
|
const options = currentPage.options;
|
return options.id;
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.upkeep-add {
|
min-height: 100vh;
|
background: #f8f9fa;
|
padding-bottom: 5rem;
|
}
|
|
.footer-btns {
|
position: fixed;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background: #fff;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
padding: 0.75rem 0;
|
box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
|
z-index: 1000;
|
}
|
|
.cancel-btn {
|
font-weight: 400;
|
font-size: 1rem;
|
color: #FFFFFF;
|
width: 6.375rem;
|
background: #C7C9CC;
|
box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
|
border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
|
}
|
|
.save-btn {
|
font-weight: 400;
|
font-size: 1rem;
|
color: #FFFFFF;
|
width: 14rem;
|
background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
|
box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
|
border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
|
}
|
|
// 响应式调整
|
@media (max-width: 768px) {
|
.submit-section {
|
padding: 12px;
|
}
|
}
|
|
.tip-text {
|
padding: 4px 16px 0 16px;
|
font-size: 12px;
|
color: #888;
|
}
|
|
.scan-icon {
|
color: #1989fa;
|
font-size: 18px;
|
margin-left: 8px;
|
cursor: pointer;
|
}
|
</style>
|