yyb
5 天以前 491585f7ad453d889f71dc549f6a4d3dee74828f
src/pages/routingInspection/detail/indexLS.vue
@@ -68,7 +68,6 @@
          <wd-form-item label="型号" prop="poleModel">
            {{ formatValue(detailData.fixedInfo?.poleModel) }}
          </wd-form-item>
          <wd-form-item label="批次" prop="poleNumber">
            {{ formatValue(detailData.fixedInfo?.poleNumber) }}
          </wd-form-item>
@@ -80,6 +79,7 @@
          </wd-form-item>
        </wd-col>
      </wd-row>
      <!-- 自检记录详情模块 -->
      <wd-row>
        <view style="margin: 10rpx">
@@ -96,6 +96,7 @@
          </wd-form-item>
        </wd-col>
      </wd-row>
      <!-- 检验结果 -->
      <wd-row>
        <view style="margin: 10rpx">
@@ -105,52 +106,186 @@
          <wd-form-item label="单丝直径" prop="dia">
            {{ formatValue(detailData.inspectionResult?.dia, "mm") || "-" }}
          </wd-form-item>
          <wd-form-item label="最大直径" prop="maxDia">
            {{ formatValue(detailData.inspectionResult?.maxDia, "mm") || "-" }}
          <wd-form-item label="最大直径" prop="maxDia" required>
            <template v-if="isEdit">
              <wd-input v-model="formData.maxDia" placeholder="请输入最大直径(mm)" type="number" />
            </template>
            <template v-else>
              {{ formatValue(detailData.inspectionResult?.maxDia, "mm") || "-" }}
            </template>
          </wd-form-item>
          <wd-form-item label="最小直径" prop="minDia">
            {{ formatValue(detailData.inspectionResult?.minDia, "mm") || "-" }}
          <wd-form-item label="最小直径" prop="minDia" required>
            <template v-if="isEdit">
              <wd-input v-model="formData.minDia" placeholder="请输入最小直径(mm)" type="number" />
            </template>
            <template v-else>
              {{ formatValue(detailData.inspectionResult?.minDia, "mm") || "-" }}
            </template>
          </wd-form-item>
          <wd-form-item label="外观" prop="appearance">
            {{ formatProductAppearance(detailData.inspectionResult?.appearance) || "-" }}
          <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">
                  {{ opt.label }}
                </wd-checkbox>
              </wd-checkbox-group>
            </template>
            <template v-else>
              {{
                formatProductAppearance(detailData.inspectionResult?.appearance).join("、") || "-"
              }}
            </template>
          </wd-form-item>
          <wd-form-item label="卷绕紧密" prop="windingTightness">
            {{ formatValue(detailData.inspectionResult?.windingTightness) }}
          <wd-form-item label="卷绕紧密" prop="windingTightness" required>
            <template v-if="isEdit">
              <wd-radio-group
                v-model="formData.windingTightness"
                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(detailData.inspectionResult?.windingTightness) }}
            </template>
          </wd-form-item>
          <wd-form-item label="排列整齐" prop="arrangementNeatness">
            {{ formatValue(detailData.inspectionResult?.arrangementNeatness) }}
          <wd-form-item label="排列整齐" prop="arrangementNeatness" required>
            <template v-if="isEdit">
              <wd-radio-group
                v-model="formData.arrangementNeatness"
                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(detailData.inspectionResult?.arrangementNeatness) }}
            </template>
          </wd-form-item>
          <wd-form-item
            label="外层铝线离侧板边缘距离"
            prop="aluminumWireDistance"
            label-width="500rpx"
            label-width="360rpx"
            required
          >
            {{ formatValue(detailData.inspectionResult?.aluminumWireDistance, "mm") || "-" }}
            <template v-if="isEdit">
              <wd-input
                v-model="formData.aluminumWireDistance"
                placeholder="请输入距离(mm)"
                type="number"
              />
            </template>
            <template v-else>
              {{ formatValue(detailData.inspectionResult?.aluminumWireDistance, "mm") || "-" }}
            </template>
          </wd-form-item>
          <wd-form-item label="成品模后接头情况" prop="jointCondition" label-width="250rpx">
            {{ formatValue(detailData.inspectionResult?.jointCondition) || "-" }}
          <wd-form-item
            label="成品模后接头情况"
            prop="jointCondition"
            label-width="280rpx"
            required
          >
            <template v-if="isEdit">
              <wd-radio-group
                v-model="formData.jointCondition"
                inline
                class="conclusion-radio-group"
              >
                <wd-radio
                  v-for="(opt, idx) in jointConditionOptions"
                  :key="idx"
                  :value="opt.value"
                  shape="dot"
                >
                  {{ opt.label }}
                </wd-radio>
              </wd-radio-group>
            </template>
            <template v-else>
              {{ formatValue(detailData.inspectionResult?.jointCondition) || "-" }}
            </template>
          </wd-form-item>
          <wd-form-item label="结论" prop="conclusion">
            {{ formatValue(detailData.inspectionResult?.conclusion) || "-" }}
          <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(detailData.inspectionResult?.conclusion) || "-" }}
            </template>
          </wd-form-item>
        </wd-col>
      </wd-row>
      <!-- 巡检结果 -->
      <wd-row v-if="detailData.processInspectionResult?.isFully">
        <view style="margin: 10rpx">
          <text class="title">{{ "巡检结果" }}</text>
        </view>
        <wd-col :span="24">
          <wd-form-item label="铝杆前、中、尾样品是否齐全" prop="processInspectionUserName">
            <wd-tag
              custom-class="space"
              :type="detailData.processInspectionResult?.isFully ? 'success' : 'danger'"
            >
              {{ detailData.processInspectionResult?.isFully ? "是" : "否" }}
            </wd-tag>
          <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>
              <wd-tag
                custom-class="space"
                :type="detailData.processInspectionResult?.isFully ? 'success' : 'danger'"
              >
                {{ detailData.processInspectionResult?.isFully ? "是" : "否" }}
              </wd-tag>
            </template>
          </wd-form-item>
        </wd-col>
      </wd-row>
      <!-- 附件模块 -->
      <wd-row class="attachment-section" v-if="detailData.files && detailData.files.length > 0">
        <view style="margin: 10rpx">
