From 3a48d44d1eb5340c7caf2b010e1e9f081955d56c Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期三, 22 四月 2026 11:52:09 +0800
Subject: [PATCH] 添加历史迁移功能,支持未发货和已发货的销售台账导入

---
 src/views/salesManagement/salesLedger/index.vue |  158 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 154 insertions(+), 4 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 5f36cee..083d3db 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -109,6 +109,20 @@
           <el-button type="primary"
                      plain
                      @click="handleImport">瀵煎叆</el-button>
+          <el-dropdown @command="handleHistoryImportCommand">
+            <el-button type="primary"
+                       plain>
+              鍘嗗彶杩佺Щ<el-icon class="el-icon--right">
+                <ArrowDown />
+              </el-icon>
+            </el-button>
+            <template #dropdown>
+              <el-dropdown-menu>
+                <el-dropdown-item command="notShipped">鏈彂璐�</el-dropdown-item>
+                <el-dropdown-item command="shipped">宸插彂璐�</el-dropdown-item>
+              </el-dropdown-menu>
+            </template>
+          </el-dropdown>
           <el-button @click="handleOut">瀵煎嚭</el-button>
           <el-button type="danger"
                      plain
@@ -1675,6 +1689,46 @@
                title="閫夋嫨鍏ュ簱浜у搧"
                width="60%"
                :close-on-click-modal="false">
+      <div style="margin-bottom: 12px;">
+        <el-form>
+          <el-form-item required>
+            <template #label>
+              <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
+                <span>瀹℃壒浜洪�夋嫨锛�</span>
+                <el-button type="primary"
+                           size="small"
+                           @click="addStockApproverNode"
+                           icon="Plus">鏂板鑺傜偣</el-button>
+              </div>
+            </template>
+            <div class="approver-nodes-container">
+              <div v-for="(node, index) in stockApproverNodes"
+                   :key="node.id"
+                   class="approver-node-item">
+                <div class="approver-node-header">
+                  <span class="approver-node-label">瀹℃壒鑺傜偣 {{ index + 1 }}</span>
+                  <el-button v-if="stockApproverNodes.length > 1"
+                             type="danger"
+                             size="small"
+                             text
+                             @click="removeStockApproverNode(index)"
+                             icon="Delete">鍒犻櫎</el-button>
+                </div>
+                <el-select v-model="node.userId"
+                           placeholder="璇烽�夋嫨瀹℃壒浜�"
+                           filterable
+                           clearable
+                           style="width: 100%;">
+                  <el-option v-for="item in stockApproverOptions"
+                             :key="item.userId"
+                             :label="item.userName"
+                             :value="item.userId" />
+                </el-select>
+              </div>
+            </div>
+          </el-form-item>
+        </el-form>
+      </div>
       <el-table :data="stockProductList"
                 border
                 stripe
@@ -1815,6 +1869,15 @@
   const selectedStockProductIds = ref([]);
   const stockLoading = ref(false);
   const currentStockLedgerId = ref(null);
+  const stockApproverOptions = ref([]);
+  const stockApproverNodes = ref([{ id: 1, userId: null }]);
+  let nextStockApproverId = 2;
+  const addStockApproverNode = () => {
+    stockApproverNodes.value.push({ id: nextStockApproverId++, userId: null });
+  };
+  const removeStockApproverNode = index => {
+    stockApproverNodes.value.splice(index, 1);
+  };
 
   const ledgerQrDialogVisible = ref(false);
   const ledgerQrCompositeUrl = ref("");
@@ -2841,6 +2904,10 @@
       proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
     },
   });
