spring
20 小时以前 b83e8417c341636a6da3a8eb7db7c151ef3c00cd
src/pages/routingInspection/detail/indexJX.vue
@@ -1,285 +1,867 @@
<template>
   <view class="list">
      <div class="inspection-report">
         <!-- 基本信息模块 -->
         <wd-row>
            <text class="title">{{ "基本信息" }}</text>
            <wd-col :span="24">
               <wd-form-item label="日期"
                  prop="recordDate">{{ formatDate(recordData.fixedInfo?.recordDate)}}</wd-form-item>
               <wd-form-item label="班次"
                  prop="workShift">{{formatValue(recordData.fixedInfo?.workShift)}}</wd-form-item>
               <wd-form-item label="型号规格" prop="model">{{ formatValue(recordData.fixedInfo?.model)}}</wd-form-item>
               <wd-form-item label="成品线盘号"
                  prop="systemNo">{{ formatValue(recordData.fixedInfo?.systemNo)}}</wd-form-item>
               <wd-form-item label="记录人"
                  prop="createUserName">{{ formatValue(recordData.fixedInfo?.createUserName) }}</wd-form-item>
               <wd-form-item label="机台"
                  prop="deviceModel">{{ formatValue(recordData.fixedInfo?.deviceModel)}}</wd-form-item>
               <wd-form-item label="产品类别"
                  prop="productType">{{ formatValue(recordData.fixedInfo?.productType)}}</wd-form-item>
               <wd-form-item label="生产长度"
                  prop="actuallyLength">{{ formatValue(recordData.fixedInfo?.actuallyLength, "m")}}</wd-form-item>
               <wd-form-item label="张力设置"
                  prop="twistTension">{{ formatValue(recordData.fixedInfo?.twistTension, "N/m") }}</wd-form-item>
               <wd-form-item label="绞制外径"
                  prop="twistDiameter">{{ formatValue(recordData.inspectionResult?.twistDiameter, "mm") }}</wd-form-item>
            </wd-col>
         </wd-row>
         <!-- 自检记录详情模块 -->
         <wd-row>
            <text class="title">{{ "自检记录详情" }}</text>
            <wd-col :span="24">
               <wd-form-item label="记录位置"
                  prop="recordPosition">{{ recordData.structureInfo?.recordPosition || "-" }}</wd-form-item>
               <wd-form-item label="记录人"
                  prop="createUserName">{{ recordData.structureInfo?.createUserName || "-"}}</wd-form-item>
               <wd-form-item label="状态" prop="status">
                  <wd-tag custom-class="space"
                     :type="getStatusType(recordData.structureInfo?.status)">{{ getStatusText(recordData.structureInfo?.status) }}</wd-tag>
               </wd-form-item>
            </wd-col>
         </wd-row>
         <!-- 结构检查模块 -->
         <wd-row>
            <text class="title">{{ "结构检查" }}</text>
            <wd-col :span="24">
               <wd-form-item label="成品结构"
                  prop="inspectStructure">{{recordData.structureInfo.structureRecordResult.inspectStructure.structureFormula || "-"}}</wd-form-item>
            </wd-col>
         </wd-row>
         <wd-row v-if="recordData.structureInfo.structureRecordResult.inspectStructure.structureItems">
            <text class="title">{{ "结构标准值和实测" }}</text>
            <wd-col :span="24"
               v-for="(item, index) in recordData.structureInfo.structureRecordResult.inspectStructure.structureItems"
               :key="index" style="padding-bottom: 10px;">
               <wd-form-item :label="formatValue(item.structureName)" label-width="400rpx"
                  style="color: red;"></wd-form-item>
               <wd-form-item label="标准值" prop="structureValue">{{formatValue(item.structureValue)}}</wd-form-item>
               <wd-form-item label="实测根数"
                  prop="actualValue1">{{formatValue(item.actualValue1, "根")}}</wd-form-item>
               <wd-form-item label="实测直径"
                  prop="actualValue2">{{formatValue(item.actualValue2, "mm")}}</wd-form-item>
            </wd-col>
         </wd-row>
         <!-- 绞线工艺质量控制模块 -->
         <wd-row v-if="recordData.structureInfo?.structureRecordResult?.inspectTwist">
            <text class="title">{{ "绞线工艺质量控制" }}</text>
            <wd-col :span="24" v-for="(item, index) in recordData.structureInfo.structureRecordResult.inspectTwist"
               :key="index" style="padding-bottom: 10px;">
               <wd-form-item :label="formatValue(item.twistName)" label-width="400rpx"
                  style="color: red;"></wd-form-item>
               <wd-form-item label="绞向" prop="direction">{{ formatValue(item.direction) }}</wd-form-item>
               <wd-form-item label="节距" prop="pitch">{{ formatValue(item.pitch, "mm") }}</wd-form-item>
               <wd-form-item label="节径比" prop="pitchRatio">{{ formatValue(item.pitchRatio) }}</wd-form-item>
            </wd-col>
         </wd-row>
         <!-- 外观和结论模块 -->
         <wd-row>
            <text class="title">{{ "外观和结论" }}</text>
            <wd-col :span="24">
               <wd-form-item label="结论"
                  prop="conclusion">{{formatValue(recordData.structureInfo.structureRecordResult.conclusion)}}</wd-form-item>
               <wd-form-item label="产品外观"
                  prop="productAppearance">{{formatProductAppearance(recordData.structureInfo.structureRecordResult.productAppearance)}}</wd-form-item>
            </wd-col>
         </wd-row>
         <!-- 巡检结果模块 -->
         <wd-row>
            <text class="title">{{ "巡检结果" }}</text>
            <wd-col :span="24">
               <wd-form-item label="样品是否齐全"
                  prop="sampleComplete">{{formatValue(recordData.inspectionResult?.sampleComplete)}}</wd-form-item>
            </wd-col>
         </wd-row>
         <!-- 附件模块 -->
         <wd-row class="attachment-section">
            <text class="title">{{ "附件" }}</text>
            <!-- 用 flex 容器包裹图片列,实现自动换行 -->
            <view class="attachment-grid">
               <wd-col v-for="(file, index) in recordData.structureInfo.files" :key="index"
                  class="attachment-item">
                  <wd-img :width="80" :height="80" :src="file.url" @click="previewImage(file.url)">
                     <template #error>
                        <view class="error-wrap">加载失败</view>
                     </template>
                     <template #loading>
                        <view class="loading-wrap">
                           <wd-loading />
                        </view>
                     </template>
                  </wd-img>
               </wd-col>
            </view>
         </wd-row>
      </div>
      <wd-popup v-model="show" custom-style="border-radius:32rpx;" @close="handleClose">
         <div class="image-preview">
            <img :src="previewImageUrl" alt="预览图片" style="width: 100%; height: auto" />
         </div>
      </wd-popup>
   </view>
  <view class="fixed-header">
    <view class="header-container">
      <wd-button
        icon="file-add"
        :round="false"
        size="small"
        custom-class="add_btn"
        @click="editList"
        v-if="!isEdit"
      >
        编辑
      </wd-button>
      <wd-button
        icon="close"
        type="info"
        :round="false"
        size="small"
        custom-class="add_btn"
        @click="close"
        v-if="isEdit"
      >
        取消
      </wd-button>
      <wd-button
        icon="check"
        type="success"
        :round="false"
        size="small"
        custom-class="add_btn"
        @click="saveList"
        v-if="isEdit"
      >
        保存
      </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>
    </view>
  </view>
  <view class="list">
    <!-- 基本信息模块 -->
    <wd-row>
      <view style="margin: 10rpx">
        <text class="title">{{ "基本信息" }}</text>
      </view>
      <wd-col :span="24">
        <wd-form-item label="日期" prop="recordDate">
          {{ formatDate(recordData.fixedInfo?.recordDate) }}
        </wd-form-item>
        <wd-form-item label="班次" prop="workShift">
          {{ formatValue(recordData.fixedInfo?.workShift) }}
        </wd-form-item>
        <wd-form-item label="型号规格" prop="model">
          {{ formatValue(recordData.fixedInfo?.model) }}
        </wd-form-item>
        <wd-form-item label="成品线盘号" prop="systemNo">
          {{ formatValue(recordData.fixedInfo?.systemNo) }}
        </wd-form-item>
        <wd-form-item label="记录人" prop="createUserName">
          {{ formatValue(recordData.fixedInfo?.createUserName) }}
        </wd-form-item>
        <wd-form-item label="机台" prop="deviceModel">
          {{ formatValue(recordData.fixedInfo?.deviceModel) }}
        </wd-form-item>
        <wd-form-item label="产品类别" prop="productType">
          {{ formatValue(recordData.fixedInfo?.productType) }}
        </wd-form-item>
        <wd-form-item label="生产长度" prop="actuallyLength">
          {{ formatValue(recordData.fixedInfo?.actuallyLength, "m") }}
        </wd-form-item>
        <wd-form-item label="张力设置" prop="tensionSetting">
          {{ formatValue(recordData.fixedInfo?.tensionSetting, "N/m") }}
        </wd-form-item>
        <!-- 绞制外径(可编辑) -->
        <wd-form-item label="绞合外径" prop="twistedOuterDiameter" required>
          <template v-if="isEdit">
            <wd-input
              v-model="formData.twistedOuterDiameter"
              placeholder="请输入绞合外径(mm)"
              type="number"
            />
          </template>
          <template v-else>
            {{ formatValue(formData.twistedOuterDiameter, "mm") }}
          </template>
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 自检记录详情模块 -->
    <wd-row>
      <view style="margin: 10rpx">
        <text class="title">{{ "自检记录详情" }}</text>
      </view>
      <wd-col :span="24">
        <wd-form-item label="记录位置" prop="recordPosition">
          {{ recordData.structureInfo?.recordPosition || "-" }}
        </wd-form-item>
        <wd-form-item label="记录人" prop="createUserName">
          {{ recordData.structureInfo?.createUserName || "-" }}
        </wd-form-item>
        <wd-form-item label="状态" prop="status">
          <wd-tag custom-class="space" :type="getStatusType(recordData.structureInfo?.status)">
            {{ getStatusText(recordData.structureInfo?.status) }}
          </wd-tag>
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 结构检查模块 -->
    <wd-row>
      <view style="margin: 10rpx">
        <text class="title">{{ "结构检查" }}</text>
      </view>
      <wd-col :span="24">
        <wd-form-item label="成品结构" prop="structureFormula" required>
          <template v-if="isEdit">
            <wd-input v-model="formData.structureFormula" placeholder="请输入成品结构" />
          </template>
          <template v-else>
            {{ formData.structureFormula || "-" }}
          </template>
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 结构标准值和实测(可编辑) -->
    <wd-row v-if="formData.structureItems.length">
      <view style="margin: 10rpx">
        <text class="title">{{ "结构标准值和实测" }}</text>
      </view>
      <wd-col
        :span="24"
        v-for="(item, index) in formData.structureItems"
        :key="index"
        style="padding-bottom: 10px"
      >
        <wd-form-item
          prop="structureItemsGroup"
          :label="formatValue(item.structureName)"
          label-width="400rpx"
          style="color: red"
          required
        ></wd-form-item>
        <wd-form-item label="标准值" prop="structureValue" required>
          {{ formatValue(item.structureValue) }}
        </wd-form-item>
        <wd-form-item label="实测根数" prop="actualValue1" required>
          <template v-if="isEdit">
            <wd-input v-model="item.actualValue1" placeholder="请输入实测根数" type="number" />
          </template>
          <template v-else>
            {{ formatValue(item.actualValue1, "根") }}
          </template>
        </wd-form-item>
        <wd-form-item label="实测直径" prop="actualValue2" required>
          <template v-if="isEdit">
            <wd-input
              v-model="item.actualValue2"
              placeholder="请输入实测直径(mm)"
              type="number"
            />
          </template>
          <template v-else>
            {{ formatValue(item.actualValue2, "mm") }}
          </template>
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 绞线工艺质量控制(可编辑) -->
    <wd-row v-if="formData.inspectTwist.length">
      <view style="margin: 10rpx">
        <text class="title">{{ "绞线工艺质量控制" }}</text>
      </view>
      <wd-col
        :span="24"
        v-for="(item, index) in formData.inspectTwist"
        :key="index"
        style="padding-bottom: 10px"
      >
        <wd-form-item
          :label="formatValue(item.twistName)"
          label-width="400rpx"
          style="color: red"
          prop="inspectTwistGroup"
          required
        ></wd-form-item>
        <wd-form-item label="绞向" prop="direction" required>
          <template v-if="isEdit">
            <wd-select-picker
              label=""
              v-model="item.direction"
              :columns="twistDirectionOptions"
              type="radio"
              placeholder="请选择绞向"
              :clearable="false"
            ></wd-select-picker>
          </template>
          <template v-else>
            {{ formatValue(item.direction) }}
          </template>
        </wd-form-item>
        <wd-form-item label="节距" prop="pitch" required>
          <template v-if="isEdit">
            <wd-input
              v-model="item.pitch"
              placeholder="请输入节距(mm)"
              type="number"
              @input="updatePitchRatio(item)"
            />
          </template>
          <template v-else>
            {{ formatValue(item.pitch, "mm") }}
          </template>
        </wd-form-item>
        <wd-form-item label="节径比" prop="pitchRatio" required>
          {{ formatValue(item.pitchRatio) }}
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 外观和结论(可编辑) -->
    <wd-row>
      <view style="margin: 10rpx">
        <text class="title">{{ "外观和结论" }}</text>
      </view>
      <wd-col :span="24">
        <wd-form-item label="产品外观" prop="productAppearance" required>
          <template v-if="isEdit">
            <view style="display: flex; flex-wrap: wrap; gap: 10px">
              <wd-checkbox
                v-for="(opt, idx) in appearanceOptions"
                :key="idx"
                :value="opt.value"
                :modelValue="formData.productAppearance.includes(opt.value)"
                @click="handleAppearanceClick(opt.value)"
                style="width: 100px"
              >
                {{ opt.label }}
              </wd-checkbox>
            </view>
          </template>
          <template v-else>
            {{ formatProductAppearance(formData.productAppearance) }}
          </template>
        </wd-form-item>
        <wd-form-item label="结论" prop="conclusion" required>
          <template v-if="isEdit">
            <wd-radio-group v-model="formData.conclusion" inline class="conclusion-radio-group">
              <wd-radio
                v-for="(opt, idx) in conclusionOptions"
                :key="idx"
                :value="opt.value"
                shape="dot"
              >
                {{ opt.label }}
              </wd-radio>
            </wd-radio-group>
          </template>
          <template v-else>
            {{ formatValue(formData.conclusion) }}
          </template>
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 巡检结果模块 -->
    <wd-row>
      <view style="margin: 10rpx">
        <text class="title">{{ "巡检结果" }}</text>
      </view>
      <wd-col :span="24">
        <wd-form-item label="样品是否齐全" prop="isFully" required>
          <template v-if="isEdit">
            <wd-radio-group v-model="formData.isFully" inline class="conclusion-radio-group">
              <wd-radio
                v-for="(opt, idx) in sampleCompleteOptions"
                :key="idx"
                :value="opt.value"
                shape="dot"
              >
                {{ opt.label }}
              </wd-radio>
            </wd-radio-group>
          </template>
          <template v-else>
            {{ formatValue(formData.isFully) }}
          </template>
        </wd-form-item>
      </wd-col>
    </wd-row>
    <!-- 附件模块(含上传功能) -->
    <wd-row class="attachment-section">
      <view style="margin: 10rpx">
        <text class="title">{{ "附件" }}</text>
      </view>
      <wd-col :span="24">
        <AttachmentUpload
          :detailData="detailData"
          :isEdit="isEdit"
          :deviceType="paramsType"
          ref="attachmentRef"
          v-if="detailDataLoaded"
        />
      </wd-col>
    </wd-row>
    <wd-popup v-model="show" custom-style="border-radius:32rpx;" @close="handleClose">
      <div class="image-preview">
        <img :src="previewImageUrl" alt="预览图片" style="width: 100%; height: auto" />
      </div>
    </wd-popup>
    <wd-toast />
  </view>
