From 805b087e4d036c51e0b377b7264a99d37fb15ff0 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期六, 16 五月 2026 10:58:28 +0800
Subject: [PATCH] 更新质量管理模块,新增合格数量和不合格数量字段,修改数量标签为总数量,计算合格率展示

---
 src/pages/qualityManagement/processInspection/detail.vue  |   46 ++-
 src/pages/qualityManagement/processInspection/index.vue   |   48 +++
 src/pages/qualityManagement/finalInspection/index.vue     |   48 +++
 src/pages/qualityManagement/finalInspection/add.vue       |  123 ++++++-----
 src/pages/qualityManagement/materialInspection/add.vue    |  123 ++++++-----
 src/pages/qualityManagement/materialInspection/detail.vue |   47 +++-
 src/pages/qualityManagement/materialInspection/index.vue  |   48 +++
 src/pages/qualityManagement/processInspection/add.vue     |  123 ++++++-----
 src/pages/qualityManagement/finalInspection/detail.vue    |   46 ++-
 9 files changed, 415 insertions(+), 237 deletions(-)

diff --git a/src/pages/qualityManagement/finalInspection/add.vue b/src/pages/qualityManagement/finalInspection/add.vue
index ccacef9..c297bbc 100644
--- a/src/pages/qualityManagement/finalInspection/add.vue
+++ b/src/pages/qualityManagement/finalInspection/add.vue
@@ -67,14 +67,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"
@@ -82,19 +100,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"
@@ -207,12 +212,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"
@@ -339,8 +338,6 @@
   const showProductTree = ref(false);
   // 瑙勬牸鍨嬪彿閫夋嫨
   const showModelSheet = ref(false);
-  // 妫�娴嬬粨鏋滈�夋嫨
-  const showResultSheet = ref(false);
   // 妫�楠屽憳閫夋嫨
   const showInspectorSheet = ref(false);
   // 鎸囨爣閫夋嫨
@@ -358,8 +355,9 @@
     testStandardId: "",
     unit: "",
     quantity: "",
+    qualifiedQuantity: "",
+    unqualifiedQuantity: "",
     checkCompany: "",
-    checkResult: "",
     productMainId: null,
     purchaseLedgerId: null,
   });
@@ -379,11 +377,6 @@
   const modelOptions = ref([]);
   // 妫�楠屽憳鍒楄〃
   const userList = ref([]);
-  // 妫�娴嬬粨鏋滈�夐」
-  const resultOptions = ref([
-    { label: "鍚堟牸", value: "鍚堟牸" },
-    { label: "涓嶅悎鏍�", value: "涓嶅悎鏍�" },
-  ]);
   // 鎸囨爣閫夐」
   const testStandardOptions = ref([]);
   // 褰撳墠浜у搧ID
@@ -408,13 +401,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,
     }));
   });
 
@@ -446,10 +432,13 @@
     ],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-    checkResult: [
-      { required: true, message: "璇烽�夋嫨妫�娴嬬粨鏋�", trigger: "change" },
+    qualifiedQuantity: [
+      { required: true, message: "璇疯緭鍏ュ悎鏍兼暟閲�", trigger: "blur" },
     ],
+    unqualifiedQuantity: [
+      { required: true, message: "璇疯緭鍏ヤ笉鍚堟牸鏁伴噺", trigger: "blur" },
+    ],
+    checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
   };
 
   // 鏄惁涓虹紪杈戞ā寮�
@@ -554,12 +543,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;
   };
 
   // 閫夋嫨妫�楠屽憳
@@ -683,16 +666,41 @@
       //   showToast("璇烽�夋嫨宸ュ簭");
       //   return;
       // }
