8fba42cefa944e11e189d8bf8dcb0b50bfe3cc67..a9561a3189d50f0e33d693b5226ea56adda06a08
5 天以前 yyb
巡检编辑和扫码
a9561a 对比 | 目录
5 天以前 yyb
拉丝和绞线的详情
9b1805 对比 | 目录
5 天以前 yyb
巡检
d840ec 对比 | 目录
已添加7个文件
已修改2个文件
1408 ■■■■■ 文件已修改
src/api/routingInspection/routingInspection.ts 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/routingInspection/detail/indexJX.vue 463 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/routingInspection/detail/indexLS.vue 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/routingInspection/index.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/routingInspection/list/index.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/routingInspection/product_card/index.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/icons/routingInspection.png 补丁 | 查看 | 原始文档 | blame | 历史
src/api/routingInspection/routingInspection.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
import request from "@/utils/request";
import { BaseResult } from "@/models/base";
const RoutingInspectionApi = {
  // æŸ¥è¯¢å·¡æ£€è®°å½•
  getDeviceInspectListByPatrol(params: any) {
    return request<BaseResult<any>>({
      url: "/wireInspection/getDeviceInspectListByPatrol",
      method: "GET",
      data: params,
    });
  },
  // èŽ·å–å·¡æ£€æ•°æ®
  getInspectListByPatrol(data: any) {
    return request<BaseResult<any>>({
      url: "/wireInspection/getInspectListByPatrol",
      method: "POST",
      data: data,
    });
  },
  // èŽ·å–æ‹‰ä¸å•ä¸ªç»“æž„è®°å½• 0
  getDrawInspectInfoById(params: any) {
    return request<BaseResult<any>>({
      url: "/wireInspection/getDrawInspectInfoById/" + params.id,
      method: "GET",
      // data: params,
    });
  },
  // èŽ·å–ç»žçº¿å•ä¸ªç»“æž„è®°å½• 1
  getStrandedInspectionStructureInfoById(params: any) {
    return request<BaseResult<any>>({
      url: "/wireInspection/getStrandedInspectionStructureInfoById/" + params.id,
      method: "GET",
      // data: params,
    });
  },
};
export default RoutingInspectionApi;
src/pages.json
@@ -6,7 +6,6 @@
      "^cu-(.*)": "@/components/cu-$1/index.vue"
    }
  },
  "pages": [
    {
      "path": "pages/index/index",
@@ -98,7 +97,6 @@
        "navigationBarTitleText": "个人资料"
      }
    },
    {
      "path": "pages/work/user/index",
      "style": {
@@ -284,6 +282,24 @@
      "style": {
        "navigationBarTitleText": "时效报工"
      }
    },
    {
      "path": "pages/routingInspection/index",
      "style": {
        "navigationBarTitleText": "巡检"
      }
    },
    {
      "path": "pages/routingInspection/detail/indexJX",
      "style": {
        "navigationBarTitleText": "绞线巡检详情"
      }
    },
    {
      "path": "pages/routingInspection/detail/indexLS",
      "style": {
        "navigationBarTitleText": "拉丝巡检详情"
      }
    }
  ],
  "globalStyle": {
@@ -317,4 +333,4 @@
      }
    ]
  }
}
}
src/pages/index/index.vue
@@ -177,6 +177,12 @@
    url: "/pages/timely/index",
    show: false,
  },
  {
    icon: "/static/icons/routingInspection.png",
    title: "巡检",
    url: "/pages/routingInspection/index",
    show: true,
  },
]);
// åŠ è½½è®¿é—®ç»Ÿè®¡æ•°æ®
src/pages/routingInspection/detail/indexJX.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,463 @@
<template>
  <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-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="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>
      <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="inspectStructure">
          {{
            recordData.structureInfo.structureRecordResult.inspectStructure.structureFormula || "-"
          }}
        </wd-form-item>
      </wd-col>
    </wd-row>
    <wd-row v-if="recordData.structureInfo.structureRecordResult.inspectStructure.structureItems">
      <view style="margin: 10rpx">
        <text class="title">{{ "结构标准值和实测" }}</text>
      </view>
      <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">
      <view style="margin: 10rpx">
        <text class="title">{{ "绞线工艺质量控制" }}</text>
      </view>
      <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>
      <view style="margin: 10rpx">
        <text class="title">{{ "外观和结论" }}</text>
      </view>
      <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>
      <view style="margin: 10rpx">
        <text class="title">{{ "巡检结果" }}</text>
      </view>
      <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">
      <view style="margin: 10rpx">
        <text class="title">{{ "附件" }}</text>
      </view>
      <!-- ç”¨ 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>
    <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>
