From 06d627bc28e77e1a314d8e35914512d63dbab1bd Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 20 三月 2026 17:14:48 +0800
Subject: [PATCH] fix: 点击取消时将表单子元素全部销毁

---
 src/views/productionPlan/productionPlan/index.vue |  310 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 235 insertions(+), 75 deletions(-)

diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index 7214e1a..30e1a3c 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -3,36 +3,9 @@
     <div class="search_form">
       <el-form :model="searchForm"
                :inline="true">
-        <el-form-item label="瀹㈡埛鍚嶇О:">
-          <el-input v-model="searchForm.customerName"
-                    placeholder="璇疯緭鍏�"
-                    clearable
-                    style="width: 160px;"
-                    @keyup.enter="handleQuery" />
-        </el-form-item>
+        <!-- 绠�鍖栫増鎼滅储鏉′欢 -->
         <el-form-item label="浜у搧鍚嶇О:">
           <el-input v-model="searchForm.productName"
-                    placeholder="璇疯緭鍏�"
-                    clearable
-                    style="width: 160px;"
-                    @keyup.enter="handleQuery" />
-        </el-form-item>
-        <el-form-item label="浜у搧瑙勬牸:">
-          <el-input v-model="searchForm.specification"
-                    placeholder="璇疯緭鍏�"
-                    clearable
-                    style="width: 160px;"
-                    @keyup.enter="handleQuery" />
-        </el-form-item>
-        <el-form-item label="鐗╂枡缂栫爜:">
-          <el-input v-model="searchForm.materialCode"
-                    placeholder="璇疯緭鍏�"
-                    clearable
-                    style="width: 160px;"
-                    @keyup.enter="handleQuery" />
-        </el-form-item>
-        <el-form-item label="鐢宠鍗曠紪鍙�:">
-          <el-input v-model="searchForm.applyNo"
                     placeholder="璇疯緭鍏�"
                     clearable
                     style="width: 160px;"
@@ -48,6 +21,51 @@
                           style="width: 240px;"
                           @change="handleQuery" />
         </el-form-item>
+        <el-form-item label="涓嬪彂鐘舵��:">
+          <el-select v-model="searchForm.status"
+                     placeholder="璇烽�夋嫨鐘舵��"
+                     clearable
+                     filterable
+                     style="width: 100px">
+            <el-option label="寰呬笅鍙�"
+                       value="0" />
+            <el-option label="閮ㄥ垎涓嬪彂"
+                       value="1" />
+            <el-option label="宸蹭笅鍙�"
+                       value="2" />
+          </el-select>
+        </el-form-item>
+        <!-- 灞曞紑鐗堟悳绱㈡潯浠� -->
+        <template v-if="searchFormExpanded">
+          <el-form-item label="瀹㈡埛鍚嶇О:">
+            <el-input v-model="searchForm.customerName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      style="width: 160px;"
+                      @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="浜у搧瑙勬牸:">
+            <el-input v-model="searchForm.model"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      style="width: 160px;"
+                      @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐗╂枡缂栫爜:">
+            <el-input v-model="searchForm.materialCode"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      style="width: 160px;"
+                      @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐢宠鍗曠紪鍙�:">
+            <el-input v-model="searchForm.applyNo"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      style="width: 160px;"
+                      @keyup.enter="handleQuery" />
+          </el-form-item>
+        </template>
         <el-form-item>
           <el-button type="primary"
                      @click="handleQuery">鎼滅储</el-button>
@@ -68,6 +86,16 @@
       <div>
       </div>
     </div>
+    <div class="search-header">
+      <el-button type="text"
+                 @click="toggleSearchForm">
+        <el-icon>
+          <ArrowUp v-if="searchFormExpanded" />
+          <ArrowDown v-else />
+        </el-icon>
+        {{ searchFormExpanded ? '鏀惰捣鎼滅储鏉′欢' : '灞曞紑鎼滅储鏉′欢' }}
+      </el-button>
+    </div>
     <div class="table_list">
       <PIMTable rowKey="id"
                 :column="tableColumn"
@@ -83,6 +111,7 @@
     </div>
     <!-- 鍚堝苟涓嬪彂寮圭獥 -->
     <el-dialog v-model="isShowNewModal"
