From dc3fc550fe292043cc452dc9aeb0c8a1eeab3b30 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期四, 24 九月 2026 16:54:39 +0800
Subject: [PATCH] feat: 新增多模块导入导出入口

---
 src/views/inventoryManagement/dispatchLog/Record.vue        |   86 +++++++++
 src/views/basicData/product/index.vue                       |   17 +
 src/views/customerService/expiryAfterSales/index.vue        |   96 ++++++++++
 src/views/inventoryManagement/stockManagement/ImportOut.vue |   97 ++++++++++
 src/views/customerService/feedbackRegistration/index.vue    |  109 ++++++++++++
 src/views/inventoryManagement/stockManagement/Record.vue    |   19 ++
 src/views/customerService/afterSalesHandling/index.vue      |    3 
 src/views/inventoryManagement/receiptManagement/Record.vue  |   90 ++++++++++
 8 files changed, 513 insertions(+), 4 deletions(-)

diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index bb1dccf..deb3162 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -81,6 +81,10 @@
                    plain>
           鍒犻櫎
         </el-button>
+        <el-button @click="handleExportModels"
+                   style="margin-left: 10px">
+          瀵煎嚭
+        </el-button>
       </div>
       <PIMTable rowKey="id"
                 :column="tableColumn"
@@ -573,6 +577,19 @@
         proxy.$modal.msg("宸插彇娑�");
       });
   };
+  // 瀵煎嚭褰撳墠浜у搧鐨勮鏍煎瀷鍙�
+  const handleExportModels = () => {
+    if (!currentId.value) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨浜у搧");
+      return;
+    }
+    proxy.download(
+      "/basic/product/exportModel",
+      { id: currentId.value },
+      "浜у搧瑙勬牸鍨嬪彿.xlsx"
+    );
+  };
+
   const debounce = (fn, delay = 300) => {
     let timer;
     return (...args) => {
diff --git a/src/views/customerService/afterSalesHandling/index.vue b/src/views/customerService/afterSalesHandling/index.vue
index a3adcc9..c546e9f 100644
--- a/src/views/customerService/afterSalesHandling/index.vue
+++ b/src/views/customerService/afterSalesHandling/index.vue
@@ -89,6 +89,9 @@
         </el-row>
       </el-form>
     </div>
+		<div class="table_header" style="display: flex; justify-content: flex-end; padding-bottom: 10px;">
+			<el-button @click="handleOut">瀵煎嚭</el-button>
+		</div>
 		<div class="table_list">
 			<PIMTable
 				rowKey="id"
diff --git a/src/views/customerService/expiryAfterSales/index.vue b/src/views/customerService/expiryAfterSales/index.vue
index 9966785..1316593 100644
--- a/src/views/customerService/expiryAfterSales/index.vue
+++ b/src/views/customerService/expiryAfterSales/index.vue
@@ -34,10 +34,13 @@
 				>閲嶇疆</el-button
 				>
 			</div>
-			<div class="table_actions">
-				<el-button type="primary" @click="openForm('add')">鏂板</el-button>
-				<el-button type="danger" @click="handleDelete">鍒犻櫎</el-button>
-			</div>
+		</div>
+
+		<div class="table_header" style="display: flex; justify-content: flex-end; align-items: center; gap: 10px; padding-bottom: 10px;">
+			<el-button type="primary" @click="openForm('add')">鏂板</el-button>
+			<el-button type="info" plain icon="Upload" @click="handleImport">瀵煎叆</el-button>
+			<el-button @click="handleExport">瀵煎嚭</el-button>
+			<el-button type="danger" @click="handleDelete">鍒犻櫎</el-button>
 		</div>
 
 		<div class="table_list">
@@ -65,6 +68,28 @@
 			</PIMTable>
 		</div>
 		<form-dia ref="formDia" @close="handleQuery"></form-dia>
+		<!-- 涓存湡鍞悗瀵煎叆瀵硅瘽妗� -->
+		<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
+			<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url"
+				:disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess"
+				:on-error="handleFileError" :auto-upload="false" drag>
+				<el-icon class="el-icon--upload"><upload-filled /></el-icon>
+				<div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+				<template #tip>
+					<div class="el-upload__tip text-center">
+						<span>浠呭厑璁稿鍏� xls銆亁lsx 鏍煎紡鏂囦欢銆�</span>
+						<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
+							@click="importTemplate">涓嬭浇妯℃澘</el-link>
+					</div>
+				</template>
+			</el-upload>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+					<el-button @click="upload.open = false">鍙� 娑�</el-button>
+				</div>
+			</template>
+		</el-dialog>
 	</div>
 </template>
 
@@ -75,6 +100,7 @@
 import {ElMessageBox} from "element-plus";
 import {expiryAfterSalesDelete, expiryAfterSalesListPage} from "@/api/customerService/index.js";
 import useUserStore from "@/store/modules/user.js";
+import { getToken } from "@/utils/auth.js";
 const { proxy } = getCurrentInstance();
 const userStore = useUserStore()
 
@@ -263,6 +289,68 @@
 		});
 };
 