</template>
<script setup lang="ts">
import { onLoad } from "@dcloudio/uni-app";
import RoutingInspectionApi from "@/api/routingInspection/routingInspection";
const paramsId = ref("");
const recordData = ref<any>({});
const show = ref(false);
const previewImageUrl = ref("");
const isEdit = ref(false);
// çŠ¶æ€ç±»åž‹æ˜ å°„
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 getStatusText = (status: number) => {
  switch (status) {
    case 0:
      return "待巡检";
    case 1:
      return "已驳回";
    case 2:
      return "待审核";
    case 3:
      return "通过";
    default:
      return "未知";
  }
};
// èŽ·å–å¤–è§‚æ–‡æœ¬
const getAppearanceText = (appearance: string[]) => {
  if (!appearance || appearance.length === 0) return "-";
  return appearance.join("、");
};
// æ ¼å¼åŒ–产品外观显示
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 formatStructureValue = (value1: any, value2: any) => {
  const val1 = value1 || "-";
  const val2 = value2 ? `${value2}mm` : "-";
  return { count: val1, diameter: val2 };
};
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);
  }
};
onLoad((options: any) => {
  paramsId.value = options.id;
  getDetailData(options.id, options.deviceType);
});
const previewImage = (url: string) => {
  previewImageUrl.value = url;
  show.value = true;
};
const handleClose = () => {
  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",
  //   });
  // }
};
</script>
<style lang="scss" scoped>
.placeholder {
  flex: 1;
}
.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;
}
.search-wrapper {
  flex: 1;
  min-width: 0;
}
:deep(.search-wrapper .wd-search) {
  width: 100% !important;
  min-width: 0 !important;
}
.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;
}
.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;
}
.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;
}
@media (max-width: 768px) {
  .attachment-item {
    width: calc(25% - 10px);
  }
}
</style>
src/pages/routingInspection/detail/indexLS.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,382 @@
<template>
  <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-wrapper" @click="openScan">
        <wd-icon name="scan" size="24px" color="#0D867F"></wd-icon>
      </view>
    </view>
  </view>
  <view class="list">
    <div class="inspection-report">
      <!-- åŸºæœ¬ä¿¡æ¯æ¨¡å— -->
      <wd-row>
        <view style="margin: 10rpx">
          <text class="title">{{ "基本信息" }}</text>
        </view>
        <wd-col :span="24">
          <wd-form-item label="日期" prop="recordDate">
            {{ formatDate(detailData.fixedInfo?.recordDate) }}
          </wd-form-item>
          <wd-form-item label="机台" prop="deviceModel">
            {{ formatValue(detailData.fixedInfo?.deviceModel) }}
          </wd-form-item>
          <wd-form-item label="班次" prop="workShift">
            {{ formatValue(detailData.fixedInfo?.workShift) }}
          </wd-form-item>
          <wd-form-item label="班组" prop="teamName">
            {{ formatValue(detailData.fixedInfo?.teamName) }}
          </wd-form-item>
          <wd-form-item label="单丝规格" prop="model">
            {{ formatValue(detailData.fixedInfo?.model) }}
          </wd-form-item>
          <wd-form-item label="生产轴数" prop="outputNumber">
            {{ formatValue(detailData.fixedInfo?.outputNumber, "è½´") }}
          </wd-form-item>
          <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>
          <wd-form-item label="记录人" prop="createUserName">
            {{ formatValue(detailData.fixedInfo?.createUserName) }}
          </wd-form-item>
          <wd-form-item label="首检盘号" prop="firstNo">
            {{ formatValue(detailData.fixedInfo?.firstNo) }}
          </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="processInspectionUserName">
            {{ detailData.processInspectionUserName || "-" }}
          </wd-form-item>
          <wd-form-item label="状态" prop="status">
            <wd-tag custom-class="space" :type="getStatusType(detailData.status)">
              {{ getStatusText(detailData.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="dia">
            {{ formatValue(detailData.inspectionResult?.dia, "mm") || "-" }}
          </wd-form-item>
          <wd-form-item label="最大直径" prop="maxDia">
            {{ formatValue(detailData.inspectionResult?.maxDia, "mm") || "-" }}
          </wd-form-item>
          <wd-form-item label="最小直径" prop="minDia">
            {{ formatValue(detailData.inspectionResult?.minDia, "mm") || "-" }}
          </wd-form-item>
          <wd-form-item label="外观" prop="appearance">
            {{ formatProductAppearance(detailData.inspectionResult?.appearance) || "-" }}
          </wd-form-item>
          <wd-form-item label="卷绕紧密" prop="windingTightness">
            {{ formatValue(detailData.inspectionResult?.windingTightness) }}
          </wd-form-item>
          <wd-form-item label="排列整齐" prop="arrangementNeatness">
            {{ formatValue(detailData.inspectionResult?.arrangementNeatness) }}
          </wd-form-item>
          <wd-form-item
            label="外层铝线离侧板边缘距离"
            prop="aluminumWireDistance"
            label-width="500rpx"
          >
            {{ formatValue(detailData.inspectionResult?.aluminumWireDistance, "mm") || "-" }}
          </wd-form-item>
          <wd-form-item label="成品模后接头情况" prop="jointCondition" label-width="250rpx">
            {{ formatValue(detailData.inspectionResult?.jointCondition) || "-" }}
          </wd-form-item>
          <wd-form-item label="结论" prop="conclusion">
            {{ formatValue(detailData.inspectionResult?.conclusion) || "-" }}
          </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>
        </wd-col>
      </wd-row>
      <!-- é™„件模块 -->
      <wd-row class="attachment-section" v-if="detailData.files && detailData.files.length > 0">
        <view style="margin: 10rpx">
          <text class="title">{{ "附件" }}</text>
        </view>
        <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 #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>
</template>
<script setup lang="ts">
import { onLoad } from "@dcloudio/uni-app";
import RoutingInspectionApi from "@/api/routingInspection/routingInspection";
const paramsId = ref("");
const detailData = ref<any>({});
const show = ref(false);
const previewImageUrl = ref("");
const isEdit = ref(false);
// çŠ¶æ€ç±»åž‹æ˜ å°„
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 getStatusText = (status: number) => {
  switch (status) {
    case 0:
      return "待巡检";
    case 1:
      return "已驳回";
    case 2:
      return "待审核";
    case 3:
      return "通过";
    default:
      return "未知";
  }
};
// èŽ·å–å¤–è§‚æ–‡æœ¬
const getAppearanceText = (appearance: string[]) => {
  if (!appearance || appearance.length === 0) return "-";
  return appearance.join("、");
};
// æ ¼å¼åŒ–产品外观显示
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 formatStructureValue = (value1: any, value2: any) => {
  const val1 = value1 || "-";
  const val2 = value2 ? `${value2}mm` : "-";
  return { count: val1, diameter: val2 };
};
const getDetailData = async (id: string, deviceType: string) => {
  try {
    let response;
    // èŽ·å–æ‹‰ä¸å•ä¸ªç»“æž„
    response = await RoutingInspectionApi.getDrawInspectInfoById({
      id: id,
    });
    detailData.value = response.data;
    console.log(detailData.value);
  } catch (error) {
    console.error("获取详情失败:", error);
  }
};
onLoad((options: any) => {
  paramsId.value = options.id;
  getDetailData(options.id, options.deviceType);
});
const previewImage = (url: string) => {
  previewImageUrl.value = url;
  show.value = true;
};
const handleClose = () => {
  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",
  //   });
  // }
};
</script>
<style lang="scss" scoped>
.list {
  height: calc(100vh - 80px);
  padding: 12px;
  background: #f3f9f8;
  :deep() {
    .round {
      border-radius: 4px;
    }
  }
}
.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;
}
.attachment-section {
  width: 100%;
}
.attachment-grid {
  display: flex;
  flex-wrap: wrap;
  /* è¶…出自动换行 */
  gap: 10px;
  /* å›¾ç‰‡ä¹‹é—´çš„间距 */
  padding: 10px 0;
}
.attachment-item {
  width: calc(25% - 10px);
  /* æ¯è¡Œ4张,间距由gap控制,需计算宽度 */
  box-sizing: border-box;
}
/* é€‚配小屏幕,可调整每行数量(如每行2张) */
@media (max-width: 768px) {
  .attachment-item {
    width: calc(25% - 10px);
  }
}
</style>
src/pages/routingInspection/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,149 @@
<template>
  <view>
    <wd-row>
      <wd-col :span="21">
        <wd-search placeholder-left hide-cancel></wd-search>
      </wd-col>
      <wd-col :span="3">
        <view class="scan_box" @click="openScan">
          <wd-icon name="scan" size="24px" color="#0D867F"></wd-icon>
        </view>
      </wd-col>
    </wd-row>
    <wd-tabs v-model="tab" auto-line-width slidable="always" :map-num="patrolList.length">
      <wd-tab
        v-for="(item, index) in patrolList"
        :key="index"
        :title="`${item.deviceModel}(待检查${item.pendingNum}条)`"
        class="tab_bg"
      >
        <ProductList :api="RoutingInspectionApi.getInspectListByPatrol" :ProList="item" />
      </wd-tab>
    </wd-tabs>
    <Scan ref="scanRef" emitName="scan" />
    <wd-toast />
  </view>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, onMounted, onUnmounted } from "vue";
import ProductList from "./list/index.vue";
import Scan from "@/components/scan/index.vue";
import { useUserStore } from "@/store/modules/user";
import reportApi from "@/api/work/report";
import { useToast } from "wot-design-uni";
import RoutingInspectionApi from "@/api/routingInspection/routingInspection";
const scanRef = ref();
const userStore = useUserStore();
const userInfo: any = computed(() => userStore.userInfo);
const toast = useToast();
const tab = ref<number>(0);
const patrolList = ref<any[]>([]); // å·¡æ£€è®¾å¤‡åˆ—表数据
const handlePatrolData = (index: number, count: number) => {
  // å¯ä»¥åœ¨è¿™é‡Œæ›´æ–°ç‰¹å®šå·¡æ£€è®¾å¤‡çš„待检查数量
  // ä¾‹å¦‚:patrolList.value[index].pendingNum = count;
};
const openScan = () => {
  scanRef.value.triggerScan();
};
const getScanCode = async () => {
  const { code } = await reportApi.sendWorkTime({
    userName: userInfo.value.userName,
  });
  if (code == 200) {
    toast.success("扫码成功");
  }
};
// èŽ·å–ç‰¹å®šå·¡æ£€è®¾å¤‡çš„æ•°æ®
const getPatrolData = (item: any) => {
  return async (params: any) => {
    // è¿™é‡Œå¯ä»¥æ ¹æ®item中的信息调用相应的接口获取详情
    // è¿”回的数据格式需要与ProductList组件期望的格式一致
    return {
      code: 200,
      data: {
        type: "巡检",
        data: {
          total: 0,
          records: [],
        },
      },
    };
  };
};
// èŽ·å–å·¡æ£€è®¾å¤‡åˆ—è¡¨
const loadPatrolList = async () => {
  try {
    const { data } = await RoutingInspectionApi.getDeviceInspectListByPatrol({});
    if (data) {
      patrolList.value = data;
    }
  } catch (error) {
    toast.error("获取巡检设备列表失败");
  }
};
// ç¡®ä¿å…ˆç§»é™¤å†æ·»åŠ ç›‘å¬
const setupScanListener = () => {
  uni.$off("scan", getScanCode); // å…ˆç§»é™¤æ—§çš„
  uni.$on("scan", getScanCode); // å†æ·»åŠ æ–°çš„
};
onMounted(() => {
  // å¼€å¯å¹¿æ’­ç›‘听事件
  setupScanListener();
  console.log("显示1");
  // é¡µé¢åŠ è½½æ—¶èŽ·å–å·¡æ£€è®¾å¤‡åˆ—è¡¨
  loadPatrolList();
});
onUnmounted(() => {
  // å¼€å¯å¹¿æ’­ç›‘听事件
  uni.$off("scan", getScanCode);
  console.log("离开1");
});
</script>
<style lang="scss" scoped>
::v-deep .wd-search__block {
  border-radius: unset;
}
.scan_box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 6px;
  background: #fff;
}
::v-deep .wd-tabs__line {
  background: #0d867f;
}
::v-deep .wd-tabs__nav {
  border-bottom: 1px #dddddd solid;
}
.tab_bg {
  background: #f3f9f8;
}
.icon_box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  background: #e7f4ec99;
  border-radius: 50%;
}
.statistics_box {
  margin: 15px;
}
</style>
src/pages/routingInspection/list/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
<template>
    <view class="card_box">
        <z-paging ref="pagingRef" v-model="list" :fixed="false" :auto-show-back-to-top="true" @query="getList">
            <ProductCard v-for="(item, index) in list" :key="index" :data="item" :map="map"
                @click="toDetail(item.id, item.deviceType)" />
        </z-paging>
        <wd-toast />
    </view>