-      if (!form.value.quantity) {
-        showToast("璇疯緭鍏ユ暟閲�");
+      if (!form.value.quantity && form.value.quantity !== 0) {
+        showToast("璇疯緭鍏ユ�绘暟閲�");
+        return;
+      }
+      if (
+        form.value.qualifiedQuantity === "" ||
+        form.value.qualifiedQuantity === undefined
+      ) {
+        showToast("璇疯緭鍏ュ悎鏍兼暟閲�");
+        return;
+      }
+      if (
+        form.value.unqualifiedQuantity === "" ||
+        form.value.unqualifiedQuantity === undefined
+      ) {
+        showToast("璇疯緭鍏ヤ笉鍚堟牸鏁伴噺");
+        return;
+      }
+      const qty = Number(form.value.quantity);
+      const qf = Number(form.value.qualifiedQuantity);
+      const uq = Number(form.value.unqualifiedQuantity);
+      if (Number.isNaN(qty) || qty < 0) {
+        showToast("鎬绘暟閲忔牸寮忎笉姝g‘");
+        return;
+      }
+      if (Number.isNaN(qf) || qf < 0 || Number.isNaN(uq) || uq < 0) {
+        showToast("鍚堟牸/涓嶅悎鏍兼暟閲忔牸寮忎笉姝g‘");
+        return;
+      }
+      if (qf + uq !== qty) {
+        showToast("鍚堟牸鏁伴噺涓庝笉鍚堟牸鏁伴噺涔嬪拰椤荤瓑浜庢�绘暟閲�");
         return;
       }
       if (!form.value.productId) {
         showToast("璇烽�夋嫨浜у搧");
-        return;
-      }
-      if (!form.value.checkResult) {
-        showToast("璇烽�夋嫨妫�娴嬬粨鏋�");
         return;
       }
 
@@ -706,7 +714,9 @@
       }
 
       const data = { ...form.value, qualityInspectParams: tableData.value };
-      data.quantity = Number(data.quantity);
+      data.quantity = qty;
+      data.qualifiedQuantity = qf;
+      data.unqualifiedQuantity = uq;
       if (isEdit.value) {
         const res = await qualityInspectUpdate(data);
         showToast("淇濆瓨鎴愬姛");
@@ -745,8 +755,9 @@
         testStandardId: "",
         unit: "",
         quantity: "",
+        qualifiedQuantity: "",
+        unqualifiedQuantity: "",
         checkCompany: "",
-        checkResult: "",
         productMainId: null,
         purchaseLedgerId: null,
       };
@@ -767,8 +778,9 @@
         testStandardId: "1",
         unit: "kg",
         quantity: 1000,
+        qualifiedQuantity: 1000,
+        unqualifiedQuantity: 0,
         checkCompany: "绗笁鏂规娴嬫満鏋�",
-        checkResult: "鍚堟牸",
         productMainId: null,
         purchaseLedgerId: null,
       };
@@ -847,8 +859,9 @@
         testStandardId: "",
         unit: "",
         quantity: "",
+        qualifiedQuantity: "",
+        unqualifiedQuantity: "",
         checkCompany: "",
-        checkResult: "",
         productMainId: null,
         purchaseLedgerId: null,
       };
diff --git a/src/pages/qualityManagement/finalInspection/detail.vue b/src/pages/qualityManagement/finalInspection/detail.vue
index 9f209f0..7a8fed3 100644
--- a/src/pages/qualityManagement/finalInspection/detail.vue
+++ b/src/pages/qualityManagement/finalInspection/detail.vue
@@ -15,10 +15,10 @@
           </view>
           <text class="header-title">{{ detailData.productName || '-' }}</text>
           <view class="status-tags">
-            <u-tag :type="getTagType(detailData.checkResult)"
+            <u-tag :type="getPassRateTagType(detailData.passRate)"
                    size="small"
                    class="status-tag">
-              {{ detailData.checkResult || '-' }}
+              鍚堟牸鐜� {{ formatPassRate(detailData.passRate) }}
             </u-tag>
             <u-tag :type="getStateTagType(detailData.inspectState)"
                    size="small"
