|
@@ -4,12 +4,17 @@
|
|
|
* @Description: 关联广告活动-选择定向弹窗
|
|
|
* @Author: xinyan
|
|
|
*/
|
|
|
-import { provide, reactive, ref, watch } from 'vue';
|
|
|
+import { reactive, ref, watch } from 'vue';
|
|
|
import { MatchType } from '../../utils/enum';
|
|
|
-import { getTargetingRuleList } from '/@/views/efTools/automation/api';
|
|
|
+import { getProductsList, getTargetingRuleList } from '/@/views/efTools/automation/api';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
+import { storeToRefs } from 'pinia';
|
|
|
+import { useShopInfo } from '/@/stores/shopInfo';
|
|
|
+import { Share } from '@element-plus/icons-vue';
|
|
|
|
|
|
|
|
|
+const shopInfo = useShopInfo();
|
|
|
+const { profile } = storeToRefs(shopInfo);
|
|
|
const props = defineProps({
|
|
|
modelValue: {
|
|
|
type: Boolean,
|
|
@@ -41,9 +46,10 @@ const targetColumn = ref([
|
|
|
{ field: 'expressionDesc', title: '品牌', slots: { default: 'expressionDesc_default' } },
|
|
|
{ type: 'checkbox', align: 'right', width: 55 }
|
|
|
]);
|
|
|
-
|
|
|
-const keyWordData = [];
|
|
|
-const targetData = [];
|
|
|
+const productColumn = ref([
|
|
|
+ { field: 'itemName', title: '商品/分类', slots: { default: 'itemName_default' } },
|
|
|
+ { type: 'checkbox', align: 'right', width: 55 }
|
|
|
+]);
|
|
|
|
|
|
const gridOptions = reactive({
|
|
|
height: 550,
|
|
@@ -57,6 +63,14 @@ const gridOptions = reactive({
|
|
|
data: []
|
|
|
});
|
|
|
|
|
|
+const showProductSearch = computed(() => {
|
|
|
+ const columns = unref(gridOptions.columns);
|
|
|
+ return targetType.value === 'target' &&
|
|
|
+ Array.isArray(columns) &&
|
|
|
+ columns.length > 0 &&
|
|
|
+ columns[0].field === 'itemName';
|
|
|
+});
|
|
|
+
|
|
|
async function fetchTargetRuleList() {
|
|
|
try {
|
|
|
gridOptions.loading = true;
|
|
@@ -67,19 +81,48 @@ async function fetchTargetRuleList() {
|
|
|
matchType: matchType.value,
|
|
|
search: keyWord.value,
|
|
|
});
|
|
|
+
|
|
|
targetType.value = resp.data.targetType;
|
|
|
+
|
|
|
// 动态设置表格列
|
|
|
if (resp.data.targetType === 'keyword') {
|
|
|
gridOptions.columns = keyWordColumn;
|
|
|
gridOptions.rowConfig.height = 34;
|
|
|
+ gridOptions.data = resp.data.targetData;
|
|
|
+
|
|
|
} else if (resp.data.targetType === 'target') {
|
|
|
gridOptions.rowConfig.height = 85;
|
|
|
gridOptions.columns = targetColumn;
|
|
|
+ gridOptions.data = resp.data.targetData;
|
|
|
+
|
|
|
+ // 检查是否有 ASIN_SAME_AS 字段
|
|
|
+ const asinSameAsList = resp.data.targetData
|
|
|
+ .filter(item => item.expressionDesc && item.expressionDesc.ASIN_SAME_AS) // 过滤存在 ASIN_SAME_AS 的项
|
|
|
+ .map(item => item.expressionDesc.ASIN_SAME_AS); // 提取所有 ASIN_SAME_AS
|
|
|
+
|
|
|
+ if (asinSameAsList.length > 0) {
|
|
|
+ gridOptions.columns = productColumn;
|
|
|
+ gridOptions.rowConfig.height = 120;
|
|
|
+ gridOptions.data = await fetchProductsList(asinSameAsList); // 传递 ASIN 列表
|
|
|
+ }
|
|
|
}
|
|
|
- gridOptions.data = resp.data.targetData;
|
|
|
gridOptions.loading = false;
|
|
|
} catch (error) {
|
|
|
ElMessage.error('请求定向数据失败');
|
|
|
+ gridOptions.loading = false; // 确保在错误情况下也关闭 loading 状态
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// TODO: 待商品数据查询接口完成后,添加查询参数
|
|
|
+async function fetchProductsList(asinList) {
|
|
|
+ try {
|
|
|
+ const resp = await getProductsList({
|
|
|
+ asinList: asinList.join(','), // 将 ASIN 列表转换为逗号分隔的字符串
|
|
|
+ profileId: profile.value.profile_id,
|
|
|
+ });
|
|
|
+ return resp.data;
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('请求商品数据失败');
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -107,6 +150,15 @@ async function confirm() {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+// 打开指定 URL 的方法
|
|
|
+const openProductUrl = (url) => {
|
|
|
+ if (url) {
|
|
|
+ window.open(url, '_blank'); // 在新标签页中打开链接
|
|
|
+ } else {
|
|
|
+ console.warn('Product URL is not available');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
const headerCellStyle = () => {
|
|
|
return {
|
|
|
fontSize: '13px',
|
|
@@ -144,22 +196,28 @@ watch(() => props.selectedTargetedRow, () => {
|
|
|
style="border-radius: 10px;"
|
|
|
title="关联广告活动 > 选择定向"
|
|
|
width="1158px">
|
|
|
- <div>
|
|
|
- <el-select
|
|
|
- v-model="matchType"
|
|
|
- placeholder="全部匹配方式"
|
|
|
- style="width: 128px; margin-bottom: 10px"
|
|
|
- @change="fetchTargetRuleList"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in MatchType"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <el-input v-model="keyWord" class="mb-3" clearable placeholder="快速搜索关键词" @change="fetchTargetRuleList" />
|
|
|
+ <template v-if="targetType === 'keyword'">
|
|
|
+ <div>
|
|
|
+ <el-select
|
|
|
+ v-model="matchType"
|
|
|
+ placeholder="全部匹配方式"
|
|
|
+ style="width: 128px; margin-bottom: 10px"
|
|
|
+ @change="fetchTargetRuleList"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in MatchType"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <el-input v-model="keyWord" class="mb-3" clearable placeholder="快速搜索关键词" @change="fetchTargetRuleList" />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="showProductSearch">
|
|
|
+ <el-input v-model="productName" class="mb-3" placeholder="快速搜索分类名称或商品名称" style="width: 517px"
|
|
|
+ @change="fetchProductsList"></el-input>
|
|
|
+ </template>
|
|
|
<vxe-grid :cell-style="cellStyle" :header-cell-style="headerCellStyle" v-bind="gridOptions"
|
|
|
v-on="gridEvents" @checkbox-change="handleCheckChange">
|
|
|
<template #expressionDesc_default="{ row }">
|
|
@@ -172,6 +230,20 @@ watch(() => props.selectedTargetedRow, () => {
|
|
|
</div>
|
|
|
<div v-if="row.expressionDesc.ASIN_SAME_AS">asin:{{ row.expressionDesc.ASIN_SAME_AS }}</div>
|
|
|
</template>
|
|
|
+ <template #itemName_default="{ row }">
|
|
|
+ <div style="display: flex; align-items: flex-start;">
|
|
|
+ <!-- 左边图片部分 -->
|
|
|
+ <div style="flex-shrink: 0;">
|
|
|
+ <img :src="row.main_image" alt="Product Image" height="53" width="53" />
|
|
|
+ </div>
|
|
|
+ <!-- 右边文字部分 -->
|
|
|
+ <div style="margin-left: 10px;">
|
|
|
+ <div><strong>{{ row.itemName }}</strong></div>
|
|
|
+ <span>ASIN: {{ row.asin }}</span>
|
|
|
+ <el-button :icon="Share" link type="primary" @click="openProductUrl(row.productUrl)"></el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</vxe-grid>
|
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|