</template>
<script setup lang="ts">
   import { onLoad } from "@dcloudio/uni-app";
   import RoutingInspectionApi from "@/api/routingInspection/routingInspection";
import { ref, reactive, computed, onUnmounted } from "vue";
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
import RoutingInspectionApi from "@/api/routingInspection/routingInspection";
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 recordData = ref<any>({});
   const show = ref(false);
const paramsType = ref("");
const paramsId = ref("");
const recordData = ref<any>({ structureInfo: { files: [], structureRecordResult: {} } });
const show = ref(false);
const previewImageUrl = ref("");
   // 状态类型映射
   const getStatusType = (status : number) => {
      switch (status) {
         case 0:
            return "warning"; // 待巡检
         case 1:
            return "danger"; // 已驳回
         case 2:
            return "info"; // 待审核
         case 3:
            return "success"; // 通过
         default:
            return "info";
      }
   };
const isEdit = ref(false);
const tempFiles = ref<any[]>([]); // 临时存储新上传的附件
const toast = useToast();
const attachmentRef = ref<any>(null);
const detailData = reactive<any>({});
const detailDataLoaded = ref(false);
   // 状态文本映射
   const getStatusText = (status : number) => {
      switch (status) {
         case 0:
            return "待巡检";
         case 1:
            return "已驳回";
         case 2:
            return "待审核";
         case 3:
            return "通过";
         default:
            return "未知";
      }
   };