@@ -58,8 +58,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 ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鍚堟牸鏁伴噺</text>
+            <text class="detail-value">{{ detailData.qualifiedQuantity ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">涓嶅悎鏍兼暟閲�</text>
+            <text class="detail-value">{{ detailData.unqualifiedQuantity ?? '-' }}</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>
@@ -160,16 +172,22 @@
     return dayjs(date).format("YYYY-MM-DD");
   };
 
-  // 鑾峰彇鏍囩绫诲瀷
-  const getTagType = result => {
-    switch (result) {
-      case "鍚堟牸":
-        return "success";
-      case "涓嶅悎鏍�":
-        return "error";
-      default:
-        return "info";
-    }
+  const formatPassRate = val => {
+    if (val === null || val === undefined || val === "") return "-";
+    const n = Number(val);
+    if (Number.isNaN(n)) return String(val);
+    if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`;
+    return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`;
+  };
+
+  const getPassRateTagType = val => {
+    if (val === null || val === undefined || val === "") return "info";
+    let n = Number(val);
+    if (Number.isNaN(n)) return "info";
+    if (n > 0 && n <= 1) n *= 100;
+    if (n >= 100) return "success";
+    if (n >= 60) return "warning";
+    return "error";
   };
 
   // 鑾峰彇鐘舵�佹爣绛剧被鍨�
diff --git a/src/pages/qualityManagement/finalInspection/index.vue b/src/pages/qualityManagement/finalInspection/index.vue
index 691e9fc..faf77e5 100644
--- a/src/pages/qualityManagement/finalInspection/index.vue
+++ b/src/pages/qualityManagement/finalInspection/index.vue
@@ -75,11 +75,11 @@
               </view>
             </view>
             <view class="status-tags">
-              <u-tag :type="getTagType(item.checkResult)"
-                     v-if="item.checkResult!=null"
+              <u-tag :type="getPassRateTagType(item.passRate)"
+                     v-if="item.passRate != null && item.passRate !== ''"
                      size="mini"
                      class="status-tag">
-                {{ item.checkResult }}
+                {{ formatPassRate(item.passRate) }}
               </u-tag>
               <u-tag :type="getStateTagType(item.inspectState)"
                      size="mini"
@@ -107,8 +107,16 @@
               <text class="detail-value">{{ item.checkName || '-' }}</text>
             </view>
             <view class="detail-row">
-              <text class="detail-label">鏁伴噺</text>
+              <text class="detail-label">鎬绘暟閲�</text>
               <text class="detail-value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍚堟牸鏁伴噺</text>
+              <text class="detail-value">{{ item.qualifiedQuantity ?? '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">涓嶅悎鏍兼暟閲�</text>
+              <text class="detail-value">{{ item.unqualifiedQuantity ?? '-' }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">妫�娴嬪崟浣�</text>
@@ -315,11 +323,31 @@
     return inspectState ? "checkmark-circle" : "time";
   };
 
-  // 鑾峰彇鏍囩绫诲瀷
-  const getTagType = checkResult => {
-    if (checkResult === "鍚堟牸") return "success";
-    if (checkResult === "涓嶅悎鏍�") return "error";
-    return "default";
+  const formatPassRate = val => {
+    if (val === null || val === undefined || val === "") return "-";
+    const n = Number(val);
+    if (Number.isNaN(n)) return String(val);
+    if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`;
+    return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`;
+  };
+
+  const getPassRateTagType = val => {
+    if (val === null || val === undefined || val === "") return "default";
+    let n = Number(val);
+    if (Number.isNaN(n)) return "default";
+    if (n > 0 && n <= 1) n *= 100;
+    if (n >= 100) return "success";
+    if (n >= 60) return "warning";
+    return "error";
+  };
+
+  const isFullPassByPassRate = item => {
+    const v = item.passRate;
+    if (v === null || v === undefined || v === "") return false;
+    const n = Number(v);
+    if (Number.isNaN(n)) return false;
+    if (n > 0 && n <= 1) return n >= 1;
+    return n >= 100;
   };
 
   // 鑾峰彇鐘舵�佹爣绛剧被鍨�
@@ -383,7 +411,7 @@
           item => !item.inspectState
         ).length;
         qualifiedCount.value = inspectionList.value.filter(
-          item => item.checkResult === "鍚堟牸"
+          isFullPassByPassRate
         ).length;
       })
       .catch(err => {
diff --git a/src/pages/qualityManagement/materialInspection/add.vue b/src/pages/qualityManagement/materialInspection/add.vue
index 54c1550..1780e10 100644
--- a/src/pages/qualityManagement/materialInspection/add.vue
+++ b/src/pages/qualityManagement/materialInspection/add.vue
@@ -67,14 +67,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"
@@ -82,19 +100,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"
@@ -214,12 +219,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"
@@ -345,8 +344,6 @@
   const showProductTree = ref(false);
   // 瑙勬牸鍨嬪彿閫夋嫨
   const showModelSheet = ref(false);
-  // 妫�娴嬬粨鏋滈�夋嫨
-  const showResultSheet = ref(false);
   // 妫�楠屽憳閫夋嫨
   const showInspectorSheet = ref(false);
   // 鎸囨爣閫夋嫨
@@ -364,8 +361,9 @@
     testStandardId: "",
     unit: "",
     quantity: "",
+    qualifiedQuantity: "",
+    unqualifiedQuantity: "",
     checkCompany: "",
-    checkResult: "",
     productMainId: null,
     purchaseLedgerId: null,
   });
@@ -385,11 +383,6 @@
   const modelOptions = ref([]);
   // 妫�楠屽憳鍒楄〃
   const userList = ref([]);
-  // 妫�娴嬬粨鏋滈�夐」
-  const resultOptions = ref([
-    { label: "鍚堟牸", value: "鍚堟牸" },
-    { label: "涓嶅悎鏍�", value: "涓嶅悎鏍�" },
-  ]);
   // 鎸囨爣閫夐」
   const testStandardOptions = ref([]);
   // 褰撳墠浜у搧ID
@@ -414,13 +407,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,
     }));
   });
 
