Browse Source

✨ feat<自动化规则>:效率工具-自动化规则;广告管理-自动化规则;
1. 效率工具-自动化规则:
--添加已选择的定向规则;
--取消勾选时,清空表格1点击确认按钮后添加的定向规则;
--改写更新表格2数据的方法:updateSelectedAds;
--改写表格1和表格2打开选择定向弹窗按钮的方法:handleSelectTarget;
2. 广告管理-自动化规则:
--优化自动化规则pane;
--判断sp、sb、sd自动化规则是否显示;

xinyan 7 months ago
parent
commit
6682c2be80

+ 3 - 1
src/theme/app.scss

@@ -432,10 +432,12 @@ body,
   flex-direction: row;
   flex-direction: row;
   gap: 30px;
   gap: 30px;
   .label {
   .label {
-    color: #999;
+    color:#999;
+    font-size: 13px;
   }
   }
   .value {
   .value {
     color: #333;
     color: #333;
+    font-size: 13px;
   }
   }
 }
 }
 
 

+ 49 - 32
src/views/adManage/sb/campaigns/campaignDetail/index.vue

@@ -5,61 +5,77 @@
         <span> {{ campaignInfo.campaignName }}</span>
         <span> {{ campaignInfo.campaignName }}</span>
       </span>
       </span>
       <div class="asj-detail-info">
       <div class="asj-detail-info">
-        <span style="color: rgb(177, 177, 177)">状态: </span>
-        <span>
-          <el-button class="no-hover-effect" type="success" round plain size="small" style="margin-top: -3px">{{ dynStatusEnum[campaignInfo.state] }}</el-button>
-        </span><!--({{ campaignInfo.servingStatus }})-->
-        <span class="head-span">预算: </span> <span>{{ profile.currency_symbol + campaignInfo.budget }} | {{ campaignInfo.budgetType }}</span>
+        <div>
+          <span class="label">状态: </span>
+          <el-tag :type="getTagType(campaignInfo.state)">
+            {{ dynStatusEnum[campaignInfo.state] }}
+          </el-tag>
+        </div>
+        <div>
+          <span class="label">预算: </span>
+          <span class="value">{{ profile.currency_symbol + campaignInfo.budget }} | {{ dynStatusEnum[campaignInfo.budgetType] }}</span>
+        </div>
         <!-- <span>投放类型:{{ campaignInfo.targetingType }}</span> -->
         <!-- <span>投放类型:{{ campaignInfo.targetingType }}</span> -->
-        <span class="head-span">投放日期: </span> <span>{{ campaignInfo.startDate }} ~ {{ campaignInfo.endDate ?? '无结束日期' }}</span>
-        <span class="head-span">广告组合: </span> <span>{{ campaignInfo?.portfolioName }}</span>
-        <span class="head-span">竞价: </span> <span>{{ getEnumLabel(dynBidOptimizationEnum, campaignInfo.bidOptimization) }}</span>
+        <div>
+          <span class="label">投放日期: </span>
+          <span class="value">{{ campaignInfo.startDate }} ~ {{ campaignInfo.endDate ?? '无结束日期' }}</span>
+        </div>
+        <div>
+          <span class="label">广告组合: </span>
+          <span class="value">{{ campaignInfo?.portfolioName }}</span>
+        </div>
+        <div>
+          <span class="label">竞价: </span>
+          <span class="value">{{ getEnumLabel(dynBidOptimizationEnum, campaignInfo.bidOptimization) }}</span>
+        </div>
       </div>
       </div>
     </div>
     </div>
-    <el-tabs type="border-card" class="asj-detail-tabs" v-model="tabActiveName">
+    <el-tabs v-model="tabActiveName" class="asj-detail-tabs" type="border-card">
       <el-tab-pane label="广告组" name="adGroup">
       <el-tab-pane label="广告组" name="adGroup">
-        <AdGroups :campaignId="route.query.campaignId" v-if="tabActiveName==='adGroup'"></AdGroups>
+        <AdGroups v-if="tabActiveName==='adGroup'" :campaignId="route.query.campaignId"></AdGroups>
       </el-tab-pane>
       </el-tab-pane>
       <el-tab-pane label="预算" name="budget">
       <el-tab-pane label="预算" name="budget">
-        <Budget :campaignId="route.query.campaignId" v-if="tabActiveName==='budget'"></Budget>
+        <Budget v-if="tabActiveName==='budget'" :campaignId="route.query.campaignId"></Budget>
       </el-tab-pane>
       </el-tab-pane>
       <el-tab-pane label="自动化" name="automation">
       <el-tab-pane label="自动化" name="automation">
-        <Automation :campaignId="campaignId" :profileId="profile.profile_id" v-if="tabActiveName==='automation'"></Automation>
+        <Automation v-if="tabActiveName==='automation'" :campaignId="campaignId"
+                    :profileId="profile.profile_id"></Automation>
       </el-tab-pane>
       </el-tab-pane>
       <el-tab-pane label="广告位" name="placement">
       <el-tab-pane label="广告位" name="placement">
-        <Placement :campaignId="route.query.campaignId" v-if="tabActiveName==='placement'"/>
+        <Placement v-if="tabActiveName==='placement'" :campaignId="route.query.campaignId" />
       </el-tab-pane>
       </el-tab-pane>
     </el-tabs>
     </el-tabs>
   </div>
   </div>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-import {onMounted, ref, Ref} from 'vue'
-import {useRoute} from 'vue-router'
-import AdGroups from './adGroups/index.vue'
-import Placement from './placement/index.vue'
-import Budget from './budget/index.vue'
-import {getEnumLabel} from '/@/views/adManage/utils/tools.js'
-import {dynBidOptimizationEnum, dynStatusEnum} from '/@/views/adManage/utils/enum.js'
-import {useShopInfo} from '/@/stores/shopInfo'
+import { onMounted, ref, Ref } from 'vue';
+import { useRoute } from 'vue-router';
+import AdGroups from './adGroups/index.vue';
+import Placement from './placement/index.vue';
+import Budget from './budget/index.vue';
+import { getEnumLabel, getTagType } from '/@/views/adManage/utils/tools.js';
+import { dynBidOptimizationEnum, dynStatusColorEnum, dynStatusEnum } from '/@/views/adManage/utils/enum.js';
+import { useShopInfo } from '/@/stores/shopInfo';
 // import { usePublicData } from '/@/stores/publicData'
 // import { usePublicData } from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
+import { storeToRefs } from 'pinia';
 
 
-import {GetObj} from './api'
+import { GetObj } from './api';
 import Automation from '/@/views/adManage/sb/campaigns/campaignDetail/automation/index.vue';
 import Automation from '/@/views/adManage/sb/campaigns/campaignDetail/automation/index.vue';
 
 
-const shopInfo = useShopInfo()
-const { profile } = storeToRefs(shopInfo)
-const route = useRoute()
-const campaignInfo: Ref<SpCampaign> = ref({})
-const tabActiveName = ref('adGroup')
 
 
-const campaignId = ref(route.query.campaignId)
+const shopInfo = useShopInfo();
+const { profile } = storeToRefs(shopInfo);
+const route = useRoute();
+const campaignInfo: Ref<SpCampaign> = ref({});
+const tabActiveName = ref('adGroup');
+
+const campaignId = ref(route.query.campaignId);
 
 
 onMounted(async () => {
 onMounted(async () => {
-  const resp = await GetObj(route.query.campaignId)
-  campaignInfo.value = resp.data
-})
+  const resp = await GetObj(route.query.campaignId);
+  campaignInfo.value = resp.data;
+});
 
 
 </script>
 </script>
 
 
@@ -69,6 +85,7 @@ onMounted(async () => {
   color: rgb(177, 177, 177);
   color: rgb(177, 177, 177);
   margin-left: 40px;
   margin-left: 40px;
 }
 }
+
 :deep(.el-tabs--border-card) {
 :deep(.el-tabs--border-card) {
   border: none;
   border: none;
 }
 }

+ 160 - 0
src/views/adManage/sd/campaigns/campaignDetail/automation/index.vue