+               destroy-on-close
                title="鍚堝苟涓嬪彂"
                width="600px">
       <el-form :model="mergeForm"
@@ -102,7 +131,7 @@
         <el-row :gutter="20">
           <el-col :span="10">
             <el-form-item label="浜у搧瑙勬牸">
-              <div class="info-display">{{ mergeForm.specification || '-' }}</div>
+              <div class="info-display">{{ mergeForm.model || '-' }}</div>
             </el-form-item>
           </el-col>
           <el-col :span="10">
@@ -116,6 +145,21 @@
                           type="date"
                           value-format="YYYY-MM-DD"
                           style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="寮哄害"
+                      v-if="mergeForm.productName === '鐮屽潡'">
+          <div v-if="strengthError"
+               class="strength-error"
+               style="color: red; margin-bottom: 8px;">{{ strengthError }}</div>
+          <el-select v-model="mergeForm.strength"
+                     placeholder="璇烽�夋嫨寮哄害"
+                     style="width: 100%"
+                     required>
+            <el-option v-for="item in block_strength"
+                       :key="item.id"
+                       :label="item.label"
+                       :value="item.id" />
+          </el-select>
         </el-form-item>
         <el-form-item label="鐢熶骇鏂规暟">
           <el-input-number v-model="mergeForm.totalAssignedQuantity"
@@ -139,6 +183,7 @@
     </el-dialog>
     <!-- 杩借釜杩涘害寮圭獥 -->
     <el-dialog v-model="showTrackProgressDialog"
+               destroy-on-close
                :title="`杩借釜杩涘害 - ${trackProgressForm.materialCode || ''}`"
                width="600px">
       <el-form :model="trackProgressForm"
@@ -217,6 +262,7 @@
                   @close="handleImportClose" />
     <!-- 鏂板/缂栬緫寮圭獥 -->
     <el-dialog v-model="dialogVisible"
+               destroy-on-close
                :title="operationType === 'add' ? '鏂板鐢熶骇璁″垝' : '缂栬緫鐢熶骇璁″垝'"
                width="600px">
       <el-form ref="formRef"
@@ -251,9 +297,9 @@
                      filterable
                      placeholder="璇烽�夋嫨">
             <el-option v-for="item in specificationOptions"
-                       :key="item.skuId"
-                       :label="item.specification"
-                       :value="item.skuId" />
+                       :key="item.id"
+                       :label="item.model"
+                       :value="item.id" />
           </el-select>
         </el-form-item>
         <el-form-item label="鍧楁暟"
@@ -301,14 +347,15 @@
                           placeholder="璇烽�夋嫨璁″垝缁撴潫鏃ユ湡" />
         </el-form-item>
         <el-form-item label="寮哄害"
-                      prop="strength">
+                      prop="strength"
+                      v-if="form.productName === '鐮屽潡'">
           <el-select v-model="form.strength"
                      placeholder="璇烽�夋嫨寮哄害"
                      style="width: 100%">
-            <el-option label="A3.5"
-                       value="A3.5" />
-            <el-option label="A5.0"
-                       value="A5.0" />
+            <el-option v-for="item in block_strength"
+                       :key="item.id"
+                       :label="item.label"
+                       :value="item.id" />
           </el-select>
         </el-form-item>
         <el-form-item label="澶囨敞 1"
@@ -334,11 +381,13 @@
 </template>
 
 <script setup>
-  import { onMounted, ref, reactive, getCurrentInstance } from "vue";
+  import { onMounted, ref, reactive, getCurrentInstance, toRefs } from "vue";
   import { ElMessage } from "element-plus";
+  import { ArrowUp, ArrowDown } from "@element-plus/icons-vue";
   import dayjs from "dayjs";
   import ImportDialog from "@/components/Dialog/ImportDialog.vue";
   import { getToken } from "@/utils/auth";