@@ -452,10 +438,13 @@
     ],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-    checkResult: [
-      { required: true, message: "璇烽�夋嫨妫�娴嬬粨鏋�", trigger: "change" },
+    qualifiedQuantity: [
+      { required: true, message: "璇疯緭鍏ュ悎鏍兼暟閲�", trigger: "blur" },
     ],
+    unqualifiedQuantity: [
+      { required: true, message: "璇疯緭鍏ヤ笉鍚堟牸鏁伴噺", trigger: "blur" },
+    ],
+    checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
   };
 
   // 鏄惁涓虹紪杈戞ā寮�
@@ -560,12 +549,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,16 +672,41 @@
         showToast("璇烽�夋嫨渚涘簲鍟�");
         return;
       }
-      if (!form.value.quantity) {
-        showToast("璇疯緭鍏ユ暟閲�");
+      if (!form.value.quantity && form.value.quantity !== 0) {
+        showToast("璇疯緭鍏ユ�绘暟閲�");
+        return;
+      }
+      if (
+        form.value.qualifiedQuantity === "" ||
+        form.value.qualifiedQuantity === undefined
+      ) {
+        showToast("璇疯緭鍏ュ悎鏍兼暟閲�");
+        return;
+      }
+      if (
+        form.value.unqualifiedQuantity === "" ||
+        form.value.unqualifiedQuantity === undefined
+      ) {
+        showToast("璇疯緭鍏ヤ笉鍚堟牸鏁伴噺");
+        return;
+      }
+      const qty = Number(form.value.quantity);
+      const qf = Number(form.value.qualifiedQuantity);
+      const uq = Number(form.value.unqualifiedQuantity);
+      if (Number.isNaN(qty) || qty < 0) {
+        showToast("鎬绘暟閲忔牸寮忎笉姝g‘");
+        return;
+      }
+      if (Number.isNaN(qf) || qf < 0 || Number.isNaN(uq) || uq < 0) {
+        showToast("鍚堟牸/涓嶅悎鏍兼暟閲忔牸寮忎笉姝g‘");
+        return;
+      }
+      if (qf + uq !== qty) {
+        showToast("鍚堟牸鏁伴噺涓庝笉鍚堟牸鏁伴噺涔嬪拰椤荤瓑浜庢�绘暟閲�");
         return;
       }
       if (!form.value.productId) {
         showToast("璇烽�夋嫨浜у搧");
-        return;
-      }
-      if (!form.value.checkResult) {
-        showToast("璇烽�夋嫨妫�娴嬬粨鏋�");
         return;
       }
 
@@ -712,7 +720,9 @@
       }
 
       const data = { ...form.value, qualityInspectParams: tableData.value };
-      data.quantity = Number(data.quantity);
+      data.quantity = qty;
+      data.qualifiedQuantity = qf;
+      data.unqualifiedQuantity = uq;
       if (isEdit.value) {
         const res = await qualityInspectUpdate(data);
         showToast("淇濆瓨鎴愬姛");
@@ -751,8 +761,9 @@
         testStandardId: "",
         unit: "",
         quantity: "",
+        qualifiedQuantity: "",
+        unqualifiedQuantity: "",
         checkCompany: "",
-        checkResult: "",
         productMainId: null,
         purchaseLedgerId: null,
       };
