zhangwencui
8 天以前 7b7a8c6cdb1c2429fa90f05aec87b62f378a5935
Merge remote-tracking branch 'origin/dev_NEW_pro_鹤壁' into dev_NEW_pro_鹤壁
已添加2个文件
已修改14个文件
1310 ■■■■ 文件已修改
src/api/equipmentManagement/repair.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/acceptance.vue 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/add.vue 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/detail.vue 360 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/index.vue 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/maintain.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/finalInspection/add.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/finalInspection/detail.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/finalInspection/index.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/materialInspection/add.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/materialInspection/detail.vue 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/materialInspection/index.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/processInspection/add.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/processInspection/detail.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/processInspection/index.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/repair.js
@@ -70,6 +70,19 @@
    data,
  });
};
/**
 * @desc æŠ¥ä¿®éªŒæ”¶ç¡®è®¤
 * @param {验收参数} data
 * @returns
 */
export const repairAcceptance = (data) => {
  return request({
    url: "/device/repair/acceptance",
    method: "post",
    data,
  });
};
export const getSparePartsList = (params) => {
  return request({
    url: "/spareParts/listPage",
src/pages.json
@@ -689,6 +689,20 @@
      }
    },
    {
      "path": "pages/equipmentManagement/repair/acceptance",
      "style": {
        "navigationBarTitleText": "设备报修验收",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/equipmentManagement/repair/detail",
      "style": {
        "navigationBarTitleText": "设备报修详情",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/equipmentManagement/upkeep/index",
      "style": {
        "navigationBarTitleText": "设备保养",
src/pages/equipmentManagement/repair/acceptance.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,314 @@
<template>
  <view class="repair-acceptance">
    <PageHeader title="设备报修验收"
                @back="goBack" />
    <!-- æŠ¥ä¿®ä¿¡æ¯ -->
    <view class="section">
      <view class="section-title">报修信息</view>
      <view class="info-item">
        <text class="info-label">设备名称</text>
        <text class="info-value">{{ detail.deviceName || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">规格型号</text>
        <text class="info-value">{{ detail.deviceModel || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">报修日期</text>
        <text class="info-value">{{ formatDate(detail.repairTime) || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">报修人</text>
        <text class="info-value">{{ detail.repairName || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">维修人</text>
        <text class="info-value">{{ detail.maintenanceName || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">维修项目</text>
        <text class="info-value">{{ detail.machineryCategory || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">故障现象</text>
        <text class="info-value multi-line">{{ detail.remark || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">维修结果</text>
        <text class="info-value multi-line">{{ detail.maintenanceResult || '-' }}</text>
      </view>
      <view class="info-item">
        <text class="info-label">维修日期</text>
        <text class="info-value">{{ formatDateTime(detail.maintenanceTime) || '-' }}</text>
      </view>
    </view>
    <!-- éªŒæ”¶è¡¨å• -->
    <u-form ref="formRef"
            :model="form"
            label-width="110">
      <u-cell-group title="验收信息">
        <u-form-item label="验收人"
                     prop="acceptanceName"
                     required
                     border-bottom>
          <u-input v-model="form.acceptanceName"
                   disabled
                   placeholder="验收人" />
        </u-form-item>
        <u-form-item label="验收时间"
                     prop="acceptanceTime"
                     required
                     border-bottom>
          <u-input v-model="form.acceptanceTime"
                   placeholder="请选择验收时间"
                   readonly
                   @click="showDatePicker = true" />
          <template #right>
            <u-icon name="arrow-right"
                    @click="showDatePicker = true"></u-icon>
          </template>
        </u-form-item>
        <u-form-item label="验收备注"
                     prop="acceptanceRemark"
                     required
                     border-bottom>
          <u-textarea v-model="form.acceptanceRemark"
                      placeholder="请输入验收备注"
                      :maxlength="200"
                      count
                      :autoHeight="true" />
        </u-form-item>
      </u-cell-group>
      <view class="footer-btns">
        <u-button class="cancel-btn"
                  @click="goBack">取消</u-button>
        <u-button class="save-btn"
                  type="primary"
                  @click="handleSubmit"
                  :loading="loading">验收确认</u-button>
      </view>
    </u-form>
    <up-datetime-picker :show="showDatePicker"
                        v-model="pickerDateValue"
                        mode="datetime"
                        title="选择验收时间"
                        @confirm="onDateConfirm"
                        @cancel="showDatePicker = false" />
  </view>
</template>
<script setup>
  import { ref, onMounted } from "vue";
  import { onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import { repairAcceptance, getRepairById } from "@/api/equipmentManagement/repair";
  import useUserStore from "@/store/modules/user";
  import dayjs from "dayjs";
  defineOptions({ name: "repair-acceptance" });
  const showToast = message => {
    uni.showToast({ title: message, icon: "none" });
  };
  const userStore = useUserStore();
  const loading = ref(false);
  const showDatePicker = ref(false);
  const pickerDateValue = ref(Date.now());
  const repairId = ref("");
  const detail = ref({});
  const form = ref({
    id: "",
    acceptanceName: "",
    acceptanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
    acceptanceRemark: "",
  });
  const formatDate = dateStr => {
    if (!dateStr) return "";
    return dayjs(dateStr).format("YYYY-MM-DD");
  };
  const formatDateTime = dateStr => {
    if (!dateStr) return "";
    return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss");
  };
  const canAccept = item => {
    const currentName = userStore.nickName || userStore.name || "";
    return currentName && item.acceptanceName === currentName;
  };
  const loadDetail = async id => {
    try {
      const cached = uni.getStorageSync("repairDetail");
      if (cached) {
        detail.value = typeof cached === "string" ? JSON.parse(cached) : cached;
      }
      if (id && (!detail.value?.id || detail.value.id != id)) {
        const { code, data } = await getRepairById(id);
        if (code == 200) {
          detail.value = data;
        }
      }
      if (!canAccept(detail.value)) {
        showToast("仅指定验收人可进行验收");
        setTimeout(() => uni.navigateBack(), 1500);
        return;
      }
      form.value.id = detail.value.id;
      form.value.acceptanceName = detail.value.acceptanceName || "";
    } catch (e) {
      showToast("获取报修信息失败");
    }
  };
  const onDateConfirm = e => {
    form.value.acceptanceTime = dayjs(e.value).format("YYYY-MM-DD HH:mm:ss");
    pickerDateValue.value = e.value;
    showDatePicker.value = false;
  };
  const handleSubmit = async () => {
    if (!form.value.acceptanceTime?.trim()) {
      showToast("请选择验收时间");
      return;
    }
    if (!form.value.acceptanceRemark?.trim()) {
      showToast("请输入验收备注");
      return;
    }
    try {
      loading.value = true;
      const { code } = await repairAcceptance({
        id: form.value.id,
        acceptanceTime: form.value.acceptanceTime,
        acceptanceRemark: form.value.acceptanceRemark,
      });
      if (code == 200) {
        showToast("验收成功");
        uni.removeStorageSync("repairDetail");
        setTimeout(() => uni.navigateBack(), 500);
      } else {
        loading.value = false;
      }
    } catch (e) {
      loading.value = false;
      showToast("验收提交失败");
    }
  };
  const goBack = () => {
    uni.removeStorageSync("repairDetail");
    uni.navigateBack();
  };
  onLoad(options => {
    if (options.id) {
      repairId.value = options.id;
    }
  });
  onMounted(async () => {
    if (!userStore.nickName) {
      await userStore.getInfo().catch(() => {});
    }
    if (repairId.value) {
      loadDetail(repairId.value);
    }
  });
</script>
<style scoped lang="scss">
  @import "@/static/scss/form-common.scss";
  .repair-acceptance {
    min-height: 100vh;
    background-color: #f8f9fa;
    padding-bottom: 160rpx;
  }
  .section {
    background-color: #ffffff;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  }
  .section-title {
    font-size: 16px;
    font-weight: 600;
    color: #333333;
    padding: 16px 16px 12px;
    border-bottom: 1px solid #f0f0f0;
  }
  .info-item {
    display: flex;
    padding: 14px 16px;
    border-bottom: 1px solid #f8f8f8;
    align-items: flex-start;
  }
  .info-item:last-child {
    border-bottom: none;
  }
  .info-label {
    font-size: 14px;
    color: #666666;
    min-width: 80px;
    flex-shrink: 0;
    line-height: 22px;
  }
  .info-value {
    font-size: 14px;
    color: #333333;
    flex: 1;
    line-height: 22px;
    text-align: right;
  }
  .multi-line {
    text-align: left;
    word-break: break-all;
  }
  .footer-btns {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    background: #fff;
    display: flex;
    justify-content: space-around;
    align-items: center;
    padding: 0.75rem 0;
    box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
    z-index: 1000;
  }
  .cancel-btn {
    font-weight: 400;
    font-size: 1rem;
    color: #666;
    background: #f5f5f5;
    border: 1px solid #ddd;
    width: 45%;
    height: 2.5rem;
    border-radius: 2.5rem;
  }
  .save-btn {
    font-weight: 500;
    font-size: 1rem;
    color: #fff;
    background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
    border: none;
    width: 45%;
    height: 2.5rem;
    border-radius: 2.5rem;
  }
</style>
src/pages/equipmentManagement/repair/add.vue
@@ -76,6 +76,13 @@
                   placeholder="请输入维修人"
                   clearable />
        </u-form-item>
        <u-form-item label="验收人"
                     prop="acceptanceName"
                     border-bottom>
          <u-input v-model="form.acceptanceName"
                   placeholder="请输入验收人"
                   clearable />
        </u-form-item>
        <u-form-item label="维修项目"
                     prop="machineryCategory"
                     border-bottom>
@@ -198,6 +205,8 @@
    repairTime: dayjs().format("YYYY-MM-DD"), // æŠ¥ä¿®æ—¥æœŸ
    repairName: undefined, // æŠ¥ä¿®äºº
    maintenanceName: undefined, // ç»´ä¿®äºº
    acceptanceName: undefined, // éªŒæ”¶äºº
    status: "0", // æŠ¥ä¿®çŠ¶æ€
    machineryCategory: undefined, // ç»´ä¿®é¡¹ç›®
    remark: undefined, // æ•…障现象
    storageBlobDTOs: [], // å›¾ç‰‡é™„ä»¶
@@ -206,10 +215,11 @@
  // æŠ¥ä¿®çŠ¶æ€é€‰é¡¹
  const repairStatusOptions = ref([
    { name: "待维修", value: "0" },
    { name: "完结", value: "1" },
    { name: "失败", value: "2" },
    { name: "完成", value: "1" },
    { name: "维修失败", value: "2" },
    { name: "待验收", value: "3" },
  ]);
  const repairStatusText = ref("");
  const repairStatusText = ref("待维修");
  // æ‰“开报修状态选择器
  const openRepairStatusPicker = () => {
@@ -253,12 +263,15 @@
          form.value.repairTime = dayjs(data.repairTime).format("YYYY-MM-DD");
          form.value.repairName = data.repairName;
          form.value.maintenanceName = data.maintenanceName;
          form.value.acceptanceName = data.acceptanceName;
          form.value.status = String(data.status ?? "0");
          form.value.machineryCategory = data.machineryCategory;
          form.value.remark = data.remark;
          form.value.storageBlobDTOs = data.storageBlobVOs || [];
          repairStatusText.value =
            repairStatusOptions.value.find(item => item.value == data.status)
              ?.name || "";
            repairStatusOptions.value.find(
              item => item.value == String(data.status)
            )?.name || "";
          // è®¾ç½®è®¾å¤‡åç§°æ˜¾ç¤º
          const device = deviceOptions.value.find(
            item => item.id === data.deviceLedgerId
src/pages/equipmentManagement/repair/detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,360 @@
<template>
  <view class="repair-detail">
    <PageHeader title="设备报修详情"
                @back="goBack" />
    <view class="content-container">
      <!-- 1. æŠ¥ä¿®ç™»è®° -->
      <view class="section">
        <view class="section-head">
          <view class="section-bar"></view>
          <text class="section-head-text">1. æŠ¥ä¿®ç™»è®°</text>
        </view>
        <view class="desc-table">
          <view class="desc-row">
            <view class="desc-cell">
              <text class="desc-label">设备名称</text>
              <text class="desc-value">{{ detail.deviceName || '-' }}</text>
            </view>
            <view class="desc-cell">
              <text class="desc-label">规格型号</text>
              <text class="desc-value">{{ detail.deviceModel || '-' }}</text>
            </view>
          </view>
          <view class="desc-row">
            <view class="desc-cell">
              <text class="desc-label">报修日期</text>
              <text class="desc-value">{{ formatDate(detail.repairTime) || '-' }}</text>
            </view>
            <view class="desc-cell">
              <text class="desc-label">报修人</text>
              <text class="desc-value">{{ detail.repairName || '-' }}</text>
            </view>
          </view>
          <view class="desc-row">
            <view class="desc-cell">
              <text class="desc-label">验收人</text>
              <text class="desc-value">{{ detail.acceptanceName || '-' }}</text>
            </view>
            <view class="desc-cell">
              <text class="desc-label">维修人</text>
              <text class="desc-value">{{ detail.maintenanceName || '-' }}</text>
            </view>
          </view>
          <view class="desc-row full">
            <view class="desc-cell full">
              <text class="desc-label">故障现象</text>
              <text class="desc-value">{{ detail.remark || '-' }}</text>
            </view>
          </view>
          <view class="desc-row full">
            <view class="desc-cell full status-cell">
              <text class="desc-label">当前状态</text>
              <view class="desc-value">
                <u-tag :type="getStatusType(detail.status)"
                       size="mini">{{ getStatusLabel(detail.status) }}</u-tag>
              </view>
            </view>
          </view>
        </view>
        <view class="image-block">
          <text class="image-block-title">设备问题图片</text>
          <view v-if="imageList.length"
                class="image-content">
            <CommonUpload :model-value="imageList"
                          disabled />
          </view>
          <view v-else
                class="image-empty">
            <up-icon name="photo"
                     size="40"
                     color="#c0c4cc"></up-icon>
            <text class="image-empty-text">暂无设备问题图片</text>
          </view>
        </view>
      </view>
      <!-- 2. ç»´ä¿®å¤„理 -->
      <view class="section">
        <view class="section-head">
          <view class="section-bar"></view>
          <text class="section-head-text">2. ç»´ä¿®å¤„理</text>
        </view>
        <view class="desc-table">
          <view class="desc-row">
            <view class="desc-cell">
              <text class="desc-label">维修人</text>
              <text class="desc-value">{{ detail.maintenanceName || '-' }}</text>
            </view>
            <view class="desc-cell">
              <text class="desc-label">维修时间</text>
              <text class="desc-value">{{ formatDateTime(detail.maintenanceTime) || '-' }}</text>
            </view>
          </view>
          <view class="desc-row full">
            <view class="desc-cell full">
              <text class="desc-label">维修结果</text>
              <text class="desc-value">{{ detail.maintenanceResult || '-' }}</text>
            </view>
          </view>
        </view>
      </view>
      <!-- 3. éªŒæ”¶ -->
      <view class="section">
        <view class="section-head">
          <view class="section-bar"></view>
          <text class="section-head-text">3. éªŒæ”¶</text>
        </view>
        <view class="desc-table">
          <view class="desc-row">
            <view class="desc-cell">
              <text class="desc-label">验收人</text>
              <text class="desc-value">{{ detail.acceptanceName || '-' }}</text>
            </view>
            <view class="desc-cell">
              <text class="desc-label">验收时间</text>
              <text class="desc-value">{{ formatDateTime(detail.acceptanceTime) || '-' }}</text>
            </view>
          </view>
          <view class="desc-row full">
            <view class="desc-cell full">
              <text class="desc-label">验收备注</text>
              <text class="desc-value">{{ detail.acceptanceRemark || '-' }}</text>
            </view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script setup>
  import { ref, computed, onMounted } from "vue";
  import { onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import CommonUpload from "@/components/CommonUpload.vue";
  import { getRepairById } from "@/api/equipmentManagement/repair";
  import dayjs from "dayjs";
  defineOptions({ name: "repair-detail" });
  const showToast = message => {
    uni.showToast({ title: message, icon: "none" });
  };
  const repairId = ref("");
  const detail = ref({});
  const STATUS_MAP = {
    0: { label: "待维修", type: "error" },
    1: { label: "完成", type: "success" },
    2: { label: "维修失败", type: "warning" },
    3: { label: "待验收", type: "primary" },
  };
  const getStatusLabel = status => STATUS_MAP[status]?.label || "-";
  const getStatusType = status => STATUS_MAP[status]?.type || "info";
  const imageList = computed(() => {
    return detail.value.storageBlobVOs || detail.value.storageBlobDTOs || [];
  });
  const formatDate = dateStr => {
    if (!dateStr) return "";
    return dayjs(dateStr).format("YYYY-MM-DD");
  };
  const formatDateTime = dateStr => {
    if (!dateStr) return "";
    return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss");
  };
  const loadDetail = async id => {
    try {
      const cached = uni.getStorageSync("repairDetail");
      if (cached) {
        detail.value = typeof cached === "string" ? JSON.parse(cached) : cached;
      }
      if (id) {
        const { code, data } = await getRepairById(id);
        if (code == 200) {
          detail.value = { ...detail.value, ...data };
        }
      }
    } catch (e) {
      showToast("获取详情失败");
    }
  };
  const goBack = () => {
    uni.removeStorageSync("repairDetail");
    uni.navigateBack();
  };
  onLoad(options => {
    if (options.id) {
      repairId.value = options.id;
    }
  });
  onMounted(() => {
    loadDetail(repairId.value);
  });
</script>
<style scoped lang="scss">
  .repair-detail {
    min-height: 100vh;
    background-color: #f0f2f5;
    padding-bottom: 24px;
  }
  .content-container {
    padding: 12px;
  }
  .section {
    background-color: #ffffff;
    border-radius: 4px;
    margin-bottom: 12px;
    overflow: hidden;
    border: 1px solid #ebeef5;
  }
  .section-head {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid #ebeef5;
    background: #fff;
  }
  .section-bar {
    width: 4px;
    height: 16px;
    background: #409eff;
    border-radius: 2px;
    margin-right: 8px;
    flex-shrink: 0;
  }
  .section-head-text {
    font-size: 15px;
    font-weight: 600;
    color: #303133;
  }
  .desc-table {
    border-top: 1px solid #ebeef5;
  }
  .desc-row {
    display: flex;
    border-bottom: 1px solid #ebeef5;
    &:last-child {
      border-bottom: none;
    }
    &.full {
      .desc-cell.full {
        flex: 1;
        width: 100%;
      }
    }
  }
  .desc-cell {
    flex: 1;
    display: flex;
    min-width: 0;
    border-right: 1px solid #ebeef5;
    &:last-child {
      border-right: none;
    }
    &.full {
      border-right: none;
    }
  }
  .desc-label {
    width: 88px;
    flex-shrink: 0;
    padding: 10px 12px;
    font-size: 13px;
    color: #606266;
    background: #f5f7fa;
    border-right: 1px solid #ebeef5;
    line-height: 20px;
    box-sizing: border-box;
  }
  .desc-value {
    flex: 1;
    padding: 10px 12px;
    font-size: 13px;
    color: #303133;
    background: #ffffff;
    line-height: 20px;
    word-break: break-all;
    min-width: 0;
    box-sizing: border-box;
  }
  .status-cell {
    .desc-value {
      display: flex;
      align-items: center;
    }
  }
  .image-block {
    padding: 12px 16px 16px;
    border-top: 1px solid #ebeef5;
  }
  .image-block-title {
    display: block;
    font-size: 13px;
    color: #606266;
    margin-bottom: 12px;
  }
  .image-content {
    padding: 0;
  }
  .image-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 120px;
    background: #fafafa;
    border: 1px dashed #dcdfe6;
    border-radius: 4px;
    gap: 8px;
  }
  .image-empty-text {
    font-size: 13px;
    color: #c0c4cc;
  }
  @media (max-width: 400px) {
    .desc-row:not(.full) {
      flex-direction: column;
      .desc-cell {
        border-right: none;
        border-bottom: 1px solid #ebeef5;
        &:last-child {
          border-bottom: none;
        }
      }
    }
  }
</style>
src/pages/equipmentManagement/repair/index.vue
@@ -37,10 +37,8 @@
              <text class="item-id">设备名称:{{ item.deviceName }}</text>
            </view>
            <view class="status-tag">
              <u-tag v-if="item.status === 1"
                     type="success">完结</u-tag>
              <u-tag v-if="item.status === 0"
                     type="error">待维修</u-tag>
              <u-tag :type="getStatusType(item.status)"
                     size="mini">{{ getStatusLabel(item.status) }}</u-tag>
            </view>
          </view>
          <up-divider></up-divider>
@@ -62,6 +60,10 @@
              <text class="detail-value">{{ item.maintenanceName || '-' }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">验收人</text>
              <text class="detail-value">{{ item.acceptanceName || '-' }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">维修项目</text>
              <text class="detail-value">{{ item.machineryCategory || '-' }}</text>
            </view>
@@ -75,11 +77,26 @@
            </view>
            <view class="detail-row">
              <text class="detail-label">维修日期</text>
              <text class="detail-value">{{ formatDate(item.maintenanceTime) || '-' }}</text>
              <text class="detail-value">{{ formatDateTime(item.maintenanceTime) || '-' }}</text>
            </view>
          </view>
          <!-- æŒ‰é’®åŒºåŸŸ -->
          <view class="action-buttons">
            <u-button type="info"
                      size="small"
                      plain
                      class="action-btn"
                      @click="goDetail(item)">
              è¯¦æƒ…
            </u-button>
            <u-button type="success"
                      size="small"
                      class="action-btn"
                      v-if="item.status === 3"
                      :disabled="!canAccept(item)"
                      @click="goAcceptance(item)">
              éªŒæ”¶
            </u-button>
            <u-button type="primary"
                      size="small"
                      class="action-btn"
@@ -135,6 +152,22 @@
  const userStore = useUserStore();
  const STATUS_MAP = {
    0: { label: "待维修", type: "error" },
    1: { label: "完成", type: "success" },
    2: { label: "维修失败", type: "warning" },
    3: { label: "待验收", type: "primary" },
  };
  const getStatusLabel = status => STATUS_MAP[status]?.label || "-";
  const getStatusType = status => STATUS_MAP[status]?.type || "info";
  const canAccept = item => {
    if (item.status !== 3) return false;
    const currentName = userStore.nickName || userStore.name || "";
    return currentName && item.acceptanceName === currentName;
  };
  // æœç´¢å…³é”®è¯
  const searchKeyword = ref("");
@@ -154,6 +187,18 @@
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
  };
  const formatDateTime = dateStr => {
    if (!dateStr) return "";
    const date = new Date(dateStr);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    const seconds = String(date.getSeconds()).padStart(2, "0");
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  };
  // æŸ¥è¯¢åˆ—表
@@ -194,7 +239,6 @@
      showToast("参数错误");
      return;
    }
    // ä½¿ç”¨uni.setStorageSync存储id
    uni.setStorageSync("repairId", id);
    uni.navigateTo({
      url: "/pages/equipmentManagement/repair/maintain",
@@ -208,13 +252,31 @@
    });
  };
  // ç¼–辑 - è·³è½¬åˆ°add页面,通过id区分新增还是编辑
  // ç¼–辑
  const edit = id => {
    if (!id) return;
    // ä½¿ç”¨uni.setStorageSync存储id
    // uni.setStorageSync("repairId", id);
    uni.navigateTo({
      url: "/pages/equipmentManagement/repair/add?id=" + id,
    });
  };
  // è¯¦æƒ…
  const goDetail = item => {
    uni.setStorageSync("repairDetail", JSON.stringify(item));
    uni.navigateTo({
      url: "/pages/equipmentManagement/repair/detail?id=" + item.id,
    });
  };
  // éªŒæ”¶
  const goAcceptance = item => {
    if (!canAccept(item)) {
      showToast("仅指定验收人可进行验收");
      return;
    }
    uni.setStorageSync("repairDetail", JSON.stringify(item));
    uni.navigateTo({
      url: "/pages/equipmentManagement/repair/acceptance?id=" + item.id,
    });
  };
@@ -243,6 +305,9 @@
  };
  onMounted(() => {
    if (!userStore.nickName) {
      userStore.getInfo().catch(() => {});
    }
    getList();
  });
@@ -254,9 +319,8 @@
<style scoped lang="scss">
  @import "@/styles/sales-common.scss";
  // è®¾å¤‡ç»´ä¿®ç‰¹æœ‰æ ·å¼
  .sales-account {
    padding-bottom: 80px; // ä¸ºæµ®åŠ¨æŒ‰é’®ç•™å‡ºç©ºé—´
    padding-bottom: 80px;
  }
  .status-tag {
@@ -265,6 +329,7 @@
  }
  .action-buttons {
    gap: 8px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 12px ä¸åŒ
    gap: 8px;
    flex-wrap: wrap;
  }
</style>
</style>
src/pages/equipmentManagement/repair/maintain.vue
@@ -12,10 +12,10 @@
      <u-cell-group title="维修信息"
                    inset>
        <u-form-item prop="maintenanceName"
                     label="报修人"
                     label="维修人"
                     required>
          <u-input v-model="form.maintenanceName"
                   placeholder="请输入报修人"
                   placeholder="请输入维修人"
                   clearable />
        </u-form-item>
        <u-form-item prop="maintenanceResult"
@@ -177,7 +177,7 @@
  // è¡¨å•验证规则
  const formRules = {
    maintenanceName: [
      { required: true, trigger: "blur", message: "请输入报修人" },
      { required: true, trigger: "blur", message: "请输入维修人" },
    ],
    maintenanceResult: [
      { required: true, trigger: "blur", message: "请输入维修结果" },
@@ -188,10 +188,11 @@
  };
  const repairStatusOptions = ref([
    { name: "待维修", value: "0" },
    { name: "完结", value: "1" },
    { name: "失败", value: "2" },
    { name: "完成", value: "1" },
    { name: "维修失败", value: "2" },
    { name: "待验收", value: "3" },
  ]);
  const repairStatusText = ref("完结");
  const repairStatusText = ref("待验收");
  // æ‰“开报修状态选择器
  const openRepairStatusPicker = () => {
    uni.showActionSheet({
@@ -207,7 +208,7 @@
    maintenanceName: userStore.nickName || "", // é»˜è®¤ä½¿ç”¨å½“前用户昵称
    maintenanceResult: undefined, // ç»´ä¿®ç»“æžœ
    maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // ç»´ä¿®æ—¥æœŸï¼ˆåªæ˜¾ç¤ºæ—¥æœŸï¼‰
    status: "1",
    status: "3",
    sparePartsIds: [],
  });
@@ -225,7 +226,7 @@
      maintenanceName: userStore.nickName || "",
      maintenanceResult: undefined,
      maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
      status: "1",
      status: "3",
      sparePartsIds: [],
    };
    selectedSpareParts.value = [];
@@ -411,7 +412,7 @@
  // åˆå§‹åŒ–表单数据
  const initForm = async () => {
    form.value.status = "1";
    form.value.status = "3";
    // è®¾ç½®æŠ¥ä¿®äººä¸ºå½“前用户昵称
    form.value.maintenanceName = userStore.nickName || "";
    // è®¾ç½®å½“前日期(只包含年月日)
src/pages/qualityManagement/finalInspection/add.vue
@@ -68,14 +68,32 @@
                  placeholder="请输入单位"
                  disabled />
      </up-form-item>
      <up-form-item label="数量"
      <up-form-item label="总数量"
                    prop="quantity"
                    required
                    border-bottom>
        <up-input v-model="form.quantity"
                  type="number"
                  placeholder="请输入数量"
                  placeholder="请输入总数量"
                  :disabled="processQuantityDisabled" />
      </up-form-item>
      <up-form-item label="合格数量"
                    prop="qualifiedQuantity"
                    required
                    border-bottom>
        <up-input v-model="form.qualifiedQuantity"
                  type="number"
                  placeholder="请输入合格数量"
                  clearable />
      </up-form-item>
      <up-form-item label="不合格数量"
                    prop="unqualifiedQuantity"
                    required
                    border-bottom>
        <up-input v-model="form.unqualifiedQuantity"
                  type="number"
                  placeholder="请输入不合格数量"
                  clearable />
      </up-form-item>
      <up-form-item label="检测单位"
                    prop="checkCompany"
@@ -83,19 +101,6 @@
        <up-input v-model="form.checkCompany"
                  placeholder="请输入检测单位"
                  clearable />
      </up-form-item>
      <up-form-item label="检测结果"
                    prop="checkResult"
                    required
                    border-bottom>
        <up-input v-model="form.checkResult"
                  placeholder="请选择检测结果"
                  readonly
                  @click="showResultSheet" />
        <template #right>
          <up-icon @click="showResultSheet = true"
                   name="arrow-right" />
        </template>
      </up-form-item>
      <up-form-item label="检验员"
                    prop="checkName"
@@ -208,12 +213,6 @@
                     @select="selectModel"
                     @close="showModelSheet = false"
                     title="选择规格型号" />
    <!-- æ£€æµ‹ç»“果选择 -->
    <up-action-sheet :show="showResultSheet"
                     :actions="resultSheetOptions"
                     @select="selectResult"
                     @close="showResultSheet = false"
                     title="选择检测结果" />
    <!-- æ£€éªŒå‘˜é€‰æ‹© -->
    <up-action-sheet :show="showInspectorSheet"
                     :actions="userSheetOptions"
@@ -340,8 +339,6 @@
  const showProductTree = ref(false);
  // è§„格型号选择
  const showModelSheet = ref(false);
  // æ£€æµ‹ç»“果选择
  const showResultSheet = ref(false);
  // æ£€éªŒå‘˜é€‰æ‹©
  const showInspectorSheet = ref(false);
  // æŒ‡æ ‡é€‰æ‹©
@@ -359,8 +356,9 @@
    testStandardId: "",
    unit: "",
    quantity: "",
    qualifiedQuantity: "",
    unqualifiedQuantity: "",
    checkCompany: "",
    checkResult: "",
    productMainId: null,
    purchaseLedgerId: null,
  });
@@ -380,11 +378,6 @@
  const modelOptions = ref([]);
  // æ£€éªŒå‘˜åˆ—表
  const userList = ref([]);
  // æ£€æµ‹ç»“果选项
  const resultOptions = ref([
    { label: "合格", value: "合格" },
    { label: "不合格", value: "不合格" },
  ]);
  // æŒ‡æ ‡é€‰é¡¹
  const testStandardOptions = ref([]);
  // å½“前产品ID
@@ -409,13 +402,6 @@
    return modelOptions.value.map(item => ({
      name: item.model,
      value: item.id,
    }));
  });
  const resultSheetOptions = computed(() => {
    return resultOptions.value.map(item => ({
      name: item.label,
      value: item.value,
    }));
  });
@@ -447,10 +433,9 @@
    ],
    unit: [{ required: false, message: "请输入", trigger: "blur" }],
    quantity: [{ required: true, message: "请输入", trigger: "blur" }],
    qualifiedQuantity: [{ required: true, message: "请输入", trigger: "blur" }],
    unqualifiedQuantity: [{ required: true, message: "请输入", trigger: "blur" }],
    checkCompany: [{ required: false, message: "请输入", trigger: "blur" }],
    checkResult: [
      { required: true, message: "请选择检测结果", trigger: "change" },
    ],
  };
  // æ˜¯å¦ä¸ºç¼–辑模式
@@ -555,12 +540,6 @@
      modelOptions.value.find(item => item.id == value)?.model || "";
    form.value.unit =
      modelOptions.value.find(item => item.id == value)?.unit || "";
  };
  // é€‰æ‹©æ£€æµ‹ç»“æžœ
  const selectResult = e => {
    form.value.checkResult = e.value;
    showResultSheet.value = false;
  };
  // é€‰æ‹©æ£€éªŒå‘˜
@@ -685,7 +664,15 @@
      //   return;
      // }
      if (!form.value.quantity) {
        showToast("请输入数量");
        showToast("请输入总数量");
        return;
      }
      if (!form.value.qualifiedQuantity && form.value.qualifiedQuantity !== 0) {
        showToast("请输入合格数量");
        return;
      }
      if (!form.value.unqualifiedQuantity && form.value.unqualifiedQuantity !== 0) {
        showToast("请输入不合格数量");
        return;
      }
      if (!form.value.productId) {
@@ -696,11 +683,6 @@
        showToast("请选择指标");
        return;
      }
      if (!form.value.checkResult) {
        showToast("请选择检测结果");
        return;
      }
      loading.value = true;
      form.value.inspectType = 2;
@@ -712,6 +694,8 @@
      const data = { ...form.value, qualityInspectParams: tableData.value };
      data.quantity = Number(data.quantity);
      data.qualifiedQuantity = Number(data.qualifiedQuantity);
      data.unqualifiedQuantity = Number(data.unqualifiedQuantity);
      if (isEdit.value) {
        const res = await qualityInspectUpdate(data);
        showToast("保存成功");
@@ -751,7 +735,8 @@
        unit: "",
        quantity: "",
        checkCompany: "",
        checkResult: "",
        qualifiedQuantity: "",
        unqualifiedQuantity: "",
        productMainId: null,
        purchaseLedgerId: null,
      };
@@ -773,7 +758,8 @@
        unit: "kg",
        quantity: 1000,
        checkCompany: "第三方检测机构",
        checkResult: "合格",
        qualifiedQuantity: 0,
        unqualifiedQuantity: 0,
        productMainId: null,
        purchaseLedgerId: null,
      };
@@ -852,8 +838,9 @@
        testStandardId: "",
        unit: "",
        quantity: "",
        qualifiedQuantity: "",
        unqualifiedQuantity: "",
        checkCompany: "",
        checkResult: "",
        productMainId: null,
        purchaseLedgerId: null,
      };
src/pages/qualityManagement/finalInspection/detail.vue
@@ -15,11 +15,11 @@
          </view>
          <text class="header-title">{{ detailData.productName || '-' }}</text>
          <view class="status-tags">
            <u-tag v-if="detailData.checkResult"
                   :type="getTagType(detailData.checkResult)"
            <u-tag v-if="detailData.passRate != null && detailData.passRate !== ''"
                   type="primary"
                   size="small"
                   class="status-tag">
              {{ detailData.checkResult || '-' }}
              åˆæ ¼çއ {{ formatPassRate(detailData.passRate) }}
            </u-tag>
            <u-tag :type="getStateTagType(detailData.inspectState)"
                   size="small"
@@ -59,8 +59,20 @@
            <text class="detail-value">{{ detailData.unit || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">数量</text>
            <text class="detail-value">{{ detailData.quantity || 0 }}</text>
            <text class="detail-label">总数量</text>
            <text class="detail-value">{{ detailData.quantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">合格数量</text>
            <text class="detail-value">{{ detailData.qualifiedQuantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">不合格数量</text>
            <text class="detail-value">{{ detailData.unqualifiedQuantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">合格率</text>
            <text class="detail-value">{{ formatPassRate(detailData.passRate) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">检测单位</text>
@@ -162,15 +174,12 @@
  };
  // èŽ·å–æ ‡ç­¾ç±»åž‹
  const getTagType = result => {
    switch (result) {
      case "合格":
        return "success";
      case "不合格":
        return "error";
      default:
        return "info";
    }
  const formatPassRate = rate => {
    if (rate === null || rate === undefined || rate === "") return "-";
    const num = Number(rate);
    if (isNaN(num)) return rate;
    if (num <= 1) return `${(num * 100).toFixed(2)}%`;
    return `${num}%`;
  };
  // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
src/pages/qualityManagement/finalInspection/index.vue
@@ -76,11 +76,11 @@
              </view>
            </view>
            <view class="status-tags">
              <u-tag v-if="item.checkResult"
                     :type="getTagType(item.checkResult)"
              <u-tag v-if="item.passRate != null && item.passRate !== ''"
                     type="primary"
                     size="mini"
                     class="status-tag">
                {{ item.checkResult }}
                åˆæ ¼çއ {{ formatPassRate(item.passRate) }}
              </u-tag>
              <u-tag :type="getStateTagType(item.inspectState)"
                     size="mini"
@@ -316,11 +316,13 @@
    return inspectState ? "checkmark-circle" : "time";
  };
  // èŽ·å–æ ‡ç­¾ç±»åž‹
  const getTagType = checkResult => {
    if (checkResult === "合格") return "success";
    if (checkResult === "不合格") return "error";
    return "default";
  // æ ¼å¼åŒ–合格率
  const formatPassRate = rate => {
    if (rate === null || rate === undefined || rate === "") return "-";
    const num = Number(rate);
    if (isNaN(num)) return rate;
    if (num <= 1) return `${(num * 100).toFixed(2)}%`;
    return `${num}%`;
  };
  // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
@@ -383,9 +385,11 @@
        pendingCount.value = inspectionList.value.filter(
          item => !item.inspectState
        ).length;
        qualifiedCount.value = inspectionList.value.filter(
          item => item.checkResult === "合格"
        ).length;
        qualifiedCount.value = inspectionList.value.filter(item => {
          const rate = Number(item.passRate);
          if (isNaN(rate)) return false;
          return rate <= 1 ? rate >= 1 : rate >= 100;
        }).length;
      })
      .catch(err => {
        tableLoading.value = false;
src/pages/qualityManagement/materialInspection/add.vue
@@ -68,14 +68,32 @@
                  placeholder="请输入单位"
                  disabled />
      </up-form-item>
      <up-form-item label="数量"
      <up-form-item label="总数量"
                    prop="quantity"
                    required
                    border-bottom>
        <up-input v-model="form.quantity"
                  type="number"
                  placeholder="请输入数量"
                  placeholder="请输入总数量"
                  :disabled="supplierQuantityDisabled" />
      </up-form-item>
      <up-form-item label="合格数量"
                    prop="qualifiedQuantity"
                    required
                    border-bottom>
        <up-input v-model="form.qualifiedQuantity"
                  type="number"
                  placeholder="请输入合格数量"
                  clearable />
      </up-form-item>
      <up-form-item label="不合格数量"
                    prop="unqualifiedQuantity"
                    required
                    border-bottom>
        <up-input v-model="form.unqualifiedQuantity"
                  type="number"
                  placeholder="请输入不合格数量"
                  clearable />
      </up-form-item>
      <up-form-item label="检测单位"
                    prop="checkCompany"
@@ -83,19 +101,6 @@
        <up-input v-model="form.checkCompany"
                  placeholder="请输入检测单位"
                  clearable />
      </up-form-item>
      <up-form-item label="检测结果"
                    prop="checkResult"
                    required
                    border-bottom>
        <up-input v-model="form.checkResult"
                  placeholder="请选择检测结果"
                  readonly
                  @click="showResultSheet" />
        <template #right>
          <up-icon @click="showResultSheet = true"
                   name="arrow-right" />
        </template>
      </up-form-item>
      <up-form-item label="检验员"
                    prop="checkName"
@@ -220,12 +225,6 @@
                     @select="selectModel"
                     @close="showModelSheet = false"
                     title="选择规格型号" />
    <!-- æ£€æµ‹ç»“果选择 -->
    <up-action-sheet :show="showResultSheet"
                     :actions="resultSheetOptions"
                     @select="selectResult"
                     @close="showResultSheet = false"
                     title="选择检测结果" />
    <!-- æ£€éªŒå‘˜é€‰æ‹© -->
    <up-action-sheet :show="showInspectorSheet"
                     :actions="userSheetOptions"
@@ -352,8 +351,6 @@
  const showProductTree = ref(false);
  // è§„格型号选择
  const showModelSheet = ref(false);
  // æ£€æµ‹ç»“果选择
  const showResultSheet = ref(false);
  // æ£€éªŒå‘˜é€‰æ‹©
  const showInspectorSheet = ref(false);
  // æŒ‡æ ‡é€‰æ‹©
@@ -371,8 +368,9 @@
    testStandardId: "",
    unit: "",
    quantity: "",
    qualifiedQuantity: "",
    unqualifiedQuantity: "",
    checkCompany: "",
    checkResult: "",
    productMainId: null,
    purchaseLedgerId: null,
  });
@@ -392,11 +390,6 @@
  const modelOptions = ref([]);
  // æ£€éªŒå‘˜åˆ—表
  const userList = ref([]);
  // æ£€æµ‹ç»“果选项
  const resultOptions = ref([
    { label: "合格", value: "合格" },
    { label: "不合格", value: "不合格" },
  ]);
  // æŒ‡æ ‡é€‰é¡¹
  const testStandardOptions = ref([]);
  // å½“前产品ID
@@ -421,13 +414,6 @@
    return modelOptions.value.map(item => ({
      name: item.model,
      value: item.id,
    }));
  });
  const resultSheetOptions = computed(() => {
    return resultOptions.value.map(item => ({
      name: item.label,
      value: item.value,
    }));
  });
@@ -459,10 +445,9 @@
    ],
    unit: [{ required: false, message: "请输入", trigger: "blur" }],
    quantity: [{ required: true, message: "请输入", trigger: "blur" }],
    qualifiedQuantity: [{ required: true, message: "请输入", trigger: "blur" }],
    unqualifiedQuantity: [{ required: true, message: "请输入", trigger: "blur" }],
    checkCompany: [{ required: false, message: "请输入", trigger: "blur" }],
    checkResult: [
      { required: true, message: "请选择检测结果", trigger: "change" },
    ],
  };
  // æ˜¯å¦ä¸ºç¼–辑模式
@@ -568,12 +553,6 @@
      modelOptions.value.find(item => item.id == value)?.model || "";
    form.value.unit =
      modelOptions.value.find(item => item.id == value)?.unit || "";
  };
  // é€‰æ‹©æ£€æµ‹ç»“æžœ
  const selectResult = e => {
    form.value.checkResult = e.value;
    showResultSheet.value = false;
  };
  // é€‰æ‹©æ£€éªŒå‘˜
@@ -698,7 +677,15 @@
        return;
      }
      if (!form.value.quantity) {
        showToast("请输入数量");
        showToast("请输入总数量");
        return;
      }
      if (!form.value.qualifiedQuantity && form.value.qualifiedQuantity !== 0) {
        showToast("请输入合格数量");
        return;
      }
      if (!form.value.unqualifiedQuantity && form.value.unqualifiedQuantity !== 0) {
        showToast("请输入不合格数量");
        return;
      }
      if (!form.value.productId) {
@@ -709,11 +696,6 @@
        showToast("请选择指标");
        return;
      }
      if (!form.value.checkResult) {
        showToast("请选择检测结果");
        return;
      }
      loading.value = true;
      form.value.inspectType = 0;
@@ -725,6 +707,8 @@
      const data = { ...form.value, qualityInspectParams: tableData.value };
      data.quantity = Number(data.quantity);
      data.qualifiedQuantity = Number(data.qualifiedQuantity);
      data.unqualifiedQuantity = Number(data.unqualifiedQuantity);
      if (isEdit.value) {
        const res = await qualityInspectUpdate(data);
        showToast("保存成功");
@@ -764,7 +748,8 @@
        unit: "",
        quantity: "",
        checkCompany: "",
        checkResult: "",
        qualifiedQuantity: "",
        unqualifiedQuantity: "",
        productMainId: null,
        purchaseLedgerId: null,
      };
@@ -786,7 +771,8 @@
        unit: "kg",
        quantity: 1000,
        checkCompany: "第三方检测机构",
        checkResult: "合格",
        qualifiedQuantity: 0,
        unqualifiedQuantity: 0,
        productMainId: null,
        purchaseLedgerId: null,
      };
@@ -865,8 +851,9 @@
        testStandardId: "",
        unit: "",
        quantity: "",
        qualifiedQuantity: "",
        unqualifiedQuantity: "",
        checkCompany: "",
        checkResult: "",
        productMainId: null,
        purchaseLedgerId: null,
      };
src/pages/qualityManagement/materialInspection/detail.vue
@@ -15,11 +15,11 @@
          </view>
          <text class="header-title">{{ detailData.productName || '-' }}</text>
          <view class="status-tags">
            <u-tag v-if="detailData.checkResult"
                   :type="getTagType(detailData.checkResult)"
            <u-tag v-if="detailData.passRate != null && detailData.passRate !== ''"
                   type="primary"
                   size="small"
                   class="status-tag">
              {{ detailData.checkResult || '-' }}
              åˆæ ¼çއ {{ formatPassRate(detailData.passRate) }}
            </u-tag>
            <u-tag :type="getStateTagType(detailData.inspectState)"
                   size="small"
@@ -59,8 +59,20 @@
            <text class="detail-value">{{ detailData.unit || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">数量</text>
            <text class="detail-value">{{ detailData.quantity || 0 }}</text>
            <text class="detail-label">总数量</text>
            <text class="detail-value">{{ detailData.quantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">合格数量</text>
            <text class="detail-value">{{ detailData.qualifiedQuantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">不合格数量</text>
            <text class="detail-value">{{ detailData.unqualifiedQuantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">合格率</text>
            <text class="detail-value">{{ formatPassRate(detailData.passRate) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">检测单位</text>
@@ -161,16 +173,13 @@
    return dayjs(date).format("YYYY-MM-DD");
  };
  // èŽ·å–æ ‡ç­¾ç±»åž‹
  const getTagType = result => {
    switch (result) {
      case "合格":
        return "success";
      case "不合格":
        return "error";
      default:
        return "info";
    }
  // æ ¼å¼åŒ–合格率
  const formatPassRate = rate => {
    if (rate === null || rate === undefined || rate === "") return "-";
    const num = Number(rate);
    if (isNaN(num)) return rate;
    if (num <= 1) return `${(num * 100).toFixed(2)}%`;
    return `${num}%`;
  };
  // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
src/pages/qualityManagement/materialInspection/index.vue
@@ -76,11 +76,11 @@
              </view>
            </view>
            <view class="status-tags">
              <u-tag v-if="item.checkResult"
                     :type="getTagType(item.checkResult)"
              <u-tag v-if="item.passRate != null && item.passRate !== ''"
                     type="primary"
                     size="mini"
                     class="status-tag">
                {{ item.checkResult }}
                åˆæ ¼çއ {{ formatPassRate(item.passRate) }}
              </u-tag>
              <u-tag :type="getStateTagType(item.inspectState)"
                     size="mini"
@@ -316,11 +316,13 @@
    return inspectState ? "checkmark-circle" : "time";
  };
  // èŽ·å–æ ‡ç­¾ç±»åž‹
  const getTagType = checkResult => {
    if (checkResult === "合格") return "success";
    if (checkResult === "不合格") return "error";
    return "default";
  // æ ¼å¼åŒ–合格率
  const formatPassRate = rate => {
    if (rate === null || rate === undefined || rate === "") return "-";
    const num = Number(rate);
    if (isNaN(num)) return rate;
    if (num <= 1) return `${(num * 100).toFixed(2)}%`;
    return `${num}%`;
  };
  // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
@@ -383,9 +385,11 @@
        pendingCount.value = inspectionList.value.filter(
          item => !item.inspectState
        ).length;
        qualifiedCount.value = inspectionList.value.filter(
          item => item.checkResult === "合格"
        ).length;
        qualifiedCount.value = inspectionList.value.filter(item => {
          const rate = Number(item.passRate);
          if (isNaN(rate)) return false;
          return rate <= 1 ? rate >= 1 : rate >= 100;
        }).length;
      })
      .catch(err => {
        tableLoading.value = false;
src/pages/qualityManagement/processInspection/add.vue
@@ -68,14 +68,32 @@
                  placeholder="请输入单位"
                  disabled />
      </up-form-item>
      <up-form-item label="数量"
      <up-form-item label="总数量"
                    prop="quantity"
                    required
                    border-bottom>
        <up-input v-model="form.quantity"
                  type="number"
                  placeholder="请输入数量"
                  placeholder="请输入总数量"
                  :disabled="processQuantityDisabled" />
      </up-form-item>
      <up-form-item label="合格数量"
                    prop="qualifiedQuantity"
                    required
                    border-bottom>
        <up-input v-model="form.qualifiedQuantity"
                  type="number"
                  placeholder="请输入合格数量"
                  clearable />
      </up-form-item>
      <up-form-item label="不合格数量"
                    prop="unqualifiedQuantity"
                    required
                    border-bottom>
        <up-input v-model="form.unqualifiedQuantity"
                  type="number"
                  placeholder="请输入不合格数量"
                  clearable />
      </up-form-item>
      <up-form-item label="检测单位"
                    prop="checkCompany"
@@ -83,19 +101,6 @@
        <up-input v-model="form.checkCompany"
                  placeholder="请输入检测单位"
                  clearable />
      </up-form-item>
      <up-form-item label="检测结果"
                    prop="checkResult"
                    required
                    border-bottom>
        <up-input v-model="form.checkResult"
                  placeholder="请选择检测结果"
                  readonly
                  @click="showResultSheet" />
        <template #right>
          <up-icon @click="showResultSheet = true"
                   name="arrow-right" />
        </template>
      </up-form-item>
      <up-form-item label="检验员"
                    prop="checkName"
@@ -212,12 +217,6 @@
                     @select="selectModel"
                     @close="showModelSheet = false"
                     title="选择规格型号" />
    <!-- æ£€æµ‹ç»“果选择 -->
    <up-action-sheet :show="showResultSheet"
                     :actions="resultSheetOptions"
                     @select="selectResult"
                     @close="showResultSheet = false"
                     title="选择检测结果" />
    <!-- æ£€éªŒå‘˜é€‰æ‹© -->
    <up-action-sheet :show="showInspectorSheet"
                     :actions="userSheetOptions"
@@ -344,8 +343,6 @@
  const showProductTree = ref(false);
  // è§„格型号选择
  const showModelSheet = ref(false);
  // æ£€æµ‹ç»“果选择
  const showResultSheet = ref(false);
  // æ£€éªŒå‘˜é€‰æ‹©
  const showInspectorSheet = ref(false);
  // æŒ‡æ ‡é€‰æ‹©
@@ -363,8 +360,9 @@
    testStandardId: "",
    unit: "",
    quantity: "",
    qualifiedQuantity: "",
    unqualifiedQuantity: "",
    checkCompany: "",
    checkResult: "",
    productMainId: null,
    purchaseLedgerId: null,
  });
@@ -384,11 +382,6 @@
  const modelOptions = ref([]);
  // æ£€éªŒå‘˜åˆ—表
  const userList = ref([]);
  // æ£€æµ‹ç»“果选项
  const resultOptions = ref([
    { label: "合格", value: "合格" },
    { label: "不合格", value: "不合格" },
  ]);
  // æŒ‡æ ‡é€‰é¡¹
  const testStandardOptions = ref([]);
  // å½“前产品ID
@@ -413,13 +406,6 @@
    return modelOptions.value.map(item => ({
      name: item.model,
      value: item.id,
    }));
  });
  const resultSheetOptions = computed(() => {
    return resultOptions.value.map(item => ({
      name: item.label,
      value: item.value,
    }));
  });
@@ -451,10 +437,9 @@
    ],
    unit: [{ required: false, message: "请输入", trigger: "blur" }],
    quantity: [{ required: true, message: "请输入", trigger: "blur" }],
    qualifiedQuantity: [{ required: true, message: "请输入", trigger: "blur" }],
    unqualifiedQuantity: [{ required: true, message: "请输入", trigger: "blur" }],
    checkCompany: [{ required: false, message: "请输入", trigger: "blur" }],
    checkResult: [
      { required: true, message: "请选择检测结果", trigger: "change" },
    ],
  };
  // æ˜¯å¦ä¸ºç¼–辑模式
@@ -559,12 +544,6 @@
      modelOptions.value.find(item => item.id == value)?.model || "";
    form.value.unit =
      modelOptions.value.find(item => item.id == value)?.unit || "";
  };
  // é€‰æ‹©æ£€æµ‹ç»“æžœ
  const selectResult = e => {
    form.value.checkResult = e.value;
    showResultSheet.value = false;
  };
  // é€‰æ‹©æ£€éªŒå‘˜
@@ -689,7 +668,15 @@
        return;
      }
      if (!form.value.quantity) {
        showToast("请输入数量");
        showToast("请输入总数量");
        return;
      }
      if (!form.value.qualifiedQuantity && form.value.qualifiedQuantity !== 0) {
        showToast("请输入合格数量");
        return;
      }
      if (!form.value.unqualifiedQuantity && form.value.unqualifiedQuantity !== 0) {
        showToast("请输入不合格数量");
        return;
      }
      if (!form.value.productId) {
@@ -700,11 +687,6 @@
        showToast("请选择指标");
        return;
      }
      if (!form.value.checkResult) {
        showToast("请选择检测结果");
        return;
      }
      loading.value = true;
      form.value.inspectType = 1;
@@ -716,6 +698,8 @@
      const data = { ...form.value, qualityInspectParams: tableData.value };
      data.quantity = Number(data.quantity);
      data.qualifiedQuantity = Number(data.qualifiedQuantity);
      data.unqualifiedQuantity = Number(data.unqualifiedQuantity);
      if (isEdit.value) {
        const res = await qualityInspectUpdate(data);
        showToast("保存成功");
@@ -755,7 +739,8 @@
        unit: "",
        quantity: "",
        checkCompany: "",
        checkResult: "",
        qualifiedQuantity: "",
        unqualifiedQuantity: "",
        productMainId: null,
        purchaseLedgerId: null,
      };
@@ -777,7 +762,8 @@
        unit: "kg",
        quantity: 1000,
        checkCompany: "第三方检测机构",
        checkResult: "合格",
        qualifiedQuantity: 0,
        unqualifiedQuantity: 0,
        productMainId: null,
        purchaseLedgerId: null,
      };
@@ -856,8 +842,9 @@
        testStandardId: "",
        unit: "",
        quantity: "",
        qualifiedQuantity: "",
        unqualifiedQuantity: "",
        checkCompany: "",
        checkResult: "",
        productMainId: null,
        purchaseLedgerId: null,
      };
src/pages/qualityManagement/processInspection/detail.vue
@@ -15,11 +15,11 @@
          </view>
          <text class="header-title">{{ detailData.productName || '-' }}</text>
          <view class="status-tags">
            <u-tag v-if="detailData.checkResult"
                   :type="getTagType(detailData.checkResult)"
            <u-tag v-if="detailData.passRate != null && detailData.passRate !== ''"
                   type="primary"
                   size="small"
                   class="status-tag">
              {{ detailData.checkResult }}
              åˆæ ¼çއ {{ formatPassRate(detailData.passRate) }}
            </u-tag>
            <u-tag :type="getStateTagType(detailData.inspectState)"
                   size="small"
@@ -59,8 +59,20 @@
            <text class="detail-value">{{ detailData.unit || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">数量</text>
            <text class="detail-value">{{ detailData.quantity || 0 }}</text>
            <text class="detail-label">总数量</text>
            <text class="detail-value">{{ detailData.quantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">合格数量</text>
            <text class="detail-value">{{ detailData.qualifiedQuantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">不合格数量</text>
            <text class="detail-value">{{ detailData.unqualifiedQuantity ?? 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">合格率</text>
            <text class="detail-value">{{ formatPassRate(detailData.passRate) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">检测单位</text>
@@ -162,15 +174,12 @@
  };
  // èŽ·å–æ ‡ç­¾ç±»åž‹
  const getTagType = result => {
    switch (result) {
      case "合格":
        return "success";
      case "不合格":
        return "error";
      default:
        return "info";
    }
  const formatPassRate = rate => {
    if (rate === null || rate === undefined || rate === "") return "-";
    const num = Number(rate);
    if (isNaN(num)) return rate;
    if (num <= 1) return `${(num * 100).toFixed(2)}%`;
    return `${num}%`;
  };
  // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
src/pages/qualityManagement/processInspection/index.vue
@@ -76,11 +76,11 @@
              </view>
            </view>
            <view class="status-tags">
              <u-tag v-if="item.checkResult"
                     :type="getTagType(item.checkResult)"
              <u-tag v-if="item.passRate != null && item.passRate !== ''"
                     type="primary"
                     size="mini"
                     class="status-tag">
                {{ item.checkResult }}
                åˆæ ¼çއ {{ formatPassRate(item.passRate) }}
              </u-tag>
              <u-tag :type="getStateTagType(item.inspectState)"
                     size="mini"
@@ -316,11 +316,13 @@
    return inspectState ? "checkmark-circle" : "time";
  };
  // èŽ·å–æ ‡ç­¾ç±»åž‹
  const getTagType = checkResult => {
    if (checkResult === "合格") return "success";
    if (checkResult === "不合格") return "error";
    return "default";
  // æ ¼å¼åŒ–合格率
  const formatPassRate = rate => {
    if (rate === null || rate === undefined || rate === "") return "-";
    const num = Number(rate);
    if (isNaN(num)) return rate;
    if (num <= 1) return `${(num * 100).toFixed(2)}%`;
    return `${num}%`;
  };
  // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
@@ -383,9 +385,11 @@
        pendingCount.value = inspectionList.value.filter(
          item => !item.inspectState
        ).length;
        qualifiedCount.value = inspectionList.value.filter(
          item => item.checkResult === "合格"
        ).length;
        qualifiedCount.value = inspectionList.value.filter(item => {
          const rate = Number(item.passRate);
          if (isNaN(rate)) return false;
          return rate <= 1 ? rate >= 1 : rate >= 100;
        }).length;
      })
      .catch(err => {
        tableLoading.value = false;