From b47614e17a20c17279eb2192329dfae559dc4a74 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期三, 23 九月 2026 15:20:03 +0800
Subject: [PATCH] feat: 销售台账品名/材质/规格型号手工录入与材质列,回退采购台账相关改动

---
 src/views/procurementManagement/procurementLedger/index.vue |  188 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 158 insertions(+), 30 deletions(-)

diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index fa55d87..8d9caa6 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -105,8 +105,6 @@
                                width="60" />
               <el-table-column label="浜у搧澶х被"
                                prop="productCategory" />
-              <el-table-column label="鏉愯川"
-                               prop="material" />
               <el-table-column label="瑙勬牸鍨嬪彿"
                                prop="specificationModel" />
               <el-table-column label="鍗曚綅"
@@ -414,8 +412,6 @@
                            width="60" />
           <el-table-column label="浜у搧澶х被"
                            prop="productCategory" />
-          <el-table-column label="鏉愯川"
-                           prop="material" />
           <el-table-column label="瑙勬牸鍨嬪彿"
                            prop="specificationModel" />
           <el-table-column label="鍗曚綅"
@@ -544,31 +540,34 @@
                ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="鍝佸悕锛�"
-                          prop="productCategory">
-              <el-input v-model="productForm.productCategory"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="鏉愯川锛�"
-                          prop="material">
-              <el-input v-model="productForm.material"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="浜у搧澶х被锛�"
+                          prop="productId">
+              <el-tree-select v-model="productForm.productId"
+                              placeholder="璇烽�夋嫨"
+                              clearable
+                              filterable
+                              check-strictly
+                              @change="getModels"
+                              :data="productOptions"
+                              :render-after-expand="false"
+                              style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
             <el-form-item label="瑙勬牸鍨嬪彿锛�"
-                          prop="specificationModel">
-              <el-input v-model="productForm.specificationModel"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+                          prop="productModelId">
+              <el-select v-model="productForm.productModelId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable
+                         @change="getProductModel">
+                <el-option v-for="item in modelOptions"
+                           :key="item.id"
+                           :label="item.model"
+                           :value="item.id" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -745,7 +744,9 @@
   const productData = ref([]);
   const selectedRows = ref([]);
   const productSelectedRows = ref([]);
+  const modelOptions = ref([]);
   const userList = ref([]);
+  const productOptions = ref([]);
   const salesContractList = ref([]);
   const supplierList = ref([]);
   const tableLoading = ref(false);
@@ -758,6 +759,7 @@
   const total = ref(0);
   const fileList = ref([]);
   import useUserStore from "@/store/modules/user";
+  import { modelList, productTreeList } from "@/api/basicData/product.js";
   import dayjs from "dayjs";
   import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 