+  const HISTORY_IMPORT_URL_MAP = {
+    notShipped: "/sales/ledger/salesHistory/notShippingImport",
+    shipped: "/sales/ledger/salesHistory/shippingImport",
+  };
 
   const changeDaterange = value => {
     if (value) {
@@ -2957,22 +3024,36 @@
     currentStockLedgerId.value = id;
     selectedStockProductIds.value = [];
     stockProductList.value = [];
+    stockApproverNodes.value = [{ id: 1, userId: null }];
+    nextStockApproverId = 2;
     stockDialogVisible.value = true;
     stockLoading.value = true;
 
     try {
+      const approverRes = await approveUserList({ approveType: 9 });
+      stockApproverOptions.value = Array.isArray(approverRes?.data)
+        ? approverRes.data.map(item => ({
+            userId: item.userId,
+            userName: item.userName,
+          }))
+        : [];
       const res = await productList({ salesLedgerId: id, type: 1 });
       stockProductList.value = [];
       stockProductList.value =
         res.data.filter(item => item.productStockStatus == 0 || item.productStockStatus == 1) || [];
     } catch (e) {
-      proxy?.$modal?.msgError?.("鑾峰彇浜у搧鍒楄〃澶辫触");
+      proxy?.$modal?.msgError?.("鑾峰彇浜у搧鎴栧鎵逛汉澶辫触");
     } finally {
       stockLoading.value = false;
     }
   };
 
   const submitStock = async () => {
+    const hasEmptyApprover = stockApproverNodes.value.some(node => !node.userId);
+    if (hasEmptyApprover) {
+      ElMessage.warning("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜�");
+      return;
+    }
     if (selectedStockProductIds.value.length === 0) {
       ElMessage.warning("璇烽�夋嫨鑷冲皯涓�涓骇鍝佽繘琛屽叆搴�");
       return;
@@ -2990,9 +3071,16 @@
 
     proxy?.$modal?.loading?.("姝e湪鍏ュ簱锛岃绋嶅��...");
     try {
+      const approveUserIds = stockApproverNodes.value.map(node => node.userId).join(",");
+      const approveUserName = stockApproverNodes.value
+        .map(node => stockApproverOptions.value.find(item => String(item.userId) === String(node.userId))?.userName)
+        .filter(Boolean)
+        .join(",");
       await salesStock({
         salesLedgerId: currentStockLedgerId.value,
         salesLedgerProducts: selectedStockProductIds.value,
+        approveUserIds,
+        approveUserName,
       });
       proxy?.$modal?.msgSuccess?.("鍏ュ簱鎴愬姛");
       stockDialogVisible.value = false;
@@ -3776,13 +3864,25 @@
     otherAmountAddDialogVisible.value = false;
     otherAmountAddId.value = null;
   };
-  // 瀵煎叆
-  const handleImport = () => {
-    importUpload.title = "瀵煎叆閿�鍞彴璐�";
+  const openImportDialog = (title, url) => {
+    importUpload.title = title;
+    importUpload.url = import.meta.env.VITE_APP_BASE_API + url;
     importUpload.open = true;
+    importUpload.isUploading = false;
     if (importUploadRef.value) {
       importUploadRef.value.clearFiles();
     }
+  };
+  // 瀵煎叆
+  const handleImport = () => {
+    openImportDialog("瀵煎叆閿�鍞彴璐�", "/sales/ledger/import");
+  };
+  // 鍘嗗彶杩佺Щ
+  const handleHistoryImportCommand = command => {
+    const url = HISTORY_IMPORT_URL_MAP[command];
+    if (!url) return;
+    const title = command === "shipped" ? "鍘嗗彶杩佺Щ-宸插彂璐�" : "鍘嗗彶杩佺Щ-鏈彂璐�";
+    openImportDialog(title, url);
   };
 
   // 涓嬭浇瀵煎叆妯℃澘
@@ -4793,4 +4893,54 @@
   .ledger-qr-save-btn {
     margin-bottom: 12px;
   }
+
+  .approver-nodes-container {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 16px;
+    padding: 16px;
+    background-color: #f8f9fa;
+    border-radius: 4px;
+    border: 1px solid #e4e7ed;
+  }
+
+  .approver-node-item {
+    flex: 0 0 calc(33.333% - 12px);
+    min-width: 200px;
+    padding: 12px;
+    background-color: #fff;
+    border-radius: 4px;
+    border: 1px solid #dcdfe6;
+    transition: all 0.3s;
+  }
+
+  .approver-node-item:hover {
+    border-color: #409eff;
+    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
+  }
+
+  .approver-node-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 8px;
+  }
+
+  .approver-node-label {
+    font-size: 13px;
+    font-weight: 500;
+    color: #606266;
+  }
+
+  @media (max-width: 1200px) {
+    .approver-node-item {
+      flex: 0 0 calc(50% - 8px);
+    }
+  }
+
+  @media (max-width: 768px) {
+    .approver-node-item {
+      flex: 0 0 100%;
+    }
+  }
 </style>

--
Gitblit v1.9.3