+// 瀵煎嚭
+const handleExport = () => {
+	ElMessageBox.confirm("鏄惁纭瀵煎嚭鍏ㄩ儴涓存湡鍞悗鏁版嵁锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	}).then(() => {
+		proxy.download("/afterSalesNearExpiryService/export", {}, "涓存湡鍞悗绠$悊.xlsx");
+	}).catch(() => {
+		proxy.$modal.msg("宸插彇娑�");
+	});
+};
+
+// 瀵煎叆
+const uploadRef = ref();
+const upload = reactive({
+	open: false,
+	title: "",
+	isUploading: false,
+	headers: { Authorization: "Bearer " + getToken() },
+	url: import.meta.env.VITE_APP_BASE_API + "/afterSalesNearExpiryService/import",
+});
+const handleImport = () => {
+	upload.title = "涓存湡鍞悗瀵煎叆";
+	upload.open = true;
+};
+const importTemplate = () => {
+	proxy.download("/afterSalesNearExpiryService/importTemplate", {}, "涓存湡鍞悗绠$悊瀵煎叆妯℃澘.xlsx");
+};
+const submitFileForm = () => {
+	upload.isUploading = true;
+	uploadRef.value.submit();
+};
+const handleFileUploadProgress = () => {
+	upload.isUploading = true;
+};
+const handleFileSuccess = (response) => {
+	upload.isUploading = false;
+	upload.open = false;
+	uploadRef.value.clearFiles();
+	if (response.code === 200) {
+		const failCount = response.failCount || 0;
+		if (failCount > 0) {
+			const errors = Array.isArray(response.errors) ? response.errors : [];
+			proxy.$modal.alert(`${response.msg}\n\n${errors.join("\n")}`, "瀵煎叆缁撴灉", {
+				confirmButtonText: "鐭ラ亾浜�",
+			}).then(() => {
+				getList();
+			});
+		} else {
+			proxy.$modal.msgSuccess(response.msg || "瀵煎叆鎴愬姛");
+			getList();
+		}
+	} else {
+		proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+	}
+};
+const handleFileError = () => {
+	upload.isUploading = false;
+	proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+};
+
 onMounted(() => {
 	getList();
 });
diff --git a/src/views/customerService/feedbackRegistration/index.vue b/src/views/customerService/feedbackRegistration/index.vue
index bcbb326..60aed6d 100644
--- a/src/views/customerService/feedbackRegistration/index.vue
+++ b/src/views/customerService/feedbackRegistration/index.vue
@@ -95,6 +95,10 @@
         </div>
         <div>
           <el-button @click="handleOut">瀵煎嚭</el-button>
+          <el-button type="info"
+                     plain
+                     icon="Upload"
+                     @click="handleImport">瀵煎叆</el-button>
           <el-button type="danger"
                      plain
                      @click="handleDelete">鍒犻櫎</el-button>
@@ -113,6 +117,42 @@
     <form-dia ref="formDia"
               @close="handleQuery"></form-dia>
     <view-dia ref="viewDia"></view-dia>