// 获取当前登录用户信息
const userStore = useUserStore();
const userInfo: any = computed(() => userStore.userInfo);
   // 获取外观文本
   const getAppearanceText = (appearance : string[]) => {
      if (!appearance || appearance.length === 0) return "-";
      return appearance.join("、");
   };
// 使用扫码管理 composable(全局监听器,不随页面切换关闭)
const {
  deviceUid,
  deviceModel: scannedDeviceModel,
  loadFromCache,
  enableListener,
} = useScanCode("scanJX");
   // 格式化产品外观显示
   const formatProductAppearance = (productAppearance : string[]) => {
      if (!productAppearance || productAppearance.length === 0) return "-";
      return productAppearance.join("、");
   };
const formData = reactive({
  twistedOuterDiameter: "", // 绞制外径
  structureFormula: "", // 成品结构
  structureItems: [], // 结构标准值和实测
  inspectTwist: [], // 绞线工艺质量控制
  productAppearance: [] as string[], // 产品外观(改为数组存储选中值)
  conclusion: "", // 结论(改为数组存储选中值)
  isFully: "", // 样品是否齐全
});
   // 格式化数值显示
   const formatValue = (value : any, unit ?: string) => {
      if (value === null || value === undefined || value === "") return "-";
      return unit ? `${value}${unit}` : value;
   };
