spring
2 天以前 991f6f78fccb86b2718ab96969a69304daafe2b4
src/pages/routingInspection/detail/indexLS.vue
@@ -34,6 +34,9 @@
        保存
      </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>
@@ -126,17 +129,18 @@
        <wd-form-item label="外观" prop="appearance" required>
          <template v-if="isEdit">
            <wd-checkbox-group
              v-model="formData.appearance"
              inline
              v-for="(opt, idx) in appearanceOptions"
              :key="idx"
              style="text-align: justify"
            >
              <wd-checkbox :modelValue="opt.value" style="width: 100px">
            <view style="display: flex; flex-wrap: wrap; gap: 10px">
              <wd-checkbox
                v-for="(opt, idx) in appearanceOptions"
                :key="idx"
                :value="opt.value"
                :modelValue="formData.appearance?.includes(opt.value) || false"
                @click="handleAppearanceClick(opt.value)"
                style="width: 100px"
              >
                {{ opt.label }}
              </wd-checkbox>
            </wd-checkbox-group>
            </view>
          </template>
          <template v-else>
            {{ formatProductAppearance(formData.appearance) }}
@@ -293,18 +297,18 @@
        <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("");
@@ -314,17 +318,27 @@
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: "",
@@ -360,11 +374,11 @@
    case 1:
      return "danger";
    case 2:
      return "info";
      return "primary";
    case 3:
      return "success";
    default:
      return "info";
      return "default";
  }
};
@@ -385,7 +399,45 @@
// 格式化工具
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) => {
@@ -409,7 +461,12 @@
  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 || "";
@@ -423,6 +480,13 @@
  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) {
@@ -464,7 +528,16 @@
    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];
@@ -488,9 +561,20 @@
      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" });
    }
@@ -505,33 +589,36 @@
};
const openScan = () => {
  scanRef.value.triggerScan();
  console.log("indexLS - 点击扫码按钮(全局扫码模式,无需手动触发)");
  // 全局扫码模式下,硬件扫码会自动触发,无需手动调用
  uni.showToast({
    title: "请使用扫码枪扫描",
    icon: "none",
  });
};
const getScanCode = (params: any) => {
  let codeObj = {};
  try {
    codeObj = JSON.parse(params.code);
  } catch (err) {
    toast.error("扫码数据异常");
    return; // 解析失败直接返回,避免后续错误
// 页面显示时的处理
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);
    }
  }
  deviceUid.value = codeObj?.uid;
  toast.success("扫码成功");
};
// 确保先移除再添加监听
const setupScanListener = () => {
  uni.$off("scan", getScanCode); // 先移除旧的
  uni.$on("scan", getScanCode); // 再添加新的
};
onUnmounted(() => {
  // 开启广播监听事件
  uni.$off("scan", getScanCode);
  console.log("离开1");
});
onMounted(() => {
  // 开启广播监听事件
  setupScanListener();
  console.log("显示1");
});
</script>
@@ -559,6 +646,18 @@
.placeholder {
  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 {
@@ -681,4 +780,4 @@
  align-items: flex-start; // 垂直方向顶部对齐(上移关键)
  gap: 20rpx; // 选项之间的间距
}
</style>
</style>