+    <!-- 鍙嶉鐧昏瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title"
+               v-model="upload.open"
+               width="400px"
+               append-to-body>
+      <el-upload ref="uploadRef"
+                 :limit="1"
+                 accept=".xlsx, .xls"
+                 :headers="upload.headers"
+                 :action="upload.url"
+                 :disabled="upload.isUploading"
+                 :on-progress="handleFileUploadProgress"
+                 :on-success="handleFileSuccess"
+                 :on-error="handleFileError"
+                 :auto-upload="false"
+                 drag>
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏� xls銆亁lsx 鏍煎紡鏂囦欢銆�</span>
+            <el-link type="primary"
+                     :underline="false"
+                     style="font-size: 12px; vertical-align: baseline"
+                     @click="importTemplate">涓嬭浇妯℃澘</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -135,6 +175,7 @@
     getSalesLedgerDetail,
   } from "@/api/customerService/index.js";
   import useUserStore from "@/store/modules/user.js";
+  import { getToken } from "@/utils/auth.js";
   const { proxy } = getCurrentInstance();
   const userStore = useUserStore();
   import { Document, FolderOpened, UserFilled } from "@element-plus/icons-vue";
@@ -328,6 +369,16 @@
   };
   const formDia = ref();
   const viewDia = ref();
+  const uploadRef = ref();
+
+  // 瀵煎叆寮圭獥
+  const upload = reactive({
+    open: false,
+    title: "",
+    isUploading: false,
+    headers: { Authorization: "Bearer " + getToken() },
+    url: import.meta.env.VITE_APP_BASE_API + "/afterSalesService/import",
+  });
 
   // 瀛楀吀鑾峰彇
   /* 
@@ -434,6 +485,64 @@
       });
   };
 
+  /** 瀵煎叆鎸夐挳鎿嶄綔 */
+  const handleImport = () => {
+    upload.title = "鍙嶉鐧昏瀵煎叆";
+    upload.open = true;
+  };
+
+  /** 涓嬭浇妯℃澘 */
+  const importTemplate = () => {
+    proxy.download(
+      "/afterSalesService/importTemplate",
+      {},
+      "鍙嶉鐧昏瀵煎叆妯℃澘.xlsx"
+    );
+  };
+
+  /** 鎻愪氦涓婁紶鏂囦欢 */
+  const submitFileForm = () => {
+    upload.isUploading = true;
+    uploadRef.value.submit();
+  };
+
+  /** 鏂囦欢涓婁紶涓鐞� */
+  const handleFileUploadProgress = () => {
+    upload.isUploading = true;
+  };
+
+  /** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
+  const handleFileSuccess = response => {
+    upload.isUploading = false;
+    upload.open = false;
+    uploadRef.value.clearFiles();
+    if (response.code === 200) {
+      const failCount = response.failCount || 0;
+      if (failCount > 0) {
+        const errors = Array.isArray(response.errors) ? response.errors : [];
+        proxy.$modal
+          .alert(`${response.msg}\n\n${errors.join("\n")}`, "瀵煎叆缁撴灉", {
+            confirmButtonText: "鐭ラ亾浜�",
+            dangerouslyUseHTMLString: false,
+          })
+          .then(() => {
+            getList();
+          });
+      } else {
+        proxy.$modal.msgSuccess(response.msg || "瀵煎叆鎴愬姛");
+        getList();
+      }
+    } else {
+      proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+    }
+  };
+
+  /** 鏂囦欢涓婁紶澶辫触澶勭悊 */
+  const handleFileError = () => {
+    upload.isUploading = false;
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  };
+
   const getStatsCountByStatus = (list, status) => {
     if (!Array.isArray(list)) return 0;
     return list.find(item => item?.status === status)?.count || 0;
diff --git a/src/views/inventoryManagement/dispatchLog/Record.vue b/src/views/inventoryManagement/dispatchLog/Record.vue
index c7d53ab..4115621 100644
--- a/src/views/inventoryManagement/dispatchLog/Record.vue
+++ b/src/views/inventoryManagement/dispatchLog/Record.vue
@@ -76,6 +76,7 @@
     </div>
     <div class="actions">
       <!-- <el-button type="primary" @click="handleBatchApprove">瀹℃壒</el-button> -->
+      <el-button type="info" plain icon="Upload" @click="handleImport">瀵煎叆</el-button>
       <el-button @click="handleOut">瀵煎嚭</el-button>
       <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       <el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
@@ -153,6 +154,41 @@
         @pagination="paginationChange"
       />
     </div>
+    <!-- 鍑哄簱瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title"
+               v-model="upload.open"
+               width="400px"
+               append-to-body>
+      <el-upload ref="uploadRef"
+                 :limit="1"
+                 accept=".xlsx, .xls"
+                 :headers="upload.headers"
+                 :action="upload.url"
+                 :disabled="upload.isUploading"
+                 :on-progress="handleFileUploadProgress"
+                 :on-success="handleFileSuccess"
+                 :on-error="handleFileError"
+                 :auto-upload="false"
+                 drag>
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏� xls銆亁lsx 鏍煎紡鏂囦欢銆�</span>
+            <el-link type="primary"
+                     :underline="false"
+                     style="font-size: 12px; vertical-align: baseline"
+                     @click="importTemplate">涓嬭浇妯℃澘</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -172,6 +208,7 @@
   findAllUnQualifiedStockOutRecordTypeOptions,
 } from "@/api/basicData/enum.js";
 import { parseTime } from "@/utils/ruoyi";
