From 91dcbcbd7e5813a2c382d7aa57c5483c06fdf225 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期五, 18 九月 2026 18:10:07 +0800
Subject: [PATCH] feat(生产报工): 报工弹窗按四类数量录入并展示分类去向

---
 src/views/productionManagement/productionReportingEntry/index.vue |   20 +++
 src/views/productionManagement/productionReporting/index.vue      |   29 +++++
 src/views/qualityManagement/finalInspection/index.vue             |   15 +++
 src/views/qualityManagement/nonconformingManagement/index.vue     |   16 +++
 src/views/qualityManagement/processInspection/index.vue           |   14 ++
 src/views/productionManagement/workOrderManagement/index.vue      |  166 +++++++++++++++++++-------------
 6 files changed, 189 insertions(+), 71 deletions(-)

diff --git a/src/views/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue
index 6c28ef6..ccdf5b5 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -32,6 +32,17 @@
             <el-option label="鎶ュ簾" :value="3" />
           </el-select>
         </el-form-item>
+        <el-form-item label="浜у搧澶х被:">
+          <el-select v-model="searchForm.majorCategory"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 200px;"
+                     @change="handleQuery">
+            <el-option label="灏忔彁鐞�" value="灏忔彁鐞�" />
+            <el-option label="澶ф彁鐞�" value="澶ф彁鐞�" />
+            <el-option label="璐濇柉" value="璐濇柉" />
+          </el-select>
+        </el-form-item>
         <el-form-item>
           <el-button type="primary"
                      @click="handleQuery">鎼滅储</el-button>
@@ -181,6 +192,7 @@
       workOrderNo: "",
       workOrderStatus: "",
       reportType: "",
+      majorCategory: "",
     },
   });
   const { searchForm } = toRefs(data);
@@ -229,6 +241,11 @@
       width: 120,
     },
     {
+      label: "浜у搧澶х被",
+      prop: "majorCategory",
+      width: 110,
+    },
+    {
       label: "浜у搧鍚嶇О",
       prop: "productName",
       width: 120,
@@ -239,11 +256,21 @@
       width: 120,
     },
     {
-      label: "浜у嚭鏁伴噺",
+      label: "鍚堟牸鏁伴噺",
       prop: "quantity",
       width: 120,
     },
     {
+      label: "杞诲井杩斿伐鏁伴噺",
+      prop: "reworkMinorQty",
+      width: 120,
+    },
+    {
+      label: "涓ラ噸杩斿伐鏁伴噺",
+      prop: "reworkMajorQty",
+      width: 120,
+    },
+    {
       label: "鎶ュ簾鏁伴噺",
       prop: "scrapQty",
       width: 120,
diff --git a/src/views/productionManagement/productionReportingEntry/index.vue b/src/views/productionManagement/productionReportingEntry/index.vue
index 99d3467..34edcf7 100644
--- a/src/views/productionManagement/productionReportingEntry/index.vue
+++ b/src/views/productionManagement/productionReportingEntry/index.vue
@@ -44,6 +44,18 @@
           </el-select>
         </div>
         <div class="search-item">
+          <span class="search_title">浜у搧澶х被锛�</span>
+          <el-select v-model="searchForm.majorCategory"
+                     style="width: 180px"
+                     clearable
+                     placeholder="璇烽�夋嫨"
+                     @change="handleQuery">
+            <el-option label="灏忔彁鐞�" value="灏忔彁鐞�" />
+            <el-option label="澶ф彁鐞�" value="澶ф彁鐞�" />
+            <el-option label="璐濇柉" value="璐濇柉" />
+          </el-select>
+        </div>
+        <div class="search-item">
           <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
         </div>
       </div>
@@ -85,6 +97,7 @@
     workOrderNo: "",
     nickName: "",
     reportType: "",
+    majorCategory: "",
   },
 });
 const { searchForm } = toRefs(data);