</template>
<script setup lang="ts">
    import ProductCard from "../product_card/index.vue";
    import { useUserStore } from "@/store/modules/user";
    import zPaging from "@/components/z-paging/z-paging.vue";
    import { useToast } from "wot-design-uni";
    const toast = useToast();
    const userStore = useUserStore();
    const userInfo : any = computed(() => userStore.userInfo);
    const pagingRef = ref();
const map = reactive({
        deviceModel: "deviceModel",
        model: "model",
        firstNo: "firstNo",
        recordDate: "recordDate",
        workShift: "workShift",
        teamName: "teamName",
        poleModel: "poleModel",
        poleNumber: "poleNumber",
        outputNumber: "outputNumber",
        inspectPerson: "inspectPerson",
        status: "status",
    rejectList: [
      {
        rejectPerson: "rejectPerson",
        rejectTime: "rejectTime",
        rejectReason: {
          reason: "reason"
        },
      },
        ], // æ”¹ä¸ºå¯¹è±¡ï¼ŒåŒ…含所需的嵌套属性
    });
    const props = defineProps({
        api: {
            type: Function,
            default: () => { },
        },
        ProList: {
            type: Object,
            default: () => { },
        },
    });
    const list = ref<any[]>([]);
const toDetail = (id: number, deviceType: number) => {
    console.log('点击卡片', id, deviceType);
    if (deviceType == 1) {
            // ç»žçº¿
            uni.navigateTo({
                url: `/pages/routingInspection/detail/indexJX?id=${id}&deviceType=${deviceType}`,
            });
    } else if (deviceType == 0) {
            // æ‹‰ä¸
            uni.navigateTo({
                url: `/pages/routingInspection/detail/indexLS?id=${id}&deviceType=${deviceType}`,
            });
        }
    };
    const getList = async () => {
        const { code, data } = await props.api({
            deviceModel: props.ProList.deviceModel,
            status: "0",
            deviceType: props.ProList.deviceType,
        });
        if (code == 200) {
      map.deviceModel = "deviceModel";
            map.model = "model";
            map.firstNo = "firstNo";
            map.recordDate = "recordDate";
            map.workShift = "workShift";
            map.teamName = "teamName";
            map.poleModel = "poleModel";
            map.poleNumber = "poleNumber";
            map.outputNumber = "outputNumber";
      map.inspectPerson = "inspectPerson";
      map.rejectList = [
        {
          rejectPerson: "rejectPerson",
          rejectTime: "rejectTime",
          rejectReason: {
            reason: "reason"
          },
        },
      ];
            map.status = "status";
            if (data.total == 0) {
                pagingRef.value.complete(true);
      } else {
        console.log('data.records', data.records);
                pagingRef.value.complete(data.records);
            }
        }
    };