@@ -159,15 +294,29 @@
        <view class="attachment-grid">
          <wd-col v-for="(file, index) in detailData.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 #error><view class="error-wrap">加载失败</view></template>
              <template #loading>
                <view class="loading-wrap">
                  <wd-loading />
                </view>
                <view class="loading-wrap"><wd-loading /></view>
              </template>
            </wd-img>
            <!-- <wd-icon
              v-if="isEdit"
              name="close-circle"
              class="delete-icon"
              @click.stop="deleteFile(index)"
            ></wd-icon> -->
          </wd-col>
          <wd-col v-if="isEdit" class="attachment-item upload-btn">
            <wd-upload
              :multiple="true"
              :max-count="5"
              :before-upload="beforeUpload"
              @success="handleUploadSuccess"
              @fail="handleUploadFail"
              accept="all"
            >
              <view class="upload-icon">+</view>
            </wd-upload>
          </wd-col>
        </view>
      </wd-row>
@@ -177,36 +326,77 @@
        <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 RoutingInspectionApi from "@/api/routingInspection/routingInspection";
import Scan from "@/components/scan/index.vue";
import { useToast } from "wot-design-uni";
// 核心状态
const paramsId = ref("");
const detailData = ref<any>({});
const show = ref(false);
const previewImageUrl = ref("");
const isEdit = ref(false);
const tempFiles = ref<any[]>([]);
const deviceUid = ref("");
const scanRef = ref();
const toast = useToast();
// 状态类型映射
// 表单数据
const formData = reactive({
  dia: "",
  maxDia: "",
  minDia: "",
  appearance: "",
  windingTightness: "",
  arrangementNeatness: "",
  aluminumWireDistance: "",
  jointCondition: "",
  conclusion: "",
  isFully: "",
});
// 外观选项
const appearanceOptions = [
  { label: "无外观问题", value: "无外观问题" },
  { label: "表面划伤", value: "表面划伤" },
  { label: "直径不均", value: "直径不均" },
  { label: "其他缺陷", value: "其他缺陷" },
];
const sampleCompleteOptions = [
  { label: "是", value: "是" },
  { label: "否", value: "否" },
];
const jointConditionOptions = [
  { label: "有", value: "有" },
  { label: "无", value: "无" },
];
const conclusionOptions = [
  { label: "合格", value: "合格" },
  { label: "不合格", value: "不合格" },
];
// 状态映射
const getStatusType = (status: number) => {
  switch (status) {
    case 0:
      return "warning"; // 待巡检
      return "warning";
    case 1:
      return "danger"; // 已驳回
      return "danger";
    case 2:
      return "info"; // 待审核
      return "info";
    case 3:
      return "success"; // 通过
      return "success";
    default:
      return "info";
  }
};
// 状态文本映射
const getStatusText = (status: number) => {
  switch (status) {
    case 0:
@@ -222,25 +412,16 @@
  }
};
// 获取外观文本
const getAppearanceText = (appearance: string[]) => {
  if (!appearance || appearance.length === 0) return "-";
  return appearance.join("、");
// 格式化工具
const formatProductAppearance = (productAppearance: string) => {
  return !productAppearance ? "-" : productAppearance;
};
// 格式化产品外观显示
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", {
@@ -250,32 +431,145 @@
  });
};
// 格式化结构值显示
const formatStructureValue = (value1: any, value2: any) => {
  const val1 = value1 || "-";
  const val2 = value2 ? `${value2}mm` : "-";
  return { count: val1, diameter: val2 };
// 初始化表单
const initFormData = () => {
  const inspectionResult = detailData.value.inspectionResult || {};
  const processInspectionResult = detailData.value.processInspectionResult || {};
  formData.dia = inspectionResult.dia || "";
  formData.maxDia = inspectionResult.maxDia || "";
  formData.minDia = inspectionResult.minDia || "";
  formData.appearance = inspectionResult.appearance || "";
  formData.windingTightness = inspectionResult.windingTightness || "";
  formData.arrangementNeatness = inspectionResult.arrangementNeatness || "";
  formData.aluminumWireDistance = inspectionResult.aluminumWireDistance || "";
  formData.jointCondition = inspectionResult.jointCondition || "";
  formData.conclusion = inspectionResult.conclusion || "";
  formData.isFully = processInspectionResult.isFully ? "是" : "否";
};
// 获取详情
const getDetailData = async (id: string, deviceType: string) => {
  try {
    let response;
    // 获取拉丝单个结构
    response = await RoutingInspectionApi.getDrawInspectInfoById({
      id: id,
    });
    const response = await RoutingInspectionApi.getDrawInspectInfoById({ id });
    detailData.value = response.data;
    console.log(detailData.value);
    tempFiles.value = [];
    initFormData();
  } catch (error) {
    console.error("获取详情失败:", error);
  }
};
// 页面加载
onLoad((options: any) => {
  paramsId.value = options.id;
  getDetailData(options.id, options.deviceType);
});
// 编辑切换
const editList = () => {
  isEdit.value = true;
};
// 取消编辑
const close = () => {
  isEdit.value = false;
  tempFiles.value = [];
  initFormData();
};
// 保存编辑
const saveList = async () => {
  // 校验
  if (!formData.maxDia) return uni.showToast({ title: "最大直径为必填项", icon: "none" });
  if (!formData.minDia) return uni.showToast({ title: "最小直径为必填项", icon: "none" });
  if (!formData.appearance) return uni.showToast({ title: "外观为必填项", icon: "none" });
  if (!formData.windingTightness) return uni.showToast({ title: "卷绕紧密为必填项", icon: "none" });
  if (!formData.arrangementNeatness)
    return uni.showToast({ title: "排列整齐为必填项", icon: "none" });
  if (!formData.aluminumWireDistance)
    return uni.showToast({ title: "外层铝线离侧板边缘距离为必填项", icon: "none" });
  if (!formData.jointCondition)
    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" });
  // 提交
  try {
    const res = await RoutingInspectionApi.drawPatrolCheckInspection({
      deviceUid: deviceUid.value,
      id: paramsId.value,
      result: {
        dia: formData.dia,
        maxDia: formData.maxDia,
        minDia: formData.minDia,
        appearance: formData.appearance,
        windingTightness: formData.windingTightness,
        arrangementNeatness: formData.arrangementNeatness,
        aluminumWireDistance: formData.aluminumWireDistance,
        jointCondition: formData.jointCondition,
        conclusion: formData.conclusion,
      },
      inspectionResult: { isFully: formData.isFully },
      processInspectionAttachmentList: tempFiles.value.map((f) => f.url),
    });
    if (res.code === 200) {
      uni.showToast({ title: "保存成功", icon: "success" });
      isEdit.value = false;
      getDetailData(paramsId.value, detailData.value.deviceType);
    } else {
      uni.showModal({ title: res.msg || "保存失败", icon: "error" });
    }
  } catch (e) {
    console.error("保存失败:", e);
    uni.showModal({ title: e.message || "保存失败", icon: "error" });
  }
};
// 附件上传校验
const beforeUpload = (file: any) => {
  const maxSize = 2 * 1024 * 1024;
  if (file.size > maxSize) {
    uni.showToast({ title: "图片大小不能超过2M", icon: "none" });
    return false;
  }
  return true;
};
// 附件上传成功
const handleUploadSuccess = (res: any) => {
  if (Array.isArray(res)) {
    tempFiles.value = [
      ...tempFiles.value,
      ...res.map((file) => ({
        ...file,
        id: `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      })),
    ];
  } else {
    tempFiles.value.push({
      ...res,
      id: `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
    });
  }
};
// 附件上传失败
const handleUploadFail = (err: any) => {
  uni.showToast({ title: "附件上传失败", icon: "error" });
};
// 删除附件
const deleteFile = (index: number) => {
  if (index >= detailData.value.files.length) {
    tempFiles.value = tempFiles.value.filter(
      (_, idx) => idx !== index - detailData.value.files.length
    );
  } else {
    detailData.value.files = detailData.value.files.filter((_, idx) => idx !== index);
  }
};
// 图片预览
const previewImage = (url: string) => {
  previewImageUrl.value = url;
  show.value = true;
@@ -285,54 +579,82 @@
  show.value = false;
};
// 编辑列表
const editList = () => {};
// 关闭
const close = () => {};
// 保存列表
const saveList = async () => {
  // try {
  //   let response;
  //   // 保存列表
  //   response = await RoutingInspectionApi.saveStrandedInspectionStructureInfo({
  //     id: paramsId.value,
  //     structureInfo: recordData.value.structureInfo,
  //   });
  //   if (response.code === 200) {
  //     uni.showToast({
  //       title: "保存成功",
  //       icon: "success",
  //     });
  //     // 刷新详情数据
  //     getDetailData(paramsId.value, recordData.value.deviceType);
  //   } else {
  //     uni.showToast({
  //       title: response.msg || "保存失败",
  //       icon: "error",
  //     });
  //   }
  // } catch (error) {
  //   console.error("保存列表失败:", error);
  //   uni.showToast({
  //     title: "保存失败",
  //     icon: "error",
  //   });
  // }
const openScan = () => {
  scanRef.value.triggerScan();
};
</script>
<style lang="scss" scoped>
.list {
  height: calc(100vh - 80px);
  padding: 12px;
  background: #f3f9f8;
  :deep() {
    .round {
      border-radius: 4px;
    }
const getScanCode = (params: any) => {
  console.log("完整参数:", params);
  let codeObj = {};
  try {
    codeObj = JSON.parse(params.code);
  } catch (err) {
    console.error("JSON解析失败:", 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");
});
onMounted(() => {
  // 开启广播监听事件
  setupScanListener();
  console.log("显示1");
});
</script>
<style lang="scss" scoped>
.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;
}
.header-container {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 10px;
}
.placeholder {
  flex: 1;
}
.scan-wrapper {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  flex-shrink: 0;
}
.list {
  padding: 12px;
  padding-top: 84px;
  background: #f3f9f8;
  min-height: 100vh;
  box-sizing: border-box;
  overflow-y: auto;
}
.title {
@@ -361,22 +683,79 @@
.attachment-grid {
  display: flex;
  flex-wrap: wrap;
  /* 超出自动换行 */
  gap: 10px;
  /* 图片之间的间距 */
  padding: 10px 0;
}
.attachment-item {
  width: calc(25% - 10px);
  /* 每行4张,间距由gap控制,需计算宽度 */
  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;
}
/* 适配小屏幕,可调整每行数量(如每行2张) */
.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);
    margin: 10;
  }
}
: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>