@@ -92,10 +105,13 @@
 const tableColumn = [
   { label: "鎶ュ伐鍗曞彿", prop: "productNo", width: 140 },
   { label: "鎶ュ伐浜哄憳", prop: "nickName", width: 120 },
+  { label: "浜у搧澶х被", prop: "majorCategory", width: 110 },
   { label: "宸ュ簭", prop: "process", width: 140 },
   { label: "宸ュ崟缂栧彿", prop: "workOrderNo", width: 140 },
-  { label: "浜у嚭鏁伴噺", prop: "quantity", width: 120 },
-  { label: "鎶ュ簾鏁伴噺", prop: "scrapQty", width: 120 },
+  { label: "鍚堟牸鏁伴噺", prop: "quantity", width: 110 },
+  { label: "杞诲井杩斿伐鏁伴噺", prop: "reworkMinorQty", width: 120 },
+  { label: "涓ラ噸杩斿伐鏁伴噺", prop: "reworkMajorQty", width: 120 },
+  { label: "鎶ュ簾鏁伴噺", prop: "scrapQty", width: 110 },
   { label: "宸ユ椂锛坔锛�", prop: "workHour", width: 100 },
   { label: "鎶ュ伐缁撴灉", prop: "reportTypeName", width: 100 },
   { label: "瀹℃牳鐘舵��", prop: "auditStatusName", width: 100 },
diff --git a/src/views/productionManagement/workOrderManagement/index.vue b/src/views/productionManagement/workOrderManagement/index.vue
index 8e23f61..0f5799e 100644
--- a/src/views/productionManagement/workOrderManagement/index.vue
+++ b/src/views/productionManagement/workOrderManagement/index.vue
@@ -65,15 +65,35 @@
                     readonly
                     style="width: 300px" />
         </el-form-item>
-        <el-form-item label="鐢熶骇鍚堟牸鏁伴噺"
+        <el-form-item label="鍚堟牸鏁伴噺"
                       prop="quantity">
           <el-input v-model.number="reportForm.quantity"
                     type="number"
                     min="0"
                     step="0.001"
                     style="width: 300px"
-                    placeholder="璇疯緭鍏ョ敓浜у悎鏍兼暟閲�"
+                    placeholder="璇疯緭鍏ュ悎鏍奸浂浠舵暟閲�"
                     @input="handleQuantityInput" />
+        </el-form-item>
+        <el-form-item label="杞诲井杩斿伐鏁伴噺"
+                      prop="reworkMinorQty">
+          <el-input v-model.number="reportForm.reworkMinorQty"
+                    type="number"
+                    min="0"
+                    step="1"
+                    style="width: 300px"
+                    placeholder="璇疯緭鍏ヨ交寰繑宸ラ浂浠舵暟閲�"
+                    @input="handleNonNegativeIntInput('reworkMinorQty', $event)" />
+        </el-form-item>
+        <el-form-item label="涓ラ噸杩斿伐鏁伴噺"
+                      prop="reworkMajorQty">
+          <el-input v-model.number="reportForm.reworkMajorQty"
+                    type="number"
+                    min="0"
+                    step="1"
+                    style="width: 300px"
+                    placeholder="璇疯緭鍏ヤ弗閲嶈繑宸ラ浂浠舵暟閲�"
+                    @input="handleNonNegativeIntInput('reworkMajorQty', $event)" />
         </el-form-item>
         <el-form-item label="鎶ュ簾鏁伴噺"
                       prop="scrapQty">
@@ -82,19 +102,12 @@
                     min="0"
                     step="1"
                     style="width: 300px"
-                    placeholder="璇疯緭鍏ユ姤搴熸暟閲�"
+                    placeholder="璇疯緭鍏ユ姤搴熼浂浠舵暟閲�"
                     @input="handleScrapQtyInput" />
         </el-form-item>
-        <el-form-item label="鎶ュ伐绫诲瀷"
-                      prop="reportType">
-          <el-select v-model="reportForm.reportType"
-                     style="width: 300px"
-                     placeholder="璇烽�夋嫨鎶ュ伐绫诲瀷">
-            <el-option label="鍚堟牸" :value="0" />
-            <el-option label="杞诲井杩斿伐" :value="1" />
-            <el-option label="涓ラ噸杩斿伐" :value="2" />
-            <el-option label="鎶ュ簾" :value="3" />
-          </el-select>
+        <el-form-item label="璁℃暟鍚堣">
+          <span class="counted-total">{{ countedTotal }}</span>
+          <span class="counted-total-tip">锛堝悎鏍� + 杞诲井杩斿伐 + 涓ラ噸杩斿伐 + 鎶ュ簾锛屽畬鎴愬悗鍒嗙被杩涘叆璐ㄦ鍏ュ簱锛�</span>
         </el-form-item>
         <el-form-item label="鐝粍淇℃伅">
           <el-select v-model="reportForm.userId"
@@ -210,7 +223,7 @@
 </template>
 
 <script setup>
-  import { onMounted, ref, nextTick } from "vue";
+  import { onMounted, ref, nextTick, computed } from "vue";
   import { ElMessageBox } from "element-plus";
   import dayjs from "dayjs";
   import {
@@ -375,8 +388,9 @@
   const reportForm = reactive({
     planQuantity: 0,
     quantity: null,
+    reworkMinorQty: null,
+    reworkMajorQty: null,
     scrapQty: null,
-    reportType: 0,
     userName: "",
     workOrderId: "",
     reportWork: "",
@@ -396,28 +410,26 @@
   // 鐢熶骇鍚堟牸鏁伴噺楠岃瘉瑙勫垯
   const validateQuantity = (rule, value, callback) => {
     if (value === null || value === undefined || value === "") {
-      callback(new Error("璇疯緭鍏ョ敓浜у悎鏍兼暟閲�"));
+      callback();
       return;
     }
     const num = Number(value);
-    // 鏁存暟涓斿ぇ浜庣瓑浜�1
     if (isNaN(num) || num < 0) {
-      callback(new Error("鐢熶骇鍚堟牸鏁伴噺蹇呴』澶т簬绛変簬0"));
+      callback(new Error("鍚堟牸鏁伴噺蹇呴』澶т簬绛変簬0"));
       return;
     }
     callback();
   };
 
-  // 鎶ュ簾鏁伴噺楠岃瘉瑙勫垯
-  const validateScrapQty = (rule, value, callback) => {
+  // 鍒嗙被鏁伴噺锛堣繑宸�/鎶ュ簾锛夐獙璇佽鍒欙細閫夊~锛岄潪璐�
+  const validateOptionalCount = label => (rule, value, callback) => {
     if (value === null || value === undefined || value === "") {
       callback();
       return;
     }
     const num = Number(value);
-    // 鏁存暟涓斿ぇ浜庣瓑浜�0
     if (isNaN(num) || num < 0) {
-      callback(new Error("鎶ュ簾鏁伴噺蹇呴』澶т簬绛変簬0"));
+      callback(new Error(`${label}蹇呴』澶т簬绛変簬0`));
       return;
     }
     callback();
@@ -425,9 +437,25 @@
 
   // 楠岃瘉瑙勫垯
   const reportFormRules = {
-    quantity: [{ required: true, validator: validateQuantity, trigger: "blur" }],
-    scrapQty: [{ validator: validateScrapQty, trigger: "blur" }],
+    quantity: [{ validator: validateQuantity, trigger: "blur" }],
+    reworkMinorQty: [{ validator: validateOptionalCount("杞诲井杩斿伐鏁伴噺"), trigger: "blur" }],
+    reworkMajorQty: [{ validator: validateOptionalCount("涓ラ噸杩斿伐鏁伴噺"), trigger: "blur" }],
+    scrapQty: [{ validator: validateOptionalCount("鎶ュ簾鏁伴噺"), trigger: "blur" }],
   };
+
+  // 鎶ュ伐璁℃暟鍚堣 = 鍚堟牸 + 杞诲井杩斿伐 + 涓ラ噸杩斿伐 + 鎶ュ簾
+  const countedTotal = computed(() => {
+    const total = [
+      reportForm.quantity,
+      reportForm.reworkMinorQty,
+      reportForm.reworkMajorQty,
+      reportForm.scrapQty,
+    ].reduce((sum, value) => {
+      const num = Number(value);
+      return sum + (isNaN(num) || num < 0 ? 0 : num);
+    }, 0);
+    return Math.round(total * 1000) / 1000;
+  });
 
   // 澶勭悊鐢熶骇鍚堟牸鏁伴噺杈撳叆锛岄檺鍒跺繀椤诲ぇ浜庣瓑浜�0
   const handleQuantityInput = value => {
@@ -445,6 +473,20 @@
       return;
     }
     reportForm.quantity = num;
+  };
+
+  // 杩斿伐鍒嗙被鏁伴噺杈撳叆锛氶潪璐熸暣鏁�
+  const handleNonNegativeIntInput = (field, value) => {
+    if (value === "" || value === null || value === undefined) {
+      reportForm[field] = null;
+      return;
+    }
+    const num = Number(value);
+    if (isNaN(num) || num < 0) {
+      reportForm[field] = null;
+      return;
+    }
+    reportForm[field] = Number.isInteger(num) ? num : Math.floor(num);
   };
 
   // 澶勭悊鎶ュ簾鏁伴噺
@@ -628,7 +670,8 @@
     reportForm.planQuantity = remainingQuantity;
     reportForm.quantity =
       row.quantity !== undefined && row.quantity !== null ? row.quantity : null;
-    reportForm.reportType = row.reportType ?? 0;
+    reportForm.reworkMinorQty = row.reworkMinorQty ?? null;
+    reportForm.reworkMajorQty = row.reworkMajorQty ?? null;
     reportForm.productProcessRouteItemId = row.productProcessRouteItemId;
     reportForm.workOrderId = row.id;
     reportForm.reportWork = row.reportWork;
@@ -681,49 +724,25 @@
         return;
       }
 
-      // 楠岃瘉鐢熶骇鍚堟牸鏁伴噺
-      if (
-        reportForm.quantity === null ||
-        reportForm.quantity === undefined ||
-        reportForm.quantity === ""
-      ) {
-        ElMessageBox.alert("璇疯緭鍏ョ敓浜у悎鏍兼暟閲�", "鎻愮ず", {
-          confirmButtonText: "纭畾",
-        });
+      // 鍒嗙被鏁伴噺鍙栧�硷細绌烘垨闈炴硶鎸�0澶勭悊
+      const toCount = value => {
+        const num = Number(value);
+        return isNaN(num) || num < 0 ? 0 : num;
+      };
+      const quantity = toCount(reportForm.quantity);
+      const reworkMinorQty = toCount(reportForm.reworkMinorQty);
+      const reworkMajorQty = toCount(reportForm.reworkMajorQty);
+      const scrapQty = toCount(reportForm.scrapQty);
+
+      // 瀵硅鏁扮殑闆朵欢鍋氬尯鍒嗭細鍥涚被鏁伴噺鍚堣蹇呴』澶т簬0
+      if (quantity + reworkMinorQty + reworkMajorQty + scrapQty <= 0) {
+        ElMessageBox.alert(
+          "璇锋寜鍚堟牸/杞诲井杩斿伐/涓ラ噸杩斿伐/鎶ュ簾鍒嗙被濉啓闆朵欢鏁伴噺锛屼笖鍚堣闇�澶т簬0",
+          "鎻愮ず",
+          { confirmButtonText: "纭畾" }
+        );
         return;
       }
-
-      const quantity = Number(reportForm.quantity);
-
-      if (isNaN(quantity) || quantity < 0) {
-        ElMessageBox.alert("鐢熶骇鍚堟牸鏁伴噺蹇呴』澶т簬绛変簬0", "鎻愮ず", {
-          confirmButtonText: "纭畾",
-        });
-        return;
-      }
-
-      // if (quantity > reportForm.planQuantity) {
-      //   ElMessageBox.alert("鏈鐢熶骇鏁伴噺涓嶈兘瓒呰繃寰呯敓浜ф暟閲�", "鎻愮ず", {
-      //     confirmButtonText: "纭畾",
-      //   });
-      //   return;
-      // }
-
-      // 楠岃瘉鎶ュ簾鏁伴噺
-      const scrapQty = Number(reportForm.scrapQty);
-      if (!isNaN(scrapQty) && scrapQty < 0) {
-        ElMessageBox.alert("鎶ュ簾鏁伴噺涓嶈兘灏忎簬0", "鎻愮ず", {
-          confirmButtonText: "纭畾",
-        });
-        return;
-      }
-
-      // if (!isNaN(scrapQty) && scrapQty > quantity) {
-      //   ElMessageBox.alert("鎶ュ簾鏁伴噺涓嶈兘澶т簬鏈鐢熶骇鏁伴噺", "鎻愮ず", {
-      //     confirmButtonText: "纭畾",
-      //   });
-      //   return;
-      // }
 
       const productionOperationParamList = params.value.map(param => ({
         ...param,
@@ -732,8 +751,9 @@
 
       const submitParams = {
         quantity: quantity,
-        scrapQty: isNaN(scrapQty) ? 0 : scrapQty,
-        reportType: reportForm.reportType,
+        reworkMinorQty: reworkMinorQty,
+        reworkMajorQty: reworkMajorQty,
+        scrapQty: scrapQty,
         userId: reportForm.userId,
         userName: reportForm.userName,
         productionOperationTaskId: reportForm.workOrderId,
@@ -913,6 +933,16 @@
     font-size: 12px;
     min-width: 30px;
   }
+  .counted-total {
+    font-size: 16px;
+    font-weight: 600;
+    color: #409eff;
+  }
+  .counted-total-tip {
+    margin-left: 8px;
+    font-size: 12px;
+    color: #909399;
+  }
 </style>
 
 <style  lang="scss">
diff --git a/src/views/qualityManagement/finalInspection/index.vue b/src/views/qualityManagement/finalInspection/index.vue
index 4a59fa4..0b0912e 100644
--- a/src/views/qualityManagement/finalInspection/index.vue
+++ b/src/views/qualityManagement/finalInspection/index.vue
@@ -44,6 +44,15 @@
                         clearable />
             </el-form-item>
           </el-col>
+          <el-col :span="4">
+            <el-form-item label="鎶ュ伐鍗曞彿"
+                          prop="reportNo">
+              <el-input v-model="searchForm.reportNo"
+                        style="width: 240px"
+                        placeholder="璇疯緭鍏ユ姤宸ュ崟鍙锋悳绱�"
+                        clearable />
+            </el-form-item>
+          </el-col>
           <!-- 鎸夐挳 -->
           <el-col :span="4">
             <el-form-item>
@@ -143,6 +152,7 @@
       productName: "",
       salesContractNo: "",
       workOrderNo: "",
+      reportNo: "",
       entryDate: undefined, // 褰曞叆鏃ユ湡
       entryDateStart: undefined,
       entryDateEnd: undefined,
@@ -169,6 +179,11 @@
       width: 120,
     },
     {
+      label: "鏉ユ簮鎶ュ伐鍗曞彿",
+      prop: "reportNo",
+      width: 140,
+    },
+    {
       label: "妫�楠屽憳",
       prop: "checkName",
     },
diff --git a/src/views/qualityManagement/nonconformingManagement/index.vue b/src/views/qualityManagement/nonconformingManagement/index.vue
index 7cc984e..c45083c 100644
--- a/src/views/qualityManagement/nonconformingManagement/index.vue
+++ b/src/views/qualityManagement/nonconformingManagement/index.vue
@@ -25,6 +25,16 @@
               :prefix-icon="Search"
           />
         </el-form-item>
+        <el-form-item label="鏉ユ簮鎶ュ伐鍗曞彿锛�">
+          <el-input
+              v-model="searchForm.reportNo"
+              style="width: 200px"
+              placeholder="璇疯緭鍏ユ姤宸ュ崟鍙锋悳绱�"
+              @change="handleQuery"
+              clearable
+              :prefix-icon="Search"
+          />
+        </el-form-item>
         <el-form-item label="妫�娴嬫棩鏈燂細">
           <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                           style="width: 300px"
@@ -107,6 +117,7 @@
     inspectType: "",
     inspectState: "",
     productName: "",
+    reportNo: "",
     entryDate: undefined, // 褰曞叆鏃ユ湡
     entryDateStart: undefined,
     entryDateEnd: undefined,
@@ -167,6 +178,11 @@
     },
   },
   {
+    label: "鏉ユ簮鎶ュ伐鍗曞彿",
+    prop: "reportNo",
+    width: 140,
+  },
+  {
     label: "妫�楠屽憳",
     prop: "checkName",
   },
diff --git a/src/views/qualityManagement/processInspection/index.vue b/src/views/qualityManagement/processInspection/index.vue
index 58d1a3a..2b54de7 100644
--- a/src/views/qualityManagement/processInspection/index.vue
+++ b/src/views/qualityManagement/processInspection/index.vue
@@ -26,6 +26,14 @@
                   @change="handleQuery"
                   clearable
                   :prefix-icon="Search" />
+        <span style="margin-left: 10px"
+              class="search_title">鎶ュ伐鍗曞彿锛�</span>
+        <el-input v-model="searchForm.reportNo"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ユ姤宸ュ崟鍙锋悳绱�"
+                  @change="handleQuery"
+                  clearable
+                  :prefix-icon="Search" />
         <el-button type="primary"
                    @click="handleQuery"
                    style="margin-left: 10px">鎼滅储</el-button>
@@ -118,6 +126,7 @@
       process: "",
       entryDate: undefined, // 褰曞叆鏃ユ湡
       workOrderNo: "",
+      reportNo: "",
       entryDateStart: undefined,
       entryDateEnd: undefined,
     },
@@ -138,6 +147,11 @@
       width: 120,
     },
     {
+      label: "鏉ユ簮鎶ュ伐鍗曞彿",
+      prop: "reportNo",
+      width: 140,
+    },
+    {
       label: "宸ュ簭",
       prop: "process",
       width: 230,

--
Gitblit v1.9.3