@@ -773,8 +784,9 @@
         testStandardId: "1",
         unit: "kg",
         quantity: 1000,
+        qualifiedQuantity: 1000,
+        unqualifiedQuantity: 0,
         checkCompany: "绗笁鏂规娴嬫満鏋�",
-        checkResult: "鍚堟牸",
         productMainId: null,
         purchaseLedgerId: null,
       };
@@ -853,8 +865,9 @@
         testStandardId: "",
         unit: "",
         quantity: "",
+        qualifiedQuantity: "",
+        unqualifiedQuantity: "",
         checkCompany: "",
-        checkResult: "",
         productMainId: null,
         purchaseLedgerId: null,
       };
diff --git a/src/pages/qualityManagement/materialInspection/detail.vue b/src/pages/qualityManagement/materialInspection/detail.vue
index e45b9c0..6b3bfe8 100644
--- a/src/pages/qualityManagement/materialInspection/detail.vue
+++ b/src/pages/qualityManagement/materialInspection/detail.vue
@@ -15,10 +15,10 @@
           </view>
           <text class="header-title">{{ detailData.productName || '-' }}</text>
           <view class="status-tags">
-            <u-tag :type="getTagType(detailData.checkResult)"
+            <u-tag :type="getPassRateTagType(detailData.passRate)"
                    size="small"
                    class="status-tag">
-              {{ detailData.checkResult || '-' }}
+              鍚堟牸鐜� {{ formatPassRate(detailData.passRate) }}
             </u-tag>
             <u-tag :type="getStateTagType(detailData.inspectState)"
                    size="small"
