| | |
| | | <u-form-item label="设备名称" |
| | | prop="deviceLedgerId" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="deviceNameText" |
| | | placeholder="请选择设备名称" |
| | | @click="showDevicePicker" |
| | | clearable |
| | | readonly="" /> |
| | | <template #right> |
| | | <u-icon name="scan" |
| | | @click="startScan" |
| | | class="scan-icon" /> |
| | | </template> |
| | | border-bottom |
| | | class="device-name-form-item"> |
| | | <view class="device-picker-wrap"> |
| | | <picker mode="selector" |
| | | class="device-picker-full" |
| | | :range="deviceOptions" |
| | | range-key="deviceName" |
| | | :value="deviceIndex" |
| | | @change="onDevicePickerChange"> |
| | | <view class="picker-input-row"> |
| | | <text class="picker-input-text" |
| | | :class="{ placeholder: !deviceNameText }">{{ deviceNameText || "请选择设备名称" }}</text> |
| | | <view class="picker-input-arrow"><u-icon name="arrow-right" /></view> |
| | | </view> |
| | | </picker> |
| | | </view> |
| | | </u-form-item> |
| | | <u-form-item label="规格型号" |
| | | prop="deviceModel" |
| | |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item label="报修状态" |
| | | prop="repairTime" |
| | | prop="status" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="repairStatusText" |
| | |
| | | :loading="loading">保存</u-button> |
| | | </view> |
| | | </u-form> |
| | | <!-- 设备选择器 --> |
| | | <up-action-sheet :show="showDevice" |
| | | :actions="deviceActionList" |
| | | title="选择设备名称" |
| | | @select="onDeviceSelect" |
| | | @close="showDevice = false" /> |
| | | <!-- 日期选择器 --> |
| | | <up-datetime-picker :show="showDate" |
| | | v-model="pickerDateValue" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted, onUnmounted } from "vue"; |
| | | import { ref, computed, onMounted } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | |
| | | const formRef = ref(null); |
| | | const operationType = ref("add"); |
| | | const loading = ref(false); |
| | | const showDevice = ref(false); |
| | | const showDate = ref(false); |
| | | const pickerDateValue = ref(Date.now()); |
| | | |
| | | // 设备选项 |
| | | const deviceOptions = ref([]); |
| | | const deviceNameText = ref(""); |
| | | const deviceActionList = computed(() => { |
| | | return deviceOptions.value.map(item => ({ |
| | | name: item.deviceName, |
| | | value: item.id, |
| | | })); |
| | | const deviceIndex = computed(() => { |
| | | const id = form.value.deviceLedgerId; |
| | | if (id == null || !deviceOptions.value.length) return 0; |
| | | const idx = deviceOptions.value.findIndex(item => item.id === id || item.id == id); |
| | | return idx >= 0 ? idx : 0; |
| | | }); |
| | | |
| | | // 扫码相关状态 |
| | | const isScanning = ref(false); |
| | | const scanTimer = ref(null); |
| | | |
| | | // 表单验证规则 |
| | | const formRules = { |
| | |
| | | ], |
| | | repairTime: [ |
| | | { required: true, trigger: "change", message: "请选择报修日期" }, |
| | | ], |
| | | status: [ |
| | | { required: true, trigger: "change", message: "请选择报修状态" }, |
| | | ], |
| | | repairName: [{ required: true, trigger: "blur", message: "请输入报修人" }], |
| | | remark: [{ required: true, trigger: "blur", message: "请输入故障现象" }], |
| | |
| | | deviceLedgerId: undefined, // 设备ID |
| | | deviceModel: undefined, // 规格型号 |
| | | repairTime: dayjs().format("YYYY-MM-DD"), // 报修日期 |
| | | status: undefined, // 报修状态 |
| | | repairName: undefined, // 报修人 |
| | | remark: undefined, // 故障现象 |
| | | }); |
| | |
| | | form.value.deviceLedgerId = data.deviceLedgerId; |
| | | form.value.deviceModel = data.deviceModel; |
| | | form.value.repairTime = dayjs(data.repairTime).format("YYYY-MM-DD"); |
| | | form.value.status = data.status; |
| | | form.value.repairName = data.repairName; |
| | | form.value.remark = data.remark; |
| | | repairStatusText.value = |
| | |
| | | } |
| | | }; |
| | | |
| | | // 扫描二维码功能 |
| | | const startScan = () => { |
| | | if (isScanning.value) { |
| | | showToast("正在扫描中,请稍候..."); |
| | | return; |
| | | // 下拉框选择设备 |
| | | const onDevicePickerChange = e => { |
| | | const index = Number(e.detail?.value ?? 0); |
| | | const item = deviceOptions.value[index]; |
| | | if (item) { |
| | | form.value.deviceLedgerId = item.id; |
| | | setDeviceModel(item.id); |
| | | } |
| | | |
| | | // 调用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秒后处理扫码结果 |
| | | scanTimer.value = setTimeout(() => { |
| | | processScanResult(scanResult); |
| | | isScanning.value = false; |
| | | }, 100); |
| | | }; |
| | | function getDeviceIdByRegExp(url) { |
| | | // 匹配deviceId=后面的数字 |
| | | const reg = /deviceId=(\d+)/; |
| | | const match = url.match(reg); |
| | | // 如果匹配到结果,返回数字类型,否则返回null |
| | | return match ? Number(match[1]) : null; |
| | | } |
| | | |
| | | // 处理扫码结果并匹配设备 |
| | | const processScanResult = scanResult => { |
| | | const deviceId = getDeviceIdByRegExp(scanResult); |
| | | const matchedDevice = deviceOptions.value.find(item => item.id == deviceId); |
| | | |
| | | 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 onDeviceSelect = e => { |
| | | form.value.deviceLedgerId = e.value; |
| | | setDeviceModel(e.value); |
| | | showDevice.value = false; |
| | | }; |
| | | |
| | | // 显示日期选择器 |
| | |
| | | }); |
| | | |
| | | // 组件卸载时清理定时器 |
| | | onUnmounted(() => { |
| | | if (scanTimer.value) { |
| | | clearTimeout(scanTimer.value); |
| | | } |
| | | }); |
| | | |
| | | // 提交表单 |
| | | const sendForm = async () => { |
| | |
| | | } else if (!form.value.repairTime || form.value.repairTime.trim() === "") { |
| | | isValid = false; |
| | | errorMessage = "请选择报修日期"; |
| | | } else if (form.value.status === undefined || form.value.status === null || form.value.status === "") { |
| | | isValid = false; |
| | | errorMessage = "请选择报修状态"; |
| | | } else if (!form.value.repairName || form.value.repairName.trim() === "") { |
| | | isValid = false; |
| | | errorMessage = "请输入报修人"; |
| | |
| | | color: #888; |
| | | } |
| | | |
| | | .scan-icon { |
| | | color: #1989fa; |
| | | font-size: 18px; |
| | | margin-left: 8px; |
| | | cursor: pointer; |
| | | :deep(.device-name-form-item .u-form-item__content) { |
| | | justify-content: flex-start !important; |
| | | } |
| | | |
| | | .device-picker-wrap { |
| | | width: 100%; |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .device-picker-full { |
| | | display: block; |
| | | width: 100%; |
| | | } |
| | | |
| | | .picker-input-row { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | width: 100%; |
| | | min-height: 36px; |
| | | padding: 0; |
| | | } |
| | | |
| | | .picker-input-text { |
| | | flex: 1; |
| | | min-width: 0; |
| | | font-size: 15px; |
| | | color: #333; |
| | | line-height: 36px; |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .picker-input-arrow { |
| | | flex-shrink: 0; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .picker-input-text.placeholder { |
| | | color: #c0c4cc; |
| | | } |
| | | </style> |