+  import { useDict } from "@/utils/dict";
   import {
     productionPlanListPage,
     loadProdData,
@@ -376,7 +425,6 @@
       label: "鐢宠鍗曠紪鍙�",
       prop: "applyNo",
       width: "150px",
-      className: "code-cell",
     },
     {
       label: "瀹㈡埛鍚嶇О",
@@ -389,16 +437,17 @@
       width: "200px",
       dataType: "tag",
       formatType: params => {
-        const typeMap = {
-          鏉挎潗: "primary",
-          鐮屽潡: "warning",
-        };
-        return typeMap[params] || "info";
+        // const typeMap = {
+        //   鏉挎潗: "primary",
+        //   鐮屽潡: "warning",
+        // };
+        // return typeMap[params] || "info";
+        return "primary";
       },
     },
     {
       label: "浜у搧瑙勬牸",
-      prop: "specification",
+      prop: "model",
       width: "150px",
       className: "spec-cell",
     },
@@ -406,12 +455,10 @@
       label: "鐗╂枡缂栫爜",
       prop: "materialCode",
       width: "150px",
-      className: "code-cell",
     },
     {
       label: "鍧楁暟",
       prop: "quantity",
-      className: "quantity-cell",
       formatData: cell => (cell ? `${cell}鍧梎 : ""),
     },
     {
@@ -492,14 +539,21 @@
     {
       label: "寮哄害",
       prop: "strength",
+      formatData: cell => {
+        if (!cell) return "";
+        const strengthItem = block_strength.value.find(item => item.id === cell);
+        return strengthItem ? strengthItem.label : cell;
+      },
     },
 
     {
       label: "澶囨敞 1",
+      width: "150px",
       prop: "remarkOne",
     },
     {
       label: "澶囨敞 2",
+      width: "150px",
       prop: "remarkTwo",
     },
 
@@ -546,16 +600,18 @@
           clickFun: row => {
             // 鍗曠嫭涓嬪彂鎿嶄綔
             // 璁剧疆琛ㄥ崟鏁版嵁
+            strengthError.value = "";
             mergeForm.ids = [row.id];
             mergeForm.materialCode = row.materialCode;
             mergeForm.productName = row.productName || "";
-            mergeForm.specification = row.specification || "";
+            mergeForm.model = row.model || "";
             mergeForm.length = row.length || 0;
             mergeForm.width = row.width || 0;
             mergeForm.height = row.height || 0;
             mergeForm.totalAssignedQuantity =
               (Number(row.volume) - Number(row.assignedQuantity)).toFixed(4) || 0;
             mergeForm.planCompleteTime = row.planCompleteTime || "";
+            mergeForm.strength = row.strength || "";
             sumAssignedQuantity.value = mergeForm.totalAssignedQuantity;
             // 鎵撳紑寮圭獥
             isShowNewModal.value = true;
@@ -591,12 +647,13 @@
   const mergeForm = reactive({
     materialCode: "",
     productName: "",
-    specification: "",
+    model: "",
     length: 0,
     width: 0,
     height: 0,
     totalAssignedQuantity: 0,
     planCompleteTime: "",
+    strength: "",
   });
 
   // 杩借釜杩涘害寮圭獥鎺у埗
@@ -625,6 +682,8 @@
   const productOptions = ref([]);
   const specificationOptions = ref([]);
   const formRef = ref(null);
+  // 鑾峰彇寮哄害瀛楀吀
+  const { block_strength } = useDict("block_strength");
   const form = reactive({
     id: undefined,
     applyNo: "",
@@ -632,7 +691,7 @@
     productMaterialId: undefined,
     productMaterialSkuId: undefined,
     productName: "",
-    specification: "",
+    model: "",
     materialCode: "",
     quantity: 0,
     volume: 0,
@@ -641,6 +700,7 @@
     height: 0,
     startDate: "",
     endDate: "",
+    status: "",
     strength: "",
     remarkOne: "",
     remarkTwo: "",
@@ -656,6 +716,19 @@
     volume: [{ required: true, message: "璇疯緭鍏ユ柟鏁�", trigger: "blur" }],
     productMaterialId: [
       { required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" },
+    ],
+    strength: [
+      {
+        validator: (rule, value, callback) => {
+          if (form.productName === "鐮屽潡" && !value) {
+            callback(new Error("鐮屽潡浜у搧鐨勫己搴︿负蹇呭~椤�"));
+          } else {
+            callback();
+          }
+        },
+        trigger: ["blur", "change"],
+        required: false,
+      },
     ],
   });
 
@@ -699,7 +772,7 @@
       if (item.materialList && item.materialList.length > 0) {
         newItem.children = item.materialList.map(material => ({
           value: material.id, // 浣跨敤material鐨刬d浣滀负value
-          label: material.materialName, // 浣跨敤materialName浣滀负label
+          label: material.productName, // 浣跨敤materialName浣滀负label
         }));
       }
 
@@ -709,31 +782,49 @@
 
   const handleProductChange = value => {
     form.productMaterialSkuId = undefined;
+    // 鏌ユ壘閫変腑鐨勪骇鍝佸悕绉�
+    const findProductName = (options, value) => {
+      for (const option of options) {
+        if (option.value === value) {
+          return option.label;
+        }
+        if (option.children) {
+          const found = findProductName(option.children, value);
+          if (found) {
+            return found;
+          }
+        }
+      }
+      return "";
+    };
+    form.productName = findProductName(productOptions.value, value);
+    // 瑙﹀彂寮哄害瀛楁楠岃瘉
+    if (formRef.value) {
+      formRef.value.validateField("strength");
+    }
     fetchSpecificationOptions(value);
   };
 
-  const fetchSpecificationOptions = materialId => {
+  const fetchSpecificationOptions = productId => {
     specificationOptions.value = [];
-    if (materialId) {
-      modelListPage({ materialId: materialId, size: -1, current: -1 }).then(
-        res => {
-          specificationOptions.value = res.data.records;
-        }
-      );
+    if (productId) {
+      modelListPage({ productId: productId, size: -1, current: -1 }).then(res => {
+        specificationOptions.value = res.data.records;
+      });
     }
   };
 
   const handleChangeSpecification = value => {
     form.materialCode = undefined;
     const selectedModel = specificationOptions.value.find(
-      item => item.skuId === value
+      item => item.id === value
     );
     if (selectedModel) {
       form.materialCode = selectedModel.materialCode;
       // 瑙f瀽瑙勬牸瀛楃涓茶幏鍙栭暱瀹介珮
-      const specification = selectedModel.specification;
-      if (specification) {
-        const dimensions = specification.match(/^(\d+)\*(\d+)\*(\d+)$/);
+      const model = selectedModel.model;
+      if (model) {
+        const dimensions = model.match(/^(\d+)\*(\d+)\*(\d+)$/);
         if (dimensions && dimensions.length === 4) {
           form.length = parseInt(dimensions[1]);
           form.width = parseInt(dimensions[2]);
@@ -818,13 +909,19 @@
     searchForm: {
       customerName: "",
       productName: "",
-      specification: "",
+      model: "",
       materialCode: "",
       applyNo: "",
       dateRange: [],
     },
+    searchFormExpanded: false,
   });
-  const { searchForm } = toRefs(data);
+  const { searchForm, searchFormExpanded } = toRefs(data);
+
+  // 鍒囨崲鎼滅储琛ㄥ崟灞曞紑/鏀惰捣鐘舵��
+  const toggleSearchForm = () => {
+    data.searchFormExpanded = !data.searchFormExpanded;
+  };
 
   // 鏌ヨ鍒楄〃
   /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -838,7 +935,7 @@
     Object.assign(searchForm.value, {
       customerName: "",
       productName: "",
-      specification: "",
+      model: "",
       materialCode: "",
       applyNo: "",
       dateRange: [],
@@ -933,6 +1030,9 @@
       .catch(() => {});
   };
   const sumAssignedQuantity = ref(0);
+  // 鍝嶅簲寮忔暟鎹�
+  const strengthError = ref("");
+
   // 澶勭悊鍚堝苟涓嬪彂鎸夐挳鐐瑰嚮
   const handleMerge = () => {
     if (selectedRows.value.length === 0) {
@@ -940,6 +1040,26 @@
       return;
     }
     console.log(selectedRows.value);
+    // 妫�鏌ュ己搴︿竴鑷存��
+    const firstRow = selectedRows.value[0];
+    const productName = firstRow.productName || "";
+    let strengthConsistent = true;
+    let firstStrength = firstRow.strength || "";
+    strengthError.value = "";
+
+    if (productName === "鐮屽潡") {
+      for (const row of selectedRows.value) {
+        if (row.strength !== firstStrength) {
+          strengthConsistent = false;
+          break;
+        }
+      }
+
+      if (!strengthConsistent) {
+        strengthError.value = "閫夋嫨鐨勭爩鍧楀己搴︿笉涓�鑷达紝璇烽噸鏂伴�夋嫨";
+      }
+    }
+
     // 璁$畻鎬诲埗閫犳暟閲�
     const totalAssignedQuantity = selectedRows.value.reduce((sum, row) => {
       return (
@@ -952,15 +1072,15 @@
     sumAssignedQuantity.value = totalAssignedQuantity;
     console.log(totalAssignedQuantity);
     // 璁剧疆琛ㄥ崟鏁版嵁
-    const firstRow = selectedRows.value[0];
     mergeForm.materialCode = selectedserialNo.value;
-    mergeForm.productName = firstRow.productName || "";
-    mergeForm.specification = firstRow.specification || "";
+    mergeForm.productName = productName;
+    mergeForm.model = firstRow.model || "";
     mergeForm.length = firstRow.length || 0;
     mergeForm.width = firstRow.width || 0;
     mergeForm.height = firstRow.height || 0;
     mergeForm.totalAssignedQuantity = totalAssignedQuantity;
     mergeForm.planCompleteTime = firstRow.planCompleteTime || "";
+    mergeForm.strength = firstStrength;
     mergeForm.ids = selectedRows.value.map(row => row.id);
 
     // 鎵撳紑寮圭獥
@@ -971,6 +1091,11 @@
   const handleMergeSubmit = () => {
     if (mergeForm.totalAssignedQuantity === 0) {
       ElMessage.warning("璇疯緭鍏ョ敓浜ф柟鏁�");
+      return;
+    }
+    // 楠岃瘉鐮屽潡浜у搧鐨勫己搴�
+    if (mergeForm.productName === "鐮屽潡" && !mergeForm.strength) {
+      ElMessage.error("鐮屽潡浜у搧鐨勫己搴︿负蹇呭~椤�");
       return;
     }
     console.log(sumAssignedQuantity.value, "sumAssignedQuantity");
@@ -986,7 +1111,14 @@
     }
 
     console.log(mergeForm, "mergeForm");
-    productionPlanCombine(mergeForm)
+    const strengthItem = block_strength.value.find(
+      item => item.id === mergeForm.strength
+    );
+    const payload = {
+      ...mergeForm,
+      strength: strengthItem ? strengthItem.label : mergeForm.strength,
+    };
+    productionPlanCombine(payload)
       .then(res => {
         if (res.code === 200) {
           ElMessage.success("涓嬪彂鎴愬姛");
@@ -1091,7 +1223,7 @@
       productName: "",
       productMaterialId: undefined,
       productMaterialSkuId: undefined,
-      specification: "",
+      model: "",
       materialCode: "",
       quantity: 0,
       volume: 0,
@@ -1118,7 +1250,7 @@
       productName: row.productName || "",
       productMaterialId: row.productMaterialId || undefined,
       productMaterialSkuId: row.productMaterialSkuId || undefined,
-      specification: row.specification || "",
+      model: row.model || "",
       materialCode: row.materialCode || "",
       quantity: row.quantity || 0,
       volume: row.volume || 0,
@@ -1217,10 +1349,7 @@
   }
 
   .search_form {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 24px;
+    // margin-bottom: 24px;
     padding: 20px;
     background-color: #ffffff;
     border-radius: 6px;
@@ -1232,6 +1361,36 @@
     }
   }
 
+  .search-header {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    // margin-bottom: 5px;
+    // padding-bottom: 5px;
+    position: relative;
+    bottom: 35px;
+    // border-bottom: 1px solid #ebeef5;
+  }
+
+  .search-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #303133;
+  }
+
+  .search-header .el-button {
+    color: #606266;
+    transition: all 0.3s ease;
+  }
+
+  .search-header .el-button:hover {
+    color: #409eff;
+  }
+
+  .search-header .el-icon {
+    margin-right: 4px;
+  }
+
   .table_list {
     // margin-bottom: 24px;
     background-color: #ffffff;
@@ -1239,6 +1398,7 @@
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
     overflow: hidden;
     height: calc(100vh - 250px);
+    margin-top: 0px !important;
   }
 
   :deep(.el-table) {

--
Gitblit v1.9.3