+import { getToken } from "@/utils/auth.js";
 
 const userStore = useUserStore();
 const { proxy } = getCurrentInstance();
@@ -682,6 +719,55 @@
   const seconds = String(date.getSeconds()).padStart(2, "0");
   return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
 };
+// 瀵煎叆
+const uploadRef = ref();
+const upload = reactive({
+  open: false,
+  title: "",
+  isUploading: false,
+  headers: { Authorization: "Bearer " + getToken() },
+  url: import.meta.env.VITE_APP_BASE_API + "/stockOutRecord/import?type=" + props.type,
+});
+const handleImport = () => {
+  upload.title = "鍑哄簱瀵煎叆";
+  upload.open = true;
+};
+const importTemplate = () => {
+  proxy.download("/stockOutRecord/importTemplate", {}, "鍑哄簱瀵煎叆妯℃澘.xlsx");
+};
+const submitFileForm = () => {
+  upload.isUploading = true;
+  uploadRef.value.submit();
+};
+const handleFileUploadProgress = () => {
+  upload.isUploading = true;
+};
+const handleFileSuccess = (response) => {
+  upload.isUploading = false;
+  upload.open = false;
+  uploadRef.value.clearFiles();
+  if (response.code === 200) {
+    const failCount = response.failCount || 0;
+    if (failCount > 0) {
+      const errors = Array.isArray(response.errors) ? response.errors : [];
+      proxy.$modal.alert(`${response.msg}\n\n${errors.join("\n")}`, "瀵煎叆缁撴灉", {
+        confirmButtonText: "鐭ラ亾浜�",
+      }).then(() => {
+        getList();
+      });
+    } else {
+      proxy.$modal.msgSuccess(response.msg || "瀵煎叆鎴愬姛");
+      getList();
+    }
+  } else {
+    proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+  }
+};
+const handleFileError = () => {
+  upload.isUploading = false;
+  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+};
+
 onMounted(() => {
   getList();
   fetchStockRecordTypeOptions();
diff --git a/src/views/inventoryManagement/receiptManagement/Record.vue b/src/views/inventoryManagement/receiptManagement/Record.vue
index 344bf50..020b3ff 100644
--- a/src/views/inventoryManagement/receiptManagement/Record.vue
+++ b/src/views/inventoryManagement/receiptManagement/Record.vue
@@ -84,6 +84,10 @@
                  @click="handleBatchApprove">瀹℃壒</el-button>
       <el-button :disabled="!canReverseApprove"
                  @click="handleReverseApprove">鍙嶅</el-button> -->
+      <el-button type="info"
+                 plain
+                 icon="Upload"
+                 @click="handleImport">瀵煎叆</el-button>
       <el-button @click="handleOut">瀵煎嚭</el-button>
       <el-button type="danger"
                  plain
@@ -173,6 +177,42 @@
                   :limit="page.size"
                   @pagination="pageProductChange"/>
     </div>
+    <!-- 鍏ュ簱瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title"
+               v-model="upload.open"
+               width="400px"
+               append-to-body>
+      <el-upload ref="uploadRef"
+                 :limit="1"
+                 accept=".xlsx, .xls"
+                 :headers="upload.headers"
+                 :action="upload.url"
+                 :disabled="upload.isUploading"
+                 :on-progress="handleFileUploadProgress"
+                 :on-success="handleFileSuccess"
+                 :on-error="handleFileError"
+                 :auto-upload="false"
+                 drag>
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏� xls銆亁lsx 鏍煎紡鏂囦欢銆�</span>
+            <el-link type="primary"
+                     :underline="false"
+                     style="font-size: 12px; vertical-align: baseline"
+                     @click="importTemplate">涓嬭浇妯℃澘</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -198,6 +238,7 @@
   // findAllUnQualifiedStockInRecordTypeOptions,
 } from "@/api/basicData/enum.js";
 import { parseTime } from "@/utils/ruoyi";
+import { getToken } from "@/utils/auth.js";
 
 const {proxy} = getCurrentInstance();
 
@@ -454,6 +495,55 @@
       });
 };
 