@@ -58,8 +58,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 ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鍚堟牸鏁伴噺</text>
+            <text class="detail-value">{{ detailData.qualifiedQuantity ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">涓嶅悎鏍兼暟閲�</text>
+            <text class="detail-value">{{ detailData.unqualifiedQuantity ?? '-' }}</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>
@@ -160,16 +172,23 @@
     return dayjs(date).format("YYYY-MM-DD");
   };
 
-  // 鑾峰彇鏍囩绫诲瀷
-  const getTagType = result => {
-    switch (result) {
-      case "鍚堟牸":
-        return "success";
-      case "涓嶅悎鏍�":
-        return "error";
-      default:
-        return "info";
-    }
+  // 鏍煎紡鍖栧悎鏍肩巼锛堟敮鎸� 0鈥�1 灏忔暟鎴栫櫨鍒嗘暟锛�
+  const formatPassRate = val => {
+    if (val === null || val === undefined || val === "") return "-";
+    const n = Number(val);
+    if (Number.isNaN(n)) return String(val);
+    if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`;
+    return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`;
+  };
+
+  const getPassRateTagType = val => {
+    if (val === null || val === undefined || val === "") return "info";
+    let n = Number(val);
+    if (Number.isNaN(n)) return "info";
+    if (n > 0 && n <= 1) n *= 100;
+    if (n >= 100) return "success";
+    if (n >= 60) return "warning";
+    return "error";
   };
 
   // 鑾峰彇鐘舵�佹爣绛剧被鍨�
diff --git a/src/pages/qualityManagement/materialInspection/index.vue b/src/pages/qualityManagement/materialInspection/index.vue
index 8449522..d3ef2bb 100644
--- a/src/pages/qualityManagement/materialInspection/index.vue
+++ b/src/pages/qualityManagement/materialInspection/index.vue
@@ -75,11 +75,11 @@
               </view>
             </view>
             <view class="status-tags">
-              <u-tag :type="getTagType(item.checkResult)"
-                     v-if="item.checkResult!=null"
+              <u-tag :type="getPassRateTagType(item.passRate)"
+                     v-if="item.passRate != null && item.passRate !== ''"
                      size="mini"
                      class="status-tag">
-                {{ item.checkResult }}
+                {{ formatPassRate(item.passRate) }}
               </u-tag>
               <u-tag :type="getStateTagType(item.inspectState)"
                      size="mini"
@@ -107,8 +107,16 @@
               <text class="detail-value">{{ item.checkName || '-' }}</text>
             </view>
             <view class="detail-row">
-              <text class="detail-label">鏁伴噺</text>
+              <text class="detail-label">鎬绘暟閲�</text>
               <text class="detail-value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍚堟牸鏁伴噺</text>
+              <text class="detail-value">{{ item.qualifiedQuantity ?? '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">涓嶅悎鏍兼暟閲�</text>
+              <text class="detail-value">{{ item.unqualifiedQuantity ?? '-' }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">妫�娴嬪崟浣�</text>
@@ -315,11 +323,31 @@
     return inspectState ? "checkmark-circle" : "time";
   };
 
-  // 鑾峰彇鏍囩绫诲瀷
-  const getTagType = checkResult => {
-    if (checkResult === "鍚堟牸") return "success";
-    if (checkResult === "涓嶅悎鏍�") return "error";
-    return "default";
+  const formatPassRate = val => {
+    if (val === null || val === undefined || val === "") return "-";
+    const n = Number(val);
+    if (Number.isNaN(n)) return String(val);
+    if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`;
+    return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`;
+  };
+
+  const getPassRateTagType = val => {
+    if (val === null || val === undefined || val === "") return "default";
+    let n = Number(val);
+    if (Number.isNaN(n)) return "default";
+    if (n > 0 && n <= 1) n *= 100;
+    if (n >= 100) return "success";
+    if (n >= 60) return "warning";
+    return "error";
+  };
+
+  const isFullPassByPassRate = item => {
+    const v = item.passRate;
+    if (v === null || v === undefined || v === "") return false;
+    const n = Number(v);
+    if (Number.isNaN(n)) return false;
+    if (n > 0 && n <= 1) return n >= 1;
+    return n >= 100;
   };
 
   // 鑾峰彇鐘舵�佹爣绛剧被鍨�
@@ -383,7 +411,7 @@
           item => !item.inspectState
         ).length;
         qualifiedCount.value = inspectionList.value.filter(
-          item => item.checkResult === "鍚堟牸"
+          isFullPassByPassRate
         ).length;
       })
       .catch(err => {
diff --git a/src/pages/qualityManagement/processInspection/add.vue b/src/pages/qualityManagement/processInspection/add.vue
index 5654083..4b80cb9 100644
--- a/src/pages/qualityManagement/processInspection/add.vue
+++ b/src/pages/qualityManagement/processInspection/add.vue
@@ -67,14 +67,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"
@@ -82,19 +100,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"
@@ -207,12 +212,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"
@@ -339,8 +338,6 @@
   const showProductTree = ref(false);
   // 瑙勬牸鍨嬪彿閫夋嫨
   const showModelSheet = ref(false);
-  // 妫�娴嬬粨鏋滈�夋嫨
-  const showResultSheet = ref(false);
   // 妫�楠屽憳閫夋嫨
   const showInspectorSheet = ref(false);
   // 鎸囨爣閫夋嫨
@@ -358,8 +355,9 @@
     testStandardId: "",
     unit: "",
     quantity: "",
+    qualifiedQuantity: "",
+    unqualifiedQuantity: "",
     checkCompany: "",
-    checkResult: "",
     productMainId: null,
     purchaseLedgerId: null,
   });
@@ -379,11 +377,6 @@
   const modelOptions = ref([]);
   // 妫�楠屽憳鍒楄〃
   const userList = ref([]);
-  // 妫�娴嬬粨鏋滈�夐」
-  const resultOptions = ref([
-    { label: "鍚堟牸", value: "鍚堟牸" },
-    { label: "涓嶅悎鏍�", value: "涓嶅悎鏍�" },
-  ]);
   // 鎸囨爣閫夐」
   const testStandardOptions = ref([]);
   // 褰撳墠浜у搧ID
@@ -408,13 +401,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,
     }));
   });
 
@@ -446,10 +432,13 @@
     ],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-    checkResult: [
-      { required: true, message: "璇烽�夋嫨妫�娴嬬粨鏋�", trigger: "change" },
+    qualifiedQuantity: [
+      { required: true, message: "璇疯緭鍏ュ悎鏍兼暟閲�", trigger: "blur" },
     ],
+    unqualifiedQuantity: [
+      { required: true, message: "璇疯緭鍏ヤ笉鍚堟牸鏁伴噺", trigger: "blur" },
+    ],
+    checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
   };
 
   // 鏄惁涓虹紪杈戞ā寮�
@@ -554,12 +543,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;
   };
 
   // 閫夋嫨妫�楠屽憳