const twistDirectionOptions = [
  { label: "左向", value: "左向" },
  { label: "右向", value: "右向" },
];
   // 格式化日期显示
   const formatDate = (date : string) => {
      if (!date) return "-";
      return new Date(date).toLocaleDateString("zh-CN", {
         year: "numeric",
         month: "2-digit",
         day: "2-digit"
      });
   };
const appearanceOptions = [
  { label: "无外观问题", value: "无外观问题" },
  { label: "表面划伤", value: "表面划伤" },
  { label: "直径不均", value: "直径不均" },
  { label: "其他缺陷", value: "其他缺陷" },
];
   // 格式化结构值显示
   const formatStructureValue = (value1 : any, value2 : any) => {
      const val1 = value1 || "-";
      const val2 = value2 ? `${value2}mm` : "-";
      return { count: val1, diameter: val2 };
   };
const conclusionOptions = [
  { label: "合格", value: "合格" },
  { label: "不合格", value: "不合格" },
];
const sampleCompleteOptions = [
  { label: "是", value: "是" },
  { label: "否", value: "否" },
];
   const getDetailData = async (id : string, deviceType : string) => {
      try {
         let response;
            // 获取绞线单个结构
            response = await RoutingInspectionApi.getStrandedInspectionStructureInfoById({
               id: id,
            });
            recordData.value = response.data;
            console.log(recordData.value);
      } catch (error) {
         console.error("获取详情失败:", error);
      }
   };