+// 瀵煎叆
+const uploadRef = ref();
+const upload = reactive({
+  open: false,
+  title: "",
+  isUploading: false,
+  headers: { Authorization: "Bearer " + getToken() },
+  url: import.meta.env.VITE_APP_BASE_API + "/stockInRecord/import?type=" + props.type,
+});
+const handleImport = () => {
+  upload.title = "鍏ュ簱瀵煎叆";
+  upload.open = true;
+};
+const importTemplate = () => {
+  proxy.download("/stockInRecord/importTemplate", {}, "鍏ュ簱瀵煎叆妯℃澘.xlsx");
+};
+const submitFileForm = () => {
+  upload.isUploading = true;
+  uploadRef.value.submit();
+};
+const handleFileUploadProgress = () => {
+  upload.isUploading = true;
+};
+const handleFileSuccess = (response) => {
+  upload.isUploading = false;
+  upload.open = false;
+  uploadRef.value.clearFiles();
+  if (response.code === 200) {
+    const failCount = response.failCount || 0;
+    if (failCount > 0) {
+      const errors = Array.isArray(response.errors) ? response.errors : [];
+      proxy.$modal.alert(`${response.msg}\n\n${errors.join("\n")}`, "瀵煎叆缁撴灉", {
+        confirmButtonText: "鐭ラ亾浜�",
+      }).then(() => {
+        getList();
+      });
+    } else {
+      proxy.$modal.msgSuccess(response.msg || "瀵煎叆鎴愬姛");
+      getList();
+    }
+  } else {
+    proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+  }
+};
+const handleFileError = () => {
+  upload.isUploading = false;
+  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+};
+
 onMounted(() => {
   getList();
   fetchStockRecordTypeOptions();
diff --git a/src/views/inventoryManagement/stockManagement/ImportOut.vue b/src/views/inventoryManagement/stockManagement/ImportOut.vue
new file mode 100644
index 0000000..b8d4ccb
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/ImportOut.vue
@@ -0,0 +1,97 @@
+<template>
+  <el-dialog v-model="isShow" title="瀵煎叆鍑哄簱" @close="closeModal">
+    <FileUpload
+      ref="fileUploadRef"
+      accept=".xlsx, .xls"
+      :headers="upload.headers"
+      :action="upload.url"
+      :disabled="upload.isUploading"
+      :showTip="true"
+      @success="handleFileSuccess"
+      :downloadTemplate="downloadTemplate"
+    />
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+        <el-button @click="closeModal">鍙� 娑�</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { computed, getCurrentInstance, reactive } from "vue";
+import { getToken } from "@/utils/auth.js";
+import { FileUpload } from "@/components/Upload";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "瀵煎叆鍑哄簱",
+});
+
+const { proxy } = getCurrentInstance();
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+});
+
+const emit = defineEmits(["update:visible", "uploadSuccess"]);
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit("update:visible", val);
+  },
+});
+
+const fileUploadRef = ref();
+const upload = reactive({
+  // 鏄惁绂佺敤涓婁紶
+  isUploading: false,
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken() },
+  // 涓婁紶鍦板潃锛氬鐢ㄥ嚭搴撳彴璐﹀鍏ユ帴鍙o紙type=0 鍚堟牸锛夛紝鐢熸垚寰呭鎵瑰嚭搴撹褰曪紝瀵煎叆鏃朵笉鎵e簱瀛�
+  url: import.meta.env.VITE_APP_BASE_API + "/stockOutRecord/import?type=0",
+});
+
+const submitFileForm = () => {
+  fileUploadRef.value.uploadApi();
+};
+
+const handleFileSuccess = (response) => {
+  const { code, msg } = response;
+  if (code == 200) {
+    const failCount = response.failCount || 0;
+    if (failCount > 0) {
+      const errors = Array.isArray(response.errors) ? response.errors : [];
+      proxy.$modal
+        .alert(`${response.msg}\n\n${errors.join("\n")}`, "瀵煎叆缁撴灉", {
+          confirmButtonText: "鐭ラ亾浜�",
+        })
+        .then(() => {
+          emit("uploadSuccess");
+          closeModal();
+        });
+    } else {
+      ElMessage({ message: response.msg || "瀵煎叆鎴愬姛", type: "success" });
+      emit("uploadSuccess");
+      closeModal();
+    }
+  } else {
+    ElMessage({ message: msg, type: "error" });
+  }
+};
+
+const downloadTemplate = () => {
+  proxy.download("/stockOutRecord/importTemplate", {}, "鍑哄簱瀵煎叆妯℃澘.xlsx");
+};
+
+const closeModal = () => {
+  isShow.value = false;
+};
+</script>
diff --git a/src/views/inventoryManagement/stockManagement/Record.vue b/src/views/inventoryManagement/stockManagement/Record.vue
index 054548f..f517061 100644
--- a/src/views/inventoryManagement/stockManagement/Record.vue
+++ b/src/views/inventoryManagement/stockManagement/Record.vue
@@ -54,6 +54,14 @@
                   >
                     瀵煎叆搴撳瓨
                   </el-button>