@@ -952,8 +954,9 @@
   const currentId = ref("");
   const productFormData = reactive({
     productForm: {
+      productId: "",
       productCategory: "",
-      material: "",
+      productModelId: "",
       specificationModel: "",
       unit: "",
       quantity: "",
@@ -966,11 +969,8 @@
       isChecked: false,
     },
     productRules: {
-      productCategory: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-      material: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-      specificationModel: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-      ],
+      productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
       unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
       quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
       taxInclusiveUnitPrice: [
@@ -1457,7 +1457,7 @@
     dialogFormVisible.value = false;
   };
   // 鎵撳紑浜у搧寮规
-  const openProductForm = (type, row, index) => {
+  const openProductForm = async (type, row, index) => {
     // 缂栬緫鏃舵鏌ヤ骇鍝佸叆搴撳鏍哥姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
     if (type === "edit" && row && row.stockInApprovalStatus === "瀹屽叏鍏ュ簱") {
       proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑浜у搧涓嶈兘缂栬緫");
@@ -1470,6 +1470,12 @@
     proxy.resetForm("productFormRef");
     productFormVisible.value = true;
 
+    // 鍏堣幏鍙栦骇鍝侀�夐」锛岀‘淇濇暟鎹姞杞藉畬鎴�
+    await getProductOptions();
+
+    // 绛夊緟 DOM 鏇存柊
+    await nextTick();
+
     if (type === "add") {
       productForm.value.isChecked = false;
     }
@@ -1477,8 +1483,130 @@
     if (type === "edit") {
       // 澶嶅埗琛屾暟鎹�
       productForm.value = { ...row };
+
+      // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
+      // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
+      if (!productForm.value.productId && productForm.value.productCategory) {
+        // 鏍规嵁 productCategory 鏌ユ壘 productId
+        const findProductIdByCategory = (nodes, categoryName) => {
+          for (let i = 0; i < nodes.length; i++) {
+            if (nodes[i].label === categoryName) {
+              return nodes[i].value;
+            }
+            if (nodes[i].children && nodes[i].children.length > 0) {
+              const found = findProductIdByCategory(
+                nodes[i].children,
+                categoryName
+              );
+              if (found) return found;
+            }
+          }
+          return null;
+        };
+
+        const productId = findProductIdByCategory(
+          productOptions.value,
+          productForm.value.productCategory
+        );
+        if (productId) {
+          productForm.value.productId = productId;
+          // 鑾峰彇鍨嬪彿鍒楄〃骞剁瓑寰呭畬鎴�
+          const modelRes = await modelList({ id: productId });
+          modelOptions.value = modelRes;
+
+          // 绛夊緟 DOM 鏇存柊
+          await nextTick();
+
+          // 鏍规嵁 specificationModel 鏌ユ壘 productModelId
+          if (
+            productForm.value.specificationModel &&
+            modelOptions.value.length > 0
+          ) {
+            const modelItem = modelOptions.value.find(
+              item => item.model === productForm.value.specificationModel
+            );
+            if (modelItem) {
+              productForm.value.productModelId = modelItem.id;
+              // 璁剧疆瑙勬牸鍨嬪彿鍜屽崟浣�
+              getProductModel(modelItem.id);
+            }
+          }
+        }
+      } else if (productForm.value.productId) {
+        // 濡傛灉鏈� productId锛屾甯稿姞杞藉瀷鍙峰垪琛�
+        await getModels(productForm.value.productId);
+
+        // 绛夊緟 DOM 鏇存柊
+        await nextTick();
+
+        if (productForm.value.productModelId) {
+          getProductModel(productForm.value.productModelId);
+        }
+      }
+
+      // 鏈�鍚庡啀绛夊緟涓�娆� DOM 鏇存柊锛岀‘淇濇墍鏈夋暟鎹兘宸茶缃�
+      await nextTick();
     }
   };
+  const getProductOptions = () => {
+    return productTreeList().then(res => {
+      productOptions.value = convertIdToValue(res);
+      return res;
+    });
+  };
+  const getModels = value => {
+    if (value) {
+      productForm.value.productCategory =
+        findNodeById(productOptions.value, value) || "";
+      return modelList({ id: value }).then(res => {
+        modelOptions.value = res;
+        return res;
+      });
+    } else {
+      productForm.value.productCategory = "";
+      modelOptions.value = [];
+      return Promise.resolve([]);
+    }
+  };
+  const getProductModel = value => {
+    const index = modelOptions.value.findIndex(item => item.id === value);
+    if (index !== -1) {
+      productForm.value.specificationModel = modelOptions.value[index].model;
+      productForm.value.unit = modelOptions.value[index].unit;
+    } else {
+      productForm.value.specificationModel = null;
+      productForm.value.unit = null;
+    }
+  };
+  const findNodeById = (nodes, productId) => {
+    for (let i = 0; i < nodes.length; i++) {
+      if (nodes[i].value === productId) {
+        return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
+      }
+      if (nodes[i].children && nodes[i].children.length > 0) {
+        const foundNode = findNodeById(nodes[i].children, productId);
+        if (foundNode) {
+          return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
+        }
+      }
+    }
+    return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+  };
+
+  function convertIdToValue(data) {
+    return data.map(item => {
+      const { id, children, ...rest } = item;
+      const newItem = {
+        ...rest,
+        value: id, // 灏� id 鏀逛负 value
+      };
+      if (children && children.length > 0) {
+        newItem.children = convertIdToValue(children);
+      }
+
+      return newItem;
+    });
+  }
 
   // 鎻愪氦浜у搧琛ㄥ崟
   const submitProduct = () => {

--
Gitblit v1.9.3