@@ -683,16 +666,41 @@
         showToast("璇烽�夋嫨宸ュ簭");
         return;
       }
-      if (!form.value.quantity) {
-        showToast("璇疯緭鍏ユ暟閲�");
+      if (!form.value.quantity && form.value.quantity !== 0) {
+        showToast("璇疯緭鍏ユ�绘暟閲�");
+        return;
+      }
+      if (
+        form.value.qualifiedQuantity === "" ||
+        form.value.qualifiedQuantity === undefined
+      ) {
+        showToast("璇疯緭鍏ュ悎鏍兼暟閲�");
+        return;
+      }
+      if (
+        form.value.unqualifiedQuantity === "" ||
+        form.value.unqualifiedQuantity === undefined
+      ) {
+        showToast("璇疯緭鍏ヤ笉鍚堟牸鏁伴噺");
+        return;
+      }
+      const qty = Number(form.value.quantity);
+      const qf = Number(form.value.qualifiedQuantity);
+      const uq = Number(form.value.unqualifiedQuantity);
+      if (Number.isNaN(qty) || qty < 0) {
+        showToast("鎬绘暟閲忔牸寮忎笉姝g‘");
+        return;
+      }
+      if (Number.isNaN(qf) || qf < 0 || Number.isNaN(uq) || uq < 0) {
+        showToast("鍚堟牸/涓嶅悎鏍兼暟閲忔牸寮忎笉姝g‘");
+        return;
+      }
+      if (qf + uq !== qty) {
+        showToast("鍚堟牸鏁伴噺涓庝笉鍚堟牸鏁伴噺涔嬪拰椤荤瓑浜庢�绘暟閲�");
         return;
       }
       if (!form.value.productId) {
         showToast("璇烽�夋嫨浜у搧");
-        return;
-      }
-      if (!form.value.checkResult) {
-        showToast("璇烽�夋嫨妫�娴嬬粨鏋�");
         return;
       }
 
@@ -706,7 +714,9 @@
       }
 
       const data = { ...form.value, qualityInspectParams: tableData.value };
-      data.quantity = Number(data.quantity);
+      data.quantity = qty;
+      data.qualifiedQuantity = qf;
+      data.unqualifiedQuantity = uq;
       if (isEdit.value) {
         const res = await qualityInspectUpdate(data);
         showToast("淇濆瓨鎴愬姛");
@@ -745,8 +755,9 @@
         testStandardId: "",
         unit: "",
         quantity: "",
+        qualifiedQuantity: "",
+        unqualifiedQuantity: "",
         checkCompany: "",
-        checkResult: "",
         productMainId: null,
         purchaseLedgerId: null,
       };
@@ -767,8 +778,9 @@
         testStandardId: "1",
         unit: "kg",
         quantity: 1000,
+        qualifiedQuantity: 1000,
+        unqualifiedQuantity: 0,
         checkCompany: "绗笁鏂规娴嬫満鏋�",
-        checkResult: "鍚堟牸",
         productMainId: null,
         purchaseLedgerId: null,
       };
@@ -847,8 +859,9 @@
         testStandardId: "",
         unit: "",
         quantity: "",
+        qualifiedQuantity: "",
+        unqualifiedQuantity: "",
         checkCompany: "",
-        checkResult: "",
         productMainId: null,
         purchaseLedgerId: null,
       };
diff --git a/src/pages/qualityManagement/processInspection/detail.vue b/src/pages/qualityManagement/processInspection/detail.vue
index 721bb2a..655bbb8 100644
--- a/src/pages/qualityManagement/processInspection/detail.vue
+++ b/src/pages/qualityManagement/processInspection/detail.vue
@@ -15,10 +15,10 @@
           </view>
           <text class="header-title">{{ detailData.productName || '-' }}</text>
           <view class="status-tags">
-            <u-tag :type="getTagType(detailData.checkResult)"
+            <u-tag :type="getPassRateTagType(detailData.passRate)"
                    size="small"
                    class="status-tag">
-              {{ detailData.checkResult || '-' }}
+              鍚堟牸鐜� {{ formatPassRate(detailData.passRate) }}
             </u-tag>
             <u-tag :type="getStateTagType(detailData.inspectState)"
                    size="small"