@@ -0,0 +1,160 @@
+<script lang="ts" setup>
+import { nextTick, onMounted, ref } from 'vue';
+import TimerBid from '/@/views/components/auto/auto-campaigns/timer-bid.vue';
+import TimerBudget from '/@/views/components/auto/auto-campaigns/timer-budget.vue';
+import SwitchCampaign from '/@/views/components/auto/auto-campaigns/switch-campaign.vue';
+import TargetRule from '/@/views/components/auto/auto-campaigns/target-rule.vue';
+import SearchTermRule from '/@/views/components/auto/auto-campaigns/search-term.vue';
+import NegKeywordRule from '/@/views/components/auto/auto-campaigns/neg-keyword.vue';
+// import * as api from './api';
+
+interface Props {
+  campaignId: string;
+  profileId: string;
+}
+
+const props = defineProps<Props>();
+const campaignType = 'sd';
+const activeTab = ref(1);
+const RuleStatusButton = ref({
+  '1': 0,
+  '2': 0,
+  '3': 0,
+  '4': 0,
+  '5': 0,
+  '6': 0,
+})
+
+const baseData = ref({
+  campaignId: props.campaignId,
+  campaignType: campaignType,
+  profileId: props.profileId,
+  ruleType: activeTab,
+});
+
+async function changeStatus(newStatus: number, tabIndex: string) {
+  const body = {
+    ...baseData.value,
+    ruleType: Number(tabIndex),
+    status: newStatus
+  };
+  try {
+    const response = await postCampaignStatus(body);
+    if (response.code === 2000) {
+      ElMessage.success('更新状态成功');
+      // const resp = await getCampaignRuleInfo(baseData.value);
+      // RuleStatusButton.value = resp.data[0].RuleStatusButton;
+    } else if (response.code == 5000) {
+      ElMessage.warning(`${ response.data.description }`);
+    } else {
+      ElMessage.error('状态更新失败');
+    }
+  } catch (error) {
+    console.log('error:', error);
+  }
+}
+function updateRuleStatusButton(newValue) {
+  if (newValue !== undefined) {
+    RuleStatusButton.value = { ...RuleStatusButton.value, ...newValue }
+  } else {
+    console.error('接收到的 newValue 是 undefined')
+  }
+}
+
+async function refresh(tab: number) {
+  activeTab.value = 0;
+  nextTick(() => {
+    activeTab.value = tab;
+  });
+}
+
+onMounted(async () => {
+  // await initData();
+});
+</script>
+
+<template>
+  <el-tabs v-model="activeTab" tab-position="left" @tab-change="changeTab">
+    <el-tab-pane :name="1" label="分时调价">
+      <template #label>
+        <div class="tab-label">
+          <el-switch v-model="RuleStatusButton['1']" :active-value="1" :disabled="RuleStatusButton['1'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '1')" @click.stop="">
+          </el-switch>
+          <span>分时调价</span>
+        </div>
+      </template>
+      <TimerBid v-if="activeTab === 1" :RuleStatusButton="RuleStatusButton" :data="baseData" @refresh="refresh(1)"  @updateRuleStatusButton="updateRuleStatusButton"/>
+    </el-tab-pane>
+    <el-tab-pane :name="2" label="分时预算" v-if="false">
+    <!--  <template #label>-->
+    <!--    <div class="tab-label">-->
+    <!--      <el-switch v-model="RuleStatusButton['2']" :active-value="1" :disabled="RuleStatusButton['2'] === '-'"-->
+    <!--                 :inactive-value="0" size="small" @change="(val) => changeStatus(val, '2')" @click.stop="">-->
+    <!--      </el-switch>-->
+    <!--      <span>分时预算</span>-->
+    <!--    </div>-->
+    <!--  </template>-->
+    <!--  <TimerBudget v-if="activeTab === 2" :RuleStatusButton="RuleStatusButton" :data="baseData" @refresh="refresh(2)" />-->
+    </el-tab-pane>
+    <el-tab-pane :name="3" label="开启/暂停广告活动">
+      <template #label>
+        <div class="tab-label">
+          <el-switch v-model="RuleStatusButton['3']" :active-value="1" :disabled="RuleStatusButton['3'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '3')" @click.stop="">
+          </el-switch>
+          <span>开启/暂停广告活动</span>
+        </div>
+      </template>
+      <SwitchCampaign v-if="activeTab === 3" :RuleStatusButton="RuleStatusButton" :data="baseData"
+                      @refresh="refresh(3)" />
+    </el-tab-pane>
+    <el-tab-pane :name="4" label="定向规则">
+      <template #label>
+        <div class="tab-label">
+          <el-switch v-model="RuleStatusButton['4']" :active-value="1" :disabled="RuleStatusButton['4'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '4')" @click.stop="">
+          </el-switch>
+          <span>定向规则</span>
+        </div>
+      </template>
+      <TargetRule v-if="activeTab === 4" :RuleStatusButton="RuleStatusButton" :data="baseData"
+                  @refresh="refresh(4)"></TargetRule>
+    </el-tab-pane>
+    <el-tab-pane :name="5" label="添加搜索词" v-if="false">
+      <!--<template #label>-->
+      <!--  <div class="tab-label">-->
+      <!--    <el-switch v-model="RuleStatusButton['5']" :active-value="1" :disabled="RuleStatusButton['5'] === '-'"-->
+      <!--               :inactive-value="0" size="small" @change="(val) => changeStatus(val, '5')" @click.stop="">-->
+      <!--    </el-switch>-->
+      <!--    <span>添加搜索词</span>-->
+      <!--  </div>-->
+      <!--</template>-->
+      <!--<SearchTermRule v-if="activeTab === 5" :RuleStatusButton="RuleStatusButton" :data="baseData"-->
+      <!--                @refresh="refresh(5)">-->
+      <!--</SearchTermRule>-->
+    </el-tab-pane>
+    <el-tab-pane :name="6" label="添加否定词" v-if="false">
+      <!--<template #label>-->
+      <!--  <div class="tab-label">-->
+      <!--    <el-switch v-model="RuleStatusButton['6']" :active-value="1" :disabled="RuleStatusButton['6'] === '-'"-->
+      <!--               :inactive-value="0" size="small" @change="(val) => changeStatus(val, '6')" @click.stop="">-->
+      <!--    </el-switch>-->
+      <!--    <span>添加否定词</span>-->
+      <!--  </div>-->
+      <!--</template>-->
+      <!--<NegKeywordRule v-if="activeTab === 6" :RuleStatusButton="RuleStatusButton" :data="baseData"-->
+      <!--                @refresh="refresh(6)">-->
+      <!--</NegKeywordRule>-->
+    </el-tab-pane>
+  </el-tabs>
+</template>
+
+<style lang="scss" scoped>
+.tab-label {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 155px;
+}
+</style>

+ 53 - 34
src/views/adManage/sd/campaigns/campaignDetail/index.vue

@@ -5,29 +5,44 @@
         <span> {{ campaignInfo.campaignName }}</span>
         <span> {{ campaignInfo.campaignName }}</span>
       </span>
       </span>
       <div class="asj-detail-info">
       <div class="asj-detail-info">
-        <span style="color: rgb(177, 177, 177)">状态: </span>
-        <span v-if="campaignInfo.state==='enabled'">
-          <el-button class="no-hover-effect" type="success" round plain size="small" style="margin-top: -3px">{{( dynStatusEnum[campaignInfo.state] )}}</el-button>
-        </span><!--({{ campaignInfo.servingStatus }})-->
-        <span v-else>
-          <el-button class="no-hover-effect-ban" type="danger" round plain size="small" style="margin-top: -3px">{{( dynStatusEnum[campaignInfo.state] )}}</el-button>
-        </span>
-        <span class="head-span">预算: </span> <span>{{ profile.currency_symbol + campaignInfo.budget }} | {{ dynStatusEnum[campaignInfo.budgetType] }}</span>
-        <span class="head-span">投放类型:</span> <span>{{ dynStatusEnum[campaignInfo.tactic] }}</span>
-        <span class="head-span">投放日期: </span> <span>{{ campaignInfo.startDate }} ~ {{ campaignInfo.endDate ?? '无结束日期' }}</span>
-        <span class="head-span">广告组合: </span> <span>{{ campaignInfo?.portfolio_name ? campaignInfo.portfolio_name : '--'}}</span>
-        <span class="head-span">成本类型: </span> <span>{{ campaignInfo.costType }}</span>
+        <div>
+          <span class="label">状态: </span>
+          <el-tag :type="getTagType(campaignInfo.state)">
+            {{ dynStatusEnum[campaignInfo.state] }}
+          </el-tag>
+        </div>
+        <div>
+          <span class="label">预算: </span>
+          <span class="value"> {{ profile.currency_symbol + campaignInfo.budget }} | {{dynStatusEnum[campaignInfo.budgetType] }}</span>
+        </div>
+        <div>
+          <span class="label">投放类型:</span>
+          <span class="value">{{ targetTypeEnum[campaignInfo.tactic] }}</span>
+        </div>
+        <div>
+          <span class="label">投放日期: </span>
+          <span class="value">{{ campaignInfo.startDate }} ~ {{ campaignInfo.endDate ?? '无结束日期' }}</span>
+        </div>
+        <div>
+          <span class="label">广告组合: </span>
+          <span class="value">{{ campaignInfo?.portfolio_name ? campaignInfo.portfolio_name : '--' }}</span>
+        </div>
+        <div>
+          <span class="label">成本类型: </span>
+          <span class="value">{{ campaignInfo.costType }}</span>
+        </div>
       </div>
       </div>
     </div>
     </div>
-    <el-tabs type="border-card" class="asj-detail-tabs" v-model="tabActiveName">
+    <el-tabs v-model="tabActiveName" class="asj-detail-tabs" type="border-card">
       <el-tab-pane label="广告组" name="adGroup">
       <el-tab-pane label="广告组" name="adGroup">
-        <AdGroups :campaignId="route.query.campaignId" v-if="tabActiveName==='adGroup'"></AdGroups>
+        <AdGroups v-if="tabActiveName==='adGroup'" :campaignId="route.query.campaignId"></AdGroups>
       </el-tab-pane>
       </el-tab-pane>
       <!-- <el-tab-pane label="预算" name="budget">
       <!-- <el-tab-pane label="预算" name="budget">
         <Budget :campaignId="route.query.campaignId" v-if="tabActiveName==='budget'"></Budget>
         <Budget :campaignId="route.query.campaignId" v-if="tabActiveName==='budget'"></Budget>
       </el-tab-pane> -->
       </el-tab-pane> -->
       <el-tab-pane label="自动化" name="automation">
       <el-tab-pane label="自动化" name="automation">
-        自动化
+        <Automation v-if="tabActiveName==='automation'" :campaignId="campaignId"
+                    :profileId="profile.profile_id"></Automation>
       </el-tab-pane>
       </el-tab-pane>
       <!-- <el-tab-pane label="广告位" name="placement">
       <!-- <el-tab-pane label="广告位" name="placement">
         <Placement :campaignId="route.query.campaignId" v-if="tabActiveName==='placement'"/>
         <Placement :campaignId="route.query.campaignId" v-if="tabActiveName==='placement'"/>
@@ -37,29 +52,30 @@
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-import {onMounted, ref, Ref} from 'vue'
-import {useRoute} from 'vue-router'
-import AdGroups from './adGroups/index.vue'
-import Placement from './placement/index.vue'
-import Budget from './budget/index.vue'
-import {getEnumLabel} from '/@/views/adManage/utils/tools.js'
-import {dynBidOptimizationEnum, dynStatusEnum} from '/@/views/adManage/utils/enum.js'
-import {useShopInfo} from '/@/stores/shopInfo'
+import { onMounted, ref, Ref } from 'vue';
+import { useRoute } from 'vue-router';
+import AdGroups from './adGroups/index.vue';
+import { getTagType } from '/@/views/adManage/utils/tools.js';
+import { dynStatusEnum, targetTypeEnum } from '/@/views/adManage/utils/enum.js';
+import { useShopInfo } from '/@/stores/shopInfo';
 // import { usePublicData } from '/@/stores/publicData'
 // import { usePublicData } from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
