|
|
@@ -53,7 +53,7 @@
|
|
|
<el-dialog v-model="productDialog.visible" title="推荐商品" width="1000px" append-to-body>
|
|
|
<div class="product-dialog-header">
|
|
|
<el-button type="default" @click="handleAddProduct">新增商品</el-button>
|
|
|
- <el-button type="default">导入商品</el-button>
|
|
|
+ <el-button type="default" @click="handleImportProduct">导入商品</el-button>
|
|
|
</div>
|
|
|
<el-table v-loading="productLoading" :data="productList" border max-height="450px">
|
|
|
<el-table-column label="轮播商品编号" align="center" prop="productNo" width="140" />
|
|
|
@@ -84,7 +84,8 @@
|
|
|
<!-- 新增商品选择对话框 -->
|
|
|
<el-dialog v-model="selectProductDialog.visible" title="商品信息" width="800px" append-to-body>
|
|
|
<div class="select-product-search">
|
|
|
- <el-input v-model="selectProductQuery.keyword" placeholder="请输入商品编号名称输入搜索" style="width: 350px" />
|
|
|
+ <el-input v-model="selectProductQuery.productNo" placeholder="请输入商品编号" clearable style="width: 220px" />
|
|
|
+ <el-input v-model="selectProductQuery.itemName" placeholder="请输入商品名称" clearable style="width: 220px" />
|
|
|
<el-button type="primary" @click="handleSearchProduct">搜 索</el-button>
|
|
|
</div>
|
|
|
<el-table
|
|
|
@@ -124,6 +125,24 @@
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
|
|
|
+ <!-- 导入商品对话框 -->
|
|
|
+ <el-dialog v-model="importProductDialog.visible" title="导入商品" width="500px" append-to-body>
|
|
|
+ <el-form label-width="90px">
|
|
|
+ <el-form-item label="商品编号">
|
|
|
+ <el-input
|
|
|
+ v-model="importProductDialog.productNos"
|
|
|
+ type="textarea"
|
|
|
+ :rows="5"
|
|
|
+ placeholder="请输入商品编号,多个用逗号隔开"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button type="primary" @click="confirmImportProducts">确 定</el-button>
|
|
|
+ <el-button @click="importProductDialog.visible = false">取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
<!-- 添加/编辑对话框 -->
|
|
|
<el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" append-to-body>
|
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
|
|
@@ -319,14 +338,22 @@ const selectProductLoading = ref(false);
|
|
|
const selectProductTotal = ref(0);
|
|
|
const selectedProducts = ref<any[]>([]);
|
|
|
const selectProductQuery = reactive({
|
|
|
- keyword: '',
|
|
|
+ productNo: '',
|
|
|
+ itemName: '',
|
|
|
pageNum: 1,
|
|
|
pageSize: 10
|
|
|
});
|
|
|
|
|
|
+// 导入商品对话框
|
|
|
+const importProductDialog = reactive({
|
|
|
+ visible: false,
|
|
|
+ productNos: ''
|
|
|
+});
|
|
|
+
|
|
|
// 打开新增商品对话框
|
|
|
const handleAddProduct = () => {
|
|
|
- selectProductQuery.keyword = '';
|
|
|
+ selectProductQuery.productNo = '';
|
|
|
+ selectProductQuery.itemName = '';
|
|
|
selectProductQuery.pageNum = 1;
|
|
|
selectedProducts.value = [];
|
|
|
selectProductDialog.visible = true;
|
|
|
@@ -339,7 +366,8 @@ const getSelectProductList = async () => {
|
|
|
try {
|
|
|
const res = await request.get('/product/base/list', {
|
|
|
params: {
|
|
|
- itemName: selectProductQuery.keyword,
|
|
|
+ productNo: selectProductQuery.productNo,
|
|
|
+ itemName: selectProductQuery.itemName,
|
|
|
pageNum: selectProductQuery.pageNum,
|
|
|
pageSize: selectProductQuery.pageSize
|
|
|
}
|
|
|
@@ -398,6 +426,73 @@ const handleConfirmSelect = async () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 打开导入商品对话框
|
|
|
+const handleImportProduct = () => {
|
|
|
+ importProductDialog.productNos = '';
|
|
|
+ importProductDialog.visible = true;
|
|
|
+};
|
|
|
+
|
|
|
+// 确认导入商品
|
|
|
+const confirmImportProducts = async () => {
|
|
|
+ const input = importProductDialog.productNos.trim();
|
|
|
+ if (!input) {
|
|
|
+ ElMessage.warning('请输入商品编号');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const productNos = input
|
|
|
+ .split(/[,,\s\n]+/)
|
|
|
+ .map((s: string) => s.trim())
|
|
|
+ .filter(Boolean);
|
|
|
+ if (productNos.length === 0) {
|
|
|
+ ElMessage.warning('请输入有效的商品编号');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const existingProductNos = productList.value.map((item: any) => item.productNo);
|
|
|
+ const newProductNos = productNos.filter((no: string) => !existingProductNos.includes(no));
|
|
|
+ if (newProductNos.length === 0) {
|
|
|
+ ElMessage.warning('所有商品编号已存在,请勿重复添加');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const productRes: any = await request.get('/product/base/list', {
|
|
|
+ params: { productNos: newProductNos.join(','), pageSize: 1000 }
|
|
|
+ });
|
|
|
+ const productMap = new Map<string, any>((productRes.rows || []).map((p: any) => [p.productNo, p]));
|
|
|
+ let successCount = 0;
|
|
|
+ const notFound: string[] = [];
|
|
|
+ for (const productNo of newProductNos) {
|
|
|
+ const product = productMap.get(productNo);
|
|
|
+ if (!product) {
|
|
|
+ notFound.push(productNo);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ await request.post('/product/categoryRecommendedLink', {
|
|
|
+ categoryId: productDialog.categoryId,
|
|
|
+ productId: product.id,
|
|
|
+ productNo: product.productNo,
|
|
|
+ sort: 0
|
|
|
+ });
|
|
|
+ successCount++;
|
|
|
+ }
|
|
|
+ const skipped = productNos.length - newProductNos.length;
|
|
|
+ const tips: string[] = [];
|
|
|
+ if (successCount > 0) tips.push(`成功导入${successCount}个`);
|
|
|
+ if (skipped > 0) tips.push(`${skipped}个已存在被跳过`);
|
|
|
+ if (notFound.length > 0) tips.push(`${notFound.length}个商品编号不存在`);
|
|
|
+ if (successCount > 0) {
|
|
|
+ ElMessage.success(tips.join(','));
|
|
|
+ } else {
|
|
|
+ ElMessage.warning(tips.join(',') || '未导入任何商品');
|
|
|
+ }
|
|
|
+ importProductDialog.visible = false;
|
|
|
+ if (productDialog.categoryId) {
|
|
|
+ getProductList(productDialog.categoryId);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('导入失败');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
// 提交表单
|
|
|
const submitForm = () => {
|
|
|
formRef.value?.validate(async (valid: boolean) => {
|