+                  <el-button
+                    type="info"
+                    plain
+                    icon="Upload"
+                    @click="isShowImportOutModal = true"
+                  >
+                    瀵煎叆鍑哄簱
+                  </el-button>
                   <el-button @click="handleOut">瀵煎嚭</el-button>
                 </div>
               </div>
@@ -169,6 +177,12 @@
       type="qualified"
       @uploadSuccess="handleQuery"
     />
+    <!-- 瀵煎叆鍑哄簱-->
+    <import-stock-out
+      v-if="isShowImportOutModal"
+      v-model:visible="isShowImportOutModal"
+      @uploadSuccess="handleQuery"
+    />
     <!-- 鍐荤粨/瑙e喕搴撳瓨-->
     <frozen-and-thaw-stock-inventory
       v-if="isShowFrozenAndThawModal"
@@ -203,6 +217,9 @@
 const ImportStockInventory = defineAsyncComponent(() =>
   import("@/views/inventoryManagement/stockManagement/Import.vue")
 );
+const ImportStockOut = defineAsyncComponent(() =>
+  import("@/views/inventoryManagement/stockManagement/ImportOut.vue")
+);
 const FrozenAndThawStockInventory = defineAsyncComponent(() =>
   import("@/views/inventoryManagement/stockManagement/FrozenAndThaw.vue")
 );
@@ -231,6 +248,8 @@
 const operationType = ref("frozen");
 // 鏄惁鏄剧ず瀵煎叆寮规
 const isShowImportModal = ref(false);
+// 鏄惁鏄剧ず瀵煎叆鍑哄簱寮规
+const isShowImportOutModal = ref(false);
 const data = reactive({
   searchForm: {
     productName: "",

--
Gitblit v1.9.3