| | |
| | | 保存 |
| | | </wd-button> |
| | | <view class="placeholder"></view> |
| | | <view class="scan-info"> |
| | | <text class="scan-device-text">当前扫码机台: {{ scannedDeviceModel || "未扫码" }}</text> |
| | | </view> |
| | | <view class="scan-wrapper" @click="openScan"> |
| | | <wd-icon name="scan" size="24px" color="#0D867F"></wd-icon> |
| | | </view> |
| | |
| | | |
| | | <wd-form-item label="外观" prop="appearance" required> |
| | | <template v-if="isEdit"> |
| | | <wd-checkbox-group |
| | | v-model="formData.appearance" |
| | | inline |
| | | <view style="display: flex; flex-wrap: wrap; gap: 10px"> |
| | | <wd-checkbox |
| | | v-for="(opt, idx) in appearanceOptions" |
| | | :key="idx" |
| | | style="text-align: justify" |
| | | :value="opt.value" |
| | | :modelValue="formData.appearance?.includes(opt.value) || false" |
| | | @click="handleAppearanceClick(opt.value)" |
| | | style="width: 100px" |
| | | > |
| | | <wd-checkbox :modelValue="opt.value" style="width: 100px"> |
| | | {{ opt.label }} |
| | | </wd-checkbox> |
| | | </wd-checkbox-group> |
| | | </view> |
| | | </template> |
| | | <template v-else> |
| | | {{ formatProductAppearance(formData.appearance) }} |
| | |
| | | <img :src="previewImageUrl" alt="预览图片" style="width: 100%; height: auto" /> |
| | | </div> |
| | | </wd-popup> |
| | | <Scan ref="scanRef" emitName="scan" /> |
| | | <wd-toast /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive } from "vue"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import { ref, reactive, computed, onUnmounted } from "vue"; |
| | | import { onLoad, onShow, onHide } from "@dcloudio/uni-app"; |
| | | import RoutingInspectionApi from "@/api/routingInspection/routingInspection"; |
| | | import Scan from "@/components/scan/index.vue"; |
| | | import { useToast } from "wot-design-uni"; |
| | | import AttachmentUpload from "../upload.vue"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import { useScanCode } from "@/composables/useScanCode"; |
| | | |
| | | // 核心状态 |
| | | const paramsId = ref(""); |
| | |
| | | const previewImageUrl = ref(""); |
| | | const isEdit = ref(false); |
| | | const tempFiles = ref<any[]>([]); |
| | | const deviceUid = ref(""); |
| | | const scanRef = ref(); |
| | | const toast = useToast(); |
| | | const attachmentRef = ref<any>(null); |
| | | |
| | | // 获取当前登录用户信息 |
| | | const userStore = useUserStore(); |
| | | const userInfo: any = computed(() => userStore.userInfo); |
| | | |
| | | // 使用扫码管理 composable(全局监听器,不随页面切换关闭) |
| | | const { |
| | | deviceUid, |
| | | deviceModel: scannedDeviceModel, |
| | | loadFromCache, |
| | | enableListener, |
| | | } = useScanCode("scanLS"); |
| | | |
| | | // 表单数据 |
| | | const formData = reactive({ |
| | | dia: "", |
| | | maxDia: "", |
| | | minDia: "", |
| | | appearance: [], |
| | | appearance: [] as string[], |
| | | windingTightness: "", |
| | | arrangementNeatness: "", |
| | | aluminumWireDistance: "", |
| | |
| | | case 1: |
| | | return "danger"; |
| | | case 2: |
| | | return "info"; |
| | | return "primary"; |
| | | case 3: |
| | | return "success"; |
| | | default: |
| | | return "info"; |
| | | return "default"; |
| | | } |
| | | }; |
| | | |
| | |
| | | |
| | | // 格式化工具 |
| | | const formatProductAppearance = (productAppearance: string[]) => { |
| | | return !productAppearance.length ? "-" : productAppearance.join("、"); |
| | | if (!productAppearance || !Array.isArray(productAppearance) || !productAppearance.length) { |
| | | return "-"; |
| | | } |
| | | return productAppearance.join("、"); |
| | | }; |
| | | |
| | | // 处理外观选择的互斥逻辑 |
| | | const handleAppearanceClick = (value: string) => { |
| | | // 确保 appearance 是数组 |
| | | if (!Array.isArray(formData.appearance)) { |
| | | formData.appearance = []; |
| | | } |
| | | |
| | | const currentValues = [...formData.appearance]; |
| | | const isCurrentlyChecked = currentValues.includes(value); |
| | | |
| | | let newSelection: string[] = []; |
| | | |
| | | if (value === "无外观问题") { |
| | | if (isCurrentlyChecked) { |
| | | // 取消选中"无外观问题" |
| | | newSelection = []; |
| | | } else { |
| | | // 选中"无外观问题",清空其他选项 |
| | | newSelection = ["无外观问题"]; |
| | | } |
| | | } else { |
| | | // 点击其他选项 |
| | | if (isCurrentlyChecked) { |
| | | // 取消选中该选项 |
| | | newSelection = currentValues.filter((v) => v !== value); |
| | | } else { |
| | | // 选中该选项,移除"无外观问题" |
| | | const filteredValues = currentValues.filter((v) => v !== "无外观问题"); |
| | | newSelection = [...filteredValues, value]; |
| | | } |
| | | } |
| | | |
| | | formData.appearance = newSelection; |
| | | }; |
| | | |
| | | const formatValue = (value: any, unit?: string) => { |
| | |
| | | formData.dia = inspectionResult.dia || ""; |
| | | formData.maxDia = inspectionResult.maxDia || ""; |
| | | formData.minDia = inspectionResult.minDia || ""; |
| | | formData.appearance = inspectionResult.appearance || []; |
| | | // 确保 appearance 是数组 |
| | | formData.appearance = Array.isArray(inspectionResult.appearance) |
| | | ? inspectionResult.appearance |
| | | : inspectionResult.appearance |
| | | ? [inspectionResult.appearance] |
| | | : []; |
| | | formData.windingTightness = inspectionResult.windingTightness || ""; |
| | | formData.arrangementNeatness = inspectionResult.arrangementNeatness || ""; |
| | | formData.aluminumWireDistance = inspectionResult.aluminumWireDistance || ""; |
| | |
| | | try { |
| | | const response = await RoutingInspectionApi.getDrawInspectInfoById({ id }); |
| | | detailData.value = response.data; |
| | | |
| | | // 如果巡检员为空,默认设置为当前登录用户 |
| | | if (!detailData.value.processInspectionUserName) { |
| | | detailData.value.processInspectionUserName = |
| | | userInfo.value?.nickName || userInfo.value?.userName || ""; |
| | | } |
| | | |
| | | tempFiles.value = []; |
| | | initFormData(); |
| | | } catch (error) { |
| | |
| | | return uni.showToast({ title: "成品模后接头情况为必填项", icon: "none" }); |
| | | if (!formData.conclusion) return uni.showToast({ title: "结论为必填项", icon: "none" }); |
| | | if (!formData.isFully) return uni.showToast({ title: "铝杆样品是否齐全为必填项", icon: "none" }); |
| | | if (!deviceUid.value) return uni.showToast({ title: "请扫描二维码", icon: "none" }); |
| | | |
| | | // 验证扫码数据(从缓存或新扫码获取) |
| | | console.log("保存前检查 deviceUid:", deviceUid.value); |
| | | if (!deviceUid.value) { |
| | | return uni.showToast({ |
| | | title: "请先扫描设备二维码", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | } |
| | | const { newFiles } = attachmentRef.value.getSubmitFiles(); |
| | | console.log("newFiles", newFiles); |
| | | const allFileIds = [...newFiles]; |
| | |
| | | processInspectionAttachmentList: allFileIds, |
| | | }); |
| | | if (res.code === 200) { |
| | | uni.showToast({ title: "保存成功", icon: "success" }); |
| | | isEdit.value = false; |
| | | getDetailData(paramsId.value, paramsType.value); |
| | | // 设置刷新标记,告诉列表页需要刷新 |
| | | uni.setStorageSync("needRefreshInspectionList", true); |
| | | |
| | | uni.showToast({ |
| | | title: "保存成功", |
| | | icon: "success", |
| | | duration: 1500, |
| | | }); |
| | | // 延迟返回列表页,让用户看到成功提示 |
| | | setTimeout(() => { |
| | | uni.navigateBack({ |
| | | delta: 1, |
| | | }); |
| | | }, 1500); |
| | | } else { |
| | | uni.showModal({ title: res.msg || "保存失败", icon: "error" }); |
| | | } |
| | |
| | | }; |
| | | |
| | | const openScan = () => { |
| | | scanRef.value.triggerScan(); |
| | | }; |
| | | const getScanCode = (params: any) => { |
| | | let codeObj = {}; |
| | | try { |
| | | codeObj = JSON.parse(params.code); |
| | | } catch (err) { |
| | | toast.error("扫码数据异常"); |
| | | return; // 解析失败直接返回,避免后续错误 |
| | | } |
| | | deviceUid.value = codeObj?.uid; |
| | | toast.success("扫码成功"); |
| | | }; |
| | | // 确保先移除再添加监听 |
| | | const setupScanListener = () => { |
| | | uni.$off("scan", getScanCode); // 先移除旧的 |
| | | uni.$on("scan", getScanCode); // 再添加新的 |
| | | }; |
| | | onUnmounted(() => { |
| | | // 开启广播监听事件 |
| | | uni.$off("scan", getScanCode); |
| | | console.log("离开1"); |
| | | console.log("indexLS - 点击扫码按钮(全局扫码模式,无需手动触发)"); |
| | | // 全局扫码模式下,硬件扫码会自动触发,无需手动调用 |
| | | uni.showToast({ |
| | | title: "请使用扫码枪扫描", |
| | | icon: "none", |
| | | }); |
| | | onMounted(() => { |
| | | // 开启广播监听事件 |
| | | setupScanListener(); |
| | | console.log("显示1"); |
| | | }; |
| | | |
| | | // 页面显示时的处理 |
| | | onShow(() => { |
| | | console.log("========== indexLS - onShow 触发 =========="); |
| | | // 重新启用监听器(确保监听器有效) |
| | | enableListener(); |
| | | // 加载缓存(更新UI显示) |
| | | const cachedData = loadFromCache(); |
| | | |
| | | // 如果没有缓存数据,提示用户需要扫码 |
| | | if (!cachedData || !cachedData.uid) { |
| | | console.log("⚠️ 未检测到扫码缓存,用户需要扫描设备二维码"); |
| | | // 在编辑模式下才提示 |
| | | if (isEdit.value) { |
| | | setTimeout(() => { |
| | | uni.showToast({ |
| | | title: "请扫描设备二维码后再保存", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | }, 500); |
| | | } |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | |
| | | flex: 1; |
| | | } |
| | | |
| | | .scan-info { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 10px; |
| | | |
| | | .scan-device-text { |
| | | font-size: 14px; |
| | | color: #0d867f; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | |
| | | .scan-wrapper { |
| | | width: 38px; |
| | | height: 38px; |