|
@@ -9,6 +9,7 @@ import { getAdGroupList, getRelationCampaign } from '/@/views/efTools/automation
|
|
|
import { storeToRefs } from 'pinia';
|
|
|
import { useShopInfo } from '/@/stores/shopInfo';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
+import TargetRuleDialog from '/@/views/efTools/automation/components/targetRuleDialog.vue';
|
|
|
|
|
|
const props = defineProps({
|
|
|
templateId: {
|
|
@@ -30,7 +31,14 @@ const { templateId } = toRefs(props);
|
|
|
const { activeModel } = toRefs(props);
|
|
|
|
|
|
const dialogVisible = ref(props.modelValue);
|
|
|
-//筛选条件
|
|
|
+const targetRuleDialogVisible = ref(false);
|
|
|
+
|
|
|
+// 定向规则
|
|
|
+//const adGroupId = ref('')
|
|
|
+//const campaignId = ref('')
|
|
|
+const selectedTargetedRow = ref(null);
|
|
|
+
|
|
|
+// 筛选条件
|
|
|
const searchAdCampaign = ref('');
|
|
|
const selectedCampaignType = ref('sp');
|
|
|
const selectedAdGroup = ref('');
|
|
@@ -49,7 +57,7 @@ const campaignStatus = [
|
|
|
{ value: 'PAUSED', label: '已暂停' },
|
|
|
];
|
|
|
|
|
|
-//表格
|
|
|
+// 表格
|
|
|
const currentPage = ref(1);
|
|
|
const pageSize = ref(25);
|
|
|
const total = ref(0);
|
|
@@ -89,7 +97,6 @@ async function fetchAdCampaign() {
|
|
|
limit: pageSize.value,
|
|
|
});
|
|
|
adCampaignName.value = resp.data;
|
|
|
-
|
|
|
total.value = resp.total;
|
|
|
currentPage.value = resp.page;
|
|
|
// 开始恢复勾选状态
|
|
@@ -110,45 +117,124 @@ async function fetchAdCampaign() {
|
|
|
}
|
|
|
|
|
|
function handleSelectionChange(selection) {
|
|
|
- if (isRestoringSelection) return; // 恢复勾选时跳过该方法
|
|
|
-
|
|
|
- selections = selection;
|
|
|
- const newSelections = selections.filter(
|
|
|
- (sel) => !selectedAds.value.some((added) => added.campaignId === sel.campaignId)
|
|
|
- );
|
|
|
- if (newSelections.length > 0) {
|
|
|
- selectedAds.value.push(...newSelections);
|
|
|
- }
|
|
|
- // 处理取消选中的项
|
|
|
- const removedSelections = selectedAds.value.filter(
|
|
|
- (added) => !selections.some((sel) => sel.campaignId === added.campaignId)
|
|
|
- );
|
|
|
-
|
|
|
- if (removedSelections.length > 0) {
|
|
|
- selectedAds.value = selectedAds.value.filter(
|
|
|
- (added) => !removedSelections.some((removed) => removed.campaignId === added.campaignId)
|
|
|
- );
|
|
|
- }
|
|
|
+ if (isRestoringSelection) return;
|
|
|
+
|
|
|
+ const newSelectedAds = [];
|
|
|
+
|
|
|
+ selection.forEach(item => {
|
|
|
+ if (item.campaignGroupInfo) {
|
|
|
+ // 这是父节点(广告活动)
|
|
|
+ newSelectedAds.push({
|
|
|
+ campaignId: item.campaignId,
|
|
|
+ campaignName: item.campaignName,
|
|
|
+ campaignType: item.campaignType,
|
|
|
+ isParent: true
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 这是子节点(广告组)
|
|
|
+ const parent = adCampaignName.value.find(ad =>
|
|
|
+ ad.campaignGroupInfo && ad.campaignGroupInfo.some(group => group.adGroupId === item.adGroupId)
|
|
|
+ );
|
|
|
+ if (parent) {
|
|
|
+ // 添加父节点(如果还没有添加)
|
|
|
+ if (!newSelectedAds.some(ad => ad.campaignId === parent.campaignId)) {
|
|
|
+ newSelectedAds.push({
|
|
|
+ campaignId: parent.campaignId,
|
|
|
+ campaignName: parent.campaignName,
|
|
|
+ campaignType: parent.campaignType,
|
|
|
+ isParent: true
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 添加子节点(广告组)
|
|
|
+ newSelectedAds.push({
|
|
|
+ adGroupId: item.adGroupId,
|
|
|
+ adGroupName: item.adGroupName,
|
|
|
+ parentCampaignId: parent.campaignId,
|
|
|
+ parentCampaignName: parent.campaignName,
|
|
|
+ campaignType: parent.campaignType
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ selectedAds.value = newSelectedAds;
|
|
|
}
|
|
|
|
|
|
+const groupedSelectedAds = computed(() => {
|
|
|
+ const groups = {};
|
|
|
+ selectedAds.value.forEach(ad => {
|
|
|
+ if (ad.isParent) {
|
|
|
+ if (!groups[ad.campaignId]) {
|
|
|
+ groups[ad.campaignId] = {
|
|
|
+ id: ad.campaignId,
|
|
|
+ name: ad.campaignName,
|
|
|
+ campaignType: ad.campaignType,
|
|
|
+ campaignGroupInfo: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!groups[ad.parentCampaignId]) {
|
|
|
+ groups[ad.parentCampaignId] = {
|
|
|
+ id: ad.parentCampaignId,
|
|
|
+ name: ad.parentCampaignName,
|
|
|
+ campaignType: ad.campaignType,
|
|
|
+ campaignGroupInfo: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+ groups[ad.parentCampaignId].campaignGroupInfo.push({
|
|
|
+ id: ad.adGroupId,
|
|
|
+ name: ad.adGroupName
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return Object.values(groups);
|
|
|
+});
|
|
|
+
|
|
|
function removeSelectedAd(index) {
|
|
|
const removedAd = selectedAds.value.splice(index, 1)[0];
|
|
|
- const targetIndex = adCampaignName.value.findIndex(ad => ad.campaignName === removedAd.campaignName);
|
|
|
- if (targetIndex !== -1) {
|
|
|
- const adTable = refTable.value;
|
|
|
- adTable.toggleRowSelection(adCampaignName.value[targetIndex], false);
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-function removeAllSelectedAds() {
|
|
|
- const adTable = refTable.value;
|
|
|
- selectedAds.value.forEach(ad => {
|
|
|
- const targetIndex = adCampaignName.value.findIndex(item => item.campaignName === ad.campaignName);
|
|
|
+ if (removedAd.parentCampaignId) {
|
|
|
+ // 查找同一父节点下的其他子节点
|
|
|
+ const remainingChildren = selectedAds.value.filter(ad => ad.parentCampaignId === removedAd.parentCampaignId);
|
|
|
+
|
|
|
+ // 如果父节点下还有其他子节点,父节点不删除
|
|
|
+ if (remainingChildren.length > 0) {
|
|
|
+ // 取消表格1中该子节点的勾选
|
|
|
+ const targetParent = adCampaignName.value.find(ad => ad.campaignId === removedAd.parentCampaignId);
|
|
|
+ if (targetParent) {
|
|
|
+ const targetChildIndex = targetParent.campaignGroupInfo.findIndex(group => group.adGroupId === removedAd.adGroupId);
|
|
|
+ if (targetChildIndex !== -1) {
|
|
|
+ const adTable = refTable.value;
|
|
|
+ adTable.toggleRowSelection(targetParent.campaignGroupInfo[targetChildIndex], false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果没有其他子节点了,移除父节点
|
|
|
+ const parentIndex = selectedAds.value.findIndex(ad => ad.campaignId === removedAd.parentCampaignId);
|
|
|
+ if (parentIndex !== -1) {
|
|
|
+ selectedAds.value.splice(parentIndex, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 取消表格1中父节点的勾选
|
|
|
+ const parentIndexInTable = adCampaignName.value.findIndex(ad => ad.campaignId === removedAd.parentCampaignId);
|
|
|
+ if (parentIndexInTable !== -1) {
|
|
|
+ const adTable = refTable.value;
|
|
|
+ adTable.toggleRowSelection(adCampaignName.value[parentIndexInTable], false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果删除的项是父节点
|
|
|
+ const targetIndex = adCampaignName.value.findIndex(ad => ad.campaignId === removedAd.campaignId);
|
|
|
if (targetIndex !== -1) {
|
|
|
+ const adTable = refTable.value;
|
|
|
adTable.toggleRowSelection(adCampaignName.value[targetIndex], false);
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function removeAllSelectedAds() {
|
|
|
selectedAds.value = [];
|
|
|
+ const adTable = refTable.value;
|
|
|
+ adTable.clearSelection();
|
|
|
}
|
|
|
|
|
|
function cancel() {
|
|
@@ -197,6 +283,51 @@ async function fetchAdGroupList() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function handleSelectTarget(row) {
|
|
|
+ console.log("=>(adActivityDialog.vue:287) row", row);
|
|
|
+ // 获取父节点数据
|
|
|
+ const parent = adCampaignName.value.find(ad =>
|
|
|
+ ad.campaignGroupInfo && ad.campaignGroupInfo.some(group => group.adGroupId === row.adGroupId)
|
|
|
+ );
|
|
|
+ if (parent) {
|
|
|
+ // 构造包含父节点和子节点的数据对象
|
|
|
+ selectedTargetedRow.value = {
|
|
|
+ parentCampaignId: parent.campaignId,
|
|
|
+ parentCampaignName: parent.campaignName,
|
|
|
+ campaignType: parent.campaignType,
|
|
|
+ adGroupId: row.adGroupId,
|
|
|
+ adGroupName: row.adGroupName,
|
|
|
+ isSelected: row.isSelected || false, // 同步 isSelected 状态
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ targetRuleDialogVisible.value = true;
|
|
|
+}
|
|
|
+
|
|
|
+function handleConfirm(campaignKeywordInfo) {
|
|
|
+ selectedTargetedRow.value.keywordInfo = campaignKeywordInfo;
|
|
|
+ selectedTargetedRow.value.isSelected = true;
|
|
|
+
|
|
|
+ // 更新子节点状态
|
|
|
+ const parent = adCampaignName.value.find(ad =>
|
|
|
+ ad.campaignGroupInfo && ad.campaignGroupInfo.some(group => group.adGroupId === selectedTargetedRow.value.adGroupId)
|
|
|
+ );
|
|
|
+ if (parent) {
|
|
|
+ const group = parent.campaignGroupInfo.find(group => group.adGroupId === selectedTargetedRow.value.adGroupId);
|
|
|
+ if (group) {
|
|
|
+ group.isSelected = true; // 更新子节点的 isSelected 状态
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 勾选子节点行
|
|
|
+ const table = refTable.value;
|
|
|
+ const targetRow = parent.campaignGroupInfo.find(group => group.adGroupId === selectedTargetedRow.value.adGroupId);
|
|
|
+
|
|
|
+ if (table && targetRow) {
|
|
|
+ table.toggleRowSelection(targetRow, true); // 勾选目标子节点行
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const headerCellStyle = (args) => {
|
|
|
if (args.rowIndex === 0) {
|
|
|
return {
|
|
@@ -244,13 +375,16 @@ watch(dialogVisible, (newValue) => {
|
|
|
|
|
|
const treeProps = computed(() => {
|
|
|
if (activeModel.value === 'adGroup' || activeModel.value === 'specified') {
|
|
|
- return { children: 'campaignGroupInfo' };
|
|
|
+ return {
|
|
|
+ children: 'campaignGroupInfo',
|
|
|
+ checkStrictly: false
|
|
|
+ };
|
|
|
}
|
|
|
return {};
|
|
|
});
|
|
|
|
|
|
onMounted(() => {
|
|
|
- //fetchAdGroupList();
|
|
|
+ fetchAdGroupList();
|
|
|
});
|
|
|
|
|
|
</script>
|
|
@@ -258,14 +392,13 @@ onMounted(() => {
|
|
|
<template>
|
|
|
<el-dialog
|
|
|
v-model="dialogVisible"
|
|
|
- class="custom-dialog"
|
|
|
style="border-radius: 10px;"
|
|
|
title="关联广告活动"
|
|
|
width="1158px"
|
|
|
>
|
|
|
<div class="container">
|
|
|
<div class="container-left">
|
|
|
- <el-input v-model="searchAdCampaign" placeholder="请输入广告活动" style="width: 100%;"
|
|
|
+ <el-input v-model="searchAdCampaign" clearable placeholder="请输入广告活动" style="width: 100%;"
|
|
|
@change="fetchAdCampaign()"></el-input>
|
|
|
<div class="custom-inline">
|
|
|
<el-select v-model="selectedCampaignType" placeholder="选择广告类型">
|
|
@@ -299,12 +432,11 @@ onMounted(() => {
|
|
|
v-loading="loading"
|
|
|
:cell-style="cellStyle"
|
|
|
:data="adCampaignName"
|
|
|
- :row-key="'campaignId'"
|
|
|
:header-cell-style="headerCellStyle"
|
|
|
+ :row-key="'adGroupId'"
|
|
|
+ :tree-props="treeProps"
|
|
|
height="400"
|
|
|
style="width: 100%;"
|
|
|
- :tree-props="treeProps"
|
|
|
- v-bind="activeModel === 'adGroup' || activeModel === 'specified' ? treeProps : {}"
|
|
|
@selection-change="handleSelectionChange"
|
|
|
>
|
|
|
<el-table-column label="广告活动名称">
|
|
@@ -319,6 +451,14 @@ onMounted(() => {
|
|
|
</el-tag>
|
|
|
{{ scope.row.campaignName }}
|
|
|
{{ scope.row.adGroupName }}
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.adGroupName && activeModel==='specified'&&!scope.row.isSelected"
|
|
|
+ class="btn-link"
|
|
|
+ link
|
|
|
+ @click="handleSelectTarget(scope.row)">
|
|
|
+ 选择定向
|
|
|
+ </el-button>
|
|
|
+ <span v-else-if="scope.row.adGroupName">已选择</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column type="selection" width="55"></el-table-column>
|
|
@@ -341,14 +481,15 @@ onMounted(() => {
|
|
|
<h3>已选择({{ selectedAds.length }})</h3>
|
|
|
<el-table
|
|
|
:cell-style="cellStyle"
|
|
|
- :data="selectedAds"
|
|
|
+ :data="groupedSelectedAds"
|
|
|
:header-cell-style="headerCellStyle"
|
|
|
- height="484"
|
|
|
+ :row-key="'id'"
|
|
|
:tree-props="treeProps"
|
|
|
- v-bind="activeModel === 'adGroup' || activeModel === 'specified' ? treeProps : {}"
|
|
|
+ height="484"
|
|
|
style="width: 100%; margin-top: 20px;"
|
|
|
+ v-bind="activeModel === 'adGroup' || activeModel === 'specified' ? treeProps : {}"
|
|
|
>
|
|
|
- <el-table-column label="广告活动" prop="campaignName">
|
|
|
+ <el-table-column label="广告活动" prop="name">
|
|
|
<template #default="scope">
|
|
|
<el-tag
|
|
|
v-if="scope.row.campaignType"
|
|
@@ -359,7 +500,7 @@ onMounted(() => {
|
|
|
{{ scope.row.campaignType }}
|
|
|
</el-tag>
|
|
|
{{ scope.row.campaignName }}
|
|
|
- {{ scope.row.adGroupName }}
|
|
|
+ {{ scope.row.name }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
@@ -386,6 +527,11 @@ onMounted(() => {
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+ <TargetRuleDialog v-if="activeModel === 'specified'"
|
|
|
+ v-model="targetRuleDialogVisible"
|
|
|
+ :selectedTargetedRow="selectedTargetedRow"
|
|
|
+ @confirm:targetRule="handleConfirm"
|
|
|
+ ></TargetRuleDialog>
|
|
|
</template>
|
|
|
|
|
|
<style scoped>
|
|
@@ -438,4 +584,10 @@ onMounted(() => {
|
|
|
padding: 15px
|
|
|
}
|
|
|
|
|
|
+.btn-link {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #0085ff;
|
|
|
+ /* ling-heigt: 23px; */
|
|
|
+}
|
|
|
+
|
|
|
</style>
|