Selaa lähdekoodia

✨ feat<广告管理>: 自动化-定向选择添加

xinyan 8 kuukautta sitten
vanhempi
commit
0c4f43df99

+ 8 - 0
src/views/components/auto/auto-campaigns/api.ts

@@ -19,4 +19,12 @@ export const saveCampaignRule = (data: any) => {
   })
 }
 
+export const getCampaignRuleList = (params: any) => {
+  return request({
+    url: '/api/ad_manage/template/check_target_select/',
+    method: 'get',
+    params,
+  })
+}
+
 export const getTemplateList = GetList

+ 1 - 1
src/views/components/auto/auto-campaigns/common.ts

@@ -66,7 +66,7 @@ export const userFormData = (props: Props) => {
       delete body.rule.id
     }
     console.log('body', body);
-    // await api.saveCampaignRule(body)
+    await api.saveCampaignRule(body)
   }
 
   watch(

+ 249 - 0
src/views/components/auto/auto-campaigns/select-target.vue

@@ -0,0 +1,249 @@
+<script lang="ts" setup>
+/**
+ * @Name: select-target.vue
+ * @Description: 选择定向组件
+ * @Author: xinyan
+ */
+
+import { Share } from '@element-plus/icons-vue';
+import { reactive, ref, watch } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getCampaignRuleList } from '/@/views/components/auto/auto-campaigns/api';
+import { useShopInfo } from '/@/stores/shopInfo';
+import { storeToRefs } from 'pinia';
+import { getTargetingRuleList } from '/@/views/efTools/automation/api';
+import { MatchType } from '/@/views/efTools/utils/enum';
+
+const shopInfo = useShopInfo();
+const { profile } = storeToRefs(shopInfo);
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    required: true,
+  },
+  selectedTargetedRow: {
+    type: Object,
+    required: true,
+  },
+});
+const emits = defineEmits(['update:modelValue']);
+const targetRuleDialogVisible = ref(props.modelValue);
+const { selectedTargetedRow } = toRefs(props);
+const adGroupId = ref(props.adGroupId);
+const campaignInfo = ref(null);
+const targetType = ref(null);
+
+
+const keyWordColumn = ref([
+  { field: 'keywordText', title: '关键词', width: 220, },
+  { field: 'matchType', title: '匹配方式', formatter: ({ cellValue }) => getMatchTypeLabel(cellValue).label, },
+  { type: 'checkbox', align: 'right', width: 55 }
+]);
+const targetColumn = ref([
+  { field: 'expressionDesc', title: '品牌', slots: { default: 'expressionDesc_default' } },
+  { type: 'checkbox', align: 'right', width: 55 }
+]);
+const productColumn = ref([
+  { field: 'itemName', title: '商品/分类', slots: { default: 'itemName_default' } },
+  { type: 'checkbox', align: 'right', width: 55 }
+]);
+
+const gridOptions = reactive({
+  height: 550,
+  showOverflow: true,
+  loading: false,
+  checkboxConfig: {
+    checkField: 'isSelected'
+  },
+  rowConfig: {
+    isHover: true,
+    height: 85,
+  },
+  columns: keyWordColumn,
+  data: []
+});
+
+async function fetchTargetRuleList() {
+  try {
+    gridOptions.loading = true;
+    const resp = await getTargetingRuleList({
+      campaignType: selectedTargetedRow.value.campaignType,
+      campaignId: selectedTargetedRow.value.campaignId,
+      adGroupId: selectedTargetedRow.value.adGroupId,
+    });
+
+    targetType.value = resp.data.targetType;
+
+    if (targetType.value === 'keyword') {
+      gridOptions.columns = keyWordColumn;
+      gridOptions.rowConfig.height = 34;
+      gridOptions.data = resp.data.targetData.map(item => ({
+        ...item,
+        isSelected: selectedTargetedRow.value.keywordInfo.some(keyword => keyword.keywordId === item.keywordId)
+      }));
+    } else if (targetType.value === 'target') {
+      gridOptions.rowConfig.height = 85;
+      gridOptions.columns = targetColumn;
+      gridOptions.data = resp.data.targetData.map(item => ({
+        ...item,
+        isSelected: selectedTargetedRow.value.campaignTargetInfo.some(target => target.targetId === item.targetId)
+      }));
+
+      // 处理 ASIN_SAME_AS 字段
+      const asinSameAsList = gridOptions.data
+          .filter(item => item.expressionDesc && item.expressionDesc.ASIN_SAME_AS)
+          .map(item => item.expressionDesc.ASIN_SAME_AS);
+
+      if (asinSameAsList.length > 0) {
+        gridOptions.columns = productColumn;
+        gridOptions.rowConfig.height = 120;
+        const products = await fetchProductsList(asinSameAsList);
+
+        // 创建一个映射,用于快速查找原始定向规则数据
+        const targetMap = new Map(
+            gridOptions.data
+                .filter(item => item.expressionDesc && item.expressionDesc.ASIN_SAME_AS)
+                .map(item => [item.expressionDesc.ASIN_SAME_AS, item])
+        );
+
+        gridOptions.data = products.map(product => {
+          const originalTarget = targetMap.get(product.asin);
+          return {
+            ...product,
+            targetId: originalTarget?.targetId,
+            adGroup_id: originalTarget?.adGroup_id,
+            bid: originalTarget?.bid,
+            isSelected: selectedTargetedRow.value.campaignTargetInfo.some(
+                target => target.targetId === originalTarget?.targetId
+            )
+          };
+        });
+      }
+    }
+
+    // 预选已选择的定向规则
+    campaignInfo.value = gridOptions.data.filter(item => item.isSelected);
+
+    gridOptions.loading = false;
+  } catch (error) {
+    console.error('Error fetching target rule list:', error);
+    ElMessage.error('请求定向数据失败');
+    gridOptions.loading = false;
+  }
+}
+
+function handleCheckChange({ records, row, checked }) {
+  if (row) {
+    // 单个选择/取消选择
+    row.isSelected = checked;
+  } else {
+    // 全选/取消全选
+    records.forEach(record => record.isSelected = checked);
+  }
+  campaignInfo.value = gridOptions.data.filter(item => item.isSelected);
+}
+
+function getMatchTypeLabel(type: string) {
+  const matchType = MatchType.find(item => item.value === type);
+  if (matchType) {
+    return { label: matchType.label, type: type };
+  }
+  return { label: type, type: '' };
+}
+
+function cancel() {
+  targetRuleDialogVisible.value = false;
+}
+
+function confirm() {
+  targetRuleDialogVisible.value = false;
+  emits('confirm:selectTarget', {
+    campaignInfo: campaignInfo.value,
+    targetType: targetType.value,
+    adGroupId: selectedTargetedRow.value.adGroupId,  // 添加这行
+    campaignId: selectedTargetedRow.value.campaignId  // 添加这行
+  });
+}
+
+const openProductUrl = (url) => {
+  if (url) {
+    window.open(url, '_blank');  // 在新标签页中打开链接
+  } else {
+    console.warn('Product URL is not available');
+  }
+};
+
+const headerCellStyle = () => {
+  return {
+    fontSize: '13px',
+    // height: '34px',
+  };
+};
+
+const cellStyle = () => {
+  return {
+    fontSize: '13px',
+    //fontWeight: '500',
+  };
+};
+
+watch(() => props.modelValue, (newValue) => {
+  targetRuleDialogVisible.value = newValue;
+});
+
+watch(targetRuleDialogVisible, (newValue) => {
+  emits('update:modelValue', newValue);
+  fetchTargetRuleList();
+});
+
+watch(() => props.selectedTargetedRow, () => {
+  // fetchTargetRuleList();
+});
+
+</script>
+
+
+<template>
+  <el-dialog v-model="targetRuleDialogVisible"
+             style="border-radius: 10px;"
+             title="关联广告活动 > 选择定向"
+             width="1158px">
+    <vxe-grid :cell-style="cellStyle" :header-cell-style="headerCellStyle" v-bind="gridOptions"
+              v-on="gridEvents" @checkbox-change="handleCheckChange">
+      <template #expressionDesc_default="{ row }">
+        <div v-if="row.expressionDesc.ASIN_CATEGORY_SAME_AS">分类:{{ row.expressionDesc.ASIN_CATEGORY_SAME_AS }}</div>
+        <div v-if="row.expressionDesc.ASIN_BRAND_SAME_AS">品牌:{{ row.expressionDesc.ASIN_BRAND_SAME_AS }}</div>
+        <div v-if="row.expressionDesc.ASIN_PRICE_BETWEEN">商品价格:{{ row.expressionDesc.ASIN_PRICE_BETWEEN }}</div>
+        <div v-if="row.expressionDesc.ASIN_REVIEW_RATING_BETWEEN">评分:{{
+            row.expressionDesc.ASIN_REVIEW_RATING_BETWEEN
+          }}
+        </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">
+        <el-button @click="cancel">取消</el-button>
+        <el-button type="primary" @click="confirm">确定</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<style scoped>
+
+</style>