</script>
<style lang="scss" scoped>
    .card_box {
        height: calc(100vh - 120px);
    }
</style>
src/pages/routingInspection/product_card/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,235 @@
<template>
  <wd-card class="card_bg" @click="handleCardClick">
    <template #title>
      <view class="flex justify-between w-full">
        <text class="font-medium text-[#252525]">机台: {{ data[map.deviceModel] }}</text>
        <wd-tag color="#0D867F" bg-color="#E7F4EC">
          <text class="text-xs">{{ data[map.model] }}</text>
        </wd-tag>
      </view>
    </template>
    <wd-row class="my-2">
      <wd-col :span="24">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            é¦–检单号:
            <text class="text-[#252525]">{{ data[map.firstNo] }}</text>
          </text>
        </view>
      </wd-col>
    </wd-row>
    <wd-row class="my-2">
      <wd-col :span="24">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            ç­æ¬¡:
            <text class="text-[#252525]">{{ data[map.workShift] }}</text>
          </text>
        </view>
      </wd-col>
    </wd-row>
    <wd-row class="my-2">
      <wd-col :span="24">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            ç­ç»„:
            <text class="text-[#252525]">{{ data[map.teamName] }}</text>
          </text>
        </view>
      </wd-col>
    </wd-row>
    <wd-row class="my-2">
      <wd-col :span="24">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            é¢†ç”¨æ†å·:
            <text class="text-[#252525]">{{ data[map.poleNumber] }}</text>
          </text>
        </view>
      </wd-col>
    </wd-row>
    <wd-col :span="12">
      <view class="flex">
        <view class="icon_box">
          <wd-icon name="folder" color="#0D867F"></wd-icon>
        </view>
        <text class="text-[#646874] mx-2">
          æ†åž‹å·:
          <text class="text-[#252525]">{{ data[map.poleModel] }}</text>
        </text>
      </view>
    </wd-col>
    <wd-row class="my-2">
      <wd-col :span="12">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            ç”Ÿäº§è½´æ•°:
            <text class="text-[#252525]">{{ data[map.outputNumber] }}</text>
          </text>
        </view>
      </wd-col>
    </wd-row>
    <wd-row class="my-2">
      <wd-col :span="12">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            è‡ªæ£€äºº:
            <text class="text-[#252525]">{{ data[map.inspectPerson] }}</text>
          </text>
        </view>
      </wd-col>
      <wd-col :span="12">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            çŠ¶æ€:
            <text class="text-[#252525]">{{ data[map.status] == 1 ? "被驳回" : "巡检" }}</text>
          </text>
        </view>
      </wd-col>
    </wd-row>
    <wd-row class="my-2">
      <wd-col :span="16">
        <view class="flex">
          <view class="icon_box">
            <wd-icon name="folder" color="#0D867F"></wd-icon>
          </view>
          <text class="text-[#646874] mx-2">
            è®°å½•æ—¶é—´:
            <text class="text-[#252525]">{{ data[map.recordDate] }}</text>
          </text>
        </view>
      </wd-col>
      <wd-col :span="8">
        <view class="flex">
          <wd-button
            v-if="data[map.status] == 1"
            size="small"
            type="primary"
            @click.stop="showRejectPopup = true"
            style="margin-left: auto"
          >
            æŸ¥çœ‹é©³å›žä¿¡æ¯
          </wd-button>
        </view>
      </wd-col>
    </wd-row>
  </wd-card>
  <wd-popup
    v-model="showRejectPopup"
    title="驳回信息"
    custom-style="border-radius:32rpx;height: 800rpx;width: 600rpx;"
  >
    <wd-card
      v-for="(item, index) in data.rejectList"
      :key="index"
      :class="index % 2 === 0 ? 'reject-card-bg-1' : 'reject-card-bg-2'"
      style="margin-bottom: 8px; padding: 10px; border-radius: 8px"
    >
      <view class="content">
        <view>
          <view
            style="
              display: flex;
              justify-content: space-between;
              align-items: center;
              color: rgba(0, 0, 0, 0.85);
              font-size: 14px;
              margin-bottom: 8px;
            "
          >
            <view>{{ item.rejectPerson }}</view>
            <view>{{ item.rejectTime }}</view>
          </view>
          <view
            style="
              color: rgba(0, 0, 0, 0.85);
              font-size: 14px;
              word-break: break-word;
              overflow-wrap: break-word;
              max-width: 100%;
              padding: 5px 0;
            "
          >
            {{ item.rejectReason.reason }}
          </view>
        </view>
      </view>
    </wd-card>
  </wd-popup>
</template>
<script setup lang="ts">
import { ref } from "vue";
const emit = defineEmits(["click"]);
defineProps({
  data: {
    type: Object,
    default: () => {},
  },
  map: {
    type: Object,
    default: () => {},
  },
});
const showRejectPopup = ref<boolean>(false);
const handleCardClick = () => {
  emit("click");
};
</script>
<style lang="scss" scoped>
.card_bg {
  box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
  padding-bottom: 10px;
}
// æ·»åŠ ï¼šä¸¤ç§ä¸åŒçš„èƒŒæ™¯è‰²æ ·å¼
.reject-card-bg-1 {
  background-color: #f5f7fa;
}
.reject-card-bg-2 {
  background-color: #eef2f7;
}
.page-class {
  :deep() {
    .custom-shadow {
      box-shadow: 0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%),
        0 1px 5px 0 rgb(0 0 0 / 12%);
    }
  }
}
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
// ä¿®æ”¹ï¼šè°ƒæ•´å†…容区域的样式
.content {
  padding: 5px;
}
</style>
src/static/icons/routingInspection.png