const initFormData = () => {
  const structureResult = recordData.value.structureInfo?.structureRecordResult || {};
  const inspectionResult = recordData.value.inspectionResult || {};
   onLoad((options : any) => {
      paramsId.value = options.id;
      getDetailData(options.id, options.deviceType);
   });
  formData.twistedOuterDiameter =
    recordData.value.structureInfo.structureRecordResult.twistedOuterDiameter || "";
  formData.structureFormula = structureResult.inspectStructure?.structureFormula || "";
  formData.isFully = inspectionResult.isFully || "";
  formData.conclusion = structureResult.conclusion || "";
   const previewImage = (url : string) => {
      previewImageUrl.value = url;
      show.value = true;
   };
  // 初始化产品外观
  const appearance = Array.isArray(structureResult.productAppearance)
    ? structureResult.productAppearance
    : structureResult.productAppearance
      ? [structureResult.productAppearance]
      : [];
  formData.productAppearance = appearance;
   const handleClose = () => {
      show.value = false;
   };
  formData.structureItems = JSON.parse(
    JSON.stringify(structureResult.inspectStructure?.structureItems || [])
  );
  formData.inspectTwist = JSON.parse(JSON.stringify(structureResult.inspectTwist || []));
  formData.inspectTwist.forEach((item: any) => {
    if (!item.direction) item.direction = "";
  });
};
const getDetailData = async (id: string, deviceType: string) => {
  try {
    const response = await RoutingInspectionApi.getStrandedInspectionStructureInfoById({ id });
    recordData.value = response.data;
    detailData.value = response.data.structureInfo;
    // 如果记录人为空,默认设置为当前登录用户
    if (recordData.value.structureInfo && !recordData.value.structureInfo.createUserName) {
      recordData.value.structureInfo.createUserName =
        userInfo.value?.nickName || userInfo.value?.userName || "";
    }
    console.log("detailData.value", detailData.value);
    tempFiles.value = []; // 清空临时文件
    initFormData(); // 数据返回后初始化表单
    detailDataLoaded.value = true; // 数据加载完成后,渲染子组件
    console.log("父组件-数据就绪后打印");
  } catch (error) {
    console.error("获取详情失败:", error);
    uni.showToast({ title: "加载失败", icon: "error" });
  }
};
// 页面加载
onLoad((options: any) => {
  try {
    paramsId.value = options.id;
    paramsType.value = options.deviceType;
    getDetailData(options.id, options.deviceType);
  } catch (error) {
    console.error("获取详情失败:", error);
    uni.showToast({ title: "加载失败", icon: "error" });
  }
});
// 编辑模式切换
const editList = () => {
  isEdit.value = true;
};
// 取消编辑(重置表单)
const close = () => {
  isEdit.value = false;
  tempFiles.value = [];
  initFormData();
};
// 保存编辑(含必填项校验)
const saveList = async () => {
  // 1. 基础字段校验
  if (!formData.structureFormula) return uni.showToast({ title: "成品结构为必填项", icon: "none" });
  if (!formData.twistedOuterDiameter)
    return uni.showToast({ title: "绞制外径为必填项", icon: "none" });
  if (!formData.productAppearance.length)
    return uni.showToast({ title: "产品外观为必填项", icon: "none" });
  if (!formData.conclusion) return uni.showToast({ title: "结论为必填项", icon: "none" });
  if (!formData.isFully) return uni.showToast({ title: "样品是否齐全为必填项", icon: "none" });
  // 2. 结构项循环校验
  for (const item of formData.structureItems) {
    if (!item.structureValue)
      return uni.showToast({ title: `${item.structureName}标准值为必填项`, icon: "none" });
    if (!item.actualValue1)
      return uni.showToast({ title: `${item.structureName}实测根数为必填项`, icon: "none" });
    if (!item.actualValue2)
      return uni.showToast({ title: `${item.structureName}实测直径为必填项`, icon: "none" });
  }
  // 3. 绞线工艺项循环校验
  for (const item of formData.inspectTwist) {
    if (!item.direction)
      return uni.showToast({ title: `${item.twistName}绞向为必填项`, icon: "none" });
    if (!item.pitch) return uni.showToast({ title: `${item.twistName}节距为必填项`, icon: "none" });
    if (!item.pitchRatio)
      return uni.showToast({ title: `${item.twistName}节径比为必填项`, 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];
  try {
    const res = await RoutingInspectionApi.strandedPatrolCheckInspection({
      deviceUid: deviceUid.value,
      id: paramsId.value,
      inspectionResult: {
        twistedOuterDiameter: formData.twistedOuterDiameter,
        structureFormula: formData.structureFormula,
        structureItems: formData.structureItems,
        inspectTwist: formData.inspectTwist,
        productAppearance: formData.productAppearance,
        conclusion: formData.conclusion,
        isFully: formData.isFully,
      },
      result: {
        isFully: formData.isFully,
      },
      processInspectionAttachmentList: allFileIds,
    });
    if (res.code === 200) {
      // 设置刷新标记,告诉列表页需要刷新
      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" });
    }
  } catch (e) {
    console.error("保存失败:", e);
    uni.showModal({ title: e.message || "保存失败", icon: "error" });
  }
};
const handleClose = () => {
  show.value = false;
};
// 状态类型映射
const getStatusType = (status: number) => {
  switch (status) {
    case 0:
      return "warning"; // 待巡检
    case 1:
      return "danger"; // 已驳回
    case 2:
      return "primary"; // 待审核
    case 3:
      return "success"; // 通过
    default:
      return "default";
  }
};
// 状态文本映射
const getStatusText = (status: number) => {
  switch (status) {
    case 0:
      return "待巡检";
    case 1:
      return "已驳回";
    case 2:
      return "待审核";
    case 3:
      return "通过";
    default:
      return "未知";
  }
};
// 格式化产品外观显示
const formatProductAppearance = (productAppearance: string[]) => {
  if (!productAppearance || productAppearance.length === 0) return "-";
  return productAppearance.join("、");
};
// 格式化数值显示
const formatValue = (value: any, unit?: string) => {
  if (value === null || value === undefined || value === "") return "-";
  return unit ? `${value}${unit}` : value;
};
// 格式化日期显示
const formatDate = (date: string) => {
  if (!date) return "-";
  return new Date(date).toLocaleDateString("zh-CN", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
  });
};
// 计算节径比
const calculatePitchRatio = (pitch: string, dia: string) => {
  // 如果pitch或dia为空,则返回"-"
  if (!pitch || !dia) return "-";
  // 将pitch和dia转换为浮点数
  const pitchNum = parseFloat(pitch);
  const diaNum = parseFloat(dia);
  // 如果pitchNum或diaNum是NaN,或者diaNum为0,则返回"-"
  if (isNaN(pitchNum) || isNaN(diaNum) || diaNum === 0) return "-";
  // 计算pitchNum和diaNum的比值,并保留两位小数
  return (pitchNum / diaNum).toFixed(2);
};
// 更新节径比(当节距变化时自动计算)
const updatePitchRatio = (item: any) => {
  // 使用绞合外径作为直径来计算节径比
  const dia = item.dia;
  item.pitchRatio = calculatePitchRatio(item.pitch, dia);
};
// 处理产品外观选择的互斥逻辑
const handleAppearanceClick = (value: string) => {
  const currentValues = [...formData.productAppearance];
  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.productAppearance = newSelection;
};
const openScan = () => {
  console.log("indexJX - 点击扫码按钮(全局扫码模式,无需手动触发)");
  // 全局扫码模式下,硬件扫码会自动触发,无需手动调用
  uni.showToast({
    title: "请使用扫码枪扫描",
    icon: "none",
  });
};
// 页面显示时的处理
onShow(() => {
  console.log("========== indexJX - 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>
<style lang="scss" scoped>
   .list {
      height: calc(100vh - 80px);
      padding: 12px;
      background: #f3f9f8;
.fixed-header {
  position: fixed;
  top: 44;
  left: 0;
  right: 0;
  background: #f3f9f8;
  z-index: 999;
  padding: 12px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  min-height: 60px;
  box-sizing: border-box;
  overflow: visible;
}
      :deep() {
         .round {
            border-radius: 4px;
         }
      }
   }
.header-container {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 10px;
}
   .title {
      position: relative;
      margin-left: 10px;
      font-size: 16px;
      font-weight: 500;
      color: #0d867f;
   }
.placeholder {
  flex: 1;
}
   .title::after {
      position: absolute;
      content: "";
      top: 4px;
      left: -10px;
      width: 4px;
      height: 16px;
      background: #0d867f;
      border-radius: 2px;
   }
.scan-info {
  display: flex;
  align-items: center;
  margin-right: 10px;
   .attachment-section {
      width: 100%;
   }
  .scan-device-text {
    font-size: 14px;
    color: #0d867f;
    font-weight: 500;
  }
}
   .attachment-grid {
      display: flex;
      flex-wrap: wrap;
      /* 超出自动换行 */
      gap: 10px;
      /* 图片之间的间距 */
      padding: 10px 0;
   }
.scan-wrapper {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  flex-shrink: 0;
}
   .attachment-item {
      width: calc(25% - 10px);
      /* 每行4张,间距由gap控制,需计算宽度 */
      box-sizing: border-box;
   }
.list {
  padding: 12px;
  padding-top: 84px;
  background: #f3f9f8;
  min-height: 100vh;
  box-sizing: border-box;
  overflow-y: auto;
}
   /* 适配小屏幕,可调整每行数量(如每行2张) */
   @media (max-width: 768px) {
      .attachment-item {
         width: calc(25% - 10px);
      }
   }
</style>
.title {
  position: relative;
  margin-left: 10px;
  font-size: 16px;
  font-weight: 500;
  color: #0d867f;
}
.title::after {
  position: absolute;
  content: "";
  top: 4px;
  left: -10px;
  width: 4px;
  height: 16px;
  background: #0d867f;
  border-radius: 2px;
}
// 产品外观和结论选择器样式(一行两个)
.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx;
  padding: 8rpx 0;
}
.checkbox-item {
  width: calc(50% - 8rpx);
  margin-bottom: 8rpx;
}
// 附件相关样式
.attachment-section {
  width: 100%;
}
.attachment-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 0;
}
.attachment-item {
  width: calc(25% - 10px);
  box-sizing: border-box;
  position: relative;
}
.upload-btn {
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}
.upload-icon {
  font-size: 32px;
  color: #0d867f;
}
// 附件删除图标
.delete-icon {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 24px;
  height: 24px;
  background-color: rgba(255, 0, 0, 0.8);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
@media (max-width: 768px) {
  .attachment-item {
    width: calc(25% - 10px);
  }
}
// 编辑模式下表单组件样式优化
:deep(.wd-form-item) {
  margin-bottom: 8rpx;
}
:deep(.wd-input, .wd-select, .wd-radio-group, .wd-checkbox-group) {
  width: 100%;
  box-sizing: border-box;
}
:deep(.wd-form-item__label) {
  &::after {
    content: "*";
    color: red;
    margin-left: 4rpx;
  }
}
// 修复选择器样式
:deep(.wd-select) {
  width: 100%;
}
:deep(.wd-checkbox) {
  margin-right: 0;
}
.conclusion-radio-group {
  display: flex;
  align-items: flex-start; // 垂直方向顶部对齐(上移关键)
  gap: 20rpx; // 选项之间的间距
}
</style>