+ 0 - 1
src/views/components/auto/auto-campaigns/select-tmpl.vue

@@ -32,7 +32,6 @@ onMounted(async () => {
 watch(
     () => props.data.useTmpl,
     () => {
-      console.log("=>(select-tmpl.vue:26) props.data.useTmpl", props.data.useTmpl);
       if (props.data.useTmpl) {
         ruleUsage.value = 'tmpl';
         tmplId.value = props.data.template.id;

+ 448 - 0
src/views/components/auto/auto-campaigns/view-target-rules.vue

@@ -0,0 +1,448 @@
+<script lang="ts" setup>
+/**
+ * @Name: view-target-rules.vue
+ * @Description: 点击选择定向按钮弹窗
+ * @Author: xinyan
+ */
+
+import { DocumentAdd } from '@element-plus/icons-vue';
+import { computed, onMounted, reactive, ref, watch } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getCampaignRuleList } from '/@/views/components/auto/auto-campaigns/api';
+import SelectTarget from '/@/views/components/auto/auto-campaigns/select-target.vue';
+
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    required: true,
+  },
+  checkTarget: {
+    type: Object,
+    required: true,
+  },
+});
+
+const emits = defineEmits(['update:modelValue']);
+
+const loading = ref(false);
+const xGridOne = ref(null);
+const xGridTwo = ref(null);
+let selectedAds = ref([]);
+
+const dialogVisible = ref(false);
+const SelectTargetVisible = ref(false);
+
+const selectedTargetedRow = ref(null);
+
+const selectedColumns = [
+  {
+    field: 'campaignName',
+    title: '广告活动',
+    slots: { default: 'campaignName_default' },
+    treeNode: true
+  },
+  { title: '操作', width: 65, align: 'center', slots: { header: 'header_operation', default: 'default_operation' } }
+];
+
+const treeProps = computed(() => {
+  return {
+    rowField: 'campaignId',
+    childrenField: 'adGroupInfo',  // 子节点字段
+    expandAll: true,
+  };
+});
+
+const gridOptions = reactive({
+  border: 'inner',
+  height: 500,
+  loading: false,
+  rowConfig: {
+    isHover: true,
+    keyField: 'campaignId',
+  },
+  treeConfig: treeProps,
+  checkboxConfig: {
+    labelField: 'name',
+    reserve: true,
+    checkStrictly: false,
+    checkMethod: ({ row }) => {
+      // 只允许取消选中
+      return row.isSelected;
+    }
+  },
+  columns: [
+    {
+      field: 'campaignName',
+      title: '广告活动',
+      slots: { default: 'campaignName_default' },
+      treeNode: true
+    },
+    {
+      type: 'checkbox',
+      width: 55,
+      fixed: 'right',
+      slots: { header: 'checkbox_header', checkbox: 'checkbox_cell' }
+    },
+  ],
+  data: []
+});
+
+function handleGridChange({ records, row, checked }) {
+  console.log(12321312312);
+  if (row) {
+    if (!checked) {
+      row.isSelected = false;
+      updateSelectedAds();
+    }
+  } else {
+    // 全选/取消全选
+    records.forEach(record => {
+      if (record.isSelected) {
+        record.isSelected = checked;
+      }
+    });
+    updateSelectedAds();
+  }
+}
+
+function toggleCheckboxEvent(row) {
+
+    if (row.isSelected) {
+      // 只有已选择的行可以被取消选中
+      xGridOne.value.setCheckboxRow(row, false);
+      handleGridChange({ records: [row], row, checked: false });
+    }
+  }
+
+
+async function fetchAdCampaign() {
+  try {
+    const resp = await getCampaignRuleList({
+      profileId: props.checkTarget.profileId,
+      campaignId: props.checkTarget.campaignId
+    });
+    gridOptions.data = [resp.data];
+
+    // // 默认勾选有 selectTargetId 的数据
+    // const adGroupsToCheck = resp.data.adGroupInfo.filter(group =>
+    //     group.selectTargetId && group.selectTargetId.length > 0
+    // );
+    //
+    // // 更新选中的广告
+    // selectedAds.value = [{
+    //   campaignId: resp.data.campaignId,
+    //   campaignType: resp.data.campaignType,
+    //   campaignName: resp.data.campaignName,
+    //   adGroupInfo: adGroupsToCheck
+    // }];
+    //
+    // // 在 nextTick 中设置选中状态,确保表格已经渲染
+    // nextTick(() => {
+    //   if (xGridOne.value) {
+    //     adGroupsToCheck.forEach(group => {
+    //       group.isSelected = true;
+    //       xGridOne.value.setCheckboxRow(group, true);
+    //     });
+    //   }
+    // });
+  } catch (error) {
+    ElMessage.error('请求广告活动数据失败');
+  } finally {
+    // gridOptions.loading = false;
+  }
+}
+
+function handleSelectTarget(row) {
+  // 获取父节点数据
+  const parent = gridOptions.data.find(campaign =>
+      campaign.adGroupInfo.some(group => group.adGroupId === row.adGroupId)
+  );
+  selectedTargetedRow.value = {
+    campaignType: parent.campaignType,
+    campaignId: parent.campaignId,
+    adGroupId: row.adGroupId,
+    isSelected: row.isSelected || false,
+    keywordInfo: row.keywordInfo || [],
+    campaignTargetInfo: row.campaignTargetInfo || [],
+  };
+  SelectTargetVisible.value = true;
+  console.log('SelectTargetVisible', SelectTargetVisible.value);
+}
+
+function updateSelectedAds() {
+  selectedAds.value = gridOptions.data
+      .filter(ad => ad.adGroupInfo && ad.adGroupInfo.some(group => group.isSelected))
+      .map(ad => ({
+        ...ad,
+        adGroupInfo: ad.adGroupInfo.filter(group => group.isSelected),
+      }));
+  console.log('selectedAds.value', selectedAds.value);
+}
+
+// 选择定向弹窗确认按钮
+function handleConfirm({ campaignInfo, targetType }) {
+  if (!selectedTargetedRow.value) return;
+
+  // 找到父级广告活动
+  const parentCampaign = gridOptions.data.find(campaign =>
+      campaign.adGroupInfo.some(group => group.adGroupId === selectedTargetedRow.value.adGroupId)
+  );
+
+  if (parentCampaign) {
+    // 更新子节点(广告组)的信息
+    const group = parentCampaign.adGroupInfo.find(group => group.adGroupId === selectedTargetedRow.value.adGroupId);
+    if (group) {
+      if (targetType === 'keyword') {
+        group.keywordInfo = campaignInfo;
+      } else if (targetType === 'target') {
+        group.campaignTargetInfo = campaignInfo;
+      }
+      group.isSelected = true; // 更新子节点的选择状态
+      group.targetLength = (group.keywordInfo?.length || 0) + (group.campaignTargetInfo?.length || 0);
+    }
+
+    // 勾选表格1中的对应行,只有在定向大于0时进行勾选
+    if (group && group.targetLength > 0) {
+      if (xGridOne.value) {
+        xGridOne.value.toggleCheckboxRow(group, true); // 手动勾选复选框
+      }
+    }
+  }
+  // 更新选中的广告
+  updateSelectedAds();
+}
+
+// 删除选中的广告
+const removeSelectedAd = async (row) => {
+  const $grid = xGridTwo.value;
+  if ($grid) {
+    if (row.adGroupId) {
+      // 删除子节点(广告组)
+      selectedAds.value = selectedAds.value.map(ad => {
+        if (ad.adGroupInfo) {
+          return {
+            ...ad,
+            adGroupInfo: ad.adGroupInfo.filter(group => group.adGroupId !== row.adGroupId)
+          };
+        }
+        return ad;
+      }).filter(ad => ad.adGroupInfo && ad.adGroupInfo.length > 0);
+    } else {
+      // 删除父节点(广告活动)
+      selectedAds.value = selectedAds.value.filter(ad => ad.campaignId !== row.campaignId);
+    }
+
+    await $grid.remove(row);
+  }
+
+  if (xGridOne.value) {
+    await xGridOne.value.toggleCheckboxRow(row);
+  }
+};
+
+function removeAllSelectedAds() {
+  selectedAds.value = [];
+  const $grid = xGridOne.value;
+  if ($grid) {
+    $grid.clearCheckboxRow();
+  }
+}
+
+const headerCellStyle = (args) => {
+  if (args.rowIndex === 0) {
+    return {
+      backgroundColor: 'rgba(245, 245, 245, 0.9)',
+      fontWeight: '500',
+    };
+  }
+};
+
+const cellStyle = () => {
+  return {
+    fontSize: '13px',
+    //fontWeight: '500',
+  };
+};
+
+watch(() => props.modelValue, (newValue) => {
+  dialogVisible.value = newValue;
+});
+
+watch(dialogVisible, (newValue) => {
+  emits('update:modelValue', newValue);
+  fetchAdCampaign();
+});
+
+watch(props.checkTarget, () => {
+  fetchAdCampaign();
+});
+
+onMounted(() => {
+  // fetchAdCampaign();
+});
+
+</script>
+
+<template>
+  <el-dialog
+      v-model="dialogVisible"
+      style="border-radius: 10px;"
+      title="关联广告活动"
+      width="1158px"
+  >
+    <div class="container">
+      <div class="container-left">
+        <vxe-grid ref="xGridOne" :cell-style="cellStyle" :header-cell-style="headerCellStyle" v-bind="gridOptions"
+                  @checkbox-change="handleGridChange" @checkbox-all="handleGridChange">
+          <template #campaignName_default="{ row }">
+            <el-tag
+                v-if="row.campaignType"
+                :color="row.campaignType === 'sb' ? '#0163d2' : (row.campaignType === 'sp' ? '#ff7424' : '#365672')"
+                class="campaign-type"
+                disable-transitions
+                round>
+              {{ row.campaignType }}
+            </el-tag>
+            <span>  {{ row.campaignName }}</span>
+            <span class="flex-container">
+              {{ row.adGroupName }}
+            <el-button
+                v-if="row.adGroupName && row.selectTargetId.length!==0"
+                class="btn-link"
+                link
+                @click="handleSelectTarget(row)">
+              选择定向
+            </el-button>
+            <span v-else-if="row.adGroupName">已选择定向</span>
+            </span>
+          </template>
+          <template #checkbox_header="{ checked, indeterminate }">
+        <span class="custom-checkbox" @click.stop="toggleAllCheckboxEvent">
+          <i v-if="indeterminate" class="vxe-icon-square-minus-fill" style="color: #0d84ff"></i>
+          <i v-else-if="checked" class="vxe-icon-square-checked-fill" style="color: #0d84ff"></i>
+          <i v-else class="vxe-icon-checkbox-unchecked" style="color: #0d84ff"></i>
+        </span>
+          </template>
+          <template #checkbox_cell="{ row, checked, indeterminate }">
+            <span class="custom-checkbox" @click.stop="toggleCheckboxEvent(row)">
+              <i v-if="indeterminate" class="vxe-icon-square-minus-fill" style="color: #0d84ff"></i>
+              <i v-else-if="checked" class="vxe-icon-square-checked-fill" style="color: #0d84ff"></i>
+              <el-tooltip v-else
+                          class="box-item"
+                          content="请选择定向"
+                          effect="dark"
+                          placement="top"
+              >
+                <i class="vxe-icon-checkbox-unchecked" style="color: #0d84ff"></i>
+              </el-tooltip>
+            </span>
+          </template>
+        </vxe-grid>
+      </div>
+      <div class="container-right">
+        <h3>已选择({{ selectedAds.length }})</h3>
+        <vxe-grid ref="xGridTwo"
+                  :cell-style="cellStyle"
+                  :columns="selectedColumns"
+                  :data="selectedAds"
+                  :header-cell-style="headerCellStyle"
+                  :tree-config="treeProps"
+                  border="inner"
+                  height="484">
+          <template #campaignName_default="{ row }">
+            <template v-if="!row.adGroupId">
+              <!-- 父节点(广告活动) -->
+              <el-tag
+                  v-if="row.campaignType"
+                  :color="row.campaignType === 'sb' ? '#0163d2' : (row.campaignType === 'sp' ? '#ff7424' : '#365672')"
+                  class="campaign-type"
+                  disable-transitions
+                  round>
+                {{ row.campaignType }}
+              </el-tag>
+              <span>{{ row.campaignName }}</span>
+            </template>
+            <template v-else>
+              <!-- 子节点(广告组) -->
+              <span class="flex-container">
+                {{ row.adGroupName }}
+                <el-button
+                    v-if="row.isSelected"
+                    :icon="DocumentAdd"
+                    class="btn-link"
+                    link
+                    @click="handleSelectTarget(row)">
+                  共{{ row.targetLength }}个定向规则
+                </el-button>
+              </span>
+            </template>
+          </template>
+          <template #header_operation>
+            <el-button link size="default" style="color: #2077d7;font-size: 13px" @click="removeAllSelectedAds">
+              删除全部
+            </el-button>
+          </template>
+          <template #default_operation="{row}">
+            <el-button type="text" @click="removeSelectedAd(row)">
+              <CircleClose style="width:16px;color:#4b5765" />
+            </el-button>
+          </template>
+        </vxe-grid>
+      </div>
+    </div>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="cancel">取消</el-button>
+        <el-button type="primary" @click="confirm">确定</el-button>
+      </div>
+    </template>
+  </el-dialog>
+  <SelectTarget v-model="SelectTargetVisible"
+                :selectedTargetedRow="selectedTargetedRow"
+                @confirm:selectTarget="handleConfirm"
+  ></SelectTarget>
+</template>
+
+<style scoped>
+.container {
+  width: 100%;
+  height: 100%;
+  border: 1px solid #d6dbe2;
+  border-radius: 4px;
+  display: flex;
+  overflow: hidden;
+  align-content: center;
+  flex-wrap: nowrap;
+  flex-direction: row;
+  /* padding: 10px; */
+}
+
+.container-left {
+  width: 50%;
+  border-right: 1px solid #d6dbe2;
+  padding: 15px
+}
+
+.container-right {
+  flex: 1;
+  padding: 15px
+}
+
+.campaign-type {
+  color: #fff;
+  border-color: #fff;
+  border-radius: 12px;
+  margin-right: 4px;
+}
+
+.btn-link {
+  font-size: 13px;
+  color: #0085ff;
+}
+
+.flex-container {
+  display: flex;
+  justify-content: space-between;
+}
+</style>

+ 33 - 10
src/views/components/auto/target-select.vue

@@ -5,7 +5,10 @@
  * @Author: Cheney
  */
 import AdGroupSelect from '/@/views/components/ad-group-select/index.vue';
-import { watch } from 'vue';
+import SelectTarget from '/@/views/components/auto/auto-campaigns/select-target.vue';
+import { ref, watch } from 'vue';
+import ViewTargetRules from '/@/views/components/auto/auto-campaigns/view-target-rules.vue';
+
 
 interface Props {
   mode: string;
@@ -13,11 +16,22 @@ interface Props {
   useTmpl?: boolean;
   campaignId: string;
 }
+
 const props = defineProps<Props>();
+const dialogVisible = ref(false);
+const checkTarget = ref(null);
+
+function handleSelectTarget() {
+  checkTarget.value = {
+    profileId:3006125408623189,
+    campaignId:483046146089241,
+  }
+  dialogVisible.value = true;
+}
 
-watch(()=>props.data.campaignAd, (val)=>{
+watch(() => props.data.campaignAd, (val) => {
 
-})
+});
 
 </script>
 
@@ -40,23 +54,31 @@ watch(()=>props.data.campaignAd, (val)=>{
           <div class="target-radio-group-item">
             <el-radio label="adGroup">当前广告活动的指定广告组(所有定向)</el-radio>
             <AdGroupSelect
-              v-show="mode === 'auto' && data.activeModel === 'adGroup'"
-              v-model="data.campaignAd"
-              style="padding-left: 23px; width: 450px"
-              :multiple="true"
-              :query="{ profileId: '3006125408623189', campaignType: data.campaignType, campaignId: campaignId }">
+                v-show="mode === 'auto' && data.activeModel === 'adGroup'"
+                v-model="data.campaignAd"
+                :multiple="true"
+                :query="{ profileId: '3006125408623189', campaignType: data.campaignType, campaignId: campaignId }"
+                style="padding-left: 23px; width: 450px">
             </AdGroupSelect>
           </div>
           <div class="target-radio-group-item">
             <el-radio label="specified">指定定向</el-radio>
-            <el-button v-show="mode === 'auto' && data.activeModel === 'specified'" style="margin-left: 20px; color: blue" link
-              >选择定向</el-button
+            <el-button v-show="mode === 'auto' && data.activeModel === 'specified'"
+                       link style="margin-left: 20px; font-size: 13px;color: #0085ff;"
+                       @click="handleSelectTarget">选择定向
+            </el-button
             >
           </div>
         </div>
       </el-radio-group>
     </div>
   </div>
+  <!--选择定向弹窗-->
+  <ViewTargetRules v-if="data.activeModel === 'specified'"
+                    v-model="dialogVisible"
+                    :checkTarget="checkTarget"
+                    @confirm:targetRule="handleConfirm"
+  ></ViewTargetRules>
 </template>
 
 <style lang="scss" scoped>
@@ -64,6 +86,7 @@ watch(()=>props.data.campaignAd, (val)=>{
   display: flex;
   justify-content: flex-start;
   flex-direction: column;
+
   .target-radio-group-item {
     display: flex;
     flex-direction: column;

+ 1 - 3
src/views/efTools/automation/components/adActivityDialog.vue

@@ -48,7 +48,6 @@ const selectedCampaignType = ref('sp');
 const selectedAdGroup = ref('');
 const selectedStatus = ref('');
 
-const adCampaignName = ref([]);
 const campaignType = [
   { value: 'sb', label: 'SB' },
   { value: 'sp', label: 'SP' },
@@ -82,7 +81,6 @@ const selectedColumns = computed(() => [
 
 const treeProps = computed(() => {
   activeModel.value = 'specified';
-
   if (activeModel.value === 'adGroup' || activeModel.value === 'specified') {
     return {
       rowField: 'campaignId',
@@ -158,7 +156,7 @@ async function fetchAdCampaign() {
     const cachedSelectedAds = [...selectedAds.value];
     const resp = await getRelationCampaign({
       profileId: profile.value.profile_id,
-      templateId: 51,
+      templateId: templateId.value,
       campaignName: searchAdCampaign.value,
       portfolioId: selectedAdGroup.value,
       campaignStatus: selectedStatus.value,