From b4735c89f5359d0c25fb0ec23480227e4358ec8e Mon Sep 17 00:00:00 2001 From: "pikachu1995@126.com" Date: Tue, 10 Nov 2026 18:58:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(goods):=20=E5=95=86=E5=93=81=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=A1=B5=E6=96=B0=E5=A2=9E=E6=89=B9=E9=87=8F=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seller/src/api/goods.js | 24 ++- .../components/GoodsImportDialog.vue | 184 ++++++++++++++++++ seller/src/views/goods/goods-seller/goods.vue | 13 ++ 3 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 seller/src/views/goods/goods-seller/components/GoodsImportDialog.vue diff --git a/seller/src/api/goods.js b/seller/src/api/goods.js index 298654007..385e78542 100644 --- a/seller/src/api/goods.js +++ b/seller/src/api/goods.js @@ -4,8 +4,10 @@ import { postRequest, putRequest, deleteRequest, - postRequestWithNoForm + postRequestWithNoForm, + uploadFileRequest } from "@/libs/axios"; +import { downloadBlob } from "@/utils/downloadBlob"; // 获取数据字典 export const getDictData = "/dictData/getByType/"; // Websocket @@ -386,3 +388,23 @@ export const downLoadGoods = () => { export const uploadGoodsExcel = params => { return postRequestWithNoForm(`/goods/import/import`, params ); }; + +/** + * 下载商品批量导入(多规格)模板(v2,同步文件流) + * @returns {Promise} 成功时直接触发浏览器下载「商品导入模板.xlsx」 + */ +export const downloadGoodsImportTemplate = async () => { + const blob = await getRequest('/goods/import/downLoad/v2', {}, 'blob'); + downloadBlob(blob, '商品导入模板.xlsx'); +}; + +/** + * 批量导入商品(多规格)Excel(v2) + * @param {File} file 待导入的 .xlsx 文件,multipart 字段名 files + * @returns {Promise} 返回 {success, result: {successCount, failCount, failList: [{goodsNo, rows, reason}]}} + */ +export const importGoodsExcel = file => { + const formData = new FormData(); + formData.append('files', file); + return uploadFileRequest('/goods/import/import/v2', formData); +}; diff --git a/seller/src/views/goods/goods-seller/components/GoodsImportDialog.vue b/seller/src/views/goods/goods-seller/components/GoodsImportDialog.vue new file mode 100644 index 000000000..8b94f24e2 --- /dev/null +++ b/seller/src/views/goods/goods-seller/components/GoodsImportDialog.vue @@ -0,0 +1,184 @@ + + + + + + diff --git a/seller/src/views/goods/goods-seller/goods.vue b/seller/src/views/goods/goods-seller/goods.vue index fb2e9dd60..858dbe443 100644 --- a/seller/src/views/goods/goods-seller/goods.vue +++ b/seller/src/views/goods/goods-seller/goods.vue @@ -140,6 +140,9 @@ > 批量下架 + + 批量导入 + 提交 + + + @@ -269,6 +275,7 @@ import { } from "@/api/goods"; import { Message, Modal } from "@/utils/message"; import { customRouterPush } from "@/utils/filters"; +import GoodsImportDialog from "./components/GoodsImportDialog.vue"; defineOptions({ name: "goods" }); const emit = defineEmits(["edit-schedule", "delete-schedule"]); @@ -329,6 +336,7 @@ const currentStatus = ref(props.scheduledOnly ? props.scheduledStatus : "ALL"); const goodsNumerData = ref({}); const selectedRows = ref([]); // 选中的行数据 const selectAll = ref(false); // 全选状态 +const importDialogVisible = ref(false); // 批量导入弹窗显示状态 const goodsStatusWithCount = computed(() => { return [ @@ -525,6 +533,11 @@ function getNumberData() { } }) } +// 批量导入完成,刷新列表与状态数量 +function onGoodsImported() { + getDataList(); + getNumberData(); +} // 编辑 function edit(v) { id.value = v.id;