+import { storeToRefs } from 'pinia';
 
 
-import {GetObj} from './api'
-const x = 't20'
-const shopInfo = useShopInfo()
-const { profile } = storeToRefs(shopInfo)
-const route = useRoute()
-const campaignInfo: Ref<SpCampaign> = ref({})
-const tabActiveName = ref('adGroup')
+import { GetObj } from './api';
+import Automation from '/@/views/adManage/sd/campaigns/campaignDetail/automation/index.vue';
+
+
+const x = 't20';
+const shopInfo = useShopInfo();
+const { profile } = storeToRefs(shopInfo);
+const route = useRoute();
+const campaignInfo: Ref<SpCampaign> = ref({});
+const tabActiveName = ref('adGroup');
 
 
 onMounted(async () => {
 onMounted(async () => {
-  const resp = await GetObj(route.query.campaignId)
-  campaignInfo.value = resp.data[0]
-})
+  const resp = await GetObj(route.query.campaignId);
+  campaignInfo.value = resp.data[0];
+});
 
 
 </script>
 </script>
 
 
@@ -69,12 +85,15 @@ onMounted(async () => {
   color: rgb(177, 177, 177);
   color: rgb(177, 177, 177);
   margin-left: 40px;
   margin-left: 40px;
 }
 }
+
 :deep(.el-tabs--border-card) {
 :deep(.el-tabs--border-card) {
   border: none;
   border: none;
 }
 }
+
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);
   border-right: 1px solid rgb(218, 221, 223);
 }
 }
+
 ::v-deep(.el-table__header-wrapper .el-table__header tr th) {
 ::v-deep(.el-table__header-wrapper .el-table__header tr th) {
   border-right: none;
   border-right: none;
 }
 }

+ 3 - 2
src/views/adManage/sp/campaigns/campaignDetail/automation/index.vue

@@ -20,6 +20,7 @@ import { userFormData } from '/@/views/components/auto/auto-campaigns/common';
 interface Props {
 interface Props {
   campaignId: string;
   campaignId: string;
   profileId: string;
   profileId: string;
+  targetingType: string;
 }
 }
 
 
 const props = defineProps<Props>();
 const props = defineProps<Props>();