@@ -58,8 +58,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 ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鍚堟牸鏁伴噺</text>
+            <text class="detail-value">{{ detailData.qualifiedQuantity ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">涓嶅悎鏍兼暟閲�</text>
+            <text class="detail-value">{{ detailData.unqualifiedQuantity ?? '-' }}</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>
@@ -160,16 +172,22 @@
     return dayjs(date).format("YYYY-MM-DD");
   };
 
-  // 鑾峰彇鏍囩绫诲瀷
-  const getTagType = result => {
-    switch (result) {
-      case "鍚堟牸":
-        return "success";
-      case "涓嶅悎鏍�":
-        return "error";
-      default:
-        return "info";
-    }
+  const formatPassRate = val => {
+    if (val === null || val === undefined || val === "") return "-";
+    const n = Number(val);
+    if (Number.isNaN(n)) return String(val);
+    if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`;
+    return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`;
+  };
+
+  const getPassRateTagType = val => {
+    if (val === null || val === undefined || val === "") return "info";
+    let n = Number(val);
+    if (Number.isNaN(n)) return "info";
+    if (n > 0 && n <= 1) n *= 100;
+    if (n >= 100) return "success";
+    if (n >= 60) return "warning";
+    return "error";
   };
 
   // 鑾峰彇鐘舵�佹爣绛剧被鍨�
diff --git a/src/pages/qualityManagement/processInspection/index.vue b/src/pages/qualityManagement/processInspection/index.vue
index e6a7281..816143d 100644
--- a/src/pages/qualityManagement/processInspection/index.vue
+++ b/src/pages/qualityManagement/processInspection/index.vue
@@ -75,11 +75,11 @@
               </view>
             </view>
             <view class="status-tags">
-              <u-tag :type="getTagType(item.checkResult)"
-                     v-if="item.checkResult!=null"
+              <u-tag :type="getPassRateTagType(item.passRate)"
+                     v-if="item.passRate != null && item.passRate !== ''"
                      size="mini"
                      class="status-tag">
-                {{ item.checkResult }}
+                {{ formatPassRate(item.passRate) }}
               </u-tag>
               <u-tag :type="getStateTagType(item.inspectState)"
                      size="mini"
@@ -107,8 +107,16 @@
               <text class="detail-value">{{ item.checkName || '-' }}</text>
             </view>
             <view class="detail-row">
-              <text class="detail-label">鏁伴噺</text>
+              <text class="detail-label">鎬绘暟閲�</text>
               <text class="detail-value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍚堟牸鏁伴噺</text>
+              <text class="detail-value">{{ item.qualifiedQuantity ?? '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">涓嶅悎鏍兼暟閲�</text>
+              <text class="detail-value">{{ item.unqualifiedQuantity ?? '-' }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">妫�娴嬪崟浣�</text>
@@ -315,11 +323,31 @@
     return inspectState ? "checkmark-circle" : "time";
   };
 
-  // 鑾峰彇鏍囩绫诲瀷
-  const getTagType = checkResult => {
-    if (checkResult === "鍚堟牸") return "success";
-    if (checkResult === "涓嶅悎鏍�") return "error";
-    return "default";
+  const formatPassRate = val => {
+    if (val === null || val === undefined || val === "") return "-";
+    const n = Number(val);
+    if (Number.isNaN(n)) return String(val);
+    if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`;
+    return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`;
+  };
+
+  const getPassRateTagType = val => {
+    if (val === null || val === undefined || val === "") return "default";
+    let n = Number(val);
+    if (Number.isNaN(n)) return "default";
+    if (n > 0 && n <= 1) n *= 100;
+    if (n >= 100) return "success";
+    if (n >= 60) return "warning";
+    return "error";
+  };
+
+  const isFullPassByPassRate = item => {
+    const v = item.passRate;
+    if (v === null || v === undefined || v === "") return false;
+    const n = Number(v);
+    if (Number.isNaN(n)) return false;
+    if (n > 0 && n <= 1) return n >= 1;
+    return n >= 100;
   };
 
   // 鑾峰彇鐘舵�佹爣绛剧被鍨�
@@ -383,7 +411,7 @@
           item => !item.inspectState
         ).length;
         qualifiedCount.value = inspectionList.value.filter(
-          item => item.checkResult === "鍚堟牸"
+          isFullPassByPassRate
         ).length;
       })
       .catch(err => {

--
Gitblit v1.9.3