@@ -118,7 +119,7 @@ onMounted(async () => {
       <SwitchCampaign v-if="activeTab === 3" :RuleStatusButton="RuleStatusButton" :data="baseData"
       <SwitchCampaign v-if="activeTab === 3" :RuleStatusButton="RuleStatusButton" :data="baseData"
                       @refresh="refresh(3)" />
                       @refresh="refresh(3)" />
     </el-tab-pane>
     </el-tab-pane>
-    <el-tab-pane :name="4" label="定向规则">
+    <el-tab-pane :name="4" label="定向规则" v-if="targetingType !== 'AUTO'">
       <template #label>
       <template #label>
         <div class="tab-label">
         <div class="tab-label">
           <el-switch v-model="RuleStatusButton['4']" :active-value="1" :disabled="RuleStatusButton['4'] === '-'"
           <el-switch v-model="RuleStatusButton['4']" :active-value="1" :disabled="RuleStatusButton['4'] === '-'"
@@ -130,7 +131,7 @@ onMounted(async () => {
       <TargetRule v-if="activeTab === 4" :RuleStatusButton="RuleStatusButton" :data="baseData"
       <TargetRule v-if="activeTab === 4" :RuleStatusButton="RuleStatusButton" :data="baseData"
                   @refresh="refresh(4)"></TargetRule>
                   @refresh="refresh(4)"></TargetRule>
     </el-tab-pane>
     </el-tab-pane>
-    <el-tab-pane :name="5" label="添加搜索词">
+    <el-tab-pane :name="5" label="添加搜索词" v-if="targetingType !== 'AUTO'">
       <template #label>
       <template #label>
         <div class="tab-label">
         <div class="tab-label">
           <el-switch v-model="RuleStatusButton['5']" :active-value="1" :disabled="RuleStatusButton['5'] === '-'"
           <el-switch v-model="RuleStatusButton['5']" :active-value="1" :disabled="RuleStatusButton['5'] === '-'"

+ 9 - 7
src/views/adManage/sp/campaigns/campaignDetail/index.vue

@@ -5,8 +5,8 @@ import AdGroups from './adGroups/index.vue'
 import Placement from './placement/index.vue'
 import Placement from './placement/index.vue'
 import Budget from './budget/index.vue'
 import Budget from './budget/index.vue'
 import Automation from './automation/index.vue'
 import Automation from './automation/index.vue'
-import {getEnumLabel} from '/@/views/adManage/utils/tools.js'
-import {dynBidStrategyEnum} from '/@/views/adManage/utils/enum.js'
+import { getEnumLabel, getTagType } from '/@/views/adManage/utils/tools.js';
+import { dynBidStrategyEnum, dynStatusEnum, spTargetTypeEnum } from '/@/views/adManage/utils/enum.js';
 import {useShopInfo} from '/@/stores/shopInfo'
 import {useShopInfo} from '/@/stores/shopInfo'
 // import { usePublicData } from '/@/stores/publicData'
 // import { usePublicData } from '/@/stores/publicData'
 import {storeToRefs} from 'pinia'
 import {storeToRefs} from 'pinia'
@@ -37,16 +37,18 @@ onMounted(async () => {
       </span>
       </span>
       <div class="asj-detail-info">
       <div class="asj-detail-info">
         <div>
         <div>
-          <span class="label">状态:</span>
-          <span class="value">{{ campaignInfo.state }} ({{ campaignInfo.servingStatus }})</span>
+          <span class="label">状态: </span>
+          <el-tag :type="getTagType(campaignInfo.state)">
+            {{ dynStatusEnum[campaignInfo.state] }}
+          </el-tag>
         </div>
         </div>
         <div>
         <div>
           <span class="label">预算:</span>
           <span class="label">预算:</span>
-          <span class="value">{{ profile.currency_symbol + campaignInfo.budget }} | {{ campaignInfo.budgetType }}</span>
+          <span class="value">{{ profile.currency_symbol + campaignInfo.budget }} | {{ dynStatusEnum[campaignInfo.budgetType] }}</span>
         </div>
         </div>
         <div>
         <div>
           <span class="label">投放类型:</span>
           <span class="label">投放类型:</span>
-          <span class="value">{{ campaignInfo.targetingType }}</span>
+          <span class="value">{{ spTargetTypeEnum[campaignInfo.targetingType] }}</span>
         </div>
         </div>
         <div>
         <div>
           <span class="label">投放日期:</span>
           <span class="label">投放日期:</span>
@@ -70,7 +72,7 @@ onMounted(async () => {
         <Budget :campaignId="campaignId" v-if="tabActiveName==='budget'"></Budget>
         <Budget :campaignId="campaignId" v-if="tabActiveName==='budget'"></Budget>
       </el-tab-pane>
       </el-tab-pane>
       <el-tab-pane label="自动化" name="automation">
       <el-tab-pane label="自动化" name="automation">
-        <Automation :campaignId="campaignId" :profileId="profile.profile_id" v-if="tabActiveName==='automation'"></Automation>
+        <Automation :campaignId="campaignId" :profileId="profile.profile_id" :targetingType="campaignInfo.targetingType" v-if="tabActiveName==='automation'"></Automation>
       </el-tab-pane>
       </el-tab-pane>
       <el-tab-pane label="广告位" name="placement">
       <el-tab-pane label="广告位" name="placement">
         <Placement :campaignId="campaignId" v-if="tabActiveName==='placement'"/>
         <Placement :campaignId="campaignId" v-if="tabActiveName==='placement'"/>

+ 251 - 236
src/views/adManage/utils/enum.ts

@@ -1,251 +1,267 @@
 export const spCampaignMetricsEnum = [
 export const spCampaignMetricsEnum = [
-  {label: '曝光量', value: 'Impression'},
-  {label: '点击量', value: 'Click'},
-  {label: '花费', value: 'Spend'},
-  {label: '订单量', value: 'TotalPurchases'},
-  {label: '销售额', value: 'TotalSales'},
-  {label: '销量', value: 'TotalUnitOrdered'},
-  {label: '点击率', value: 'CTR'},
-  {label: '点击成本', value: 'CPC'},
-  {label: '转化率', value: 'PurchasesRate'},
-  {label: 'ACOS', value: 'ACOS'},
-  {label: 'ROAS', value: 'ROAS'},
-  {label: '订单成本', value: 'CPA'},
-  {label: '推广商品销售额', value: 'TotalSalesSameSKU'},
-  {label: '其它商品销售额', value: 'TotalSalesOtherSKU'},
-  {label: '推广商品订单量', value: 'TotalPurchasesSameSKU'},
-  {label: '其它商品订单量', value: 'TotalPurchasesOtherSKU'},
-  {label: '推广商品销量', value: 'TotalUnitOrderedSameSKU'},
-  {label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU'},
-]
+  { label: '曝光量', value: 'Impression' },
+  { label: '点击量', value: 'Click' },
+  { label: '花费', value: 'Spend' },
+  { label: '订单量', value: 'TotalPurchases' },
+  { label: '销售额', value: 'TotalSales' },
+  { label: '销量', value: 'TotalUnitOrdered' },
+  { label: '点击率', value: 'CTR' },
+  { label: '点击成本', value: 'CPC' },
+  { label: '转化率', value: 'PurchasesRate' },
+  { label: 'ACOS', value: 'ACOS' },
+  { label: 'ROAS', value: 'ROAS' },
+  { label: '订单成本', value: 'CPA' },
+  { label: '推广商品销售额', value: 'TotalSalesSameSKU' },
+  { label: '其它商品销售额', value: 'TotalSalesOtherSKU' },
+  { label: '推广商品订单量', value: 'TotalPurchasesSameSKU' },
+  { label: '其它商品订单量', value: 'TotalPurchasesOtherSKU' },
+  { label: '推广商品销量', value: 'TotalUnitOrderedSameSKU' },
+  { label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU' },
+];
 
 
 export const sbCampaignMetricsEnum = [
 export const sbCampaignMetricsEnum = [
-  {label: '曝光量', value: 'Impression'},
-  {label: '点击量', value: 'Click'},
-  {label: '花费', value: 'Spend'},
-  {label: '订单量', value: 'TotalPurchases'},
-  {label: '销售额', value: 'TotalSales'},
-  {label: '销量', value: 'TotalUnitOrdered'},
-  {label: '点击率', value: 'CTR'},
-  {label: '点击成本', value: 'CPC'},
-  {label: '转化率', value: 'PurchasesRate'},
-  {label: 'ACOS', value: 'ACOS'},
-  {label: 'ROAS', value: 'ROAS'},
-  {label: '订单成本', value: 'CPA'},
-  {label: '推广商品销售额', value: 'TotalSalesSameSKU'},
-  {label: '其它商品销售额', value: 'TotalSalesOtherSKU'},
-  {label: '推广商品订单量', value: 'TotalPurchasesSameSKU'},
-  {label: '其它商品订单量', value: 'TotalPurchasesOtherSKU'},
-  {label: '推广商品销量', value: 'TotalUnitOrderedSameSKU'},
-  {label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU'},
-  {label: '详情页浏览次数', value: 'DPV'},
-  {label: '详情页浏览率', value: 'DPVR'},
-  {label: '新客订单数', value: 'NTBOrder'},
-  {label: '新客订单占比', value: 'NTBOrderRate'},
-  {label: '新客销售额', value: 'NTBSales'},
-  {label: '新客销售占比', value: 'NTBSalesRate'},
-  {label: '新客销量', value: 'NTBUnitOrdered'},
-  {label: '新客销量占比', value: 'NTBUnitOrderedRate'},
-  {label: '浏览点击率', value: 'VCTR'},
-  {label: '可见曝光率', value: 'VIR'},
-  {label: '浏览率', value: 'VTR'},
-  {label: '播放5秒或完成数占比', value: 'Video5SecondViewRate'},
-  {label: '播放5秒或完成数', value: 'Video5SecondViews'},
-  {label: '视频播放25%', value: 'VideoFirstQuartileViews'},
-  {label: '视频播放50%', value: 'VideoMidpointViews'},
-  {label: '视频播放75%', value: 'VideoThirdQuartileViews'},
-  {label: '视频播放100%', value: 'VideoCompleteViews'},
-  {label: '视频取消静音数', value: 'VideoUnmutes'},
-  {label: '可见曝光量', value: 'ViewableImpression'},
-]
-export const sbBarOptions1= [
-  {label: '曝光量', value: 'Impression'},
-  {label: '点击量', value: 'Click'},
-  {label: '花费', value: 'Spend'},
-  {label: '订单量', value: 'TotalPurchases'},
-  {label: '销售额', value: 'TotalSales'},
-  {label: '销量', value: 'TotalUnitOrdered'},
-  {label: '点击率', value: 'CTR'},
-  {label: '点击成本', value: 'CPC'},
-  {label: '转化率', value: 'PurchasesRate'},
-  {label: 'ACOS', value: 'ACOS'},
-  {label: 'ROAS', value: 'ROAS'},
-  {label: '订单成本', value: 'CPA'},
-  {label: '推广商品销售额', value: 'TotalSalesSameSKU'},
-  {label: '其它商品销售额', value: 'TotalSalesOtherSKU'},
-  {label: '推广商品订单量', value: 'TotalPurchasesSameSKU'},
-  {label: '其它商品订单量', value: 'TotalPurchasesOtherSKU'},
-  {label: '推广商品销量', value: 'TotalUnitOrderedSameSKU'},
-  {label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU'},
-  {label: '详情页浏览次数', value: 'DPV'},
-  {label: '详情页浏览率', value: 'DPVR'},
-  {label: '新客订单数', value: 'NTBOrder'},
-  {label: '新客订单占比', value: 'NTBOrderRate'},
-  {label: '新客销售额', value: 'NTBSales'},
-  {label: '新客销售占比', value: 'NTBSalesRate'},
-  {label: '新客销量', value: 'NTBUnitOrdered'},
-  {label: '新客销量占比', value: 'NTBUnitOrderedRate'},
-  {label: '浏览点击率', value: 'VCTR'},
-  {label: '可见曝光率', value: 'VIR'},
-  {label: '浏览率', value: 'VTR'},
-  {label: '播放5秒或完成数占比', value: 'Video5SecondViewRate'},
-  {label: '播放5秒或完成数', value: 'Video5SecondViews'},
-  {label: '视频播放25%', value: 'VideoFirstQuartileViews'},
-  {label: '视频播放50%', value: 'VideoMidpointViews'},
-  {label: '视频播放75%', value: 'VideoThirdQuartileViews'},
-  {label: '视频播放100%', value: 'VideoCompleteViews'},
-  {label: '视频取消静音数', value: 'VideoUnmutes'},
-  {label: '可见曝光量', value: 'ViewableImpression'},
-]
-export const sbBarOptions2= [
-  {label: '曝光量', value: 'Impression'},
-  {label: '点击量', value: 'Click'},
-  {label: '花费', value: 'Spend'},
-  {label: '订单量', value: 'TotalPurchases'},
-  {label: '销售额', value: 'TotalSales'},
-  {label: '销量', value: 'TotalUnitOrdered'},
-  {label: '点击率', value: 'CTR'},
-  {label: '点击成本', value: 'CPC'},
-  {label: '转化率', value: 'PurchasesRate'},
-  {label: 'ACOS', value: 'ACOS'},
-  {label: 'ROAS', value: 'ROAS'},
-  {label: '订单成本', value: 'CPA'},
-  {label: '推广商品销售额', value: 'TotalSalesSameSKU'},
-  {label: '其它商品销售额', value: 'TotalSalesOtherSKU'},
-  {label: '推广商品订单量', value: 'TotalPurchasesSameSKU'},
-  {label: '其它商品订单量', value: 'TotalPurchasesOtherSKU'},
-  {label: '推广商品销量', value: 'TotalUnitOrderedSameSKU'},
-  {label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU'},
-  {label: '详情页浏览次数', value: 'DPV'},
-  {label: '详情页浏览率', value: 'DPVR'},
-  {label: '新客订单数', value: 'NTBOrder'},
-  {label: '新客订单占比', value: 'NTBOrderRate'},
-  {label: '新客销售额', value: 'NTBSales'},
-  {label: '新客销售占比', value: 'NTBSalesRate'},
-  {label: '新客销量', value: 'NTBUnitOrdered'},
-  {label: '新客销量占比', value: 'NTBUnitOrderedRate'},
-  {label: '浏览点击率', value: 'VCTR'},
-  {label: '可见曝光率', value: 'VIR'},
-  {label: '浏览率', value: 'VTR'},
-  {label: '播放5秒或完成数占比', value: 'Video5SecondViewRate'},
-  {label: '播放5秒或完成数', value: 'Video5SecondViews'},
-  {label: '视频播放25%', value: 'VideoFirstQuartileViews'},
-  {label: '视频播放50%', value: 'VideoMidpointViews'},
-  {label: '视频播放75%', value: 'VideoThirdQuartileViews'},
-  {label: '视频播放100%', value: 'VideoCompleteViews'},
-  {label: '视频取消静音数', value: 'VideoUnmutes'},
-  {label: '可见曝光量', value: 'ViewableImpression'},
-]
+  { label: '曝光量', value: 'Impression' },
+  { label: '点击量', value: 'Click' },
+  { label: '花费', value: 'Spend' },
+  { label: '订单量', value: 'TotalPurchases' },
+  { label: '销售额', value: 'TotalSales' },
+  { label: '销量', value: 'TotalUnitOrdered' },
+  { label: '点击率', value: 'CTR' },
+  { label: '点击成本', value: 'CPC' },
+  { label: '转化率', value: 'PurchasesRate' },
+  { label: 'ACOS', value: 'ACOS' },
+  { label: 'ROAS', value: 'ROAS' },
+  { label: '订单成本', value: 'CPA' },
+  { label: '推广商品销售额', value: 'TotalSalesSameSKU' },
+  { label: '其它商品销售额', value: 'TotalSalesOtherSKU' },
+  { label: '推广商品订单量', value: 'TotalPurchasesSameSKU' },
+  { label: '其它商品订单量', value: 'TotalPurchasesOtherSKU' },
+  { label: '推广商品销量', value: 'TotalUnitOrderedSameSKU' },
+  { label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU' },
+  { label: '详情页浏览次数', value: 'DPV' },
+  { label: '详情页浏览率', value: 'DPVR' },
+  { label: '新客订单数', value: 'NTBOrder' },
+  { label: '新客订单占比', value: 'NTBOrderRate' },
+  { label: '新客销售额', value: 'NTBSales' },
+  { label: '新客销售占比', value: 'NTBSalesRate' },
+  { label: '新客销量', value: 'NTBUnitOrdered' },
+  { label: '新客销量占比', value: 'NTBUnitOrderedRate' },
+  { label: '浏览点击率', value: 'VCTR' },
+  { label: '可见曝光率', value: 'VIR' },
+  { label: '浏览率', value: 'VTR' },
+  { label: '播放5秒或完成数占比', value: 'Video5SecondViewRate' },
+  { label: '播放5秒或完成数', value: 'Video5SecondViews' },
+  { label: '视频播放25%', value: 'VideoFirstQuartileViews' },
+  { label: '视频播放50%', value: 'VideoMidpointViews' },
+  { label: '视频播放75%', value: 'VideoThirdQuartileViews' },
+  { label: '视频播放100%', value: 'VideoCompleteViews' },
+  { label: '视频取消静音数', value: 'VideoUnmutes' },
+  { label: '可见曝光量', value: 'ViewableImpression' },
+];
+export const sbBarOptions1 = [
+  { label: '曝光量', value: 'Impression' },
+  { label: '点击量', value: 'Click' },
+  { label: '花费', value: 'Spend' },
+  { label: '订单量', value: 'TotalPurchases' },
+  { label: '销售额', value: 'TotalSales' },
+  { label: '销量', value: 'TotalUnitOrdered' },
+  { label: '点击率', value: 'CTR' },
+  { label: '点击成本', value: 'CPC' },
+  { label: '转化率', value: 'PurchasesRate' },
+  { label: 'ACOS', value: 'ACOS' },
+  { label: 'ROAS', value: 'ROAS' },
+  { label: '订单成本', value: 'CPA' },
+  { label: '推广商品销售额', value: 'TotalSalesSameSKU' },
+  { label: '其它商品销售额', value: 'TotalSalesOtherSKU' },
+  { label: '推广商品订单量', value: 'TotalPurchasesSameSKU' },
+  { label: '其它商品订单量', value: 'TotalPurchasesOtherSKU' },
+  { label: '推广商品销量', value: 'TotalUnitOrderedSameSKU' },
+  { label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU' },
+  { label: '详情页浏览次数', value: 'DPV' },
+  { label: '详情页浏览率', value: 'DPVR' },
+  { label: '新客订单数', value: 'NTBOrder' },
+  { label: '新客订单占比', value: 'NTBOrderRate' },
+  { label: '新客销售额', value: 'NTBSales' },
+  { label: '新客销售占比', value: 'NTBSalesRate' },
+  { label: '新客销量', value: 'NTBUnitOrdered' },
+  { label: '新客销量占比', value: 'NTBUnitOrderedRate' },
+  { label: '浏览点击率', value: 'VCTR' },
+  { label: '可见曝光率', value: 'VIR' },
+  { label: '浏览率', value: 'VTR' },
+  { label: '播放5秒或完成数占比', value: 'Video5SecondViewRate' },
+  { label: '播放5秒或完成数', value: 'Video5SecondViews' },
+  { label: '视频播放25%', value: 'VideoFirstQuartileViews' },
+  { label: '视频播放50%', value: 'VideoMidpointViews' },
+  { label: '视频播放75%', value: 'VideoThirdQuartileViews' },
+  { label: '视频播放100%', value: 'VideoCompleteViews' },
+  { label: '视频取消静音数', value: 'VideoUnmutes' },
+  { label: '可见曝光量', value: 'ViewableImpression' },
+];
+export const sbBarOptions2 = [
+  { label: '曝光量', value: 'Impression' },
+  { label: '点击量', value: 'Click' },
+  { label: '花费', value: 'Spend' },
+  { label: '订单量', value: 'TotalPurchases' },
+  { label: '销售额', value: 'TotalSales' },
+  { label: '销量', value: 'TotalUnitOrdered' },
+  { label: '点击率', value: 'CTR' },
+  { label: '点击成本', value: 'CPC' },
+  { label: '转化率', value: 'PurchasesRate' },
+  { label: 'ACOS', value: 'ACOS' },
+  { label: 'ROAS', value: 'ROAS' },
+  { label: '订单成本', value: 'CPA' },
+  { label: '推广商品销售额', value: 'TotalSalesSameSKU' },
+  { label: '其它商品销售额', value: 'TotalSalesOtherSKU' },
+  { label: '推广商品订单量', value: 'TotalPurchasesSameSKU' },
+  { label: '其它商品订单量', value: 'TotalPurchasesOtherSKU' },
+  { label: '推广商品销量', value: 'TotalUnitOrderedSameSKU' },
+  { label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU' },
+  { label: '详情页浏览次数', value: 'DPV' },
+  { label: '详情页浏览率', value: 'DPVR' },
+  { label: '新客订单数', value: 'NTBOrder' },
+  { label: '新客订单占比', value: 'NTBOrderRate' },
+  { label: '新客销售额', value: 'NTBSales' },
+  { label: '新客销售占比', value: 'NTBSalesRate' },
+  { label: '新客销量', value: 'NTBUnitOrdered' },
+  { label: '新客销量占比', value: 'NTBUnitOrderedRate' },
+  { label: '浏览点击率', value: 'VCTR' },
+  { label: '可见曝光率', value: 'VIR' },
+  { label: '浏览率', value: 'VTR' },
+  { label: '播放5秒或完成数占比', value: 'Video5SecondViewRate' },
+  { label: '播放5秒或完成数', value: 'Video5SecondViews' },
+  { label: '视频播放25%', value: 'VideoFirstQuartileViews' },
+  { label: '视频播放50%', value: 'VideoMidpointViews' },
+  { label: '视频播放75%', value: 'VideoThirdQuartileViews' },
+  { label: '视频播放100%', value: 'VideoCompleteViews' },
+  { label: '视频取消静音数', value: 'VideoUnmutes' },
+  { label: '可见曝光量', value: 'ViewableImpression' },
+];
 
 
 export const sdCampaignMetricsEnum = [
 export const sdCampaignMetricsEnum = [
-  {label: '花费', value: 'Spend'},
-  {label: '销售额', value: 'TotalSales'},
-  {label: '销售额(vCPM)', value: 'TotalUnitOrderedVCPM'},
-  {label: '销售额(Click)', value: 'TotalSalesClick'},
-  {label: '订单数', value: 'TotalPurchases'},
-  {label: '订单数(vCPM)', value: 'TotalPurchasesVCPM'},
-  {label: '订单数(Click)', value: 'TotalPurchasesClick'},
-  {label: 'ACOS', value: 'ACOS'},
-  {label: 'ROAS', value: 'ROAS'},
-  {label: '点击成本', value: 'CPC'},
-  {label: '千次可见曝光成本', value: 'VCPM' },
-  {label: '转化率', value: 'PurchasesRate'},
-  {label: '订单成本', value: 'CPA'},
-  {label: '销量', value: 'TotalUnitOrdered'},
-  {label: '销量(vCPM)', value: 'TotalUnitOrdered'},
-  {label: '销量(Click)', value: 'TotalPurchasesClick'},
-  {label: '曝光量', value: 'Impression'},
-  {label: '点击量', value: 'Click'},
-  {label: '点击率', value: 'CTR'},
-  {label: '可见曝光量', value: 'ViewableImpression'},
-  {label: '可见曝光率', value: 'VIR'},
-  {label: '详情页浏览次数', value: 'DPV'},
-  {label: '详情页浏览率', value: 'DPVR'},
-  {label: '商品详情页浏览次数(vCPM)', value: 'DPVVCPM'},
-  {label: '商品详情页浏览次数(Click)', value: 'DPVClick'},
+  { label: '花费', value: 'Spend' },
+  { label: '销售额', value: 'TotalSales' },
+  { label: '销售额(vCPM)', value: 'TotalUnitOrderedVCPM' },
+  { label: '销售额(Click)', value: 'TotalSalesClick' },
+  { label: '订单数', value: 'TotalPurchases' },
+  { label: '订单数(vCPM)', value: 'TotalPurchasesVCPM' },
+  { label: '订单数(Click)', value: 'TotalPurchasesClick' },
+  { label: 'ACOS', value: 'ACOS' },
+  { label: 'ROAS', value: 'ROAS' },
+  { label: '点击成本', value: 'CPC' },
+  { label: '千次可见曝光成本', value: 'VCPM' },
+  { label: '转化率', value: 'PurchasesRate' },
+  { label: '订单成本', value: 'CPA' },
+  { label: '销量', value: 'TotalUnitOrdered' },
+  { label: '销量(vCPM)', value: 'TotalUnitOrdered' },
+  { label: '销量(Click)', value: 'TotalPurchasesClick' },
+  { label: '曝光量', value: 'Impression' },
+  { label: '点击量', value: 'Click' },
+  { label: '点击率', value: 'CTR' },
+  { label: '可见曝光量', value: 'ViewableImpression' },
+  { label: '可见曝光率', value: 'VIR' },
+  { label: '详情页浏览次数', value: 'DPV' },
+  { label: '详情页浏览率', value: 'DPVR' },
+  { label: '商品详情页浏览次数(vCPM)', value: 'DPVVCPM' },
+  { label: '商品详情页浏览次数(Click)', value: 'DPVClick' },
   // {label: '浏览订单', value: 'DPVR'},
   // {label: '浏览订单', value: 'DPVR'},
-  {label: '推广商品销售额', value: 'TotalSalesSameSKU'},
-  {label: '其它商品销售额', value: 'TotalSalesOtherSKU'},
-  {label: '推广商品订单数', value: 'TotalPurchasesSameSKU'},
-  {label: '其它商品订单数', value: 'TotalPurchasesOtherSKU'},
-  {label: '新客订单数', value: 'NTBOrder'},
-  {label: '新客订单占比', value: 'NTBOrderRate'},
-  {label: '新客销售额', value: 'NTBSales'},
-  {label: '新客销售占比', value: 'NTBSalesRate'},
-  {label: '新客销量', value: 'NTBUnitOrdered'},
-  {label: '新客销量占比', value: 'NTBUnitOrderedRate'},
-  {label: '视频播放25%', value: 'VideoFirstQuartileViews'},
-  {label: '视频播放50%', value: 'VideoMidpointViews'},
-  {label: '视频播放75%', value: 'VideoThirdQuartileViews'},
-  {label: '视频播放100%', value: 'VideoCompleteViews'},
-  {label: '视频取消静音数', value: 'VideoUnmutes'},
-  {label: '浏览率(VTR)', value: 'VTR'},
-  {label: '浏览点击率(vCTR)', value: 'VCTR'},
-]
+  { label: '推广商品销售额', value: 'TotalSalesSameSKU' },
+  { label: '其它商品销售额', value: 'TotalSalesOtherSKU' },
+  { label: '推广商品订单数', value: 'TotalPurchasesSameSKU' },
+  { label: '其它商品订单数', value: 'TotalPurchasesOtherSKU' },
+  { label: '新客订单数', value: 'NTBOrder' },
+  { label: '新客订单占比', value: 'NTBOrderRate' },
+  { label: '新客销售额', value: 'NTBSales' },
+  { label: '新客销售占比', value: 'NTBSalesRate' },
+  { label: '新客销量', value: 'NTBUnitOrdered' },
+  { label: '新客销量占比', value: 'NTBUnitOrderedRate' },
+  { label: '视频播放25%', value: 'VideoFirstQuartileViews' },
+  { label: '视频播放50%', value: 'VideoMidpointViews' },
+  { label: '视频播放75%', value: 'VideoThirdQuartileViews' },
+  { label: '视频播放100%', value: 'VideoCompleteViews' },
+  { label: '视频取消静音数', value: 'VideoUnmutes' },
+  { label: '浏览率(VTR)', value: 'VTR' },
+  { label: '浏览点击率(vCTR)', value: 'VCTR' },
+];
 
 
 export const spCampaignPuchasedOtherProductsMetricsEnum = [
 export const spCampaignPuchasedOtherProductsMetricsEnum = [
-  {label: '其它商品订单数', value: 'TotalPurchasesOtherSKU'},
-  {label: '其它商品销售额', value: 'TotalSalesOtherSKU'},
-  {label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU'},
-  {label: '其它商品订单数占比', value: 'PurchasesOtherSKURate'},
-  {label: '其它商品销售额占比', value: 'SalesOtherSKURate'},
-  {label: '其它商品销量占比', value: 'UnitOrderedOtherSKURate'},
-]
+  { label: '其它商品订单数', value: 'TotalPurchasesOtherSKU' },
+  { label: '其它商品销售额', value: 'TotalSalesOtherSKU' },
+  { label: '其它商品销量', value: 'TotalUnitOrderedOtherSKU' },
+  { label: '其它商品订单数占比', value: 'PurchasesOtherSKURate' },
+  { label: '其它商品销售额占比', value: 'SalesOtherSKURate' },
+  { label: '其它商品销量占比', value: 'UnitOrderedOtherSKURate' },
+];
 
 
 export const dynBidStrategyEnum = [
 export const dynBidStrategyEnum = [
-  {label: '动态竞价-仅降低', value: 'LEGACY_FOR_SALES', color: ''},
-  {label: '动态竞价-提高和降低', value: 'AUTO_FOR_SALES', color: 'success'},
-  {label: '固定竞价', value: 'MANUAL', color: 'warning'}
-]
+  { label: '动态竞价-仅降低', value: 'LEGACY_FOR_SALES', color: '' },
+  { label: '动态竞价-提高和降低', value: 'AUTO_FOR_SALES', color: 'success' },
+  { label: '固定竞价', value: 'MANUAL', color: 'warning' }
+];
 
 
 export const dynBidOptimizationEnum = [
 export const dynBidOptimizationEnum = [
-  {label: '自动竞价', value: 1, color: 'success'},
-  {label: '自定义竞价', value: 0, color: 'warning'}
-]
+  { label: '自动竞价', value: 1, color: 'success' },
+  { label: '自定义竞价', value: 0, color: 'warning' }
+];
+
+export const dynStatusEnum: any = {
+  'ENABLED': '投放中',
+  'DISABLED': '禁用',
+  'PAUSED': '已暂停',
+  'paused': '已暂停',
+  'enabled': '已开启',
+  'daily': '每日',
+  'DAILY': '每日',
+  'T00020': '内容相关投放',
+  'T00030': '受众',
+};
+
+export const spTargetTypeEnum: any = {
+  'AUTO': '自动',
+  'MANUAL': '手动',
+};
+
+export const dynStatusColorEnum = {
+  'ENABLED': 'success',
+  'DISABLED': 'danger',
+  'PAUSED': 'warning',
+  'paused': 'warning',
+  'enabled': 'success',
+};
 
 
-export const dynStatusEnum:any = {
-    'ENABLED' : '投放中',
-    'DISABLED' : '禁用',
-    'paused': '已暂停',
-    'enabled': '已开启',
-    'daily': '每日',
-    'T00020': '内容相关投放',
-    'T00030': '受众'
-  }
 export const targetTypeEnum = {
 export const targetTypeEnum = {
   'PRODUCT_COLLECTION': '商品集',
   'PRODUCT_COLLECTION': '商品集',
   'VIDEO': '视频',
   'VIDEO': '视频',
   'BRAND_VIDEO': '品牌视频',
   'BRAND_VIDEO': '品牌视频',
   'STORE_SPOTLIGHT': '店铺关注(STORE_SPOTLIGHT)'
   'STORE_SPOTLIGHT': '店铺关注(STORE_SPOTLIGHT)'
-}
+};
 
 
 export const spCampaignPlacementEnum = [
 export const spCampaignPlacementEnum = [
-  {label: '搜索结果顶部', value: 'top'},
-  {label: '商品页面', value: 'product_page'},
-  {label: '搜索结果的其余位置', value: 'rest_of_search'},
-]
+  { label: '搜索结果顶部', value: 'top' },
+  { label: '商品页面', value: 'product_page' },
+  { label: '搜索结果的其余位置', value: 'rest_of_search' },
+];
 
 
 export const sbCampaignPlacementEnum = [
 export const sbCampaignPlacementEnum = [
-  {label: '详细信息首页', value: 'Detail Page on-Amazon'},
-  {label: '其他页面', value: 'Other on-Amazon'},
-  {label: '顶部搜索', value: 'Top of Search on-Amazon'},
-  {label: '首页', value: 'Homepage on-Amazon'},
-]
+  { label: '详细信息首页', value: 'Detail Page on-Amazon' },
+  { label: '其他页面', value: 'Other on-Amazon' },
+  { label: '顶部搜索', value: 'Top of Search on-Amazon' },
+  { label: '首页', value: 'Homepage on-Amazon' },
+];
 
 
 export const spCampaignStateEnum = [
 export const spCampaignStateEnum = [
-  {label: '投放中', value: 'ENABLE'},
-  {label: '已暂停', value: 'PAUSED'},
-  {label: '已归档', value: 'ARCHIVED'},
+  { label: '投放中', value: 'ENABLE' },
+  { label: '已暂停', value: 'PAUSED' },
+  { label: '已归档', value: 'ARCHIVED' },
   // { label: '', value: 'ENABLING' },
   // { label: '', value: 'ENABLING' },
   // { label: '', value: 'USER_DELETED' },
   // { label: '', value: 'USER_DELETED' },
-  {label: '其它', value: 'OTHER'},
-]
+  { label: '其它', value: 'OTHER' },
+];
 
 
 export const spCampaignServingStatusEnum = [
 export const spCampaignServingStatusEnum = [
-  {label: '投放中', value: 'CAMPAIGN_STATUS_ENABLED'},
-  {label: '已暂停', value: 'CAMPAIGN_PAUSED'},
-  {label: '已归档', value: 'CAMPAIGN_ARCHIVED'},
-  {label: '超出预算', value: 'CAMPAIGN_OUT_OF_BUDGET'},
+  { label: '投放中', value: 'CAMPAIGN_STATUS_ENABLED' },
+  { label: '已暂停', value: 'CAMPAIGN_PAUSED' },
+  { label: '已归档', value: 'CAMPAIGN_ARCHIVED' },
+  { label: '超出预算', value: 'CAMPAIGN_OUT_OF_BUDGET' },
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' },
@@ -256,7 +272,7 @@ export const spCampaignServingStatusEnum = [
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' },
   // { label: '', value: '' }
   // { label: '', value: '' }
-]
+];
 
 
 export const metricMap = {
 export const metricMap = {
   'Spend': '花费',
   'Spend': '花费',
@@ -265,15 +281,15 @@ export const metricMap = {
   'TotalUnitOrdered': '销量',
   'TotalUnitOrdered': '销量',
   'Impression': '曝光量',
   'Impression': '曝光量',
   'Click': '点击量',
   'Click': '点击量',
-}
+};
 
 
-export const sdTypeMap: {[key: string]: string} = {
+export const sdTypeMap: { [key: string]: string } = {
   'views': '浏览再营销',
   'views': '浏览再营销',
   'purchases': '购买再营销',
   'purchases': '购买再营销',
   'audience': '亚马逊受众'
   'audience': '亚马逊受众'
-}
+};
 
 
-export const sdtargetMap: {[key: string]: string} = {
+export const sdtargetMap: { [key: string]: string } = {
   'asinBrandSameAs': '品牌',
   'asinBrandSameAs': '品牌',
   'asinSameAs': '商品',
   'asinSameAs': '商品',
   'asinPriceGreaterThan': '商品价格>',
   'asinPriceGreaterThan': '商品价格>',
@@ -285,7 +301,7 @@ export const sdtargetMap: {[key: string]: string} = {
   'asinIsPrimeShippingEligible': 'asinIsPrimeShippingEligible',
   'asinIsPrimeShippingEligible': 'asinIsPrimeShippingEligible',
   'asinReviewRatingBetween': '评分 ',
   'asinReviewRatingBetween': '评分 ',
   'lookback': '回溯期'
   'lookback': '回溯期'
-}
+};
 export const targetEnum = [
 export const targetEnum = [
   { label: '类目', value: 'ASIN_CATEGORY_SAME_AS' },
   { label: '类目', value: 'ASIN_CATEGORY_SAME_AS' },
   { label: '品牌', value: 'ASIN_BRAND_SAME_AS' },
   { label: '品牌', value: 'ASIN_BRAND_SAME_AS' },
@@ -301,7 +317,7 @@ export const targetEnum = [
   // { label: '', value: 'ASIN_GENRE_SAME_AS' },
   // { label: '', value: 'ASIN_GENRE_SAME_AS' },
   // { label: '', value: 'ASIN_EXPANDED_FROM' },
   // { label: '', value: 'ASIN_EXPANDED_FROM' },
   { label: '其它', value: 'OTHER' },
   { label: '其它', value: 'OTHER' },
-]
+];
 
 
 export const sdBarOptionsMap = {
 export const sdBarOptionsMap = {
   'Spend': '花费',
   'Spend': '花费',
@@ -347,7 +363,7 @@ export const sdBarOptionsMap = {
   'VideoUnmutes': '视频取消静音数',
   'VideoUnmutes': '视频取消静音数',
   'VTR': '浏览率(VTR)',
   'VTR': '浏览率(VTR)',
   'VCTR': '浏览点击率(vCTR)'
   'VCTR': '浏览点击率(vCTR)'
-}
+};
 export const sdBarOptions1 = [
 export const sdBarOptions1 = [
   { value: 'Spend', label: '花费' },
   { value: 'Spend', label: '花费' },
   { value: 'TotalSales', label: '销售额' },
   { value: 'TotalSales', label: '销售额' },
@@ -391,7 +407,7 @@ export const sdBarOptions1 = [
   { value: 'VideoUnmutes', label: '视频取消静音数' },
   { value: 'VideoUnmutes', label: '视频取消静音数' },
   { value: 'VTR', label: '浏览率(VTR)' },
   { value: 'VTR', label: '浏览率(VTR)' },
   { value: 'VCTR', label: '浏览点击率(vCTR)' }
   { value: 'VCTR', label: '浏览点击率(vCTR)' }
-]
+];
 export const sdBarOptions2 = [
 export const sdBarOptions2 = [
   { value: 'Spend', label: '花费' },
   { value: 'Spend', label: '花费' },
   { value: 'TotalSales', label: '销售额' },
   { value: 'TotalSales', label: '销售额' },
@@ -435,8 +451,7 @@ export const sdBarOptions2 = [
   { value: 'VideoUnmutes', label: '视频取消静音数' },
   { value: 'VideoUnmutes', label: '视频取消静音数' },
   { value: 'VTR', label: '浏览率(VTR)' },
   { value: 'VTR', label: '浏览率(VTR)' },
   { value: 'VCTR', label: '浏览点击率(vCTR)' }
   { value: 'VCTR', label: '浏览点击率(vCTR)' }
-]
-
+];
 
 
 export const TargetExpressionEnum = [
 export const TargetExpressionEnum = [
   { label: '类目', value: 'ASIN_CATEGORY_SAME_AS' },
   { label: '类目', value: 'ASIN_CATEGORY_SAME_AS' },
@@ -453,7 +468,7 @@ export const TargetExpressionEnum = [
   // { label: '', value: 'ASIN_GENRE_SAME_AS' },
   // { label: '', value: 'ASIN_GENRE_SAME_AS' },
   // { label: '', value: 'ASIN_EXPANDED_FROM' },
   // { label: '', value: 'ASIN_EXPANDED_FROM' },
   { label: '其它', value: 'OTHER' },
   { label: '其它', value: 'OTHER' },
-]
+];
 
 
 export const barOptionsMap = {
 export const barOptionsMap = {
   'ACOS': 'ACOS',
   'ACOS': 'ACOS',
@@ -475,7 +490,7 @@ export const barOptionsMap = {
   'TotalUnitOrderedSameSKU': '推广商品销量',
   'TotalUnitOrderedSameSKU': '推广商品销量',
   'TotalUnitOrderedOtherSKU': '其他商品销量',
   'TotalUnitOrderedOtherSKU': '其他商品销量',
   'TopOfSearchImpressionShare': '搜索结果顶部展示份额'
   'TopOfSearchImpressionShare': '搜索结果顶部展示份额'
-}
+};
 export const barOptions1 = [
 export const barOptions1 = [
   {
   {
     value: 'ACOS',
     value: 'ACOS',
@@ -554,7 +569,7 @@ export const barOptions1 = [
     value: 'TopOfSearchImpressionShare',
     value: 'TopOfSearchImpressionShare',
     label: '搜索结果顶部展示份额'
     label: '搜索结果顶部展示份额'
   },
   },
-]
+];
 export const barOptions2 = [
 export const barOptions2 = [
   {
   {
     value: 'ACOS',
     value: 'ACOS',
@@ -633,7 +648,7 @@ export const barOptions2 = [
     value: 'TopOfSearchImpressionShare',
     value: 'TopOfSearchImpressionShare',
     label: '搜索结果顶部展示份额'
     label: '搜索结果顶部展示份额'
   },
   },
-]
+];
 export const pieOptions = [
 export const pieOptions = [
   {
   {
     value: 'Spend',
     value: 'Spend',
@@ -659,4 +674,4 @@ export const pieOptions = [
     value: 'Click',
     value: 'Click',
     label: '点击量',
     label: '点击量',
   },
   },
-]
+];

+ 15 - 0
src/views/adManage/utils/tools.ts

@@ -129,3 +129,18 @@ export function parseQueryParams(body: any) {
 export function getEnumLabel(enumObj: { label: string; value: string }[], value: any) {
 export function getEnumLabel(enumObj: { label: string; value: string }[], value: any) {
   return enumObj.find((item) => item.value === value)?.label
   return enumObj.find((item) => item.value === value)?.label
 }
 }
+
+export function getTagType(state){
+    switch (state) {
+      case 'ENABLED':
+      case 'enabled':
+        return 'success';  // 投放中或已开启
+      case 'PAUSED':
+      case 'paused':
+        return 'warning';  // 已暂停
+      case 'DISABLED':
+        return 'danger';   // 禁用
+      default:
+        return '';  // 其他状态
+    }
+}

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

@@ -123,39 +123,40 @@ async function fetchAdCampaign() {
       campaignId: props.checkTarget.campaignId
       campaignId: props.checkTarget.campaignId
     });
     });
 
 
-    // 计算并设置 targetLength
-    resp.data.adGroupInfo = resp.data.adGroupInfo.map(group => ({
-      ...group,
-      targetLength: (group.selectTargetId?.length || 0) + (group.keywordInfo?.length || 0) + (group.campaignTargetInfo?.length || 0)
-    }));
-
-    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
-    }];
-    console.log('selectedAds', selectedAds.value);
-
-    // 在 nextTick 中设置选中状态,确保表格已经渲染
-    nextTick(() => {
-      if (xGridOne.value) {
-        adGroupsToCheck.forEach(group => {
-          group.isSelected = true;
-          xGridOne.value.setCheckboxRow(group, true);
-        });
-      }
-    });
+    if (resp.code === 2000 && resp.data.length > 0){
+      // 计算并设置 targetLength
+      resp.data.adGroupInfo = resp.data.adGroupInfo.map(group => ({
+        ...group,
+        targetLength: (group.selectTargetId?.length || 0) + (group.keywordInfo?.length || 0) + (group.campaignTargetInfo?.length || 0)
+      }));
+
+      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) {
   } catch (error) {
-    ElMessage.error('请求广告活动数据失败');
+    console.log("=>(view-target-rules.vue:158) error", error);
   } finally {
   } finally {
     // gridOptions.loading = false;
     // gridOptions.loading = false;
   }
   }
@@ -221,7 +222,6 @@ function handleConfirm({ campaignInfo, targetType }) {
 
 
 // 删除选中的广告
 // 删除选中的广告
 const removeSelectedAd = async (row) => {
 const removeSelectedAd = async (row) => {
-  console.log('=>(view-target-rules.vue:224) row', row);
   const $grid = xGridTwo.value;
   const $grid = xGridTwo.value;
   if ($grid) {
   if ($grid) {
     if (row.adGroupId) {
     if (row.adGroupId) {

+ 10 - 0
src/views/efTools/automation/api.ts

@@ -69,6 +69,15 @@ export function updateAdCampaign(body) {
   });
   });
 }
 }
 
 
+// 广告关联活动
+export function getSelectedAdCampaign(query) {
+  return request({
+    url: '/api/ad_manage/template/selected-campaigns/',
+    method: 'GET',
+    params: query,
+  });
+}
+
 // 定向规则弹窗:获取定向规则列表
 // 定向规则弹窗:获取定向规则列表
 export function getTargetingRuleList(query) {
 export function getTargetingRuleList(query) {
   return request({
   return request({
@@ -89,3 +98,4 @@ export function getProductsList(query) {
 
 
 
 
 
 
+

+ 80 - 30
src/views/efTools/automation/components/adActivityDialog.vue

@@ -5,19 +5,25 @@
  * @Author: xinyan
  * @Author: xinyan
  */
  */
 import { computed, onMounted, reactive, ref, toRefs, watch } from 'vue';
 import { computed, onMounted, reactive, ref, toRefs, watch } from 'vue';
-import { getAdGroupList, getRelationCampaign, updateAdCampaign } from '/@/views/efTools/automation/api';
+import {
+  getAdGroupList,
+  getRelationCampaign,
+  getSelectedAdCampaign,
+  updateAdCampaign
+} from '/@/views/efTools/automation/api';
 import { storeToRefs } from 'pinia';
 import { storeToRefs } from 'pinia';
 import { useShopInfo } from '/@/stores/shopInfo';
 import { useShopInfo } from '/@/stores/shopInfo';
 import { ElMessage } from 'element-plus';
 import { ElMessage } from 'element-plus';
 import TargetRuleDialog from '/@/views/efTools/automation/components/targetRuleDialog.vue';
 import TargetRuleDialog from '/@/views/efTools/automation/components/targetRuleDialog.vue';
 import { DocumentAdd } from '@element-plus/icons-vue';
 import { DocumentAdd } from '@element-plus/icons-vue';
-import { allCampaignTypes ,campaignStatus} from '/@/views/efTools/utils/enum';
+import { allCampaignTypes, campaignStatus } from '/@/views/efTools/utils/enum';
+
 
 
 const shopInfo = useShopInfo();
 const shopInfo = useShopInfo();
 const { profile } = storeToRefs(shopInfo);
 const { profile } = storeToRefs(shopInfo);
 
 
 const props = defineProps({
 const props = defineProps({
-  rowData:{
+  rowData: {
     type: Object,
     type: Object,
     required: true,
     required: true,
   },
   },
@@ -26,15 +32,16 @@ const props = defineProps({
     required: true,
     required: true,
   },
   },
 });
 });
-const emits = defineEmits([ 'confirmSuccess']);
+const emits = defineEmits(['confirmSuccess']);
 const { rowData } = toRefs(props);
 const { rowData } = toRefs(props);
 const templateId = ref(rowData.value.id);
 const templateId = ref(rowData.value.id);
 const activeModel = ref(rowData.value.rule.activeModel);
 const activeModel = ref(rowData.value.rule.activeModel);
 const campaignType = ref(rowData.value.rule.campaignType);
 const campaignType = ref(rowData.value.rule.campaignType);
 const dialogVisible = defineModel({ default: false });
 const dialogVisible = defineModel({ default: false });
 
 
-
 // 定向规则
 // 定向规则
+const selected =ref([]) //存储后端中已存在的广告组
+
 const targetRuleDialogVisible = ref(false);
 const targetRuleDialogVisible = ref(false);
 const selectedTargetedRow = ref(null);
 const selectedTargetedRow = ref(null);
 const targetLength = ref(0);
 const targetLength = ref(0);
@@ -149,27 +156,27 @@ function handleAdCampaignChange() {
 }
 }
 
 
 async function fetchAdCampaign() {
 async function fetchAdCampaign() {
-  const savedAdCampaign = localStorage.getItem('searchAdCampaign');
-  if (savedAdCampaign) {
-    searchAdCampaign.value = JSON.parse(savedAdCampaign);
-  }
+  // const savedAdCampaign = localStorage.getItem('searchAdCampaign');
+  // if (savedAdCampaign) {
+  //   searchAdCampaign.value = JSON.parse(savedAdCampaign);
+  // }
   try {
   try {
     loading.value = true;
     loading.value = true;
     // const cachedSelectedAds = [...selectedAds.value];
     // const cachedSelectedAds = [...selectedAds.value];
-    if (profile.value.profile_id && templateId.value){
-    const resp = await getRelationCampaign({
-      profileId: profile.value.profile_id,
-      templateId: templateId.value,
-      campaignName: searchAdCampaign.value,
-      portfolioId: selectedAdGroup.value,
-      campaignStatus: selectedStatus.value,
-      campaignType: selectedCampaignType.value,
-      page: currentPage.value,
-      limit: pageSize.value,
-    });
-    gridOptions.data = resp.data;
-    total.value = resp.total;
-    currentPage.value = resp.page;
+    if (profile.value.profile_id && templateId.value) {
+      const resp = await getRelationCampaign({
+        profileId: profile.value.profile_id,
+        templateId: templateId.value,
+        campaignName: searchAdCampaign.value,
+        portfolioId: selectedAdGroup.value,
+        campaignStatus: selectedStatus.value,
+        campaignType: selectedCampaignType.value,
+        page: currentPage.value,
+        limit: pageSize.value,
+      });
+      gridOptions.data = resp.data;
+      total.value = resp.total;
+      currentPage.value = resp.page;
     }
     }
   } catch (error) {
   } catch (error) {
     ElMessage.error('请求广告活动数据失败');
     ElMessage.error('请求广告活动数据失败');
@@ -192,6 +199,14 @@ function handleGridChange({ records, row, checked }) {
     if (row) {
     if (row) {
       if (!checked) {
       if (!checked) {
         row.isSelected = false;
         row.isSelected = false;
+        // 清空 keywordInfo 和 campaignTargetInfo
+        if (row.keywordInfo) {
+          row.keywordInfo = [];
+        }
+
+        if (row.campaignTargetInfo) {
+          row.campaignTargetInfo = [];
+        }
         updateSelectedAds();
         updateSelectedAds();
       }
       }
     } else {
     } else {
@@ -213,7 +228,6 @@ function handleGridChange({ records, row, checked }) {
 function toggleCheckboxEvent(row) {
 function toggleCheckboxEvent(row) {
   if (activeModel.value === 'specified') {
   if (activeModel.value === 'specified') {
     if (row.isSelected) {
     if (row.isSelected) {
-      // 只有已选择的行可以被取消选中
       xGridOne.value.setCheckboxRow(row, false);
       xGridOne.value.setCheckboxRow(row, false);
       handleGridChange({ records: [row], row, checked: false });
       handleGridChange({ records: [row], row, checked: false });
     }
     }
@@ -231,14 +245,21 @@ function handelSelect({ records }) {
   ];
   ];
 }
 }
 
 
+// 处理一开始selectedAds.value为空时能正常
 function updateSelectedAds() {
 function updateSelectedAds() {
-  selectedAds.value = gridOptions.data
+  // 获取当前选中广告组
+  const filteredAds = gridOptions.data
       .filter(ad => ad.campaignGroupInfo && ad.campaignGroupInfo.some(group => group.isSelected))
       .filter(ad => ad.campaignGroupInfo && ad.campaignGroupInfo.some(group => group.isSelected))
       .map(ad => ({
       .map(ad => ({
         ...ad,
         ...ad,
         campaignGroupInfo: ad.campaignGroupInfo.filter(group => group.isSelected),
         campaignGroupInfo: ad.campaignGroupInfo.filter(group => group.isSelected),
         page: currentPage.value
         page: currentPage.value
       }));
       }));
+  // 合并新选中的广告组与现有的 selectedAds
+  selectedAds.value = [
+    ...selected.value, // 保留已存在的选中广告
+    ...filteredAds
+  ];
 }
 }
 
 
 // 树形结构的表格选择变化
 // 树形结构的表格选择变化
@@ -277,16 +298,23 @@ function handleSelectionChange({ records }) {
 
 
   // 更新选中的广告
   // 更新选中的广告
   selectedAds.value = [
   selectedAds.value = [
+    ...selectedAds.value.filter(ad => ad.page !== currentPage.value),
     ...updatedRecords.map(ad => ({ ...ad, page: currentPage.value })),
     ...updatedRecords.map(ad => ({ ...ad, page: currentPage.value })),
   ];
   ];
 }
 }
 
 
 // 选择定向按钮
 // 选择定向按钮
 function handleSelectTarget(row) {
 function handleSelectTarget(row) {
-  // 获取父节点数据
-  const parent = gridOptions.data.find(campaign =>
-      campaign.campaignGroupInfo.some(group => group.adGroupId === row.adGroupId)
-  );
+  let parent = null;
+  if (row.keywordInfo && row.keywordInfo.length > 0 || row.campaignTargetInfo && row.campaignTargetInfo.length > 0) {
+    parent = selectedAds.value.find(campaign =>
+        campaign.campaignGroupInfo.some(group => group.adGroupId === row.adGroupId)
+    );
+  } else {
+    parent = gridOptions.data.find(campaign =>
+        campaign.campaignGroupInfo.some(group => group.adGroupId === row.adGroupId)
+    );
+  }
   selectedTargetedRow.value = {
   selectedTargetedRow.value = {
     campaignType: parent.campaignType,
     campaignType: parent.campaignType,
     campaignId: parent.campaignId,
     campaignId: parent.campaignId,
@@ -356,6 +384,7 @@ const removeSelectedAd = async (row) => {
 
 
   if (xGridOne.value) {
   if (xGridOne.value) {
     await xGridOne.value.toggleCheckboxRow(row);
     await xGridOne.value.toggleCheckboxRow(row);
+    row.isSelected = false;
   }
   }
 };
 };
 
 
@@ -402,7 +431,7 @@ async function confirm() {
             }))
             }))
         );
         );
       }
       }
-      if(activeModel.value === 'adGroup'){
+      if (activeModel.value === 'adGroup') {
         if (!adGroupInfo.includes(group.adGroupId)) {
         if (!adGroupInfo.includes(group.adGroupId)) {
           adGroupInfo.push(group.adGroupId); // 直接推送 adGroupId
           adGroupInfo.push(group.adGroupId); // 直接推送 adGroupId
         }
         }
@@ -431,6 +460,26 @@ async function confirm() {
   }
   }
 }
 }
 
 
+// 获取已添加定向的广告
+async function getSelectedAds() {
+  const resp = await getSelectedAdCampaign({
+    templateId: templateId.value,
+  });
+  selected.value = resp.data;
+  // 处理已选择的广告
+  if (activeModel.value === 'specified') {
+    selected.value.forEach(ad => {
+      if (ad.campaignGroupInfo && ad.campaignGroupInfo.length > 0) {
+        ad.campaignGroupInfo.forEach(group => {
+          group.isSelected = true;
+          group.targetLength = group.keywordInfo.length;
+        });
+      }
+    });
+    updateSelectedAds();
+  }
+}
+
 // 获取广告组下拉框
 // 获取广告组下拉框
 async function fetchAdGroupList() {
 async function fetchAdGroupList() {
   try {
   try {
@@ -496,6 +545,7 @@ watch(selectedStatus, () => {
 onMounted(() => {
 onMounted(() => {
   fetchAdGroupList();
   fetchAdGroupList();
   fetchAdCampaign();
   fetchAdCampaign();
+  getSelectedAds();
 });
 });
 
 
 </script>
 </script>

+ 1 - 0
src/views/reportManage/TaskManage/index.vue

@@ -147,6 +147,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
     trigger: 'click',
     trigger: 'click',
     mode: 'row',
     mode: 'row',
     showStatus: true,
     showStatus: true,
+    showIcon:false,
     //autoClear: false,
     //autoClear: false,
   },
   },
   checkboxConfig: {
   checkboxConfig: {

+ 2 - 2
src/views/reportManage/TaskManage/utils/columns.ts

@@ -2,7 +2,7 @@ import { ref } from 'vue';
 
 
 // 任务管理表格列
 // 任务管理表格列
 export const taskColumns = ref([
 export const taskColumns = ref([
-  { type: 'checkbox', width: 50 ,fixed: 'left'},
+  { type: 'checkbox', width: 50 ,fixed: 'left',align: 'center' },
   {
   {
     field: 'platformNumber',
     field: 'platformNumber',
     title: '平台编号',
     title: '平台编号',
@@ -18,7 +18,7 @@ export const taskColumns = ref([
     editRender: { autofocus: '.vxe-input--inner' },
     editRender: { autofocus: '.vxe-input--inner' },
     slots: { edit: 'name_edit' },
     slots: { edit: 'name_edit' },
     align: 'center',
     align: 'center',
-    minWidth: 98, isEditing: false
+    minWidth: 95, isEditing: false
   },
   },
   {
   {
     field: 'country',
     field: 'country',