Parcourir la source

🌈 style: script标签置顶

WanGxC il y a 1 an
Parent
commit
d3d68c58f6
57 fichiers modifiés avec 4793 ajouts et 4793 suppressions
  1. 7 7
      src/views/adManage/ad-overview/chartComponents/dataTendency.vue
  2. 47 47
      src/views/adManage/ad-overview/daily/index.vue
  3. 52 52
      src/views/adManage/ad-overview/hourly/index.vue
  4. 11 11
      src/views/adManage/ad-overview/index.vue
  5. 52 52
      src/views/adManage/ad-overview/monthly/index.vue
  6. 89 90
      src/views/adManage/ad-overview/total/index.vue
  7. 52 52
      src/views/adManage/ad-overview/weekly/index.vue
  8. 128 128
      src/views/adManage/sb/campaigns/CreateCampaigns/component/AdCampaign.vue
  9. 25 25
      src/views/adManage/sb/campaigns/CreateCampaigns/component/AdGroup.vue
  10. 10 10
      src/views/adManage/sb/campaigns/CreateCampaigns/component/DeliveryType.vue
  11. 244 244
      src/views/adManage/sb/campaigns/CreateCampaigns/component/FocusCreativity.vue
  12. 89 89
      src/views/adManage/sb/campaigns/CreateCampaigns/component/KeywordTarget.vue
  13. 115 115
      src/views/adManage/sb/campaigns/CreateCampaigns/component/NegativeGood.vue
  14. 227 227
      src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductOrientation.vue
  15. 154 154
      src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductSetCommodity.vue
  16. 290 290
      src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductSetCreativity1.vue
  17. 140 140
      src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductSetCreativity2.vue
  18. 154 154
      src/views/adManage/sb/campaigns/CreateCampaigns/component/VideoCommodity.vue
  19. 298 298
      src/views/adManage/sb/campaigns/CreateCampaigns/component/VideoCreativity1.vue
  20. 157 157
      src/views/adManage/sb/campaigns/CreateCampaigns/component/VideoCreativity2.vue
  21. 23 23
      src/views/adManage/sb/campaigns/CreateCampaigns/index.vue
  22. 47 47
      src/views/adManage/sb/campaigns/index.vue
  23. 12 14
      src/views/adManage/sb/chartComponents/dataTendency.vue
  24. 27 27
      src/views/adManage/sb/index.vue
  25. 26 26
      src/views/adManage/sb/keywords/chartComponents/adStruct.vue
  26. 47 47
      src/views/adManage/sb/keywords/index.vue
  27. 25 25
      src/views/adManage/sb/placement/chartComponents/adStruct.vue
  28. 44 44
      src/views/adManage/sb/placement/index.vue
  29. 45 45
      src/views/adManage/sb/searchTerm/index.vue
  30. 25 25
      src/views/adManage/sb/targets/chartComponents/adStruct.vue
  31. 7 7
      src/views/adManage/sb/targets/chartComponents/dataTendency.vue
  32. 66 66
      src/views/adManage/sb/targets/index.vue
  33. 113 107
      src/views/adManage/sd/chartComponents/dataTendency.vue
  34. 27 27
      src/views/adManage/sd/index.vue
  35. 25 25
      src/views/adManage/sd/matchedDelivery/chartComponents/adStruct.vue
  36. 206 208
      src/views/adManage/sd/matchedDelivery/chartComponents/dataTendency.vue
  37. 25 25
      src/views/adManage/sd/promoteProducts/chartComponents/adStruct.vue
  38. 15 16
      src/views/adManage/sd/targets/chartComponents/adStruct.vue
  39. 7 7
      src/views/adManage/sd/targets/chartComponents/dataTendency.vue
  40. 59 59
      src/views/adManage/sp/advertisedProducts/index.vue
  41. 1005 1005
      src/views/adManage/sp/campaigns/CreateCampaigns/index.vue
  42. 113 113
      src/views/adManage/sp/campaigns/CreateCampaigns/negativeGoods/index.vue
  43. 31 31
      src/views/adManage/sp/campaigns/campaignDetail/index.vue
  44. 31 31
      src/views/adManage/sp/campaigns/chartComponents/adStruct.vue
  45. 7 7
      src/views/adManage/sp/campaigns/chartComponents/dataTendency.vue
  46. 47 47
      src/views/adManage/sp/campaigns/index.vue
  47. 12 12
      src/views/adManage/sp/chartComponents/dataTendency.vue
  48. 28 28
      src/views/adManage/sp/index.vue
  49. 25 25
      src/views/adManage/sp/keywords/chartComponents/adStruct.vue
  50. 43 43
      src/views/adManage/sp/keywords/index.vue
  51. 25 25
      src/views/adManage/sp/placement/chartComponents/adStruct.vue
  52. 44 44
      src/views/adManage/sp/placement/index.vue
  53. 46 46
      src/views/adManage/sp/purchasedOtherProducts/index.vue
  54. 46 46
      src/views/adManage/sp/searchTerm/index.vue
  55. 25 25
      src/views/adManage/sp/targets/chartComponents/adStruct.vue
  56. 7 7
      src/views/adManage/sp/targets/chartComponents/dataTendency.vue
  57. 46 46
      src/views/adManage/sp/targets/index.vue

+ 7 - 7
src/views/adManage/ad-overview/chartComponents/dataTendency.vue

@@ -1,10 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-    <div style="height: 350px;" ref="chartRef"></div>
-</div>
-</template>
-
 <script lang="ts" setup>
 import { ref,onMounted, onBeforeUnmount, Ref, unref, watch, computed } from 'vue'
 import * as echarts from 'echarts'
@@ -295,6 +288,13 @@ const removeResize = () => { window.removeEventListener('resize', resizeChart) }
 
 </script>
 
+<template>
+  <div v-loading="loading">
+    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+    <div style="height: 350px;" ref="chartRef"></div>
+</div>
+</template>
+
 <style scoped>
 .metrics-cards {
   display: flex;

+ 47 - 47
src/views/adManage/ad-overview/daily/index.vue

@@ -1,50 +1,3 @@
-<template>
-  <div class="overview-tabs">
-    <DateRangePicker v-model="dateRange"></DateRangePicker>
-    <el-select v-model="selectedPortfolios" placeholder="SP" style="width: 200px" collapse-tags collapse-tags-tooltip :max-collapse-tags="3">
-      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
-    </el-select>
-  </div>
-  <fs-page class="fs-page-custom" style="margin-top: -11px">
-    <fs-crud ref="crudRef" v-bind="crudBinding">
-      <template #header-middle>
-        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
-          <DataTendencyChart
-            v-if="tabActiveName === 'dataTendency'"
-            :query="queryParams"
-            :fetchCard="getCardData"
-            :fetchLine="getLineData"
-            :fetch-line-month="getLineMonthData"
-            :fetch-line-week="getLineWeekData"
-          >
-          </DataTendencyChart>
-        </el-tabs>
-      </template>
-      <template #cell_percentTimeInBudget="scope">
-        <el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
-      </template>
-      <template #cell_campaignName="scope">
-        <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
-      </template>
-      <template #cell_MissedImpressions="scope">
-        {{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
-      </template>
-      <template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
-      <template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
-      <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
-        <DataCompare
-          :field="field"
-          :value="scope.row[field]"
-          :prev-val="scope.row[`prev${field}`]"
-          :gap-val="scope.row[`gap${field}`]"
-          :date-range="dateRange"
-          :show-compare="showCompare"
-        />
-      </template>
-    </fs-crud>
-  </fs-page>
-</template>
-
 <script lang="ts" setup>
 import { onMounted, Ref, ref, watch } from 'vue'
 import { FsPage, useFs } from '@fast-crud/fast-crud'
@@ -118,6 +71,53 @@ watch(
 )
 </script>
 
+<template>
+  <div class="overview-tabs">
+    <DateRangePicker v-model="dateRange"></DateRangePicker>
+    <el-select v-model="selectedPortfolios" placeholder="SP" style="width: 200px" collapse-tags collapse-tags-tooltip :max-collapse-tags="3">
+      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
+    </el-select>
+  </div>
+  <fs-page class="fs-page-custom" style="margin-top: -11px">
+    <fs-crud ref="crudRef" v-bind="crudBinding">
+      <template #header-middle>
+        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
+          <DataTendencyChart
+            v-if="tabActiveName === 'dataTendency'"
+            :query="queryParams"
+            :fetchCard="getCardData"
+            :fetchLine="getLineData"
+            :fetch-line-month="getLineMonthData"
+            :fetch-line-week="getLineWeekData"
+          >
+          </DataTendencyChart>
+        </el-tabs>
+      </template>
+      <template #cell_percentTimeInBudget="scope">
+        <el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
+      </template>
+      <template #cell_campaignName="scope">
+        <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
+      </template>
+      <template #cell_MissedImpressions="scope">
+        {{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
+      </template>
+      <template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
+      <template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
+      <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
+        <DataCompare
+          :field="field"
+          :value="scope.row[field]"
+          :prev-val="scope.row[`prev${field}`]"
+          :gap-val="scope.row[`gap${field}`]"
+          :date-range="dateRange"
+          :show-compare="showCompare"
+        />
+      </template>
+    </fs-crud>
+  </fs-page>
+</template>
+
 <style lang="scss" scoped>
 .campare-switch {
   flex: none;

+ 52 - 52
src/views/adManage/ad-overview/hourly/index.vue

@@ -1,55 +1,3 @@
-<template>
-  <div class="overview-tabs">
-    <DateRangePicker v-model="dateRange"></DateRangePicker>
-    <el-select
-        v-model="selectedPortfolios"
-        placeholder="SP"
-        style="width: 200px"
-        collapse-tags
-        collapse-tags-tooltip
-        :max-collapse-tags="3"
-    >
-      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
-    </el-select>
-  </div>
-	<fs-page class="fs-page-custom" style="margin-top: -11px">
-		<fs-crud ref="crudRef" v-bind="crudBinding">
-			<template #header-middle>
-				<el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
-						<DataTendencyChart
-							v-if="tabActiveName === 'dataTendency'"
-							:query="queryParams"
-							:fetchCard="getCardData"
-							:fetchLine="getLineData"
-							:fetch-line-month="getLineMonthData"
-							:fetch-line-week="getLineWeekData">
-						</DataTendencyChart>
-				</el-tabs>
-			</template>
-			<template #cell_percentTimeInBudget="scope">
-				<el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
-			</template>
-			<template #cell_campaignName="scope">
-				<el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
-			</template>
-			<template #cell_MissedImpressions="scope">
-				{{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
-			</template>
-			<template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
-			<template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
-			<template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
-				<DataCompare
-          :field="field"
-          :value="scope.row[field]"
-          :prev-val="scope.row[`prev${field}`]"
-          :gap-val="scope.row[`gap${field}`]"
-          :date-range="dateRange"
-          :show-compare="showCompare"/>
-			</template>
-		</fs-crud>
-	</fs-page>
-</template>
-
 <script lang="ts" setup>
 import {onMounted, ref, watch} from 'vue'
 import {FsPage, useFs} from '@fast-crud/fast-crud'
@@ -122,6 +70,58 @@ watch(queryParams, async () => {
 
 </script>
 
+<template>
+  <div class="overview-tabs">
+    <DateRangePicker v-model="dateRange"></DateRangePicker>
+    <el-select
+        v-model="selectedPortfolios"
+        placeholder="SP"
+        style="width: 200px"
+        collapse-tags
+        collapse-tags-tooltip
+        :max-collapse-tags="3"
+    >
+      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
+    </el-select>
+  </div>
+	<fs-page class="fs-page-custom" style="margin-top: -11px">
+		<fs-crud ref="crudRef" v-bind="crudBinding">
+			<template #header-middle>
+				<el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
+						<DataTendencyChart
+							v-if="tabActiveName === 'dataTendency'"
+							:query="queryParams"
+							:fetchCard="getCardData"
+							:fetchLine="getLineData"
+							:fetch-line-month="getLineMonthData"
+							:fetch-line-week="getLineWeekData">
+						</DataTendencyChart>
+				</el-tabs>
+			</template>
+			<template #cell_percentTimeInBudget="scope">
+				<el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
+			</template>
+			<template #cell_campaignName="scope">
+				<el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
+			</template>
+			<template #cell_MissedImpressions="scope">
+				{{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
+			</template>
+			<template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
+			<template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
+			<template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
+				<DataCompare
+          :field="field"
+          :value="scope.row[field]"
+          :prev-val="scope.row[`prev${field}`]"
+          :gap-val="scope.row[`gap${field}`]"
+          :date-range="dateRange"
+          :show-compare="showCompare"/>
+			</template>
+		</fs-crud>
+	</fs-page>
+</template>
+
 <style lang="scss" scoped>
 .campare-switch {
 	flex: none;

+ 11 - 11
src/views/adManage/ad-overview/index.vue

@@ -1,14 +1,3 @@
-<template>
-  <div class="asj-container">
-    <div class="overview-top">
-      <div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
-        {{ tab.label }}
-      </div>
-    </div>
-    <component :is="tabsComponents[tabActiveName]"></component>
-  </div>
-</template>
-
 <script lang="ts" setup>
 import {onBeforeMount, provide, Ref, ref} from 'vue'
 import {usePublicData} from '/@/stores/publicData'
@@ -50,6 +39,17 @@ onBeforeMount(async () => {
 
 </script>
 
+<template>
+  <div class="asj-container">
+    <div class="overview-top">
+      <div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
+        {{ tab.label }}
+      </div>
+    </div>
+    <component :is="tabsComponents[tabActiveName]"></component>
+  </div>
+</template>
+
 <style scoped>
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);

+ 52 - 52
src/views/adManage/ad-overview/monthly/index.vue

@@ -1,55 +1,3 @@
-<template>
-  <div class="overview-tabs">
-    <DateRangePicker v-model="dateRange"></DateRangePicker>
-    <el-select
-        v-model="selectedPortfolios"
-        placeholder="SP"
-        style="width: 200px"
-        collapse-tags
-        collapse-tags-tooltip
-        :max-collapse-tags="3"
-    >
-      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
-    </el-select>
-  </div>
-  <fs-page class="fs-page-custom" style="margin-top: -11px">
-    <fs-crud ref="crudRef" v-bind="crudBinding">
-      <template #header-middle>
-        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
-          <DataTendencyChart
-              v-if="tabActiveName === 'dataTendency'"
-              :query="queryParams"
-              :fetchCard="getCardData"
-              :fetchLine="getLineData"
-              :fetch-line-month="getLineMonthData"
-              :fetch-line-week="getLineWeekData">
-          </DataTendencyChart>
-        </el-tabs>
-      </template>
-      <template #cell_percentTimeInBudget="scope">
-        <el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
-      </template>
-      <template #cell_campaignName="scope">
-        <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
-      </template>
-      <template #cell_MissedImpressions="scope">
-        {{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
-      </template>
-      <template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
-      <template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
-      <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
-        <DataCompare
-            :field="field"
-            :value="scope.row[field]"
-            :prev-val="scope.row[`prev${field}`]"
-            :gap-val="scope.row[`gap${field}`]"
-            :date-range="dateRange"
-            :show-compare="showCompare"/>
-      </template>
-    </fs-crud>
-  </fs-page>
-</template>
-
 <script lang="ts" setup>
 import {onMounted, Ref, ref, watch} from 'vue'
 import {FsPage, useFs} from '@fast-crud/fast-crud'
@@ -118,6 +66,58 @@ watch(queryParams, async () => {
 }, { deep: true })
 </script>
 
+<template>
+  <div class="overview-tabs">
+    <DateRangePicker v-model="dateRange"></DateRangePicker>
+    <el-select
+        v-model="selectedPortfolios"
+        placeholder="SP"
+        style="width: 200px"
+        collapse-tags
+        collapse-tags-tooltip
+        :max-collapse-tags="3"
+    >
+      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
+    </el-select>
+  </div>
+  <fs-page class="fs-page-custom" style="margin-top: -11px">
+    <fs-crud ref="crudRef" v-bind="crudBinding">
+      <template #header-middle>
+        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
+          <DataTendencyChart
+              v-if="tabActiveName === 'dataTendency'"
+              :query="queryParams"
+              :fetchCard="getCardData"
+              :fetchLine="getLineData"
+              :fetch-line-month="getLineMonthData"
+              :fetch-line-week="getLineWeekData">
+          </DataTendencyChart>
+        </el-tabs>
+      </template>
+      <template #cell_percentTimeInBudget="scope">
+        <el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
+      </template>
+      <template #cell_campaignName="scope">
+        <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
+      </template>
+      <template #cell_MissedImpressions="scope">
+        {{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
+      </template>
+      <template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
+      <template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
+      <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
+        <DataCompare
+            :field="field"
+            :value="scope.row[field]"
+            :prev-val="scope.row[`prev${field}`]"
+            :gap-val="scope.row[`gap${field}`]"
+            :date-range="dateRange"
+            :show-compare="showCompare"/>
+      </template>
+    </fs-crud>
+  </fs-page>
+</template>
+
 <style lang="scss" scoped>
 .campare-switch {
   flex: none;

+ 89 - 90
src/views/adManage/ad-overview/total/index.vue

@@ -1,92 +1,3 @@
-<template>
-  <div>
-    <div class="container-main">
-      <div class="overview-tabs">
-        <DateRangePicker v-model="dateRange"></DateRangePicker>
-        <el-select
-            v-model="selectedPortfolios"
-            placeholder="SP"
-            style="width: 200px"
-            collapse-tags
-            collapse-tags-tooltip
-            :max-collapse-tags="3"
-        >
-          <el-option v-for="info of portfolios" :key="info.value" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
-        </el-select>
-      </div>
-      <!-- 卡片内容 不要删除这个类 -->
-      <div class="home-container" style="margin-top: 0" v-loading="cardLoading">
-        <el-row :gutter="15" class="home-card-one mb15">
-          <el-col
-              :xs="24"
-              :sm="12"
-              :md="12"
-              :lg="6"
-              :xl="6"
-              v-for="(v, k) in state.homeOne"
-              :key="k"
-              :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
-          >
-            <div class="home-card-item flex">
-              <div class="flex-margin flex w100" :class="` home-one-animation${k}`">
-                <div class="flex-auto" style="margin-top: -10px">
-                  <div class="mt10">{{ v.cardTitle }}</div>
-                  <div class="font30">{{ v.num1 }}</div>
-                  <div style="display: inline-block; margin-right: 10px; margin-left: 3px;">
-                    {{ v.compareNum }}
-                  </div>
-                  <el-icon :style="{ color: String(v.num2).includes('-') ? '#59b939' : '#e36f53' }" style="display: inline-block; padding-top: 2px">
-                    <template v-if="String(v.num2).includes('-')">
-                      <Bottom/> <!-- num2 是负数时显示向下箭头 -->
-                    </template>
-                    <template v-else>
-                      <Top/> <!-- num2 不是负数时显示向上箭头 -->
-                    </template>
-                  </el-icon>
-                  <span class="l-indent" :style="{ color: String(v.num2).includes('-') ? '#59b939' : '#e36f53' }">{{ v.num2 }}%</span>
-                </div>
-                <div class="home-card-item-icon flex" :style="{ background: `var(${v.color2})` }">
-                  <i class="flex-margin font32" :class="v.num4" :style="{ color: `var(${v.color3})` }"></i>
-                </div>
-              </div>
-            </div>
-          </el-col>
-        </el-row>
-      </div>
-      <!-- 折线图 -->
-      <el-card v-loading="loading" style="margin-top: -5px;">
-        <div style="height: 350px;" ref="chartRefOne"></div>
-      </el-card>
-      <el-row :gutter="5" style="margin-top: 10px">
-        <el-col :span="12">
-          <el-card v-loading="loading">
-            <div style="height: 350px;" ref="chartRefAcos"></div>
-          </el-card>
-        </el-col>
-        <el-col :span="12">
-          <el-card v-loading="loading">
-            <div style="height: 350px;" ref="chartRefCPCandCTR"></div>
-          </el-card>
-        </el-col>
-      </el-row>
-      <el-row :gutter="5" style="margin-top: 10px">
-        <el-col :span="12">
-          <el-card v-loading="loading">
-            <div style="height: 350px;" ref="chartRefTotalPurchases"></div>
-          </el-card>
-        </el-col>
-        <el-col :span="12">
-          <el-card v-loading="loading">
-            <div style="height: 350px;" ref="chartRefImpandCli"></div>
-          </el-card>
-        </el-col>
-      </el-row>
-    </div>
-    <!--<el-button @click="changeCardData">按钮</el-button>-->
-  </div>
-
-</template>
-
 <script lang="ts" setup>
 import {nextTick, onBeforeUnmount, onMounted, reactive, Ref, ref, watch} from 'vue'
 import * as echarts from 'echarts'
@@ -95,7 +6,7 @@ import {usePublicData} from '/@/stores/publicData'
 import {storeToRefs} from 'pinia'
 import {createCrudOptions} from '/@/views/adManage/sp/targets/crud'
 import {useFs} from '@fast-crud/fast-crud'
-import {getCardTotalData, getChartTotalData} from '/src/views/adManage/ad-overview/total/api'
+import {getCardTotalData, getChartTotalData} from '/@/views/adManage/ad-overview/total/api'
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 
 const loading = ref(true)
@@ -802,6 +713,94 @@ onBeforeUnmount(() => {
 
 </script>
 
+<template>
+  <div>
+    <div class="container-main">
+      <div class="overview-tabs">
+        <DateRangePicker v-model="dateRange"></DateRangePicker>
+        <el-select
+            v-model="selectedPortfolios"
+            placeholder="SP"
+            style="width: 200px"
+            collapse-tags
+            collapse-tags-tooltip
+            :max-collapse-tags="3"
+        >
+          <el-option v-for="info of portfolios" :key="info.value" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
+        </el-select>
+      </div>
+      <!-- 卡片内容 不要删除这个类 -->
+      <div class="home-container" style="margin-top: 0" v-loading="cardLoading">
+        <el-row :gutter="15" class="home-card-one mb15">
+          <el-col
+              :xs="24"
+              :sm="12"
+              :md="12"
+              :lg="6"
+              :xl="6"
+              v-for="(v, k) in state.homeOne"
+              :key="k"
+              :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
+          >
+            <div class="home-card-item flex">
+              <div class="flex-margin flex w100" :class="` home-one-animation${k}`">
+                <div class="flex-auto" style="margin-top: -10px">
+                  <div class="mt10">{{ v.cardTitle }}</div>
+                  <div class="font30">{{ v.num1 }}</div>
+                  <div style="display: inline-block; margin-right: 10px; margin-left: 3px;">
+                    {{ v.compareNum }}
+                  </div>
+                  <el-icon :style="{ color: String(v.num2).includes('-') ? '#59b939' : '#e36f53' }" style="display: inline-block; padding-top: 2px">
+                    <template v-if="String(v.num2).includes('-')">
+                      <Bottom/> <!-- num2 是负数时显示向下箭头 -->
+                    </template>
+                    <template v-else>
+                      <Top/> <!-- num2 不是负数时显示向上箭头 -->
+                    </template>
+                  </el-icon>
+                  <span class="l-indent" :style="{ color: String(v.num2).includes('-') ? '#59b939' : '#e36f53' }">{{ v.num2 }}%</span>
+                </div>
+                <div class="home-card-item-icon flex" :style="{ background: `var(${v.color2})` }">
+                  <i class="flex-margin font32" :class="v.num4" :style="{ color: `var(${v.color3})` }"></i>
+                </div>
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+      <!-- 折线图 -->
+      <el-card v-loading="loading" style="margin-top: -5px;">
+        <div style="height: 350px;" ref="chartRefOne"></div>
+      </el-card>
+      <el-row :gutter="5" style="margin-top: 10px">
+        <el-col :span="12">
+          <el-card v-loading="loading">
+            <div style="height: 350px;" ref="chartRefAcos"></div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card v-loading="loading">
+            <div style="height: 350px;" ref="chartRefCPCandCTR"></div>
+          </el-card>
+        </el-col>
+      </el-row>
+      <el-row :gutter="5" style="margin-top: 10px">
+        <el-col :span="12">
+          <el-card v-loading="loading">
+            <div style="height: 350px;" ref="chartRefTotalPurchases"></div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card v-loading="loading">
+            <div style="height: 350px;" ref="chartRefImpandCli"></div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+    <!--<el-button @click="changeCardData">按钮</el-button>-->
+  </div>
+</template>
+
 <style scoped lang="scss">
 $homeNavLengh: 8;
 .home-container {

+ 52 - 52
src/views/adManage/ad-overview/weekly/index.vue

@@ -1,55 +1,3 @@
-<template>
-  <div class="overview-tabs">
-    <DateRangePicker v-model="dateRange"></DateRangePicker>
-    <el-select
-        v-model="selectedPortfolios"
-        placeholder="SP"
-        style="width: 200px"
-        collapse-tags
-        collapse-tags-tooltip
-        :max-collapse-tags="3"
-    >
-      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
-    </el-select>
-  </div>
-  <fs-page class="fs-page-custom" style="margin-top: -11px">
-    <fs-crud ref="crudRef" v-bind="crudBinding">
-      <template #header-middle>
-        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
-          <DataTendencyChart
-              v-if="tabActiveName === 'dataTendency'"
-              :query="queryParams"
-              :fetchCard="getCardData"
-              :fetchLine="getLineData"
-              :fetch-line-month="getLineMonthData"
-              :fetch-line-week="getLineWeekData">
-          </DataTendencyChart>
-        </el-tabs>
-      </template>
-      <template #cell_percentTimeInBudget="scope">
-        <el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
-      </template>
-      <template #cell_campaignName="scope">
-        <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
-      </template>
-      <template #cell_MissedImpressions="scope">
-        {{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
-      </template>
-      <template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
-      <template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
-      <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
-        <DataCompare
-            :field="field"
-            :value="scope.row[field]"
-            :prev-val="scope.row[`prev${field}`]"
-            :gap-val="scope.row[`gap${field}`]"
-            :date-range="dateRange"
-            :show-compare="showCompare"/>
-      </template>
-    </fs-crud>
-  </fs-page>
-</template>
-
 <script lang="ts" setup>
 import {onMounted, Ref, ref, watch} from 'vue'
 import {FsPage, useFs} from '@fast-crud/fast-crud'
@@ -118,6 +66,58 @@ watch(queryParams, async () => {
 }, { deep: true })
 </script>
 
+<template>
+  <div class="overview-tabs">
+    <DateRangePicker v-model="dateRange"></DateRangePicker>
+    <el-select
+        v-model="selectedPortfolios"
+        placeholder="SP"
+        style="width: 200px"
+        collapse-tags
+        collapse-tags-tooltip
+        :max-collapse-tags="3"
+    >
+      <el-option v-for="info of portfolios" :label="info.label" :value="info.value" :disabled="info.disabled"></el-option>
+    </el-select>
+  </div>
+  <fs-page class="fs-page-custom" style="margin-top: -11px">
+    <fs-crud ref="crudRef" v-bind="crudBinding">
+      <template #header-middle>
+        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
+          <DataTendencyChart
+              v-if="tabActiveName === 'dataTendency'"
+              :query="queryParams"
+              :fetchCard="getCardData"
+              :fetchLine="getLineData"
+              :fetch-line-month="getLineMonthData"
+              :fetch-line-week="getLineWeekData">
+          </DataTendencyChart>
+        </el-tabs>
+      </template>
+      <template #cell_percentTimeInBudget="scope">
+        <el-progress :percentage="scope.row.percentTimeInBudget > 0 ? scope.row.percentTimeInBudget * 100 : 0" />
+      </template>
+      <template #cell_campaignName="scope">
+        <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">{{ scope.row.campaignName }}</el-link>
+      </template>
+      <template #cell_MissedImpressions="scope">
+        {{ scope.row.MissedImpressionsLower ?? '0' }} ~ {{ scope.row.MissedImpressionsUpper ?? '0' }}
+      </template>
+      <template #cell_MissedClicks="scope"> {{ scope.row.MissedClicksLower ?? '0' }} ~ {{ scope.row.MissedClicksUpper ?? '0' }} </template>
+      <template #cell_MissedSales="scope"> {{ scope.row.MissedSalesLower ?? '0' }} ~ {{ scope.row.MissedSalesUpper ?? '0' }} </template>
+      <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
+        <DataCompare
+            :field="field"
+            :value="scope.row[field]"
+            :prev-val="scope.row[`prev${field}`]"
+            :gap-val="scope.row[`gap${field}`]"
+            :date-range="dateRange"
+            :show-compare="showCompare"/>
+      </template>
+    </fs-crud>
+  </fs-page>
+</template>
+
 <style lang="scss" scoped>
 .campare-switch {
   flex: none;

+ 128 - 128
src/views/adManage/sb/campaigns/CreateCampaigns/component/AdCampaign.vue

@@ -1,131 +1,3 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;" v-loading="campaignLoading">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">设置</span>
-      </div>
-      <el-form
-        ref="campaignRuleFormRef"
-        :model="campaignRuleForm"
-        :rules="campaignRules"
-        label-position="top"
-        label-width="120px"
-        class="demo-ruleForm"
-        :size="formSize"
-        status-icon>
-        <div class="flex-between">
-          <el-form-item label="广告活动名称" prop="campaignName" style="width: 48%">
-            <el-input v-model="campaignRuleForm.campaignName" placeholder="请输入广告活动名称" />
-          </el-form-item>
-          <el-form-item label="广告组合" prop="adMix" style="width: 48%">
-            <el-select v-model="campaignRuleForm.adMix" placeholder="请选择" style="width: 100%">
-              <el-option v-for="item in adMixOptions" :key="item.value" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
-        </div>
-        <div class="flex-between">
-          <div class="flex-between" style="width: 48%">
-            <el-form-item label="开始时间" prop="startDate" style="width: 49%">
-              <el-date-picker
-                v-model="campaignRuleForm.startDate"
-                type="date"
-                label="Pick a date"
-                placeholder="开始时间"
-                format="YYYY-MM-DD"
-                value-format="YYYY-MM-DD"
-                style="width: 100%" />
-            </el-form-item>
-
-            <el-form-item label="结束时间" prop="endDate" style="width: 49%">
-              <el-date-picker
-                v-model="campaignRuleForm.endDate"
-                type="date"
-                label="Pick a date"
-                placeholder="开始时间"
-                format="YYYY-MM-DD"
-                value-format="YYYY-MM-DD"
-                style="width: 100%" />
-            </el-form-item>
-          </div>
-          <div class="flex-between" style="width: 48%">
-            <el-form-item label="预算" required prop="budget" style="width: 65%">
-              <el-input v-model="campaignRuleForm.budget" minlength="1" maxlength="7" placeholder="请输入" style="width: 100%">
-                <template #prepend>$</template>
-              </el-input>
-            </el-form-item>
-            <el-form-item label="频率" prop="frequency" style="width: 34%">
-              <el-select v-model="campaignRuleForm.frequency" placeholder="请选择" style="width: 100%">
-                <el-option v-for="item in frequencyOptions" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" />
-              </el-select>
-            </el-form-item>
-          </div>
-        </div>
-        <el-form-item label="品牌" prop="brand" required style="width: 48%">
-          <el-select v-model="campaignRuleForm.brand" placeholder="请选择" style="width: 100%">
-            <el-option v-for="item in brandOptions" :key="item.brandId" :label="item.brandRegistryName" :value="item.brandEntityId" />
-          </el-select>
-        </el-form-item>
-        <div style="font-weight: 700; padding-bottom: 18px">
-          <span style="color: #306cd7; font-size: 26px">|</span>
-          <span style="font-size: 18px; padding-left: 5px">竞价</span>
-        </div>
-        <el-form-item label="自动竞价" style="margin-bottom: -13px">
-          <el-form-item>
-            <el-switch v-model="campaignRuleForm.isBid" />
-            <span style="margin-left: 10px; color: #88909b">允许亚马逊自动优化搜索结果首页以外的广告位竞价</span>
-          </el-form-item>
-        </el-form-item>
-        <div style="width: 55%" v-if="campaignRuleForm.isBid == false">
-          <el-card shadow="never" body-style="padding: 10px 10px 5px 10px;">
-            <div style="margin-bottom: 10px; font-weight: 500">
-              <span style="color:#f56c6c;margin-right: 4px;">*</span>
-              展示位置出价调整
-            </div>
-            <div style="display: flex; align-items: center">
-              <div class="left">
-                <div class="title">商品页面</div>
-                <div class="tip">产品详情页面为顾客提供在亚马逊所售卖商品的详情信息</div>
-              </div>
-              <el-form-item prop="commodityPage" style="margin-bottom: 0px !important; width: 37%;">
-                <el-input v-model="campaignRuleForm.commodityPage" maxlength="3" placeholder="-99 ~ 900">
-                  <template #append>%</template>
-                </el-input>
-              </el-form-item>
-            </div>
-            <div style="display: flex; align-items: center; margin-top: 10px">
-              <div class="left">
-                <div class="title">搜索结果顶部(首页)</div>
-                <div class="tip">亚马逊首页 http://www.amazon.com</div>
-              </div>
-              <el-form-item prop="firstPage" style="margin-bottom: 0px !important; width: 37%">
-                <el-input v-model="campaignRuleForm.firstPage" maxlength="3" placeholder="-99 ~ 900" style="width: 100%">
-                  <template #append>%</template>
-                </el-input>
-              </el-form-item>
-            </div>
-            <div style="display: flex; align-items: center; margin-top: 10px">
-              <div class="left">
-                <div class="title">搜索结果的其余位置</div>
-                <div class="tip">其他位置集合, 例如搜索页</div>
-              </div>
-              <el-form-item prop="otherPlace" style="margin-bottom: 0px !important; width: 37%">
-                <el-input v-model="campaignRuleForm.otherPlace" maxlength="3" placeholder="-99 ~ 900">
-                  <template #append>%</template>
-                </el-input>
-              </el-form-item>
-            </div>
-            <div style="color: #8d9095; padding-left: 60%; margin-top: 10px">示例: $5.00 竞价降低 40% 将变为 $3.00</div>
-          </el-card>
-        </div>
-        <el-form-item style="margin: 20px 0 -10px 48%">
-          <el-button type="primary" plain @click="submitCampaignForm(campaignRuleFormRef)">保存</el-button>
-        </el-form-item>
-      </el-form>
-    </el-card>
-  </div>
-</template>
-
 <script lang="ts" setup>
 import type { FormInstance, FormRules } from 'element-plus'
 import { ElMessage } from 'element-plus'
@@ -313,6 +185,134 @@ onMounted(() => {
 })
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;" v-loading="campaignLoading">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">设置</span>
+      </div>
+      <el-form
+        ref="campaignRuleFormRef"
+        :model="campaignRuleForm"
+        :rules="campaignRules"
+        label-position="top"
+        label-width="120px"
+        class="demo-ruleForm"
+        :size="formSize"
+        status-icon>
+        <div class="flex-between">
+          <el-form-item label="广告活动名称" prop="campaignName" style="width: 48%">
+            <el-input v-model="campaignRuleForm.campaignName" placeholder="请输入广告活动名称" />
+          </el-form-item>
+          <el-form-item label="广告组合" prop="adMix" style="width: 48%">
+            <el-select v-model="campaignRuleForm.adMix" placeholder="请选择" style="width: 100%">
+              <el-option v-for="item in adMixOptions" :key="item.value" :label="item.label" :value="item.value" />
+            </el-select>
+          </el-form-item>
+        </div>
+        <div class="flex-between">
+          <div class="flex-between" style="width: 48%">
+            <el-form-item label="开始时间" prop="startDate" style="width: 49%">
+              <el-date-picker
+                v-model="campaignRuleForm.startDate"
+                type="date"
+                label="Pick a date"
+                placeholder="开始时间"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+                style="width: 100%" />
+            </el-form-item>
+
+            <el-form-item label="结束时间" prop="endDate" style="width: 49%">
+              <el-date-picker
+                v-model="campaignRuleForm.endDate"
+                type="date"
+                label="Pick a date"
+                placeholder="开始时间"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+                style="width: 100%" />
+            </el-form-item>
+          </div>
+          <div class="flex-between" style="width: 48%">
+            <el-form-item label="预算" required prop="budget" style="width: 65%">
+              <el-input v-model="campaignRuleForm.budget" minlength="1" maxlength="7" placeholder="请输入" style="width: 100%">
+                <template #prepend>$</template>
+              </el-input>
+            </el-form-item>
+            <el-form-item label="频率" prop="frequency" style="width: 34%">
+              <el-select v-model="campaignRuleForm.frequency" placeholder="请选择" style="width: 100%">
+                <el-option v-for="item in frequencyOptions" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" />
+              </el-select>
+            </el-form-item>
+          </div>
+        </div>
+        <el-form-item label="品牌" prop="brand" required style="width: 48%">
+          <el-select v-model="campaignRuleForm.brand" placeholder="请选择" style="width: 100%">
+            <el-option v-for="item in brandOptions" :key="item.brandId" :label="item.brandRegistryName" :value="item.brandEntityId" />
+          </el-select>
+        </el-form-item>
+        <div style="font-weight: 700; padding-bottom: 18px">
+          <span style="color: #306cd7; font-size: 26px">|</span>
+          <span style="font-size: 18px; padding-left: 5px">竞价</span>
+        </div>
+        <el-form-item label="自动竞价" style="margin-bottom: -13px">
+          <el-form-item>
+            <el-switch v-model="campaignRuleForm.isBid" />
+            <span style="margin-left: 10px; color: #88909b">允许亚马逊自动优化搜索结果首页以外的广告位竞价</span>
+          </el-form-item>
+        </el-form-item>
+        <div style="width: 55%" v-if="campaignRuleForm.isBid == false">
+          <el-card shadow="never" body-style="padding: 10px 10px 5px 10px;">
+            <div style="margin-bottom: 10px; font-weight: 500">
+              <span style="color:#f56c6c;margin-right: 4px;">*</span>
+              展示位置出价调整
+            </div>
+            <div style="display: flex; align-items: center">
+              <div class="left">
+                <div class="title">商品页面</div>
+                <div class="tip">产品详情页面为顾客提供在亚马逊所售卖商品的详情信息</div>
+              </div>
+              <el-form-item prop="commodityPage" style="margin-bottom: 0px !important; width: 37%;">
+                <el-input v-model="campaignRuleForm.commodityPage" maxlength="3" placeholder="-99 ~ 900">
+                  <template #append>%</template>
+                </el-input>
+              </el-form-item>
+            </div>
+            <div style="display: flex; align-items: center; margin-top: 10px">
+              <div class="left">
+                <div class="title">搜索结果顶部(首页)</div>
+                <div class="tip">亚马逊首页 http://www.amazon.com</div>
+              </div>
+              <el-form-item prop="firstPage" style="margin-bottom: 0px !important; width: 37%">
+                <el-input v-model="campaignRuleForm.firstPage" maxlength="3" placeholder="-99 ~ 900" style="width: 100%">
+                  <template #append>%</template>
+                </el-input>
+              </el-form-item>
+            </div>
+            <div style="display: flex; align-items: center; margin-top: 10px">
+              <div class="left">
+                <div class="title">搜索结果的其余位置</div>
+                <div class="tip">其他位置集合, 例如搜索页</div>
+              </div>
+              <el-form-item prop="otherPlace" style="margin-bottom: 0px !important; width: 37%">
+                <el-input v-model="campaignRuleForm.otherPlace" maxlength="3" placeholder="-99 ~ 900">
+                  <template #append>%</template>
+                </el-input>
+              </el-form-item>
+            </div>
+            <div style="color: #8d9095; padding-left: 60%; margin-top: 10px">示例: $5.00 竞价降低 40% 将变为 $3.00</div>
+          </el-card>
+        </div>
+        <el-form-item style="margin: 20px 0 -10px 48%">
+          <el-button type="primary" plain @click="submitCampaignForm(campaignRuleFormRef)">保存</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
 <style scoped>
 .flex-between {
   display: flex;

+ 25 - 25
src/views/adManage/sb/campaigns/CreateCampaigns/component/AdGroup.vue

@@ -1,28 +1,3 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;" v-loading="groupLoading">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">广告组</span>
-      </div>
-      <el-form
-        ref="groupRuleFormRef"
-        :model="groupRuleForm"
-        :rules="groupRules"
-        label-position="left"
-        label-width="120px"
-        class="demo-ruleForm"
-        :size="formSize"
-        status-icon>
-        <el-form-item label="广告组名称" prop="groupName">
-          <el-input v-model="groupRuleForm.groupName" style="width: 600px" placeholder="请输入广告组名称" />
-          <el-button type="primary" plain :disabled="!respCampaignId" @click="submitGroupForm(groupRuleFormRef)" style="margin-left: 30px">保存</el-button>
-        </el-form-item>
-      </el-form>
-    </el-card>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { reactive, ref, inject, watch, Ref } from 'vue'
 import type { FormInstance, FormRules } from 'element-plus'
@@ -100,6 +75,31 @@ watch(respAdGroupId, () => {
 
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;" v-loading="groupLoading">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">广告组</span>
+      </div>
+      <el-form
+        ref="groupRuleFormRef"
+        :model="groupRuleForm"
+        :rules="groupRules"
+        label-position="left"
+        label-width="120px"
+        class="demo-ruleForm"
+        :size="formSize"
+        status-icon>
+        <el-form-item label="广告组名称" prop="groupName">
+          <el-input v-model="groupRuleForm.groupName" style="width: 600px" placeholder="请输入广告组名称" />
+          <el-button type="primary" plain :disabled="!respCampaignId" @click="submitGroupForm(groupRuleFormRef)" style="margin-left: 30px">保存</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
 <style lang="scss" scoped>
 .customize-container {
   margin-top: 10px;

+ 10 - 10
src/views/adManage/sb/campaigns/CreateCampaigns/component/DeliveryType.vue

@@ -1,3 +1,13 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import KeywordTarget from './KeywordTarget.vue'
+import NegativeWord from './NegativeWord.vue'
+import ProductOrientation from './ProductOrientation.vue'
+import NegativeGood from './NegativeGood.vue'
+
+const deliveryTypeRadio = ref('keyword')
+</script>
+
 <template>
   <div class="customize-container">
     <el-card body-style="padding: 20px 80px 20px 80px;">
@@ -26,16 +36,6 @@
   </div>
 </template>
 
-<script setup lang="ts">
-import { ref } from 'vue'
-import KeywordTarget from './KeywordTarget.vue'
-import NegativeWord from './NegativeWord.vue'
-import ProductOrientation from './ProductOrientation.vue'
-import NegativeGood from './NegativeGood.vue'
-
-const deliveryTypeRadio = ref('keyword')
-</script>
-
 <style scoped>
 .customize-container {
   margin-top: 10px;

+ 244 - 244
src/views/adManage/sb/campaigns/CreateCampaigns/component/FocusCreativity.vue

@@ -1,247 +1,3 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">创意</span>
-      </div>
-      <el-form
-        ref="ruleFormRef"
-        :model="ruleForm"
-        :rules="rules"
-        label-width="120px"
-        class="demo-ruleForm"
-        size="default"
-        label-position="top"
-        status-icon>
-        <el-form-item label="广告名称" prop="name">
-          <el-input v-model="ruleForm.name" style="width: 50%" />
-        </el-form-item>
-        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
-          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
-            <el-scrollbar height="700px">
-              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
-                <el-collapse-item name="1" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
-                  <el-form-item prop="brandName">
-                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 0 5px 0"></el-input>
-                  </el-form-item>
-
-                  <el-upload
-                    v-model:file-list="fileList"
-                    :on-change="changeFile"
-                    v-loading="upLoading"
-                    action="#"
-                    accept=".png, .jpg"
-                    :limit="1"
-                    list-type="picture-card"
-                    :auto-upload="false">
-                    <el-icon><Plus /></el-icon>
-                    <template #file="{ file }">
-                      <div>
-                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
-                        <span class="el-upload-list__item-actions">
-                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
-                            <el-icon><zoom-in /></el-icon>
-                          </span>
-                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
-                            <el-icon><Delete /></el-icon>
-                          </span>
-                        </span>
-                      </div>
-                    </template>
-                    <template #tip>
-                      <div style="margin-top: 10px">
-                        <div style="display: flex; align-items: center; justify-content: space-between">
-                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
-                          <el-button type="primary" :icon="Picture" @click="openDialog" disabled="true">从素材库中选择</el-button>
-                        </div>
-                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
-                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
-                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
-                        <div class="introduce-item">
-                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
-                          <span style="margin-left: 25px; position: relative">
-                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
-                            <el-link
-                              type="primary"
-                              :underline="false"
-                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
-                              target="_blank"
-                              >查看要求</el-link
-                            >
-                          </span>
-                        </div>
-                      </div>
-                    </template>
-                  </el-upload>
-                  <!-- 预览弹窗 -->
-                  <el-dialog v-model="dialogVisible">
-                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
-                  </el-dialog>
-                </el-collapse-item>
-
-                <el-collapse-item name="commodity" v-loading="commodityLoading" style="padding-right: 10px">
-                  <template #title>编辑品牌旗舰店页面</template>
-                  <div v-for="(storePage, index) in topStorePages" :key="index" style="margin-bottom: 10px; width: 85%">
-                    <el-card shadow="hover" body-style="padding: 10px;">
-                      <div style="margin-right: 8px; line-height: normal; display: flex; align-items: center">
-                        <el-image class="img-box" :src="storePage.storePageLink" />
-                        <div style="margin-left: 15px">
-                          <span><span style="color: #6d7784">当前名称:</span>{{ storePage.storePageName }}</span>
-                          <div style="margin-bottom: 5px"><span style="color: #6d7784">ASIN: </span>{{ storePage.asin }}</div>
-                          <el-input v-model="storePage.inputName" style="width: 300px" placeholder="修改品牌页面名称"></el-input>
-                        </div>
-                        <div class="card-operation">
-                          <el-button link type="primary" @click="changePicture(storePage.storePageUrl, index)" style="margin-bottom: 10px"
-                            >更换图片</el-button
-                          >
-                          <el-button link type="primary" @click="changePage(storePage.storePageUrl, index)">更换页面</el-button>
-                        </div>
-                      </div>
-                    </el-card>
-                  </div>
-                </el-collapse-item>
-                <el-dialog v-model="commodityDialog" title="更换图片" width="50%">
-                  <el-radio-group
-                    v-loading="dialogLoading3"
-                    v-model="selectedCommodity"
-                    style="display: flex; flex-direction: column; align-content: flex-start; align-items: flex-start">
-                    <div v-for="(item, index) in stock" :key="index">
-                      <el-radio :label="item.asin" style="height: 80px; border-bottom: 1px solid #ccc">
-                        <div style="padding: 10px; display: flex; align-items: center">
-                          <div style="margin-right: 8px; line-height: normal">
-                            <el-image class="img-box" :src="item.image_link" />
-                          </div>
-                          <div style="position: relative">
-                            <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                              <div class="double-line">{{ item.title }}</div>
-                            </el-tooltip>
-                            <span>
-                              <span style="color: #6d7784">ASIN: </span>
-                              <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                            </span>
-                          </div>
-                        </div>
-                      </el-radio>
-                    </div>
-                  </el-radio-group>
-                  <div style="margin-top: 20px; display: flex; justify-content: center">
-                    <el-button type="primary" :disabled="!selectedCommodity" @click="handleSelectedStore">确定</el-button>
-                  </div>
-                </el-dialog>
-                <el-dialog v-model="pageDialog" title="更换页面" width="50%">
-                  <el-radio-group v-loading="pageDialogLoading" v-model="selectedCommodity" @change="handlePageChange" class="radio-group-item">
-                    <div v-for="(item, index) in storePageData.storePageInfo" :key="index" style="width: 100%">
-                      <el-radio
-                        :label="item.storePageId"
-                        class="radio-item"
-                        :disabled="topStorePages.some((storePage) => storePage.storePageName === item.storePageName)">
-                        <div class="radio-item-content">
-                          <div style="position: relative">
-                            <el-tooltip class="box-item" effect="dark" :content="item.storePageName" placement="top">
-                              <div class="double-line">{{ item.storePageName }}</div>
-                            </el-tooltip>
-                          </div>
-                        </div>
-                      </el-radio>
-                    </div>
-                  </el-radio-group>
-                  <!-- <div style="margin-top: 20px; display: flex; justify-content: center">
-                    <el-button type="primary" :disabled="!selectedCommodity">确定</el-button>
-                  </div> -->
-                </el-dialog>
-
-                <el-collapse-item name="4" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
-                  <el-form-item prop="title">
-                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
-                  </el-form-item>
-                </el-collapse-item>
-              </el-collapse>
-            </el-scrollbar>
-          </div>
-          <div style="width: 50%; padding: 0 10px; position: relative">
-            <el-button type="primary" plain @click="submitForm(ruleFormRef)" :disabled="!fileList.length" style="position: absolute; top: 92%; left: 46%"
-              >保存</el-button
-            >
-          </div>
-        </div>
-      </el-form>
-    </el-card>
-    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in cards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <el-image class="image" :src="item.imageUrl" fit="cover" />
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">徽标</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-    <!-- <el-dialog v-model="lifeStyleDialog" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in lifeStyleCards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <el-image class="image" :src="item.imageUrl" fit="cover" />
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">徽标</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="centerDialogVisible = false">确定</el-button>
-        </span>
-      </template>
-    </el-dialog> -->
-  </div>
-</template>
-
 <script setup lang="ts">
 import { reactive, ref, inject, Ref, watch, computed, onMounted, onUnmounted } from 'vue'
 import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus'
@@ -835,6 +591,250 @@ onMounted(async () => {
 })
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">创意</span>
+      </div>
+      <el-form
+        ref="ruleFormRef"
+        :model="ruleForm"
+        :rules="rules"
+        label-width="120px"
+        class="demo-ruleForm"
+        size="default"
+        label-position="top"
+        status-icon>
+        <el-form-item label="广告名称" prop="name">
+          <el-input v-model="ruleForm.name" style="width: 50%" />
+        </el-form-item>
+        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
+          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
+            <el-scrollbar height="700px">
+              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
+                <el-collapse-item name="1" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
+                  <el-form-item prop="brandName">
+                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 0 5px 0"></el-input>
+                  </el-form-item>
+
+                  <el-upload
+                    v-model:file-list="fileList"
+                    :on-change="changeFile"
+                    v-loading="upLoading"
+                    action="#"
+                    accept=".png, .jpg"
+                    :limit="1"
+                    list-type="picture-card"
+                    :auto-upload="false">
+                    <el-icon><Plus /></el-icon>
+                    <template #file="{ file }">
+                      <div>
+                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
+                        <span class="el-upload-list__item-actions">
+                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
+                            <el-icon><zoom-in /></el-icon>
+                          </span>
+                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
+                            <el-icon><Delete /></el-icon>
+                          </span>
+                        </span>
+                      </div>
+                    </template>
+                    <template #tip>
+                      <div style="margin-top: 10px">
+                        <div style="display: flex; align-items: center; justify-content: space-between">
+                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
+                          <el-button type="primary" :icon="Picture" @click="openDialog" disabled="true">从素材库中选择</el-button>
+                        </div>
+                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
+                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
+                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
+                        <div class="introduce-item">
+                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
+                          <span style="margin-left: 25px; position: relative">
+                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
+                            <el-link
+                              type="primary"
+                              :underline="false"
+                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
+                              target="_blank"
+                              >查看要求</el-link
+                            >
+                          </span>
+                        </div>
+                      </div>
+                    </template>
+                  </el-upload>
+                  <!-- 预览弹窗 -->
+                  <el-dialog v-model="dialogVisible">
+                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
+                  </el-dialog>
+                </el-collapse-item>
+
+                <el-collapse-item name="commodity" v-loading="commodityLoading" style="padding-right: 10px">
+                  <template #title>编辑品牌旗舰店页面</template>
+                  <div v-for="(storePage, index) in topStorePages" :key="index" style="margin-bottom: 10px; width: 85%">
+                    <el-card shadow="hover" body-style="padding: 10px;">
+                      <div style="margin-right: 8px; line-height: normal; display: flex; align-items: center">
+                        <el-image class="img-box" :src="storePage.storePageLink" />
+                        <div style="margin-left: 15px">
+                          <span><span style="color: #6d7784">当前名称:</span>{{ storePage.storePageName }}</span>
+                          <div style="margin-bottom: 5px"><span style="color: #6d7784">ASIN: </span>{{ storePage.asin }}</div>
+                          <el-input v-model="storePage.inputName" style="width: 300px" placeholder="修改品牌页面名称"></el-input>
+                        </div>
+                        <div class="card-operation">
+                          <el-button link type="primary" @click="changePicture(storePage.storePageUrl, index)" style="margin-bottom: 10px"
+                            >更换图片</el-button
+                          >
+                          <el-button link type="primary" @click="changePage(storePage.storePageUrl, index)">更换页面</el-button>
+                        </div>
+                      </div>
+                    </el-card>
+                  </div>
+                </el-collapse-item>
+                <el-dialog v-model="commodityDialog" title="更换图片" width="50%">
+                  <el-radio-group
+                    v-loading="dialogLoading3"
+                    v-model="selectedCommodity"
+                    style="display: flex; flex-direction: column; align-content: flex-start; align-items: flex-start">
+                    <div v-for="(item, index) in stock" :key="index">
+                      <el-radio :label="item.asin" style="height: 80px; border-bottom: 1px solid #ccc">
+                        <div style="padding: 10px; display: flex; align-items: center">
+                          <div style="margin-right: 8px; line-height: normal">
+                            <el-image class="img-box" :src="item.image_link" />
+                          </div>
+                          <div style="position: relative">
+                            <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                              <div class="double-line">{{ item.title }}</div>
+                            </el-tooltip>
+                            <span>
+                              <span style="color: #6d7784">ASIN: </span>
+                              <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                            </span>
+                          </div>
+                        </div>
+                      </el-radio>
+                    </div>
+                  </el-radio-group>
+                  <div style="margin-top: 20px; display: flex; justify-content: center">
+                    <el-button type="primary" :disabled="!selectedCommodity" @click="handleSelectedStore">确定</el-button>
+                  </div>
+                </el-dialog>
+                <el-dialog v-model="pageDialog" title="更换页面" width="50%">
+                  <el-radio-group v-loading="pageDialogLoading" v-model="selectedCommodity" @change="handlePageChange" class="radio-group-item">
+                    <div v-for="(item, index) in storePageData.storePageInfo" :key="index" style="width: 100%">
+                      <el-radio
+                        :label="item.storePageId"
+                        class="radio-item"
+                        :disabled="topStorePages.some((storePage) => storePage.storePageName === item.storePageName)">
+                        <div class="radio-item-content">
+                          <div style="position: relative">
+                            <el-tooltip class="box-item" effect="dark" :content="item.storePageName" placement="top">
+                              <div class="double-line">{{ item.storePageName }}</div>
+                            </el-tooltip>
+                          </div>
+                        </div>
+                      </el-radio>
+                    </div>
+                  </el-radio-group>
+                  <!-- <div style="margin-top: 20px; display: flex; justify-content: center">
+                    <el-button type="primary" :disabled="!selectedCommodity">确定</el-button>
+                  </div> -->
+                </el-dialog>
+
+                <el-collapse-item name="4" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
+                  <el-form-item prop="title">
+                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
+                  </el-form-item>
+                </el-collapse-item>
+              </el-collapse>
+            </el-scrollbar>
+          </div>
+          <div style="width: 50%; padding: 0 10px; position: relative">
+            <el-button type="primary" plain @click="submitForm(ruleFormRef)" :disabled="!fileList.length" style="position: absolute; top: 92%; left: 46%"
+              >保存</el-button
+            >
+          </div>
+        </div>
+      </el-form>
+    </el-card>
+    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in cards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <el-image class="image" :src="item.imageUrl" fit="cover" />
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">徽标</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- <el-dialog v-model="lifeStyleDialog" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in lifeStyleCards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <el-image class="image" :src="item.imageUrl" fit="cover" />
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">徽标</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="centerDialogVisible = false">确定</el-button>
+        </span>
+      </template>
+    </el-dialog> -->
+  </div>
+</template>
+
 <style scoped>
 .customize-container {
   margin-top: 10px;

+ 89 - 89
src/views/adManage/sb/campaigns/CreateCampaigns/component/KeywordTarget.vue

@@ -1,92 +1,3 @@
-<template>
-  <div style="width: 100%; margin-top: 20px">
-    <el-divider content-position="left">
-      <span style="font-size: 18px; font-weight: 700">关键词定向</span>
-    </el-divider>
-    <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px" v-loading="keywordsLoading">
-      <div style="width: 50%; border-right: 1px solid #e5e7eb">
-        <el-tabs v-model="keyWordsTabs" class="demo-tabs">
-          <div style="margin: 8px">
-            <div style="display: flex; align-items: center">
-              <div style="min-width: 40px; margin-left: 8px; font-weight: 500; color: #616266">竞价:</div>
-              <el-select v-model="bidType" class="m-2" placeholder="Select" style="width: 450px">
-                <el-option v-for="item in bidTypeOptions" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" />
-              </el-select>
-              <el-input v-model="bidInput" :disabled="!(bidType == 'customBid')" placeholder="Please input">
-                <template #prepend>$</template>
-              </el-input>
-            </div>
-            <div style="display: flex; align-items: center">
-              <span style="margin: 0 10px 0 8px; font-weight: 500; color: #616266">匹配类型: </span>
-              <el-checkbox v-model="broadType" label="广泛" />
-              <el-checkbox v-model="phraseType" label="词组" />
-              <el-checkbox v-model="exactType" label="精确" />
-            </div>
-          </div>
-          <el-tab-pane label="建议" name="first">
-            <el-table
-              height="425"
-              style="width: 100%; padding-left: 5px"
-              :data="keyWordsTableData"
-              :header-cell-style="headerCellStyle"
-              :header-row-style="changeKeyWordsTableHeader">
-              <el-table-column prop="asin" label="关键词"> </el-table-column>
-              <el-table-column prop="matchType" label="匹配类型"> </el-table-column>
-              <el-table-column prop="adviceBid" label="建议出价" width="120"> </el-table-column>
-            </el-table>
-          </el-tab-pane>
-          <el-tab-pane label="输入" name="second">
-            <el-input v-model="keyWordsTextarea" :rows="10" type="textarea" style="padding-left: 5px" />
-            <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-              <el-button type="primary" text bg @click="addKeyWords">添加</el-button>
-            </div>
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-      <div style="width: 50%">
-        <el-card class="box-card" shadow="never" style="border: none">
-          <template #header>
-            <div class="card-header">
-              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedKeyWordsTableData.length }}</span>
-              <span style="color: #529b2e">成功: {{ successCount }}</span>
-              <span style="color: #c45656">失败: {{ failureCount }}</span>
-              <el-button class="button" type="danger" text bg @click="delAllKeyWords">全部删除</el-button>
-            </div>
-          </template>
-          <div class="card-body" body-style="padding-bottom: -20px;">
-            <el-table
-              :data="addedKeyWordsTableData"
-              style="width: 100%; height: 450px"
-              :header-row-style="changeKeyWordsTableHeader"
-              :header-cell-style="headerCellStyle">
-              <el-table-column prop="keyword" label="关键词" width="auto" />
-              <el-table-column prop="matchType" label="匹配类型" />
-              <el-table-column prop="bid" label="出价">
-                <template #default="scope">
-                  <el-input v-model="scope.row.bid" placeholder="Please input bid" />
-                </template>
-              </el-table-column>
-              <el-table-column prop="suggestBid" label="建议出价" align="center">
-                <template #default="{ row }">
-                  <div>{{ row.adviceBid ? row.adviceBid : '--' }}</div>
-                </template>
-              </el-table-column>
-              <el-table-column prop="operate" label="操作" width="60" align="right">
-                <template #default="scope">
-                  <el-button type="danger" size="small" link @click="delSingleKeyWord(scope)">删除</el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-        </el-card>
-        <div style="display: flex; justify-content: space-around; padding-top: 0px">
-          <el-button type="primary" plain @click="keyWordsSave" :disabled="!addedKeyWordsTableData.length">保存</el-button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { ElMessage } from 'element-plus'
 import { storeToRefs } from 'pinia'
@@ -255,6 +166,95 @@ function changeKeyWordsTableHeader(args) {
 }
 </script>
 
+<template>
+  <div style="width: 100%; margin-top: 20px">
+    <el-divider content-position="left">
+      <span style="font-size: 18px; font-weight: 700">关键词定向</span>
+    </el-divider>
+    <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px" v-loading="keywordsLoading">
+      <div style="width: 50%; border-right: 1px solid #e5e7eb">
+        <el-tabs v-model="keyWordsTabs" class="demo-tabs">
+          <div style="margin: 8px">
+            <div style="display: flex; align-items: center">
+              <div style="min-width: 40px; margin-left: 8px; font-weight: 500; color: #616266">竞价:</div>
+              <el-select v-model="bidType" class="m-2" placeholder="Select" style="width: 450px">
+                <el-option v-for="item in bidTypeOptions" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" />
+              </el-select>
+              <el-input v-model="bidInput" :disabled="!(bidType == 'customBid')" placeholder="Please input">
+                <template #prepend>$</template>
+              </el-input>
+            </div>
+            <div style="display: flex; align-items: center">
+              <span style="margin: 0 10px 0 8px; font-weight: 500; color: #616266">匹配类型: </span>
+              <el-checkbox v-model="broadType" label="广泛" />
+              <el-checkbox v-model="phraseType" label="词组" />
+              <el-checkbox v-model="exactType" label="精确" />
+            </div>
+          </div>
+          <el-tab-pane label="建议" name="first">
+            <el-table
+              height="425"
+              style="width: 100%; padding-left: 5px"
+              :data="keyWordsTableData"
+              :header-cell-style="headerCellStyle"
+              :header-row-style="changeKeyWordsTableHeader">
+              <el-table-column prop="asin" label="关键词"> </el-table-column>
+              <el-table-column prop="matchType" label="匹配类型"> </el-table-column>
+              <el-table-column prop="adviceBid" label="建议出价" width="120"> </el-table-column>
+            </el-table>
+          </el-tab-pane>
+          <el-tab-pane label="输入" name="second">
+            <el-input v-model="keyWordsTextarea" :rows="10" type="textarea" style="padding-left: 5px" />
+            <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+              <el-button type="primary" text bg @click="addKeyWords">添加</el-button>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+      <div style="width: 50%">
+        <el-card class="box-card" shadow="never" style="border: none">
+          <template #header>
+            <div class="card-header">
+              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedKeyWordsTableData.length }}</span>
+              <span style="color: #529b2e">成功: {{ successCount }}</span>
+              <span style="color: #c45656">失败: {{ failureCount }}</span>
+              <el-button class="button" type="danger" text bg @click="delAllKeyWords">全部删除</el-button>
+            </div>
+          </template>
+          <div class="card-body" body-style="padding-bottom: -20px;">
+            <el-table
+              :data="addedKeyWordsTableData"
+              style="width: 100%; height: 450px"
+              :header-row-style="changeKeyWordsTableHeader"
+              :header-cell-style="headerCellStyle">
+              <el-table-column prop="keyword" label="关键词" width="auto" />
+              <el-table-column prop="matchType" label="匹配类型" />
+              <el-table-column prop="bid" label="出价">
+                <template #default="scope">
+                  <el-input v-model="scope.row.bid" placeholder="Please input bid" />
+                </template>
+              </el-table-column>
+              <el-table-column prop="suggestBid" label="建议出价" align="center">
+                <template #default="{ row }">
+                  <div>{{ row.adviceBid ? row.adviceBid : '--' }}</div>
+                </template>
+              </el-table-column>
+              <el-table-column prop="operate" label="操作" width="60" align="right">
+                <template #default="scope">
+                  <el-button type="danger" size="small" link @click="delSingleKeyWord(scope)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-card>
+        <div style="display: flex; justify-content: space-around; padding-top: 0px">
+          <el-button type="primary" plain @click="keyWordsSave" :disabled="!addedKeyWordsTableData.length">保存</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
 <style lang="scss" scoped>
 ::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
   font-weight: 500;

+ 115 - 115
src/views/adManage/sb/campaigns/CreateCampaigns/component/NegativeGood.vue

@@ -1,118 +1,3 @@
-<template>
-  <div prop="matchType" style="width: 100%; margin-top: 20px">
-    <el-divider content-position="left">
-      <span style="font-size: 18px; font-weight: 700">否定商品</span>
-    </el-divider>
-    <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px" v-loading="negativeGoodsLoading">
-      <div style="width: 50%; border-right: 1px solid #e5e7ec">
-        <el-tabs v-model="topTabs" stretch>
-          <el-tab-pane label="排除商品" name="first">
-            <el-tabs v-model="negativeTabs" class="demo-tabs">
-              <el-tab-pane label="搜索" name="first">
-                <div style="margin-bottom: 10px">
-                  <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegativeGoods" clearable />
-                </div>
-                <el-table
-                  height="495"
-                  style="width: 100%"
-                  v-loading="loading"
-                  :data="negativeTableData"
-                  :header-cell-style="headerCellStyle"
-                  :show-header="false">
-                  <el-table-column prop="asin" label="商品">
-                    <template #default="scope">
-                      <div style="display: flex; align-items: center">
-                        <div style="margin-right: 8px; line-height: normal">
-                          <el-image class="img-box" :src="scope.row.image_link" />
-                        </div>
-                        <div>
-                          <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                            <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                          </el-tooltip>
-                          <span>
-                            ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                          </span>
-                        </div>
-                      </div>
-                    </template>
-                  </el-table-column>
-                  <el-table-column prop="name" label="Name" width="120" align="right">
-                    <template #header> </template>
-                    <template #default="scope">
-                      <el-button type="primary" size="small" @click="addSingleNegativeGoods(scope)" text>添加</el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </el-tab-pane>
-              <el-tab-pane label="输入" name="second">
-                <el-input
-                  v-model="negativeGoodsTextarea"
-                  :rows="17"
-                  type="textarea"
-                  disabled="true"
-                  maxlength="11000"
-                  style="padding: 10px 10px" />
-                <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-                  <el-button style="margin-right: 10px" type="primary" text bg @click="addNegativeGoods">添加</el-button>
-                </div>
-              </el-tab-pane>
-            </el-tabs>
-          </el-tab-pane>
-          <el-tab-pane label="排除品牌" name="second">
-
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-      <div style="width: 50%">
-        <el-card class="box-card" shadow="never" style="border: none">
-          <template #header>
-            <div class="card-header">
-              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
-              <el-button class="button" type="danger" text bg @click="delAllNegativeGoods">全部删除</el-button>
-            </div>
-          </template>
-          <div class="card-body"></div>
-        </el-card>
-        <div style="padding: 0 10px 0 10px; margin-top: -30px">
-          <el-table
-            :data="addedNegetiveTableData"
-            height="473"
-            style="width: 100%"
-            :header-cell-style="headerCellStyle"
-            @selection-change="handleAddedNegGoods">
-            <el-table-column prop="asin" label="商品">
-              <template #default="scope">
-                <div style="display: flex; align-items: center">
-                  <div style="margin-right: 8px; line-height: normal">
-                    <el-image class="img-box" :src="scope.row.image_link" />
-                  </div>
-                  <div>
-                    <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                      <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                    </el-tooltip>
-                    <span
-                      >ASIN:
-                      <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                    </span>
-                  </div>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column label="操作" width="120" align="right">
-              <template #default="scope">
-                <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <div style="display: flex; justify-content: space-around; padding-top: 10px">
-          <el-button plain type="primary" @click="negativeGoodsSave" :disabled="!addedNegetiveTableData.length">保存</el-button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { Ref, inject, reactive, ref } from 'vue'
 import { useShopInfo } from '/@/stores/shopInfo'
@@ -269,6 +154,121 @@ const headerCellStyle = (args) => {
 }
 </script>
 
+<template>
+  <div prop="matchType" style="width: 100%; margin-top: 20px">
+    <el-divider content-position="left">
+      <span style="font-size: 18px; font-weight: 700">否定商品</span>
+    </el-divider>
+    <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px" v-loading="negativeGoodsLoading">
+      <div style="width: 50%; border-right: 1px solid #e5e7ec">
+        <el-tabs v-model="topTabs" stretch>
+          <el-tab-pane label="排除商品" name="first">
+            <el-tabs v-model="negativeTabs" class="demo-tabs">
+              <el-tab-pane label="搜索" name="first">
+                <div style="margin-bottom: 10px">
+                  <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegativeGoods" clearable />
+                </div>
+                <el-table
+                  height="495"
+                  style="width: 100%"
+                  v-loading="loading"
+                  :data="negativeTableData"
+                  :header-cell-style="headerCellStyle"
+                  :show-header="false">
+                  <el-table-column prop="asin" label="商品">
+                    <template #default="scope">
+                      <div style="display: flex; align-items: center">
+                        <div style="margin-right: 8px; line-height: normal">
+                          <el-image class="img-box" :src="scope.row.image_link" />
+                        </div>
+                        <div>
+                          <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                            <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                          </el-tooltip>
+                          <span>
+                            ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                          </span>
+                        </div>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="name" label="Name" width="120" align="right">
+                    <template #header> </template>
+                    <template #default="scope">
+                      <el-button type="primary" size="small" @click="addSingleNegativeGoods(scope)" text>添加</el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-tab-pane>
+              <el-tab-pane label="输入" name="second">
+                <el-input
+                  v-model="negativeGoodsTextarea"
+                  :rows="17"
+                  type="textarea"
+                  disabled="true"
+                  maxlength="11000"
+                  style="padding: 10px 10px" />
+                <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                  <el-button style="margin-right: 10px" type="primary" text bg @click="addNegativeGoods">添加</el-button>
+                </div>
+              </el-tab-pane>
+            </el-tabs>
+          </el-tab-pane>
+          <el-tab-pane label="排除品牌" name="second">
+
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+      <div style="width: 50%">
+        <el-card class="box-card" shadow="never" style="border: none">
+          <template #header>
+            <div class="card-header">
+              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
+              <el-button class="button" type="danger" text bg @click="delAllNegativeGoods">全部删除</el-button>
+            </div>
+          </template>
+          <div class="card-body"></div>
+        </el-card>
+        <div style="padding: 0 10px 0 10px; margin-top: -30px">
+          <el-table
+            :data="addedNegetiveTableData"
+            height="473"
+            style="width: 100%"
+            :header-cell-style="headerCellStyle"
+            @selection-change="handleAddedNegGoods">
+            <el-table-column prop="asin" label="商品">
+              <template #default="scope">
+                <div style="display: flex; align-items: center">
+                  <div style="margin-right: 8px; line-height: normal">
+                    <el-image class="img-box" :src="scope.row.image_link" />
+                  </div>
+                  <div>
+                    <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                      <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                    </el-tooltip>
+                    <span
+                      >ASIN:
+                      <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                    </span>
+                  </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="120" align="right">
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <div style="display: flex; justify-content: space-around; padding-top: 10px">
+          <el-button plain type="primary" @click="negativeGoodsSave" :disabled="!addedNegetiveTableData.length">保存</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
 <style lang="scss" scoped>
 ::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
   font-weight: 500;

+ 227 - 227
src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductOrientation.vue

@@ -1,230 +1,3 @@
-<template>
-  <div style="width: 100%; margin-top: 20px">
-    <el-divider content-position="left">
-      <span style="font-size: 18px; font-weight: 700">商品定向</span>
-    </el-divider>
-    <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px" v-loading="productOrientationLoading">
-      <div style="width: 50%; border-right: 1px solid #e5e7eb">
-        <el-tabs
-          type="border-card"
-          stretch
-          class="goods-orientation-tabs"
-          style="border: 0; border-right: 0; border-bottom-left-radius: 6px; border-top-left-radius: 5px; overflow: hidden">
-          <el-tab-pane label="品类" style="border-top-left-radius: 6px">
-            <div style="display: flex; align-items: center">
-              <span style="width: 40px">竞价:</span>
-              <el-select v-model="categoryBiddingType" @change="singleGoodsBidSelectChanged" class="m-2" placeholder="Select">
-                <el-option v-for="item in categoryBiddingTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
-              </el-select>
-              <el-input v-model="singleGoodsBidInput" :disabled="categoryBiddingType === 'defaultBid'" style="width: 200px">
-                <template #prepend>$</template>
-              </el-input>
-            </div>
-
-            <el-tabs v-model="categoryTabs" class="category-tabs">
-              <el-tab-pane label="建议" name="first">
-                <el-table :data="proposalTableData" style="width: 100%" height="422">
-                  <el-table-column prop="proposal" label="建议" width="520">
-                    <template #header> 0建议 </template>
-                  </el-table-column>
-                  <el-table-column prop="address" label="Address">
-                    <template #header>
-                      <el-button type="primary" size="normal" link @click="handleGoodsAdd">全部添加</el-button>
-                    </template>
-                    <template #default="scope">
-                      <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </el-tab-pane>
-              <el-tab-pane label="搜索" name="second">
-                <el-input placeholder="请输入关键词过滤" />
-                <el-scrollbar height="390px">
-                  <el-tree :data="searchClassifyTableData" :props="defaultProps">
-                    <template #default="{ node, data }">
-                      <span class="custom-tree-node">
-                        <span style="width: 75%">{{ node.label }}</span>
-                        <span style="color: rgb(50, 108, 216)" v-if="data.ta == true">
-                          <a @click="refine(data)"> 细化 </a>
-                          <a style="margin-left: 8px" @click="orientate(node, data)"> 定向 </a>
-                        </span>
-                      </span>
-                    </template>
-                  </el-tree>
-                </el-scrollbar>
-                <el-dialog v-model="visible" :title="`细化分类: ${dialogTitle}`" @close="dialogClose" destroy-on-close>
-                  <div style="display: flex; justify-content: space-between">
-                    <span>根据特定品牌、价格范围、星级和Prime配送资格,细化分类</span>
-                    <span>
-                      <el-checkbox v-model="dialogForm.isCount" label="显示商品数量" @change="isCountChanged" />
-                    </span>
-                  </div>
-                  <el-form :model="dialogForm" :rules="dialogRules" ref="dialogFormRef" style="margin-top: 20px">
-                    <el-form-item style="padding-left: 140px">
-                      <span style="margin-right: 10px; color: #616266; font-weight: 500">品牌</span>
-                      <el-select
-                        v-model="dialogForm.dialogselectValue"
-                        @change="dialogSelectChange"
-                        multiple
-                        placeholder="请选择"
-                        :loading="dialogSelectLoading">
-                        <el-option v-for="item in dialogForm.dialogOptions" :key="item.value" :label="item.label" :value="item.value" />
-                      </el-select>
-                    </el-form-item>
-                    <el-form-item prop="prices" style="padding-left: 112px; margin-top: 10px">
-                      <span style="margin-right: 10px; color: #616266; font-weight: 500">价格范围</span>
-                      <el-input-number v-model="dialogForm.prices.lowest" :min="1" :controls="false" placeholder="无最低商品价格" />
-                      --
-                      <el-input-number v-model="dialogForm.prices.highest" :min="1" :controls="false" placeholder="无最高商品价格" />
-                    </el-form-item>
-                    <el-form-item prop="starRating" style="padding-left: 85px; margin-top: 10px">
-                      <span style="margin-right: 15px; color: #616266; font-weight: 500">查看星级评定</span>
-                      <el-slider v-model="dialogForm.starRating" range show-stops :max="5" :marks="marks" style="width: 70%" />
-                    </el-form-item>
-                    <el-form-item prop="delivery" style="padding-left: 140px; margin-top: 30px">
-                      <span style="margin-right: 10px; color: #616266; font-weight: 500">配送</span>
-                      <el-radio-group v-model="dialogForm.delivery">
-                        <el-radio label="all" style="font-weight: 400">所有</el-radio>
-                        <el-radio label="eligible" style="font-weight: 400">具备Prime资格</el-radio>
-                        <el-radio label="diseligible" style="font-weight: 400">不具备Prime资格</el-radio>
-                      </el-radio-group>
-                    </el-form-item>
-                  </el-form>
-                  <template #footer>
-                    <div style="display: flex; justify-content: space-between">
-                      <span v-loading="countLoadig">定位到的商品数量:
-                        <span v-if="dialogForm.isCount == true">{{ commodityCount[0]?.min }} - {{ commodityCount[0]?.max }}</span>
-                      </span>
-                      <span class="dialog-footer">
-                        <el-button @click="visible = false">取消</el-button>
-                        <el-button type="primary" @click="dialogFormSubmit">确定</el-button>
-                      </span>
-                    </div>
-                  </template>
-                </el-dialog>
-              </el-tab-pane>
-            </el-tabs>
-          </el-tab-pane>
-          <el-tab-pane label="单个商品">
-            <div style="display: flex; align-items: center">
-              <span style="width: 40px">竞价:</span>
-              <el-select class="m-2" v-model="singleGoodsBidSelect" @change="singleGoodsBidSelectChanged">
-                <el-option v-for="item in singleGoodsBidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
-              </el-select>
-              <el-input v-model="singleGoodsBidInput" :disabled="singleGoodsBidSelect == 'defaultBid'" style="width: 200px">
-                <template #prepend>$</template>
-              </el-input>
-              <!-- <div style="margin-left: 20px">
-                <span style="margin-right: 10px">类型:</span>
-                <el-checkbox v-model="expand" label="扩展" />
-                <el-checkbox v-model="accurate" label="精准" />
-              </div> -->
-            </div>
-            <el-tabs v-model="singleGoodsTabs" class="category-tabs">
-              <el-tab-pane label="建议" name="first">
-                <el-table :data="proposalTableData" style="width: 100%" height="342">
-                  <el-table-column prop="proposal" label="商品" width="520" />
-                  <el-table-column prop="address" label="类型" />
-                  <el-table-column prop="operational" label="操作" />
-                </el-table>
-              </el-tab-pane>
-              <el-tab-pane label="搜索" name="second">
-                <el-input v-model="singleGoodsSearchInp" @change="singleGoodsSearchChaneged" placeholder="按ASIN搜索"></el-input>
-                <el-table :data="searchTableData" style="width: 100%" height="309">
-                  <el-table-column prop="asin" label="商品" width="520">
-                    <template #default="{ row }">
-                      <div style="display: flex; align-items: center">
-                        <img :src="row.image_link" style="width: 40px; height: 40px; margin-right: 10px" />
-                        <span>{{ row.title }}</span>
-                      </div>
-                    </template>
-                  </el-table-column>
-                  <el-table-column prop="productTypes" label="类型">
-                    <template #default="scope">
-                      <div v-if="expand">扩展</div>
-                      <div v-if="accurate">精准</div>
-                    </template>
-                  </el-table-column>
-                  <el-table-column prop="operational" label="操作">
-                    <template #default="scope">
-                      <el-button class="button" text @click="addSingleSearch(scope)">添加</el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </el-tab-pane>
-              <!-- TODO: 商品定向TextArea -->
-              <el-tab-pane label="输入" name="third">待完成</el-tab-pane>
-            </el-tabs>
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-      <div style="width: 50%">
-        <el-card class="box-card" shadow="never" style="border: none">
-          <template #header>
-            <div class="card-header">
-              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ productOrientationTableData.length }}</span>
-              <el-button class="button" type="danger" text bg @click="delAllCna">全部删除</el-button>
-            </div>
-          </template>
-          <div class="card-body">
-            <el-table
-              height="460"
-              :data="productOrientationTableData"
-              style="width: 100%"
-              :header-row-style="changeKeyWordsTableHeader"
-              :header-cell-style="headerCellStyle">
-              <el-table-column prop="cna" label="分类 & 商品" width="300">
-                <template #default="scope">
-                  <div v-if="scope.row.cna || scope.row.classification">
-                    分类: <span style="color: #000000">{{ scope.row.cna ? scope.row.cna : scope.row.classification }}</span>
-                  </div>
-                  <div v-if="scope.row.asin">
-                    {{ scope.row.asin ? scope.row.asin : '--' }}
-                  </div>
-                  <div v-if="scope.row.brand">
-                    品牌: <span style="color: #000000">{{ scope.row.brand }}</span>
-                  </div>
-                  <div v-if="scope.row.low_price || scope.row.high_price">
-                    品牌价格:
-                    <span style="color: #000000">
-                      {{ scope.row.low_price ? '$' + scope.row.low_price : '--' }} -
-                      {{ scope.row.high_price ? '$' + scope.row.high_price : '--' }}
-                    </span>
-                  </div>
-                  <div v-if="scope.row.low_rating || scope.row.high_rating">
-                    评分: <span style="color: #000000">{{ scope.row.low_rating }} - {{ scope.row.high_rating }}</span>
-                  </div>
-                  <div v-if="scope.row.deliveryText">
-                    配送: <span style="color: #000000">{{ scope.row.deliveryText }}</span>
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column prop="type" label="类型">
-                <template #default="scope">
-                  {{ scope.row.productTypeText ? scope.row.productTypeText : '--' }}
-                </template>
-              </el-table-column>
-              <el-table-column prop="bid" label="竞价">
-                <template #default="scope">
-                  <el-input-number v-model="scope.row.bid" :min="0.02" :max="1000000" :controls="false" size="small" />
-                </template>
-              </el-table-column>
-              <el-table-column prop="operate" label="操作" width="60" align="right">
-                <template #default="scope">
-                  <el-button text size="small" @click="delCna(scope.$index)">删除</el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-        </el-card>
-        <div style="display: flex; justify-content: space-around; margin-top: -8px">
-          <el-button type="primary" plain @click="productTagetSave">保存</el-button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { CSSProperties, Ref, inject, onMounted, reactive, ref } from 'vue'
 import { useShopInfo } from '/@/stores/shopInfo'
@@ -669,6 +442,233 @@ onMounted(() => {
 
 </script>
 
+<template>
+  <div style="width: 100%; margin-top: 20px">
+    <el-divider content-position="left">
+      <span style="font-size: 18px; font-weight: 700">商品定向</span>
+    </el-divider>
+    <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px" v-loading="productOrientationLoading">
+      <div style="width: 50%; border-right: 1px solid #e5e7eb">
+        <el-tabs
+          type="border-card"
+          stretch
+          class="goods-orientation-tabs"
+          style="border: 0; border-right: 0; border-bottom-left-radius: 6px; border-top-left-radius: 5px; overflow: hidden">
+          <el-tab-pane label="品类" style="border-top-left-radius: 6px">
+            <div style="display: flex; align-items: center">
+              <span style="width: 40px">竞价:</span>
+              <el-select v-model="categoryBiddingType" @change="singleGoodsBidSelectChanged" class="m-2" placeholder="Select">
+                <el-option v-for="item in categoryBiddingTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+              <el-input v-model="singleGoodsBidInput" :disabled="categoryBiddingType === 'defaultBid'" style="width: 200px">
+                <template #prepend>$</template>
+              </el-input>
+            </div>
+
+            <el-tabs v-model="categoryTabs" class="category-tabs">
+              <el-tab-pane label="建议" name="first">
+                <el-table :data="proposalTableData" style="width: 100%" height="422">
+                  <el-table-column prop="proposal" label="建议" width="520">
+                    <template #header> 0建议 </template>
+                  </el-table-column>
+                  <el-table-column prop="address" label="Address">
+                    <template #header>
+                      <el-button type="primary" size="normal" link @click="handleGoodsAdd">全部添加</el-button>
+                    </template>
+                    <template #default="scope">
+                      <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-tab-pane>
+              <el-tab-pane label="搜索" name="second">
+                <el-input placeholder="请输入关键词过滤" />
+                <el-scrollbar height="390px">
+                  <el-tree :data="searchClassifyTableData" :props="defaultProps">
+                    <template #default="{ node, data }">
+                      <span class="custom-tree-node">
+                        <span style="width: 75%">{{ node.label }}</span>
+                        <span style="color: rgb(50, 108, 216)" v-if="data.ta == true">
+                          <a @click="refine(data)"> 细化 </a>
+                          <a style="margin-left: 8px" @click="orientate(node, data)"> 定向 </a>
+                        </span>
+                      </span>
+                    </template>
+                  </el-tree>
+                </el-scrollbar>
+                <el-dialog v-model="visible" :title="`细化分类: ${dialogTitle}`" @close="dialogClose" destroy-on-close>
+                  <div style="display: flex; justify-content: space-between">
+                    <span>根据特定品牌、价格范围、星级和Prime配送资格,细化分类</span>
+                    <span>
+                      <el-checkbox v-model="dialogForm.isCount" label="显示商品数量" @change="isCountChanged" />
+                    </span>
+                  </div>
+                  <el-form :model="dialogForm" :rules="dialogRules" ref="dialogFormRef" style="margin-top: 20px">
+                    <el-form-item style="padding-left: 140px">
+                      <span style="margin-right: 10px; color: #616266; font-weight: 500">品牌</span>
+                      <el-select
+                        v-model="dialogForm.dialogselectValue"
+                        @change="dialogSelectChange"
+                        multiple
+                        placeholder="请选择"
+                        :loading="dialogSelectLoading">
+                        <el-option v-for="item in dialogForm.dialogOptions" :key="item.value" :label="item.label" :value="item.value" />
+                      </el-select>
+                    </el-form-item>
+                    <el-form-item prop="prices" style="padding-left: 112px; margin-top: 10px">
+                      <span style="margin-right: 10px; color: #616266; font-weight: 500">价格范围</span>
+                      <el-input-number v-model="dialogForm.prices.lowest" :min="1" :controls="false" placeholder="无最低商品价格" />
+                      --
+                      <el-input-number v-model="dialogForm.prices.highest" :min="1" :controls="false" placeholder="无最高商品价格" />
+                    </el-form-item>
+                    <el-form-item prop="starRating" style="padding-left: 85px; margin-top: 10px">
+                      <span style="margin-right: 15px; color: #616266; font-weight: 500">查看星级评定</span>
+                      <el-slider v-model="dialogForm.starRating" range show-stops :max="5" :marks="marks" style="width: 70%" />
+                    </el-form-item>
+                    <el-form-item prop="delivery" style="padding-left: 140px; margin-top: 30px">
+                      <span style="margin-right: 10px; color: #616266; font-weight: 500">配送</span>
+                      <el-radio-group v-model="dialogForm.delivery">
+                        <el-radio label="all" style="font-weight: 400">所有</el-radio>
+                        <el-radio label="eligible" style="font-weight: 400">具备Prime资格</el-radio>
+                        <el-radio label="diseligible" style="font-weight: 400">不具备Prime资格</el-radio>
+                      </el-radio-group>
+                    </el-form-item>
+                  </el-form>
+                  <template #footer>
+                    <div style="display: flex; justify-content: space-between">
+                      <span v-loading="countLoadig">定位到的商品数量:
+                        <span v-if="dialogForm.isCount == true">{{ commodityCount[0]?.min }} - {{ commodityCount[0]?.max }}</span>
+                      </span>
+                      <span class="dialog-footer">
+                        <el-button @click="visible = false">取消</el-button>
+                        <el-button type="primary" @click="dialogFormSubmit">确定</el-button>
+                      </span>
+                    </div>
+                  </template>
+                </el-dialog>
+              </el-tab-pane>
+            </el-tabs>
+          </el-tab-pane>
+          <el-tab-pane label="单个商品">
+            <div style="display: flex; align-items: center">
+              <span style="width: 40px">竞价:</span>
+              <el-select class="m-2" v-model="singleGoodsBidSelect" @change="singleGoodsBidSelectChanged">
+                <el-option v-for="item in singleGoodsBidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+              <el-input v-model="singleGoodsBidInput" :disabled="singleGoodsBidSelect == 'defaultBid'" style="width: 200px">
+                <template #prepend>$</template>
+              </el-input>
+              <!-- <div style="margin-left: 20px">
+                <span style="margin-right: 10px">类型:</span>
+                <el-checkbox v-model="expand" label="扩展" />
+                <el-checkbox v-model="accurate" label="精准" />
+              </div> -->
+            </div>
+            <el-tabs v-model="singleGoodsTabs" class="category-tabs">
+              <el-tab-pane label="建议" name="first">
+                <el-table :data="proposalTableData" style="width: 100%" height="342">
+                  <el-table-column prop="proposal" label="商品" width="520" />
+                  <el-table-column prop="address" label="类型" />
+                  <el-table-column prop="operational" label="操作" />
+                </el-table>
+              </el-tab-pane>
+              <el-tab-pane label="搜索" name="second">
+                <el-input v-model="singleGoodsSearchInp" @change="singleGoodsSearchChaneged" placeholder="按ASIN搜索"></el-input>
+                <el-table :data="searchTableData" style="width: 100%" height="309">
+                  <el-table-column prop="asin" label="商品" width="520">
+                    <template #default="{ row }">
+                      <div style="display: flex; align-items: center">
+                        <img :src="row.image_link" style="width: 40px; height: 40px; margin-right: 10px" />
+                        <span>{{ row.title }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="productTypes" label="类型">
+                    <template #default="scope">
+                      <div v-if="expand">扩展</div>
+                      <div v-if="accurate">精准</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="operational" label="操作">
+                    <template #default="scope">
+                      <el-button class="button" text @click="addSingleSearch(scope)">添加</el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-tab-pane>
+              <!-- TODO: 商品定向TextArea -->
+              <el-tab-pane label="输入" name="third">待完成</el-tab-pane>
+            </el-tabs>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+      <div style="width: 50%">
+        <el-card class="box-card" shadow="never" style="border: none">
+          <template #header>
+            <div class="card-header">
+              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ productOrientationTableData.length }}</span>
+              <el-button class="button" type="danger" text bg @click="delAllCna">全部删除</el-button>
+            </div>
+          </template>
+          <div class="card-body">
+            <el-table
+              height="460"
+              :data="productOrientationTableData"
+              style="width: 100%"
+              :header-row-style="changeKeyWordsTableHeader"
+              :header-cell-style="headerCellStyle">
+              <el-table-column prop="cna" label="分类 & 商品" width="300">
+                <template #default="scope">
+                  <div v-if="scope.row.cna || scope.row.classification">
+                    分类: <span style="color: #000000">{{ scope.row.cna ? scope.row.cna : scope.row.classification }}</span>
+                  </div>
+                  <div v-if="scope.row.asin">
+                    {{ scope.row.asin ? scope.row.asin : '--' }}
+                  </div>
+                  <div v-if="scope.row.brand">
+                    品牌: <span style="color: #000000">{{ scope.row.brand }}</span>
+                  </div>
+                  <div v-if="scope.row.low_price || scope.row.high_price">
+                    品牌价格:
+                    <span style="color: #000000">
+                      {{ scope.row.low_price ? '$' + scope.row.low_price : '--' }} -
+                      {{ scope.row.high_price ? '$' + scope.row.high_price : '--' }}
+                    </span>
+                  </div>
+                  <div v-if="scope.row.low_rating || scope.row.high_rating">
+                    评分: <span style="color: #000000">{{ scope.row.low_rating }} - {{ scope.row.high_rating }}</span>
+                  </div>
+                  <div v-if="scope.row.deliveryText">
+                    配送: <span style="color: #000000">{{ scope.row.deliveryText }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column prop="type" label="类型">
+                <template #default="scope">
+                  {{ scope.row.productTypeText ? scope.row.productTypeText : '--' }}
+                </template>
+              </el-table-column>
+              <el-table-column prop="bid" label="竞价">
+                <template #default="scope">
+                  <el-input-number v-model="scope.row.bid" :min="0.02" :max="1000000" :controls="false" size="small" />
+                </template>
+              </el-table-column>
+              <el-table-column prop="operate" label="操作" width="60" align="right">
+                <template #default="scope">
+                  <el-button text size="small" @click="delCna(scope.$index)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-card>
+        <div style="display: flex; justify-content: space-around; margin-top: -8px">
+          <el-button type="primary" plain @click="productTagetSave">保存</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
 <style lang="scss" scoped>
 ::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
   font-weight: 500;

+ 154 - 154
src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductSetCommodity.vue

@@ -1,157 +1,3 @@
-<template>
-  <div prop="commodity" style="width: 100%" v-loading="productLoading">
-    <div style="width: 100%; height: 620px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px">
-      <div style="width: 50%; border-right: 1px solid #e5e7ec">
-        <el-tabs v-model="productTabs" class="demo-tabs">
-          <el-tab-pane label="搜索" name="first">
-            <div style="margin-bottom: 10px">
-              <el-input v-model="searchInp" placeholder="Please input" class="input-with-select" @change="inpChange" clearable>
-                <template #prepend>
-                  <el-select v-model="leftSelect" style="width: 100px" @change="selChange">
-                    <el-option label="名称" value="name" />
-                    <el-option label="ASIN" value="asin" />
-                    <el-option label="SKU" value="sku" />
-                  </el-select>
-                </template>
-                <template #append>
-                  <el-select v-model="rightSelect" style="width: 100px">
-                    <el-option label="最新优先" value="latest" />
-                    <el-option label="最早优先" value="earliest" />
-                    <el-option label="优选广告" value="optimal" />
-                  </el-select>
-                </template>
-              </el-input>
-            </div>
-            <el-table
-              height="490"
-              style="width: 100%"
-              v-loading="loading"
-              :data="productTableData"
-              :header-cell-style="headerCellStyle"
-              @selection-change="handleSelectionChange">
-              <el-table-column type="selection" width="50" />
-              <el-table-column prop="asin" label="商品">
-                <template #default="scope">
-                  <div style="display: flex; align-items: center">
-                    <div style="margin-right: 8px; line-height: normal">
-                      <el-image class="img-box" :src="scope.row.image_link" />
-                    </div>
-                    <div>
-                      <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                        <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                      </el-tooltip>
-                      <div class="data-color">
-                        <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
-                        <span style="margin: 0 5px; color: #cacdd4">|</span>
-                        <span style="color: #6d7784">{{ scope.row.quantity }}</span>
-                      </div>
-                      <span>
-                        ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                      </span>
-                      <span>
-                        SKU: <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
-                      </span>
-                    </div>
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column prop="name" label="Name" width="120" align="right">
-                <template #header>
-                  <el-button type="primary" size="normal" link @click="handleGoodsAdd">添加已选中</el-button>
-                </template>
-                <template #default="scope">
-                  <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-            <el-pagination
-              @current-change="handleCurrentChange"
-              @size-change="handleSizeChange"
-              :current-page="currentPage"
-              :page-size="pageSize"
-              :total="totalItems"
-              layout="prev, pager, next" />
-          </el-tab-pane>
-          <el-tab-pane label="输入" name="second">
-            <el-input
-              style="padding: 10px"
-              v-model="productTextarea"
-              :rows="20"
-              type="textarea"
-              placeholder="请输入ASIN,多个ASIN使用逗号、空格或换行符分隔。(未完成)"
-              maxlength="11000" />
-            <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-              <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="addGods">{{ button.text }}</el-button>
-            </div>
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-      <div style="width: 50%">
-        <el-card class="box-card" shadow="never" style="border: 0">
-          <template #header>
-            <div class="card-header">
-              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedTableData.length }}</span>
-              <el-tooltip content="添加最少3件商品。我们建议添加至少5件商品,以降低在商品缺货时出现广告活动暂停的可能性。" placement="top">
-                <el-text type="warning" truncated style="width: 350px;">添加最少3件商品。我们建议添加至少5件商品,以降低在商品缺货时出现广告活动暂停的可能性</el-text>
-              </el-tooltip>
-              <el-button class="button" type="danger" text bg @click="delAllGoods">全部删除</el-button>
-            </div>
-          </template>
-          <div class="card-body"></div>
-        </el-card>
-        <div style="padding: 0 10px 0 10px; margin-top: -12px">
-          <el-table
-            :data="addedTableData"
-            height="510"
-            style="width: 100%"
-            :header-cell-style="headerCellStyle"
-            @selection-change="handleAddedGoodsChange">
-            <el-table-column type="selection" width="50" />
-            <el-table-column prop="asin" label="ASIN">
-              <template #default="scope">
-                <div style="display: flex; align-items: center">
-                  <div style="margin-right: 8px; line-height: normal">
-                    <el-image class="img-box" :src="scope.row.image_link" />
-                  </div>
-                  <div>
-                    <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                      <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                    </el-tooltip>
-                    <div class="data-color">
-                      <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
-                      <span style="margin: 0 5px; color: #cacdd4">|</span>
-                      <span style="color: #6d7784">{{ scope.row.quantity }}</span>
-                    </div>
-                    <span
-                      >ASIN:
-                      <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                    </span>
-                    <span
-                      >SKU:
-                      <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
-                    </span>
-                  </div>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column prop="name" label="Name" width="120" align="right">
-              <template #header>
-                <el-button type="danger" size="normal" link @click="delSelectedGoods">删除已选中</el-button>
-              </template>
-              <template #default="scope">
-                <el-button type="primary" size="small" @click="delSingleGoods(scope)" text>删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <!-- <div style="display: flex; justify-content: space-around; padding-top: 5px">
-          <el-button type="primary" plain :disabled="addedTableData.length < 3"  @click="submitProductForm">保存</el-button>
-        </div> -->
-      </div>
-    </div>
-  </div>
-</template>
-
 <script setup lang="ts">
 import type { TabsPaneContext } from 'element-plus'
 import { ElMessage } from 'element-plus'
@@ -384,6 +230,160 @@ onMounted(() => {
 })
 </script>
 
+<template>
+  <div prop="commodity" style="width: 100%" v-loading="productLoading">
+    <div style="width: 100%; height: 620px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px">
+      <div style="width: 50%; border-right: 1px solid #e5e7ec">
+        <el-tabs v-model="productTabs" class="demo-tabs">
+          <el-tab-pane label="搜索" name="first">
+            <div style="margin-bottom: 10px">
+              <el-input v-model="searchInp" placeholder="Please input" class="input-with-select" @change="inpChange" clearable>
+                <template #prepend>
+                  <el-select v-model="leftSelect" style="width: 100px" @change="selChange">
+                    <el-option label="名称" value="name" />
+                    <el-option label="ASIN" value="asin" />
+                    <el-option label="SKU" value="sku" />
+                  </el-select>
+                </template>
+                <template #append>
+                  <el-select v-model="rightSelect" style="width: 100px">
+                    <el-option label="最新优先" value="latest" />
+                    <el-option label="最早优先" value="earliest" />
+                    <el-option label="优选广告" value="optimal" />
+                  </el-select>
+                </template>
+              </el-input>
+            </div>
+            <el-table
+              height="490"
+              style="width: 100%"
+              v-loading="loading"
+              :data="productTableData"
+              :header-cell-style="headerCellStyle"
+              @selection-change="handleSelectionChange">
+              <el-table-column type="selection" width="50" />
+              <el-table-column prop="asin" label="商品">
+                <template #default="scope">
+                  <div style="display: flex; align-items: center">
+                    <div style="margin-right: 8px; line-height: normal">
+                      <el-image class="img-box" :src="scope.row.image_link" />
+                    </div>
+                    <div>
+                      <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                        <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                      </el-tooltip>
+                      <div class="data-color">
+                        <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
+                        <span style="margin: 0 5px; color: #cacdd4">|</span>
+                        <span style="color: #6d7784">{{ scope.row.quantity }}</span>
+                      </div>
+                      <span>
+                        ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                      </span>
+                      <span>
+                        SKU: <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
+                      </span>
+                    </div>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column prop="name" label="Name" width="120" align="right">
+                <template #header>
+                  <el-button type="primary" size="normal" link @click="handleGoodsAdd">添加已选中</el-button>
+                </template>
+                <template #default="scope">
+                  <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+            <el-pagination
+              @current-change="handleCurrentChange"
+              @size-change="handleSizeChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              :total="totalItems"
+              layout="prev, pager, next" />
+          </el-tab-pane>
+          <el-tab-pane label="输入" name="second">
+            <el-input
+              style="padding: 10px"
+              v-model="productTextarea"
+              :rows="20"
+              type="textarea"
+              placeholder="请输入ASIN,多个ASIN使用逗号、空格或换行符分隔。(未完成)"
+              maxlength="11000" />
+            <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+              <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="addGods">{{ button.text }}</el-button>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+      <div style="width: 50%">
+        <el-card class="box-card" shadow="never" style="border: 0">
+          <template #header>
+            <div class="card-header">
+              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedTableData.length }}</span>
+              <el-tooltip content="添加最少3件商品。我们建议添加至少5件商品,以降低在商品缺货时出现广告活动暂停的可能性。" placement="top">
+                <el-text type="warning" truncated style="width: 350px;">添加最少3件商品。我们建议添加至少5件商品,以降低在商品缺货时出现广告活动暂停的可能性</el-text>
+              </el-tooltip>
+              <el-button class="button" type="danger" text bg @click="delAllGoods">全部删除</el-button>
+            </div>
+          </template>
+          <div class="card-body"></div>
+        </el-card>
+        <div style="padding: 0 10px 0 10px; margin-top: -12px">
+          <el-table
+            :data="addedTableData"
+            height="510"
+            style="width: 100%"
+            :header-cell-style="headerCellStyle"
+            @selection-change="handleAddedGoodsChange">
+            <el-table-column type="selection" width="50" />
+            <el-table-column prop="asin" label="ASIN">
+              <template #default="scope">
+                <div style="display: flex; align-items: center">
+                  <div style="margin-right: 8px; line-height: normal">
+                    <el-image class="img-box" :src="scope.row.image_link" />
+                  </div>
+                  <div>
+                    <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                      <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                    </el-tooltip>
+                    <div class="data-color">
+                      <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
+                      <span style="margin: 0 5px; color: #cacdd4">|</span>
+                      <span style="color: #6d7784">{{ scope.row.quantity }}</span>
+                    </div>
+                    <span
+                      >ASIN:
+                      <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                    </span>
+                    <span
+                      >SKU:
+                      <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
+                    </span>
+                  </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="name" label="Name" width="120" align="right">
+              <template #header>
+                <el-button type="danger" size="normal" link @click="delSelectedGoods">删除已选中</el-button>
+              </template>
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="delSingleGoods(scope)" text>删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <!-- <div style="display: flex; justify-content: space-around; padding-top: 5px">
+          <el-button type="primary" plain :disabled="addedTableData.length < 3"  @click="submitProductForm">保存</el-button>
+        </div> -->
+      </div>
+    </div>
+  </div>
+</template>
+
 <style lang="scss" scoped>
 ::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
   font-weight: 500;

+ 290 - 290
src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductSetCreativity1.vue

@@ -1,294 +1,16 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">创意</span>
-      </div>
-      <el-form
-        ref="ruleFormRef"
-        :model="ruleForm"
-        :rules="rules"
-        label-width="120px"
-        class="demo-ruleForm"
-        size="default"
-        label-position="top"
-        status-icon>
-        <el-form-item label="广告名称" prop="name">
-          <el-input v-model="ruleForm.name" style="width: 50%" />
-        </el-form-item>
-        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
-          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
-            <el-scrollbar height="700px">
-              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
-                <el-collapse-item name="1" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
-                  <el-form-item prop="brandName">
-                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 0 5px 0"></el-input>
-                  </el-form-item>
+<script setup lang="ts">
+import { Delete, Picture, Plus, Search, ZoomIn } from '@element-plus/icons-vue'
+import type { FormInstance, FormRules, UploadFile, UploadProps } from 'element-plus'
+import { ElMessage } from 'element-plus'
+import { storeToRefs } from 'pinia'
+import { Ref, computed, inject, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
+import { checkAsset, getAssets, getCommodityCard, getLifeStyleAssets, getPageAsins, postProductset, uploadFile } from '../api/index'
+import { useShopInfo } from '/@/stores/shopInfo'
+import emitter from '/@/utils/emitter'
 
-                  <el-upload
-                    v-model:file-list="fileList"
-                    :on-change="changeFile"
-                    v-loading="upLoading"
-                    :on-remove="handleRemove"
-                    action="#"
-                    accept=".png, .jpg"
-                    :limit="1"
-                    list-type="picture-card"
-                    :auto-upload="false">
-                    <el-icon><Plus /></el-icon>
-                    <template #file="{ file }">
-                      <div>
-                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
-                        <span class="el-upload-list__item-actions">
-                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
-                            <el-icon><zoom-in /></el-icon>
-                          </span>
-                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
-                            <el-icon><Delete /></el-icon>
-                          </span>
-                        </span>
-                      </div>
-                    </template>
-                    <template #tip>
-                      <div style="margin-top: 10px">
-                        <div style="display: flex; align-items: center; justify-content: space-between">
-                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
-                          <el-button type="primary" :icon="Picture" @click="openDialog">从素材库中选择</el-button>
-                        </div>
-                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
-                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
-                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
-                        <div class="introduce-item">
-                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
-                          <span style="margin-left: 25px; position: relative">
-                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
-                            <el-link
-                              type="primary"
-                              :underline="false"
-                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
-                              target="_blank"
-                              >查看要求</el-link
-                            >
-                          </span>
-                        </div>
-                      </div>
-                    </template>
-                  </el-upload>
-                  <!-- 预览弹窗 -->
-                  <el-dialog v-model="dialogVisible">
-                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
-                  </el-dialog>
-                </el-collapse-item>
-                <el-collapse-item name="2" style="padding-right: 10px">
-                  <template #title>自定义图片(可选)</template>
-                  <el-upload
-                    v-model:file-list="customFileList"
-                    :on-change="changeCustomFile"
-                    :on-remove="handleCustomRemove"
-                    v-loading="customUpLoading"
-                    action="#"
-                    accept=".png, .jpg"
-                    :limit="1"
-                    list-type="picture-card"
-                    :auto-upload="false">
-                    <el-icon><Plus /></el-icon>
-                    <template #file="{ file }">
-                      <div>
-                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
-                        <span class="el-upload-list__item-actions">
-                          <span class="el-upload-list__item-preview" @click="customPictureCardPreview(file)">
-                            <el-icon><zoom-in /></el-icon>
-                          </span>
-                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
-                            <el-icon><Delete /></el-icon>
-                          </span>
-                        </span>
-                      </div>
-                    </template>
-                    <template #tip>
-                      <div style="margin-top: 10px">
-                        <div style="display: flex; align-items: center; justify-content: space-between">
-                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">图片规格</span>
-                          <el-button type="primary" :icon="Picture" @click="openLifeStyleDialog">从素材库中选择</el-button>
-                        </div>
-                        <div class="introduce-item">1、图片大小: 1200 x 628 像素或更大</div>
-                        <div class="introduce-item">2、文件大小: 5MB 或更小</div>
-                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
-                        <div class="introduce-item">4、内容: 图片中未添加文本、图形或徽标</div>
-                      </div>
-                    </template>
-                  </el-upload>
-                  <!-- 预览弹窗 -->
-                  <el-dialog v-model="customDialogVisible">
-                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
-                  </el-dialog>
-                </el-collapse-item>
-
-                <el-collapse-item name="commodity" v-loading="commodityLoading" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品</template>
-                  <div v-for="(item, index) in flattenedCommodityCard" :key="index" style="margin: 0 0 5px 0">
-                    <el-card shadow="hover" body-style="padding: 10px; display: flex;">
-                      <div style="margin-right: 8px; line-height: normal">
-                        <el-image class="img-box" :src="item.image_link" />
-                      </div>
-                      <div style="position: relative">
-                        <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                          <div class="double-line">{{ item.title }}</div>
-                        </el-tooltip>
-                        <span>
-                          <span style="color: #6d7784">ASIN: </span>
-                          <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                        </span>
-                        <el-button
-                          type="primary"
-                          size="small"
-                          link
-                          @click="() => openCommodityDialog(index)"
-                          style="position: absolute; bottom: 2px; right: 0">
-                          更换商品
-                        </el-button>
-                      </div>
-                    </el-card>
-                  </div>
-                </el-collapse-item>
-                <el-collapse-item name="4" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
-                  <el-form-item prop="title">
-                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
-                  </el-form-item>
-                </el-collapse-item>
-              </el-collapse>
-            </el-scrollbar>
-          </div>
-          <div style="width: 50%; padding: 0 10px; position: relative">
-            <el-button
-              type="primary"
-              plain
-              @click="submitForm(ruleFormRef)"
-              :disabled="!fileList.length"
-              style="position: absolute; top: 92%; left: 46%">
-              保存</el-button
-            >
-          </div>
-        </div>
-      </el-form>
-    </el-card>
-    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in cards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <el-image class="image" :src="item.imageUrl" fit="cover" />
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">徽标</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-    <el-dialog v-model="lifeStyleDialog" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in lifeStyleCards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <el-image class="image" :src="item.imageUrl" fit="cover" />
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">徽标</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="centerDialogVisible = false">确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-    <el-dialog v-model="commodityDialog" title="更换商品" width="50%">
-      <el-radio-group
-        v-loading="dialogLoading3"
-        v-model="selectedCommodity"
-        style="display: flex; flex-direction: column; align-content: flex-start; align-items: flex-start">
-        <div v-for="(item, index) in flattenedReplaceableCommodity" :key="index">
-          <el-radio :label="item.asin" style="height: 80px; border-bottom: 1px solid #ccc">
-            <div style="padding: 10px; display: flex; align-items: center">
-              <div style="margin-right: 8px; line-height: normal">
-                <el-image class="img-box" :src="item.image_link" />
-              </div>
-              <div style="position: relative">
-                <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                  <div class="double-line">{{ item.title }}</div>
-                </el-tooltip>
-                <span>
-                  <span style="color: #6d7784">ASIN: </span>
-                  <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                </span>
-              </div>
-            </div>
-          </el-radio>
-        </div>
-      </el-radio-group>
-      <div style="margin-top: 20px; display: flex; justify-content: center">
-        <el-button type="primary" :disabled="!selectedCommodity" @click="handleSelectedCommodity">确定</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { Delete, Picture, Plus, Search, ZoomIn } from '@element-plus/icons-vue'
-import type { FormInstance, FormRules, UploadFile, UploadProps } from 'element-plus'
-import { ElMessage } from 'element-plus'
-import { storeToRefs } from 'pinia'
-import { Ref, computed, inject, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
-import { checkAsset, getAssets, getCommodityCard, getLifeStyleAssets, getPageAsins, postProductset, uploadFile } from '../api/index'
-import { useShopInfo } from '/@/stores/shopInfo'
-import emitter from '/@/utils/emitter'
-
-const respAdGroupId = inject<Ref>('respAdGroupId')
-const shopInfo = useShopInfo()
-const { profile } = storeToRefs(shopInfo)
+const respAdGroupId = inject<Ref>('respAdGroupId')
+const shopInfo = useShopInfo()
+const { profile } = storeToRefs(shopInfo)
 
 const ruleFormRef = ref<FormInstance>()
 
@@ -767,6 +489,284 @@ onUnmounted(() => {
 })
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">创意</span>
+      </div>
+      <el-form
+        ref="ruleFormRef"
+        :model="ruleForm"
+        :rules="rules"
+        label-width="120px"
+        class="demo-ruleForm"
+        size="default"
+        label-position="top"
+        status-icon>
+        <el-form-item label="广告名称" prop="name">
+          <el-input v-model="ruleForm.name" style="width: 50%" />
+        </el-form-item>
+        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
+          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
+            <el-scrollbar height="700px">
+              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
+                <el-collapse-item name="1" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
+                  <el-form-item prop="brandName">
+                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 0 5px 0"></el-input>
+                  </el-form-item>
+
+                  <el-upload
+                    v-model:file-list="fileList"
+                    :on-change="changeFile"
+                    v-loading="upLoading"
+                    :on-remove="handleRemove"
+                    action="#"
+                    accept=".png, .jpg"
+                    :limit="1"
+                    list-type="picture-card"
+                    :auto-upload="false">
+                    <el-icon><Plus /></el-icon>
+                    <template #file="{ file }">
+                      <div>
+                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
+                        <span class="el-upload-list__item-actions">
+                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
+                            <el-icon><zoom-in /></el-icon>
+                          </span>
+                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
+                            <el-icon><Delete /></el-icon>
+                          </span>
+                        </span>
+                      </div>
+                    </template>
+                    <template #tip>
+                      <div style="margin-top: 10px">
+                        <div style="display: flex; align-items: center; justify-content: space-between">
+                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
+                          <el-button type="primary" :icon="Picture" @click="openDialog">从素材库中选择</el-button>
+                        </div>
+                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
+                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
+                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
+                        <div class="introduce-item">
+                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
+                          <span style="margin-left: 25px; position: relative">
+                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
+                            <el-link
+                              type="primary"
+                              :underline="false"
+                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
+                              target="_blank"
+                              >查看要求</el-link
+                            >
+                          </span>
+                        </div>
+                      </div>
+                    </template>
+                  </el-upload>
+                  <!-- 预览弹窗 -->
+                  <el-dialog v-model="dialogVisible">
+                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
+                  </el-dialog>
+                </el-collapse-item>
+                <el-collapse-item name="2" style="padding-right: 10px">
+                  <template #title>自定义图片(可选)</template>
+                  <el-upload
+                    v-model:file-list="customFileList"
+                    :on-change="changeCustomFile"
+                    :on-remove="handleCustomRemove"
+                    v-loading="customUpLoading"
+                    action="#"
+                    accept=".png, .jpg"
+                    :limit="1"
+                    list-type="picture-card"
+                    :auto-upload="false">
+                    <el-icon><Plus /></el-icon>
+                    <template #file="{ file }">
+                      <div>
+                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
+                        <span class="el-upload-list__item-actions">
+                          <span class="el-upload-list__item-preview" @click="customPictureCardPreview(file)">
+                            <el-icon><zoom-in /></el-icon>
+                          </span>
+                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
+                            <el-icon><Delete /></el-icon>
+                          </span>
+                        </span>
+                      </div>
+                    </template>
+                    <template #tip>
+                      <div style="margin-top: 10px">
+                        <div style="display: flex; align-items: center; justify-content: space-between">
+                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">图片规格</span>
+                          <el-button type="primary" :icon="Picture" @click="openLifeStyleDialog">从素材库中选择</el-button>
+                        </div>
+                        <div class="introduce-item">1、图片大小: 1200 x 628 像素或更大</div>
+                        <div class="introduce-item">2、文件大小: 5MB 或更小</div>
+                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
+                        <div class="introduce-item">4、内容: 图片中未添加文本、图形或徽标</div>
+                      </div>
+                    </template>
+                  </el-upload>
+                  <!-- 预览弹窗 -->
+                  <el-dialog v-model="customDialogVisible">
+                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
+                  </el-dialog>
+                </el-collapse-item>
+
+                <el-collapse-item name="commodity" v-loading="commodityLoading" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品</template>
+                  <div v-for="(item, index) in flattenedCommodityCard" :key="index" style="margin: 0 0 5px 0">
+                    <el-card shadow="hover" body-style="padding: 10px; display: flex;">
+                      <div style="margin-right: 8px; line-height: normal">
+                        <el-image class="img-box" :src="item.image_link" />
+                      </div>
+                      <div style="position: relative">
+                        <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                          <div class="double-line">{{ item.title }}</div>
+                        </el-tooltip>
+                        <span>
+                          <span style="color: #6d7784">ASIN: </span>
+                          <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                        </span>
+                        <el-button
+                          type="primary"
+                          size="small"
+                          link
+                          @click="() => openCommodityDialog(index)"
+                          style="position: absolute; bottom: 2px; right: 0">
+                          更换商品
+                        </el-button>
+                      </div>
+                    </el-card>
+                  </div>
+                </el-collapse-item>
+                <el-collapse-item name="4" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
+                  <el-form-item prop="title">
+                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
+                  </el-form-item>
+                </el-collapse-item>
+              </el-collapse>
+            </el-scrollbar>
+          </div>
+          <div style="width: 50%; padding: 0 10px; position: relative">
+            <el-button
+              type="primary"
+              plain
+              @click="submitForm(ruleFormRef)"
+              :disabled="!fileList.length"
+              style="position: absolute; top: 92%; left: 46%">
+              保存</el-button
+            >
+          </div>
+        </div>
+      </el-form>
+    </el-card>
+    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in cards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <el-image class="image" :src="item.imageUrl" fit="cover" />
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">徽标</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <el-dialog v-model="lifeStyleDialog" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in lifeStyleCards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <el-image class="image" :src="item.imageUrl" fit="cover" />
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">徽标</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="centerDialogVisible = false">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <el-dialog v-model="commodityDialog" title="更换商品" width="50%">
+      <el-radio-group
+        v-loading="dialogLoading3"
+        v-model="selectedCommodity"
+        style="display: flex; flex-direction: column; align-content: flex-start; align-items: flex-start">
+        <div v-for="(item, index) in flattenedReplaceableCommodity" :key="index">
+          <el-radio :label="item.asin" style="height: 80px; border-bottom: 1px solid #ccc">
+            <div style="padding: 10px; display: flex; align-items: center">
+              <div style="margin-right: 8px; line-height: normal">
+                <el-image class="img-box" :src="item.image_link" />
+              </div>
+              <div style="position: relative">
+                <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                  <div class="double-line">{{ item.title }}</div>
+                </el-tooltip>
+                <span>
+                  <span style="color: #6d7784">ASIN: </span>
+                  <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                </span>
+              </div>
+            </div>
+          </el-radio>
+        </div>
+      </el-radio-group>
+      <div style="margin-top: 20px; display: flex; justify-content: center">
+        <el-button type="primary" :disabled="!selectedCommodity" @click="handleSelectedCommodity">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
 <style scoped>
 .customize-container {
   margin-top: 10px;

+ 140 - 140
src/views/adManage/sb/campaigns/CreateCampaigns/component/ProductSetCreativity2.vue

@@ -1,143 +1,3 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">创意</span>
-      </div>
-      <el-form
-        ref="ruleFormRef"
-        :model="ruleForm"
-        :rules="rules"
-        label-width="120px"
-        class="demo-ruleForm"
-        size="default"
-        label-position="top"
-        status-icon>
-        <el-form-item label="广告名称" prop="name">
-          <el-input v-model="ruleForm.name" style="width: 50%" />
-        </el-form-item>
-        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
-          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
-            <el-scrollbar height="700px">
-              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none; padding-right: 10px;">
-                <el-collapse-item name="1">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
-                  <el-form-item prop="brandName">
-                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 10px 5px 0"></el-input>
-                  </el-form-item>
-                  <el-upload
-                    drag
-                    v-model:file-list="fileList"
-                    :on-change="changeFile"
-                    v-loading="upLoading"
-                    action="#"
-                    accept=".png, .jpg"
-                    :auto-upload="false"
-                    :on-remove="handleRemove"
-                    style="padding-right: 10px">
-                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
-                    <div class="el-upload__text">Drop file here or <em>click to upload</em></div>
-                    <template #tip>
-                      <div style="margin-top: 10px">
-                        <div style="display: flex; align-items: center; justify-content: space-between">
-                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
-                          <el-button type="primary" :icon="Picture">从素材库中选择</el-button>
-                        </div>
-                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
-                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
-                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
-                        <div class="introduce-item">
-                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
-                          <span style="margin-left: 25px; position: relative">
-                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
-                            <el-link
-                              type="primary"
-                              :underline="false"
-                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
-                              target="_blank"
-                              >查看要求</el-link
-                            >
-                          </span>
-                        </div>
-                      </div>
-                    </template>
-                  </el-upload>
-                </el-collapse-item>
-                <el-collapse-item name="2">
-                  <template #title>自定义图片(可选)</template>
-                  <el-upload
-                    class="avatar-uploader"
-                    v-model:file-list="customFileList"
-                    :on-change="changeCustomFile"
-                    v-loading="upCustomLoading"
-                    action="#"
-                    accept=".png, .jpg"
-                    :auto-upload="false"
-                    :on-remove="handleRemove"
-                    style="padding-right: 10px">
-                    <img v-if="imageUrl" :src="imageUrl" class="avatar" />
-                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
-                    <template #tip>
-                      <div style="margin-top: 10px">
-                        <div style="display: flex; align-items: center; justify-content: space-between">
-                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">图片规格</span>
-                          <el-button type="primary" :icon="Picture">从素材库中选择</el-button>
-                        </div>
-                        <div class="introduce-item">1、图片大小: 1200 x 628 像素或更大</div>
-                        <div class="introduce-item">2、文件大小: 5MB 或更小</div>
-                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
-                        <div class="introduce-item">4、内容: 图片中未添加文本、图形或徽标</div>
-                      </div>
-                    </template>
-                  </el-upload>
-                </el-collapse-item>
-                <el-collapse-item name="3">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品</template>
-                  <div v-for="item in commodityCard" :key="item.asin" style="padding-bottom: 5px;">
-                    <el-card shadow="hover" body-style="padding: 10px">
-                      <div style="padding: 10px; display: flex; align-items: center">
-                        <div style="margin-right: 8px; line-height: normal">
-                          <el-image class="img-box" :src="item.image_link" />
-                        </div>
-                        <div style="position: relative">
-                          <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                            <div class="single-line">{{ item.title }}</div>
-                          </el-tooltip>
-                          <span>
-                            <span style="color: #6d7784">ASIN: </span>
-                            <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                          </span>
-                        </div>
-                      </div>
-                    </el-card>
-                  </div>
-                </el-collapse-item>
-                <el-collapse-item name="4">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
-                  <el-form-item prop="title">
-                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
-                  </el-form-item>
-                </el-collapse-item>
-              </el-collapse>
-            </el-scrollbar>
-          </div>
-          <div style="width: 50%; padding: 0 10px; position: relative">
-            <el-button
-              type="primary"
-              plain
-              @click="submitForm(ruleFormRef)"
-              :disabled="!fileList.length"
-              style="position: absolute; top: 92%; left: 46%">
-              保存
-            </el-button>
-          </div>
-        </div>
-      </el-form>
-    </el-card>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { reactive, ref, inject, Ref, watch, onMounted, onUnmounted } from 'vue'
 import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus'
@@ -400,6 +260,146 @@ const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
 }
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">创意</span>
+      </div>
+      <el-form
+        ref="ruleFormRef"
+        :model="ruleForm"
+        :rules="rules"
+        label-width="120px"
+        class="demo-ruleForm"
+        size="default"
+        label-position="top"
+        status-icon>
+        <el-form-item label="广告名称" prop="name">
+          <el-input v-model="ruleForm.name" style="width: 50%" />
+        </el-form-item>
+        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
+          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
+            <el-scrollbar height="700px">
+              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none; padding-right: 10px;">
+                <el-collapse-item name="1">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
+                  <el-form-item prop="brandName">
+                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 10px 5px 0"></el-input>
+                  </el-form-item>
+                  <el-upload
+                    drag
+                    v-model:file-list="fileList"
+                    :on-change="changeFile"
+                    v-loading="upLoading"
+                    action="#"
+                    accept=".png, .jpg"
+                    :auto-upload="false"
+                    :on-remove="handleRemove"
+                    style="padding-right: 10px">
+                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+                    <div class="el-upload__text">Drop file here or <em>click to upload</em></div>
+                    <template #tip>
+                      <div style="margin-top: 10px">
+                        <div style="display: flex; align-items: center; justify-content: space-between">
+                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
+                          <el-button type="primary" :icon="Picture">从素材库中选择</el-button>
+                        </div>
+                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
+                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
+                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
+                        <div class="introduce-item">
+                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
+                          <span style="margin-left: 25px; position: relative">
+                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
+                            <el-link
+                              type="primary"
+                              :underline="false"
+                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
+                              target="_blank"
+                              >查看要求</el-link
+                            >
+                          </span>
+                        </div>
+                      </div>
+                    </template>
+                  </el-upload>
+                </el-collapse-item>
+                <el-collapse-item name="2">
+                  <template #title>自定义图片(可选)</template>
+                  <el-upload
+                    class="avatar-uploader"
+                    v-model:file-list="customFileList"
+                    :on-change="changeCustomFile"
+                    v-loading="upCustomLoading"
+                    action="#"
+                    accept=".png, .jpg"
+                    :auto-upload="false"
+                    :on-remove="handleRemove"
+                    style="padding-right: 10px">
+                    <img v-if="imageUrl" :src="imageUrl" class="avatar" />
+                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+                    <template #tip>
+                      <div style="margin-top: 10px">
+                        <div style="display: flex; align-items: center; justify-content: space-between">
+                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">图片规格</span>
+                          <el-button type="primary" :icon="Picture">从素材库中选择</el-button>
+                        </div>
+                        <div class="introduce-item">1、图片大小: 1200 x 628 像素或更大</div>
+                        <div class="introduce-item">2、文件大小: 5MB 或更小</div>
+                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
+                        <div class="introduce-item">4、内容: 图片中未添加文本、图形或徽标</div>
+                      </div>
+                    </template>
+                  </el-upload>
+                </el-collapse-item>
+                <el-collapse-item name="3">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品</template>
+                  <div v-for="item in commodityCard" :key="item.asin" style="padding-bottom: 5px;">
+                    <el-card shadow="hover" body-style="padding: 10px">
+                      <div style="padding: 10px; display: flex; align-items: center">
+                        <div style="margin-right: 8px; line-height: normal">
+                          <el-image class="img-box" :src="item.image_link" />
+                        </div>
+                        <div style="position: relative">
+                          <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                            <div class="single-line">{{ item.title }}</div>
+                          </el-tooltip>
+                          <span>
+                            <span style="color: #6d7784">ASIN: </span>
+                            <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                          </span>
+                        </div>
+                      </div>
+                    </el-card>
+                  </div>
+                </el-collapse-item>
+                <el-collapse-item name="4">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
+                  <el-form-item prop="title">
+                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
+                  </el-form-item>
+                </el-collapse-item>
+              </el-collapse>
+            </el-scrollbar>
+          </div>
+          <div style="width: 50%; padding: 0 10px; position: relative">
+            <el-button
+              type="primary"
+              plain
+              @click="submitForm(ruleFormRef)"
+              :disabled="!fileList.length"
+              style="position: absolute; top: 92%; left: 46%">
+              保存
+            </el-button>
+          </div>
+        </div>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
 <style scoped>
 .customize-container {
   margin-top: 10px;

+ 154 - 154
src/views/adManage/sb/campaigns/CreateCampaigns/component/VideoCommodity.vue

@@ -1,157 +1,3 @@
-<template>
-  <div prop="commodity" style="width: 100%" v-loading="productLoading">
-    <div style="width: 100%; height: 620px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px">
-      <div style="width: 50%; border-right: 1px solid #e5e7ec">
-        <el-tabs v-model="productTabs" class="demo-tabs">
-          <el-tab-pane label="搜索" name="first">
-            <div style="margin-bottom: 10px">
-              <el-input v-model="searchInp" placeholder="Please input" class="input-with-select" @change="inpChange" clearable>
-                <template #prepend>
-                  <el-select v-model="leftSelect" style="width: 100px" @change="selChange">
-                    <el-option label="名称" value="name" />
-                    <el-option label="ASIN" value="asin" />
-                    <el-option label="SKU" value="sku" />
-                  </el-select>
-                </template>
-                <template #append>
-                  <el-select v-model="rightSelect" style="width: 100px">
-                    <el-option label="最新优先" value="latest" />
-                    <el-option label="最早优先" value="earliest" />
-                    <el-option label="优选广告" value="optimal" />
-                  </el-select>
-                </template>
-              </el-input>
-            </div>
-            <el-table
-              height="490"
-              style="width: 100%"
-              v-loading="loading"
-              :data="productTableData"
-              :header-cell-style="headerCellStyle"
-              @selection-change="handleSelectionChange">
-              <el-table-column type="selection" width="50" />
-              <el-table-column prop="asin" label="商品">
-                <template #default="scope">
-                  <div style="display: flex; align-items: center">
-                    <div style="margin-right: 8px; line-height: normal">
-                      <el-image class="img-box" :src="scope.row.image_link" />
-                    </div>
-                    <div>
-                      <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                        <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                      </el-tooltip>
-                      <div class="data-color">
-                        <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
-                        <span style="margin: 0 5px; color: #cacdd4">|</span>
-                        <span style="color: #6d7784">{{ scope.row.quantity }}</span>
-                      </div>
-                      <span>
-                        ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                      </span>
-                      <span>
-                        SKU: <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
-                      </span>
-                    </div>
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column prop="name" label="Name" width="120" align="right">
-                <template #header>
-                  <el-button type="primary" size="normal" link :disabled="addedTableData.length >= 1" @click="handleGoodsAdd">添加已选中</el-button>
-                </template>
-                <template #default="scope">
-                  <el-button type="primary" size="small" :disabled="addedTableData.length >= 1" @click="addSingleGoods(scope)" text>添加</el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-            <el-pagination
-              @current-change="handleCurrentChange"
-              @size-change="handleSizeChange"
-              :current-page="currentPage"
-              :page-size="pageSize"
-              :total="totalItems"
-              layout="prev, pager, next" />
-          </el-tab-pane>
-          <el-tab-pane label="输入" name="second">
-            <el-input
-              style="padding: 10px"
-              v-model="productTextarea"
-              :rows="20"
-              type="textarea"
-              placeholder="请输入ASIN,多个ASIN使用逗号、空格或换行符分隔。(未完成)"
-              maxlength="11000" />
-            <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-              <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="addGods">{{ button.text }}</el-button>
-            </div>
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-      <div style="width: 50%">
-        <el-card class="box-card" shadow="never" style="border: 0">
-          <template #header>
-            <div class="card-header">
-              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedTableData.length }}</span>
-
-                <el-text type="warning" truncated>最多添加一个产品</el-text>
-
-              <el-button class="button" type="danger" text bg @click="delAllGoods">全部删除</el-button>
-            </div>
-          </template>
-          <div class="card-body"></div>
-        </el-card>
-        <div style="padding: 0 10px 0 10px; margin-top: -12px">
-          <el-table
-            :data="addedTableData"
-            height="475"
-            style="width: 100%"
-            :header-cell-style="headerCellStyle"
-            @selection-change="handleAddedGoodsChange">
-            <el-table-column type="selection" width="50" />
-            <el-table-column prop="asin" label="ASIN">
-              <template #default="scope">
-                <div style="display: flex; align-items: center">
-                  <div style="margin-right: 8px; line-height: normal">
-                    <el-image class="img-box" :src="scope.row.image_link" />
-                  </div>
-                  <div>
-                    <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                      <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                    </el-tooltip>
-                    <div class="data-color">
-                      <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
-                      <span style="margin: 0 5px; color: #cacdd4">|</span>
-                      <span style="color: #6d7784">{{ scope.row.quantity }}</span>
-                    </div>
-                    <span
-                      >ASIN:
-                      <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                    </span>
-                    <span
-                      >SKU:
-                      <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
-                    </span>
-                  </div>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column prop="name" label="Name" width="120" align="right">
-              <template #header>
-                <el-button type="danger" size="normal" link @click="delSelectedGoods">删除已选中</el-button>
-              </template>
-              <template #default="scope">
-                <el-button type="primary" size="small" @click="delSingleGoods(scope)" text>删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <!-- <div style="display: flex; justify-content: space-around; padding-top: 5px">
-          <el-button type="primary" plain :disabled="productSave" @click="submitProductForm">保存</el-button>
-        </div> -->
-      </div>
-    </div>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { inject, onMounted, ref, watch, provide, onUnmounted } from 'vue'
 import type { Ref } from 'vue'
@@ -392,6 +238,160 @@ onMounted(() => {
 })
 </script>
 
+<template>
+  <div prop="commodity" style="width: 100%" v-loading="productLoading">
+    <div style="width: 100%; height: 620px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px">
+      <div style="width: 50%; border-right: 1px solid #e5e7ec">
+        <el-tabs v-model="productTabs" class="demo-tabs">
+          <el-tab-pane label="搜索" name="first">
+            <div style="margin-bottom: 10px">
+              <el-input v-model="searchInp" placeholder="Please input" class="input-with-select" @change="inpChange" clearable>
+                <template #prepend>
+                  <el-select v-model="leftSelect" style="width: 100px" @change="selChange">
+                    <el-option label="名称" value="name" />
+                    <el-option label="ASIN" value="asin" />
+                    <el-option label="SKU" value="sku" />
+                  </el-select>
+                </template>
+                <template #append>
+                  <el-select v-model="rightSelect" style="width: 100px">
+                    <el-option label="最新优先" value="latest" />
+                    <el-option label="最早优先" value="earliest" />
+                    <el-option label="优选广告" value="optimal" />
+                  </el-select>
+                </template>
+              </el-input>
+            </div>
+            <el-table
+              height="490"
+              style="width: 100%"
+              v-loading="loading"
+              :data="productTableData"
+              :header-cell-style="headerCellStyle"
+              @selection-change="handleSelectionChange">
+              <el-table-column type="selection" width="50" />
+              <el-table-column prop="asin" label="商品">
+                <template #default="scope">
+                  <div style="display: flex; align-items: center">
+                    <div style="margin-right: 8px; line-height: normal">
+                      <el-image class="img-box" :src="scope.row.image_link" />
+                    </div>
+                    <div>
+                      <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                        <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                      </el-tooltip>
+                      <div class="data-color">
+                        <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
+                        <span style="margin: 0 5px; color: #cacdd4">|</span>
+                        <span style="color: #6d7784">{{ scope.row.quantity }}</span>
+                      </div>
+                      <span>
+                        ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                      </span>
+                      <span>
+                        SKU: <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
+                      </span>
+                    </div>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column prop="name" label="Name" width="120" align="right">
+                <template #header>
+                  <el-button type="primary" size="normal" link :disabled="addedTableData.length >= 1" @click="handleGoodsAdd">添加已选中</el-button>
+                </template>
+                <template #default="scope">
+                  <el-button type="primary" size="small" :disabled="addedTableData.length >= 1" @click="addSingleGoods(scope)" text>添加</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+            <el-pagination
+              @current-change="handleCurrentChange"
+              @size-change="handleSizeChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              :total="totalItems"
+              layout="prev, pager, next" />
+          </el-tab-pane>
+          <el-tab-pane label="输入" name="second">
+            <el-input
+              style="padding: 10px"
+              v-model="productTextarea"
+              :rows="20"
+              type="textarea"
+              placeholder="请输入ASIN,多个ASIN使用逗号、空格或换行符分隔。(未完成)"
+              maxlength="11000" />
+            <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+              <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="addGods">{{ button.text }}</el-button>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+      <div style="width: 50%">
+        <el-card class="box-card" shadow="never" style="border: 0">
+          <template #header>
+            <div class="card-header">
+              <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedTableData.length }}</span>
+
+                <el-text type="warning" truncated>最多添加一个产品</el-text>
+
+              <el-button class="button" type="danger" text bg @click="delAllGoods">全部删除</el-button>
+            </div>
+          </template>
+          <div class="card-body"></div>
+        </el-card>
+        <div style="padding: 0 10px 0 10px; margin-top: -12px">
+          <el-table
+            :data="addedTableData"
+            height="475"
+            style="width: 100%"
+            :header-cell-style="headerCellStyle"
+            @selection-change="handleAddedGoodsChange">
+            <el-table-column type="selection" width="50" />
+            <el-table-column prop="asin" label="ASIN">
+              <template #default="scope">
+                <div style="display: flex; align-items: center">
+                  <div style="margin-right: 8px; line-height: normal">
+                    <el-image class="img-box" :src="scope.row.image_link" />
+                  </div>
+                  <div>
+                    <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                      <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                    </el-tooltip>
+                    <div class="data-color">
+                      <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
+                      <span style="margin: 0 5px; color: #cacdd4">|</span>
+                      <span style="color: #6d7784">{{ scope.row.quantity }}</span>
+                    </div>
+                    <span
+                      >ASIN:
+                      <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                    </span>
+                    <span
+                      >SKU:
+                      <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
+                    </span>
+                  </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="name" label="Name" width="120" align="right">
+              <template #header>
+                <el-button type="danger" size="normal" link @click="delSelectedGoods">删除已选中</el-button>
+              </template>
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="delSingleGoods(scope)" text>删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <!-- <div style="display: flex; justify-content: space-around; padding-top: 5px">
+          <el-button type="primary" plain :disabled="productSave" @click="submitProductForm">保存</el-button>
+        </div> -->
+      </div>
+    </div>
+  </div>
+</template>
+
 <style lang="scss" scoped>
 ::v-deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {
   font-weight: 500;

+ 298 - 298
src/views/adManage/sb/campaigns/CreateCampaigns/component/VideoCreativity1.vue

@@ -1,303 +1,18 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">创意</span>
-      </div>
-      <el-form
-        ref="ruleFormRef"
-        :model="ruleForm"
-        :rules="rules"
-        label-width="120px"
-        class="demo-ruleForm"
-        size="default"
-        label-position="top"
-        status-icon>
-        <el-form-item label="广告名称" prop="name">
-          <el-input v-model="ruleForm.name" style="width: 50%" />
-        </el-form-item>
-        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
-          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
-            <el-scrollbar height="700px">
-              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
-                <el-collapse-item name="1" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
-                  <el-form-item prop="brandName">
-                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 0 5px 0"></el-input>
-                  </el-form-item>
+<script setup lang="ts">
+import { reactive, ref, inject, Ref, watch, computed, onMounted, onUnmounted } from 'vue'
+import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Plus, Picture, Search, Delete, Download, ZoomIn } from '@element-plus/icons-vue'
+import type { UploadFile } from 'element-plus'
+import { getAssets, getLifeStyleAssets, getPageAsins, getCommodityCard, uploadFile, checkAsset, postBrandVideo } from '../api/index'
+import emitter from '/@/utils/emitter'
+import { storeToRefs } from 'pinia'
+import { useShopInfo } from '/@/stores/shopInfo'
 
-                  <el-upload
-                    v-model:file-list="fileList"
-                    list-type="picture-card"
-                    :on-change="changeFile"
-                    v-loading="upLoading"
-                    action="#"
-                    accept=".png, .jpg"
-                    :limit="1"
-                    :auto-upload="false">
-                    <el-icon><Plus /></el-icon>
-                    <template #file="{ file }">
-                      <div>
-                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
-                        <span class="el-upload-list__item-actions">
-                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
-                            <el-icon><zoom-in /></el-icon>
-                          </span>
-                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
-                            <el-icon><Delete /></el-icon>
-                          </span>
-                        </span>
-                      </div>
-                    </template>
-                    <template #tip>
-                      <div style="margin-top: 10px">
-                        <div style="display: flex; align-items: center; justify-content: space-between">
-                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
-                          <el-button type="primary" :icon="Picture" disabled="true" @click="openDialog">从素材库中选择</el-button>
-                        </div>
-                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
-                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
-                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
-                        <div class="introduce-item">
-                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
-                          <span style="margin-left: 25px; position: relative">
-                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
-                            <el-link
-                              type="primary"
-                              :underline="false"
-                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
-                              target="_blank"
-                              >查看要求</el-link
-                            >
-                          </span>
-                        </div>
-                      </div>
-                    </template>
-                  </el-upload>
-                  <!-- 预览弹窗 -->
-                  <el-dialog v-model="dialogVisible">
-                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
-                  </el-dialog>
-                </el-collapse-item>
-                <el-collapse-item name="2" style="padding-right: 10px">
-                  <template #title><span style="color: #e47470; margin-right: 4px">*</span>视频</template>
-                  <div style="display: flex; justify-content: space-between">
-                    <div style="font-weight: 700; color: #1d2129; line-height: 18px; font-size: 14px">选择视频</div>
-                    <el-button type="primary" link>查看视频批准提示</el-button>
-                  </div>
-                  <div style="margin: 10px 0; font-size: 12px; font-weight: 400; color: #666; line-height: 18px">
-                    保持视频简短并紧扣主题。视频会自动播放,因此请确保前 2
-                    秒极具吸引力,并且不依靠声音来传递信息。如果您在视频中使用了文字,请确保文字清晰易辨。字幕或音频必须与将展示您广告的区域相匹配。
-                  </div>
-                  <el-upload
-                    v-model:file-list="videoList"
-                    :on-change="changeVideo"
-                    v-loading="videoLoading"
-                    accept=".mp4, .mov"
-                    action="#"
-                    :limit="1"
-                    :auto-upload="false"
-                    :on-remove="handleRemoveVideo"
-                    class="upload-demo">
-                    <el-button type="primary">上传视频</el-button>
-                    <template #tip>
-                      <el-button type="primary" disabled="true" style="margin-left: 20px">从素材库中选择</el-button>
-                      <!-- <div class="el-upload__tip">div> -->
-                      <hr style="margin: 10px 0" />
-                      <div>
-                        <div style="display: flex; justify-content: space-between">
-                          <span style="font-weight: 700; color: #1d2129; line-height: 18px; font-size: 14px">视频文件要求:</span>
-                          <el-button type="primary" link>了解更多</el-button>
-                        </div>
-                        <div class="tip-list-title">视频格式</div>
-                        <div class="tip-item">1.纵横比:16:9</div>
-                        <div class="tip-item">2.尺寸:1280 x 720 像素、1920 x 1080 像素或 3840 x 2160 像素</div>
-                        <div class="tip-item">3.文件大小:500MB 或更小</div>
-                        <div class="tip-item">4.文件格式:MP4 或 MOV</div>
-                        <div class="tip-item">5.长度:6-45 秒</div>
-                        <div class="tip-item">6.帧率:23.976、23.98、24、25、29.97 或 29.98 fps</div>
-                        <div class="tip-item">7.比特率:1 Mbps 或更高</div>
-                        <div class="tip-item">8.编解码器:H.264 或 H.2651</div>
-                        <div class="tip-item">9.配置文件:主配置文件或基线配置文件</div>
-                        <div class="tip-item">10.视频流:仅为 1</div>
-                        <div class="tip-list-title">音频规格</div>
-                        <div class="tip-item">1.语言:必须与广告投放区域匹配</div>
-                        <div class="tip-item">2.采样率:44.1 kHz 或更高</div>
-                        <div class="tip-item">3.编解码器:PCM、AAC 或 MP3</div>
-                        <div class="tip-item">4.比特率:96 kbps 或更高</div>
-                        <div class="tip-item">5.格式:立体声或单声道</div>
-                        <div class="tip-item">6.音频流:仅为 1</div>
-                      </div>
-                    </template>
-                  </el-upload>
+const shopInfo = useShopInfo()
+const { profile } = storeToRefs(shopInfo)
 
-                  <!-- 预览弹窗 -->
-                  <el-dialog v-model="dialogVisible">
-                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
-                  </el-dialog>
-                </el-collapse-item>
-
-                <el-collapse-item name="commodity" v-loading="commodityLoading" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品</template>
-                  <div v-for="(item, index) in flattenedCommodityCard" :key="index" style="margin: 0 0 5px 0">
-                    <el-card shadow="hover" body-style="padding: 10px; display: flex;">
-                      <div style="margin-right: 8px; line-height: normal">
-                        <el-image class="img-box" :src="item.image_link" />
-                      </div>
-                      <div style="position: relative">
-                        <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                          <div class="double-line">{{ item.title }}</div>
-                        </el-tooltip>
-                        <span>
-                          <span style="color: #6d7784">ASIN: </span>
-                          <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                        </span>
-                        <el-button
-                          type="primary"
-                          size="small"
-                          link
-                          @click="() => openCommodityDialog(index)"
-                          style="position: absolute; bottom: 2px; right: 0">
-                          更换商品
-                        </el-button>
-                      </div>
-                    </el-card>
-                  </div>
-                </el-collapse-item>
-                <el-collapse-item name="4" style="padding-right: 10px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
-                  <el-form-item prop="title">
-                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
-                  </el-form-item>
-                </el-collapse-item>
-              </el-collapse>
-            </el-scrollbar>
-          </div>
-          <div style="width: 50%; padding: 0 10px; position: relative">
-            <el-button type="primary" plain @click="submitForm(ruleFormRef)" :disabled="!fileList.length" style="position: absolute; top: 92%; left: 46%"
-              >保存</el-button
-            >
-          </div>
-        </div>
-      </el-form>
-    </el-card>
-    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in cards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <el-image class="image" :src="item.imageUrl" fit="cover" />
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">徽标</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-    <el-dialog v-model="lifeStyleDialog" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in lifeStyleCards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <el-image class="image" :src="item.imageUrl" fit="cover" />
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">徽标</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="centerDialogVisible = false">确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-    <el-dialog v-model="commodityDialog" title="更换商品" width="50%">
-      <el-radio-group
-        v-loading="dialogLoading3"
-        v-model="selectedCommodity"
-        style="display: flex; flex-direction: column; align-content: flex-start; align-items: flex-start">
-        <div v-for="(item, index) in flattenedReplaceableCommodity" :key="index">
-          <el-radio :label="item.asin" style="height: 80px; border-bottom: 1px solid #ccc">
-            <div style="padding: 10px; display: flex; align-items: center">
-              <div style="margin-right: 8px; line-height: normal">
-                <el-image class="img-box" :src="item.image_link" />
-              </div>
-              <div style="position: relative">
-                <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                  <div class="double-line">{{ item.title }}</div>
-                </el-tooltip>
-                <span>
-                  <span style="color: #6d7784">ASIN: </span>
-                  <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                </span>
-              </div>
-            </div>
-          </el-radio>
-        </div>
-      </el-radio-group>
-      <div style="margin-top: 20px; display: flex; justify-content: center">
-        <el-button type="primary" :disabled="!selectedCommodity" @click="handleSelectedCommodity">确定</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { reactive, ref, inject, Ref, watch, computed, onMounted, onUnmounted } from 'vue'
-import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Picture, Search, Delete, Download, ZoomIn } from '@element-plus/icons-vue'
-import type { UploadFile } from 'element-plus'
-import { getAssets, getLifeStyleAssets, getPageAsins, getCommodityCard, uploadFile, checkAsset, postBrandVideo } from '../api/index'
-import emitter from '/@/utils/emitter'
-import { storeToRefs } from 'pinia'
-import { useShopInfo } from '/@/stores/shopInfo'
-
-const shopInfo = useShopInfo()
-const { profile } = storeToRefs(shopInfo)
-
-const ruleFormRef = ref<FormInstance>()
+const ruleFormRef = ref<FormInstance>()
 
 interface RuleForm {
   name: string
@@ -766,6 +481,291 @@ const flattenedReplaceableCommodity = computed(() => {
 })
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">创意</span>
+      </div>
+      <el-form
+        ref="ruleFormRef"
+        :model="ruleForm"
+        :rules="rules"
+        label-width="120px"
+        class="demo-ruleForm"
+        size="default"
+        label-position="top"
+        status-icon>
+        <el-form-item label="广告名称" prop="name">
+          <el-input v-model="ruleForm.name" style="width: 50%" />
+        </el-form-item>
+        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
+          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
+            <el-scrollbar height="700px">
+              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
+                <el-collapse-item name="1" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>品牌名称和徽标</template>
+                  <el-form-item prop="brandName">
+                    <el-input v-model="ruleForm.brandName" placeholder="请输入品牌名称" style="padding: 0 0 5px 0"></el-input>
+                  </el-form-item>
+
+                  <el-upload
+                    v-model:file-list="fileList"
+                    list-type="picture-card"
+                    :on-change="changeFile"
+                    v-loading="upLoading"
+                    action="#"
+                    accept=".png, .jpg"
+                    :limit="1"
+                    :auto-upload="false">
+                    <el-icon><Plus /></el-icon>
+                    <template #file="{ file }">
+                      <div>
+                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
+                        <span class="el-upload-list__item-actions">
+                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
+                            <el-icon><zoom-in /></el-icon>
+                          </span>
+                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
+                            <el-icon><Delete /></el-icon>
+                          </span>
+                        </span>
+                      </div>
+                    </template>
+                    <template #tip>
+                      <div style="margin-top: 10px">
+                        <div style="display: flex; align-items: center; justify-content: space-between">
+                          <span style="line-height: 17px; font-weight: 600; color: #1e2128">徽标规格</span>
+                          <el-button type="primary" :icon="Picture" disabled="true" @click="openDialog">从素材库中选择</el-button>
+                        </div>
+                        <div class="introduce-item">1、图片大小: 400x400 像素或更大</div>
+                        <div class="introduce-item">2、文件大小: 1MB 或更小</div>
+                        <div class="introduce-item">3、文件格式: PNG 或 JPG</div>
+                        <div class="introduce-item">
+                          4、内容: 徽标必须填满图片或置于白色或透明背景上详细了解我们的徽标要求
+                          <span style="margin-left: 25px; position: relative">
+                            <el-icon size="14" style="position: absolute; left: -14px; top: 1px"><Link /></el-icon>
+                            <el-link
+                              type="primary"
+                              :underline="false"
+                              href="https://advertising.amazon.com/resources/ad-policy/sponsored-ads-policies#brandlogo"
+                              target="_blank"
+                              >查看要求</el-link
+                            >
+                          </span>
+                        </div>
+                      </div>
+                    </template>
+                  </el-upload>
+                  <!-- 预览弹窗 -->
+                  <el-dialog v-model="dialogVisible">
+                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
+                  </el-dialog>
+                </el-collapse-item>
+                <el-collapse-item name="2" style="padding-right: 10px">
+                  <template #title><span style="color: #e47470; margin-right: 4px">*</span>视频</template>
+                  <div style="display: flex; justify-content: space-between">
+                    <div style="font-weight: 700; color: #1d2129; line-height: 18px; font-size: 14px">选择视频</div>
+                    <el-button type="primary" link>查看视频批准提示</el-button>
+                  </div>
+                  <div style="margin: 10px 0; font-size: 12px; font-weight: 400; color: #666; line-height: 18px">
+                    保持视频简短并紧扣主题。视频会自动播放,因此请确保前 2
+                    秒极具吸引力,并且不依靠声音来传递信息。如果您在视频中使用了文字,请确保文字清晰易辨。字幕或音频必须与将展示您广告的区域相匹配。
+                  </div>
+                  <el-upload
+                    v-model:file-list="videoList"
+                    :on-change="changeVideo"
+                    v-loading="videoLoading"
+                    accept=".mp4, .mov"
+                    action="#"
+                    :limit="1"
+                    :auto-upload="false"
+                    :on-remove="handleRemoveVideo"
+                    class="upload-demo">
+                    <el-button type="primary">上传视频</el-button>
+                    <template #tip>
+                      <el-button type="primary" disabled="true" style="margin-left: 20px">从素材库中选择</el-button>
+                      <!-- <div class="el-upload__tip">div> -->
+                      <hr style="margin: 10px 0" />
+                      <div>
+                        <div style="display: flex; justify-content: space-between">
+                          <span style="font-weight: 700; color: #1d2129; line-height: 18px; font-size: 14px">视频文件要求:</span>
+                          <el-button type="primary" link>了解更多</el-button>
+                        </div>
+                        <div class="tip-list-title">视频格式</div>
+                        <div class="tip-item">1.纵横比:16:9</div>
+                        <div class="tip-item">2.尺寸:1280 x 720 像素、1920 x 1080 像素或 3840 x 2160 像素</div>
+                        <div class="tip-item">3.文件大小:500MB 或更小</div>
+                        <div class="tip-item">4.文件格式:MP4 或 MOV</div>
+                        <div class="tip-item">5.长度:6-45 秒</div>
+                        <div class="tip-item">6.帧率:23.976、23.98、24、25、29.97 或 29.98 fps</div>
+                        <div class="tip-item">7.比特率:1 Mbps 或更高</div>
+                        <div class="tip-item">8.编解码器:H.264 或 H.2651</div>
+                        <div class="tip-item">9.配置文件:主配置文件或基线配置文件</div>
+                        <div class="tip-item">10.视频流:仅为 1</div>
+                        <div class="tip-list-title">音频规格</div>
+                        <div class="tip-item">1.语言:必须与广告投放区域匹配</div>
+                        <div class="tip-item">2.采样率:44.1 kHz 或更高</div>
+                        <div class="tip-item">3.编解码器:PCM、AAC 或 MP3</div>
+                        <div class="tip-item">4.比特率:96 kbps 或更高</div>
+                        <div class="tip-item">5.格式:立体声或单声道</div>
+                        <div class="tip-item">6.音频流:仅为 1</div>
+                      </div>
+                    </template>
+                  </el-upload>
+
+                  <!-- 预览弹窗 -->
+                  <el-dialog v-model="dialogVisible">
+                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
+                  </el-dialog>
+                </el-collapse-item>
+
+                <el-collapse-item name="commodity" v-loading="commodityLoading" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品</template>
+                  <div v-for="(item, index) in flattenedCommodityCard" :key="index" style="margin: 0 0 5px 0">
+                    <el-card shadow="hover" body-style="padding: 10px; display: flex;">
+                      <div style="margin-right: 8px; line-height: normal">
+                        <el-image class="img-box" :src="item.image_link" />
+                      </div>
+                      <div style="position: relative">
+                        <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                          <div class="double-line">{{ item.title }}</div>
+                        </el-tooltip>
+                        <span>
+                          <span style="color: #6d7784">ASIN: </span>
+                          <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                        </span>
+                        <el-button
+                          type="primary"
+                          size="small"
+                          link
+                          @click="() => openCommodityDialog(index)"
+                          style="position: absolute; bottom: 2px; right: 0">
+                          更换商品
+                        </el-button>
+                      </div>
+                    </el-card>
+                  </div>
+                </el-collapse-item>
+                <el-collapse-item name="4" style="padding-right: 10px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>标题</template>
+                  <el-form-item prop="title">
+                    <el-input v-model="ruleForm.title" maxlength="50" placeholder="请输入标题" show-word-limit style="padding: 0 10px 0 0"></el-input>
+                  </el-form-item>
+                </el-collapse-item>
+              </el-collapse>
+            </el-scrollbar>
+          </div>
+          <div style="width: 50%; padding: 0 10px; position: relative">
+            <el-button type="primary" plain @click="submitForm(ruleFormRef)" :disabled="!fileList.length" style="position: absolute; top: 92%; left: 46%"
+              >保存</el-button
+            >
+          </div>
+        </div>
+      </el-form>
+    </el-card>
+    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in cards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <el-image class="image" :src="item.imageUrl" fit="cover" />
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">徽标</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <el-dialog v-model="lifeStyleDialog" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in lifeStyleCards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <el-image class="image" :src="item.imageUrl" fit="cover" />
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">徽标</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="centerDialogVisible = false">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <el-dialog v-model="commodityDialog" title="更换商品" width="50%">
+      <el-radio-group
+        v-loading="dialogLoading3"
+        v-model="selectedCommodity"
+        style="display: flex; flex-direction: column; align-content: flex-start; align-items: flex-start">
+        <div v-for="(item, index) in flattenedReplaceableCommodity" :key="index">
+          <el-radio :label="item.asin" style="height: 80px; border-bottom: 1px solid #ccc">
+            <div style="padding: 10px; display: flex; align-items: center">
+              <div style="margin-right: 8px; line-height: normal">
+                <el-image class="img-box" :src="item.image_link" />
+              </div>
+              <div style="position: relative">
+                <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                  <div class="double-line">{{ item.title }}</div>
+                </el-tooltip>
+                <span>
+                  <span style="color: #6d7784">ASIN: </span>
+                  <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                </span>
+              </div>
+            </div>
+          </el-radio>
+        </div>
+      </el-radio-group>
+      <div style="margin-top: 20px; display: flex; justify-content: center">
+        <el-button type="primary" :disabled="!selectedCommodity" @click="handleSelectedCommodity">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
 <style scoped>
 .customize-container {
   margin-top: 10px;

+ 157 - 157
src/views/adManage/sb/campaigns/CreateCampaigns/component/VideoCreativity2.vue

@@ -1,160 +1,3 @@
-<template>
-  <div class="customize-container">
-    <el-card body-style="padding: 20px 80px 0 80px;" v-loading="loading">
-      <div style="font-weight: 700; padding-bottom: 18px">
-        <span style="color: #306cd7; font-size: 26px">|</span>
-        <span style="font-size: 18px; padding-left: 5px">创意</span>
-      </div>
-      <el-form
-        ref="ruleFormRef"
-        :model="ruleForm"
-        :rules="rules"
-        label-width="120px"
-        class="demo-ruleForm"
-        size="default"
-        label-position="top"
-        status-icon>
-        <el-form-item label="广告名称" prop="name">
-          <el-input v-model="ruleForm.name" style="width: 50%" />
-        </el-form-item>
-        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
-          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
-            <el-scrollbar height="700px">
-              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
-                <el-collapse-item name="video" style="padding: 0 10px 0 5px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>视频 </template>
-                  <div>
-                    <div style="display: flex; align-items: center; justify-content: space-between">
-                      <span style="color: #1e2128; font-size: 15px; font-weight: 450">选择视频</span>
-                      <el-button type="primary" link>查看视频批准提示</el-button>
-                    </div>
-                    <div style="color: #666666; margin-bottom: 10px">
-                      保持视频简短并紧扣主题。视频会自动播放,因此请确保前 2
-                      秒极具吸引力,并且不依靠声音来传递信息。如果您在视频中使用了文字,请确保文字清晰易辨。字幕或音频必须与将展示您广告的区域相匹配。
-                    </div>
-                    <div class="upload-button-group">
-                      <el-upload
-                        v-model:file-list="fileList"
-                        :on-change="changeFile"
-                        v-loading="upLoading"
-                        accept=".mp4, .mov"
-                        action="#"
-                        :limit="1"
-                        :auto-upload="false"
-                        :on-remove="handleRemove"
-                        class="upload-demo">
-                        <el-button type="primary">上传文件</el-button>
-
-                        <!-- <template #tip>
-                          <div class="el-upload__tip"><el-button type="primary" :icon="Picture"  :disabled="true" @click="handleSelect">从素材库中选择</el-button></div>
-                        </template> -->
-                      </el-upload>
-                      <!-- <el-button type="primary" :icon="Picture" style="margin-left: -120px" :disabled="true" @click="handleSelect">从素材库中选择</el-button> -->
-                    </div>
-                  </div>
-                </el-collapse-item>
-                <div style="display: flex; align-items: center; justify-content: space-between; padding: 0 10px 0 5px">
-                  <span style="color: #1e2128; font-size: 15px; font-weight: 450">视频文件要求:</span>
-                  <el-button type="primary" link>了解更多</el-button>
-                </div>
-                <div style="padding: 0 10px 0 5px">
-                  <span style="color: #1e2128; font-size: 13px; font-weight: 450">视频规格</span>
-                  <div class="introduce-item">1.纵横比:16:9</div>
-                  <div class="introduce-item">2.尺寸:1280 x 720 像素、1920 x 1080 像素或 3840 x 2160 像素</div>
-                  <div class="introduce-item">3.文件大小:500MB 或更小</div>
-                  <div class="introduce-item">4.文件格式:MP4 或 MOV</div>
-                  <div class="introduce-item">5.长度:6-45 秒</div>
-                  <div class="introduce-item">6.帧率:23.976、23.98、24、25、29.97 或 29.98 fps</div>
-                  <div class="introduce-item">7.比特率:1 Mbps 或更高</div>
-                  <div class="introduce-item">8.编解码器:H.264 或 H.265</div>
-                  <div class="introduce-item">9.配置文件:主配置文件或基线配置文件</div>
-                  <div class="introduce-item">10.视频流:仅为 1</div>
-                </div>
-                <div style="padding: 0 10px 0 5px">
-                  <span style="color: #1e2128; font-size: 13px; font-weight: 450">音频规格</span>
-                  <div class="introduce-item">1.语言:必须与广告投放区域匹配</div>
-                  <div class="introduce-item">2.采样率:44.1 kHz 或更高</div>
-                  <div class="introduce-item">3.编解码器:PCM、AAC 或 MP3</div>
-                  <div class="introduce-item">4.比特率:96 kbps 或更高</div>
-                  <div class="introduce-item">5.格式:立体声或单声道</div>
-                  <div class="introduce-item">6.音频流:仅为 1</div>
-                </div>
-                <hr style="color: #eceef4; margin: 8px 10px 0 5px" />
-                <el-collapse-item name="commodity" style="padding: 0 10px 0 5px">
-                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品 </template>
-                  <div v-for="item in addedTableDataForVc2" :key="item.asin">
-                    <el-card shadow="hover" body-style="padding: 10px">
-                      <div style="padding: 10px; display: flex; align-items: center">
-                        <div style="margin-right: 8px; line-height: normal">
-                          <el-image class="img-box" :src="item.image_link" />
-                        </div>
-                        <div style="position: relative">
-                          <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
-                            <div class="double-line">{{ item.title }}</div>
-                          </el-tooltip>
-                          <span>
-                            <span style="color: #6d7784">ASIN: </span>
-                            <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
-                          </span>
-                        </div>
-                      </div>
-                    </el-card>
-                  </div>
-                </el-collapse-item>
-              </el-collapse>
-            </el-scrollbar>
-          </div>
-          <div style="width: 50%; padding: 0 10px; position: relative">
-            <el-button
-              type="primary"
-              plain
-              @click="submitForm(ruleFormRef)"
-              :disabled="!commodityCard.length && addedTableDataForVc2"
-              style="position: absolute; top: 92%; left: 46%"
-              >保存</el-button
-            >
-          </div>
-        </div>
-      </el-form>
-    </el-card>
-    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
-      <el-input :prefix-icon="Search"></el-input>
-      <div class="grid-container">
-        <div
-          class="grid-item"
-          v-for="item in cards"
-          :key="item.id"
-          @click="selectCard(item)"
-          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
-          @mouseover="hoverId = item.id"
-          @mouseleave="hoverId = null">
-          <el-card :body-style="{ padding: '0px' }">
-            <video class="image" :src="item.imageUrl" controls preload="none" @click.stop></video>
-            <div style="padding: 10px">
-              <span>
-                <el-tooltip placement="top" :content="item.title">
-                  {{ item.title }}
-                </el-tooltip>
-              </span>
-              <div class="bottom">
-                <div class="bottom-item">{{ item.size }}KB</div>
-                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
-                <div class="bottom-item">背景视频</div>
-              </div>
-            </div>
-          </el-card>
-        </div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="centerDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
 <script setup lang="ts">
 import { reactive, ref, watch, inject, Ref, onMounted } from 'vue'
 import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus'
@@ -430,6 +273,163 @@ watch(
 )
 </script>
 
+<template>
+  <div class="customize-container">
+    <el-card body-style="padding: 20px 80px 0 80px;" v-loading="loading">
+      <div style="font-weight: 700; padding-bottom: 18px">
+        <span style="color: #306cd7; font-size: 26px">|</span>
+        <span style="font-size: 18px; padding-left: 5px">创意</span>
+      </div>
+      <el-form
+        ref="ruleFormRef"
+        :model="ruleForm"
+        :rules="rules"
+        label-width="120px"
+        class="demo-ruleForm"
+        size="default"
+        label-position="top"
+        status-icon>
+        <el-form-item label="广告名称" prop="name">
+          <el-input v-model="ruleForm.name" style="width: 50%" />
+        </el-form-item>
+        <div style="display: flex; border: 1px solid #dddfe6; padding: 0 0 0 5px; margin-bottom: 20px" v-loading="createLoading">
+          <div style="width: 50%; padding-left: 5px; border-right: 1px solid #dddfe6">
+            <el-scrollbar height="700px">
+              <el-collapse v-model="activeNames" @change="handleChange" style="border-top: none; border-bottom: none">
+                <el-collapse-item name="video" style="padding: 0 10px 0 5px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>视频 </template>
+                  <div>
+                    <div style="display: flex; align-items: center; justify-content: space-between">
+                      <span style="color: #1e2128; font-size: 15px; font-weight: 450">选择视频</span>
+                      <el-button type="primary" link>查看视频批准提示</el-button>
+                    </div>
+                    <div style="color: #666666; margin-bottom: 10px">
+                      保持视频简短并紧扣主题。视频会自动播放,因此请确保前 2
+                      秒极具吸引力,并且不依靠声音来传递信息。如果您在视频中使用了文字,请确保文字清晰易辨。字幕或音频必须与将展示您广告的区域相匹配。
+                    </div>
+                    <div class="upload-button-group">
+                      <el-upload
+                        v-model:file-list="fileList"
+                        :on-change="changeFile"
+                        v-loading="upLoading"
+                        accept=".mp4, .mov"
+                        action="#"
+                        :limit="1"
+                        :auto-upload="false"
+                        :on-remove="handleRemove"
+                        class="upload-demo">
+                        <el-button type="primary">上传文件</el-button>
+
+                        <!-- <template #tip>
+                          <div class="el-upload__tip"><el-button type="primary" :icon="Picture"  :disabled="true" @click="handleSelect">从素材库中选择</el-button></div>
+                        </template> -->
+                      </el-upload>
+                      <!-- <el-button type="primary" :icon="Picture" style="margin-left: -120px" :disabled="true" @click="handleSelect">从素材库中选择</el-button> -->
+                    </div>
+                  </div>
+                </el-collapse-item>
+                <div style="display: flex; align-items: center; justify-content: space-between; padding: 0 10px 0 5px">
+                  <span style="color: #1e2128; font-size: 15px; font-weight: 450">视频文件要求:</span>
+                  <el-button type="primary" link>了解更多</el-button>
+                </div>
+                <div style="padding: 0 10px 0 5px">
+                  <span style="color: #1e2128; font-size: 13px; font-weight: 450">视频规格</span>
+                  <div class="introduce-item">1.纵横比:16:9</div>
+                  <div class="introduce-item">2.尺寸:1280 x 720 像素、1920 x 1080 像素或 3840 x 2160 像素</div>
+                  <div class="introduce-item">3.文件大小:500MB 或更小</div>
+                  <div class="introduce-item">4.文件格式:MP4 或 MOV</div>
+                  <div class="introduce-item">5.长度:6-45 秒</div>
+                  <div class="introduce-item">6.帧率:23.976、23.98、24、25、29.97 或 29.98 fps</div>
+                  <div class="introduce-item">7.比特率:1 Mbps 或更高</div>
+                  <div class="introduce-item">8.编解码器:H.264 或 H.265</div>
+                  <div class="introduce-item">9.配置文件:主配置文件或基线配置文件</div>
+                  <div class="introduce-item">10.视频流:仅为 1</div>
+                </div>
+                <div style="padding: 0 10px 0 5px">
+                  <span style="color: #1e2128; font-size: 13px; font-weight: 450">音频规格</span>
+                  <div class="introduce-item">1.语言:必须与广告投放区域匹配</div>
+                  <div class="introduce-item">2.采样率:44.1 kHz 或更高</div>
+                  <div class="introduce-item">3.编解码器:PCM、AAC 或 MP3</div>
+                  <div class="introduce-item">4.比特率:96 kbps 或更高</div>
+                  <div class="introduce-item">5.格式:立体声或单声道</div>
+                  <div class="introduce-item">6.音频流:仅为 1</div>
+                </div>
+                <hr style="color: #eceef4; margin: 8px 10px 0 5px" />
+                <el-collapse-item name="commodity" style="padding: 0 10px 0 5px">
+                  <template #title> <span style="color: #e47470; margin-right: 4px">*</span>商品 </template>
+                  <div v-for="item in addedTableDataForVc2" :key="item.asin">
+                    <el-card shadow="hover" body-style="padding: 10px">
+                      <div style="padding: 10px; display: flex; align-items: center">
+                        <div style="margin-right: 8px; line-height: normal">
+                          <el-image class="img-box" :src="item.image_link" />
+                        </div>
+                        <div style="position: relative">
+                          <el-tooltip class="box-item" effect="dark" :content="item.title" placement="top">
+                            <div class="double-line">{{ item.title }}</div>
+                          </el-tooltip>
+                          <span>
+                            <span style="color: #6d7784">ASIN: </span>
+                            <span class="data-color" style="margin-right: 8px">{{ item.asin }}</span>
+                          </span>
+                        </div>
+                      </div>
+                    </el-card>
+                  </div>
+                </el-collapse-item>
+              </el-collapse>
+            </el-scrollbar>
+          </div>
+          <div style="width: 50%; padding: 0 10px; position: relative">
+            <el-button
+              type="primary"
+              plain
+              @click="submitForm(ruleFormRef)"
+              :disabled="!commodityCard.length && addedTableDataForVc2"
+              style="position: absolute; top: 92%; left: 46%"
+              >保存</el-button
+            >
+          </div>
+        </div>
+      </el-form>
+    </el-card>
+    <el-dialog v-model="centerDialogVisible" title="从素材库中选择" width="65%">
+      <el-input :prefix-icon="Search"></el-input>
+      <div class="grid-container">
+        <div
+          class="grid-item"
+          v-for="item in cards"
+          :key="item.id"
+          @click="selectCard(item)"
+          :class="{ selected: isSelected(item.id), hover: hoverId === item.id }"
+          @mouseover="hoverId = item.id"
+          @mouseleave="hoverId = null">
+          <el-card :body-style="{ padding: '0px' }">
+            <video class="image" :src="item.imageUrl" controls preload="none" @click.stop></video>
+            <div style="padding: 10px">
+              <span>
+                <el-tooltip placement="top" :content="item.title">
+                  {{ item.title }}
+                </el-tooltip>
+              </span>
+              <div class="bottom">
+                <div class="bottom-item">{{ item.size }}KB</div>
+                <div class="bottom-item">{{ item.width }} * {{ item.height }}</div>
+                <div class="bottom-item">背景视频</div>
+              </div>
+            </div>
+          </el-card>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="centerDialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleConfirmSelection">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <style scoped>
 .customize-container {
   margin-top: 10px;

+ 23 - 23
src/views/adManage/sb/campaigns/CreateCampaigns/index.vue

@@ -1,26 +1,3 @@
-<template>
-  <div class="page-container">
-    <AdCampaign @update-campaign="handleCampaignUpdate"></AdCampaign>
-    <AdGroup @update-group-id="handleGroupIdUpdate"></AdGroup>
-    <AdFormat
-      @update:adFormatRadio="handleAdFormatRadioChange"
-      @update:arrivalsRadio="handleArrivalsRadioChange"
-      @update:flagshipStoreShop="handleFlagshipStoreShopChange"
-      @update:pageOptions="handlePageOptionsChange"
-      @update:addedTableData="handleUpdateAddedData"
-      @update:focusShopSelect="handleFocusShopSelectChange"></AdFormat>
-    
-    <ProductSetCreativity1 v-if="adFormatRadioValue === 'productSet' && arrivalsRadioValue === 'flagshipStore' && flagshipStoreShopValue === 'ZOSI'">
-    </ProductSetCreativity1>
-    <FocusCreativity v-if="adFormatRadioValue === 'focus' && focusShop === 'ENTITY2NJKG6JSUTTPB'"></FocusCreativity>
-    <VideoCreativity1 v-if="adFormatRadioValue === 'video' && arrivalsRadioValue === 'flagshipStore' && flagshipStoreShopValue === 'ZOSI'">
-    </VideoCreativity1>
-    <VideoCreativity2 v-if="adFormatRadioValue === 'video' && arrivalsRadioValue === 'productDetailsPage'"></VideoCreativity2>
-    <ProductSetCreativity2 v-if="adFormatRadioValue === 'productSet' && arrivalsRadioValue === 'newArrivals'"></ProductSetCreativity2>
-    <DeliveryType></DeliveryType>
-  </div>
-</template>
-
 <script lang="ts" setup>
 import { provide, ref, onMounted, onUnmounted} from 'vue'
 import AdCampaign from './component/AdCampaign.vue'
@@ -94,6 +71,29 @@ onMounted(()=>{
 })
 </script>
 
+<template>
+  <div class="page-container">
+    <AdCampaign @update-campaign="handleCampaignUpdate"></AdCampaign>
+    <AdGroup @update-group-id="handleGroupIdUpdate"></AdGroup>
+    <AdFormat
+      @update:adFormatRadio="handleAdFormatRadioChange"
+      @update:arrivalsRadio="handleArrivalsRadioChange"
+      @update:flagshipStoreShop="handleFlagshipStoreShopChange"
+      @update:pageOptions="handlePageOptionsChange"
+      @update:addedTableData="handleUpdateAddedData"
+      @update:focusShopSelect="handleFocusShopSelectChange"></AdFormat>
+    
+    <ProductSetCreativity1 v-if="adFormatRadioValue === 'productSet' && arrivalsRadioValue === 'flagshipStore' && flagshipStoreShopValue === 'ZOSI'">
+    </ProductSetCreativity1>
+    <FocusCreativity v-if="adFormatRadioValue === 'focus' && focusShop === 'ENTITY2NJKG6JSUTTPB'"></FocusCreativity>
+    <VideoCreativity1 v-if="adFormatRadioValue === 'video' && arrivalsRadioValue === 'flagshipStore' && flagshipStoreShopValue === 'ZOSI'">
+    </VideoCreativity1>
+    <VideoCreativity2 v-if="adFormatRadioValue === 'video' && arrivalsRadioValue === 'productDetailsPage'"></VideoCreativity2>
+    <ProductSetCreativity2 v-if="adFormatRadioValue === 'productSet' && arrivalsRadioValue === 'newArrivals'"></ProductSetCreativity2>
+    <DeliveryType></DeliveryType>
+  </div>
+</template>
+
 <style scoped>
 .page-container {
   padding: 12px;

+ 47 - 47
src/views/adManage/sb/campaigns/index.vue

@@ -1,3 +1,50 @@
+<script lang="ts" setup>
+import { onMounted, ref, watch } from 'vue'
+import { FsPage, useFs } from '@fast-crud/fast-crud'
+import { createCrudOptions } from './crud'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
+import { useRouter } from 'vue-router'
+import AdStructChart from './chartComponents/adStruct.vue'
+import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
+import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+import { SbBaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+import DataCompare from '/@/components/dataCompare/index.vue'
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange,
+})
+const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+const router = useRouter()
+const showCompare = ref(false)
+
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'SbCampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+onMounted(async () => {
+  crudExpose.doRefresh()
+})
+
+watch(
+  queryParams,
+  async () => {
+    crudExpose.doRefresh()
+  },
+  { deep: true }
+)
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -58,53 +105,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-import { onMounted, ref, watch } from 'vue'
-import { FsPage, useFs } from '@fast-crud/fast-crud'
-import { createCrudOptions } from './crud'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from '/@/stores/publicData'
-import { storeToRefs } from 'pinia'
-import { useRouter } from 'vue-router'
-import AdStructChart from './chartComponents/adStruct.vue'
-import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
-import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import { SbBaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
-import DataCompare from '/@/components/dataCompare/index.vue'
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const { dateRange } = storeToRefs(publicData)
-const { profile } = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange,
-})
-const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-const router = useRouter()
-const showCompare = ref(false)
-
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'SbCampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-onMounted(async () => {
-  crudExpose.doRefresh()
-})
-
-watch(
-  queryParams,
-  async () => {
-    crudExpose.doRefresh()
-  },
-  { deep: true }
-)
-</script>
-
 <style lang="scss" scoped>
 .compare-switch {
   flex: none;

+ 12 - 14
src/views/adManage/sb/chartComponents/dataTendency.vue

@@ -1,15 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
-      <el-radio-button label="day">日</el-radio-button>
-      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
-      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
-    </el-radio-group>
-    <div style="height: 350px;" ref="chartRef"></div>
-</div>
-</template>
-
 <script lang="ts" setup>
 import { ref,onMounted, onBeforeUnmount, Ref, unref, watch, computed } from 'vue'
 import * as echarts from 'echarts'
@@ -300,10 +288,20 @@ watch(
 const resizeChart = () => { chartObj.resize() }
 const addResize = () => { window.addEventListener('resize', resizeChart) }
 const removeResize = () => { window.removeEventListener('resize', resizeChart) }
-
-
 </script>
 
+<template>
+  <div v-loading="loading">
+    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
+      <el-radio-button label="day">日</el-radio-button>
+      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
+      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
+    </el-radio-group>
+    <div style="height: 350px;" ref="chartRef"></div>
+</div>
+</template>
+
 <style scoped>
 .metrics-cards {
   display: flex;

+ 27 - 27
src/views/adManage/sb/index.vue

@@ -1,30 +1,3 @@
-<template>
-  <div class="asj-container">
-    <div class="public-search">
-      <DateRangePicker v-model="dateRange"></DateRangePicker>
-      <el-select
-          v-model="selectedPortfolios"
-          placeholder="广告组合"
-          clearable
-          multiple
-          style="width: 400px"
-          collapse-tags
-          collapse-tags-tooltip
-          :max-collapse-tags="3"
-          disabled="true"
-      >
-        <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
-      </el-select>
-    </div>
-    <div class="asj-tabs">
-      <div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
-        {{ tab.label }}
-      </div>
-    </div>
-    <component :is="tabsComponents[tabActiveName]"></component>
-  </div>
-</template>
-
 <script lang="ts" setup>
 import { storeToRefs } from 'pinia'
 import { Ref, onBeforeMount, provide, ref } from 'vue'
@@ -71,6 +44,33 @@ onBeforeMount(async () => {
 
 </script>
 
+<template>
+  <div class="asj-container">
+    <div class="public-search">
+      <DateRangePicker v-model="dateRange"></DateRangePicker>
+      <el-select
+          v-model="selectedPortfolios"
+          placeholder="广告组合"
+          clearable
+          multiple
+          style="width: 400px"
+          collapse-tags
+          collapse-tags-tooltip
+          :max-collapse-tags="3"
+          disabled="true"
+      >
+        <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
+      </el-select>
+    </div>
+    <div class="asj-tabs">
+      <div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
+        {{ tab.label }}
+      </div>
+    </div>
+    <component :is="tabsComponents[tabActiveName]"></component>
+  </div>
+</template>
+
 <style scoped>
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);

+ 26 - 26
src/views/adManage/sb/keywords/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import * as echarts from 'echarts'
 import { storeToRefs } from 'pinia'
@@ -86,7 +61,7 @@ async function initBarData() {
   SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
   xAxisList = barData.map((item) => item.matchType)
-  console.log('🚀 ~ xAxisList', xAxisList)
+  // console.log('🚀 ~ xAxisList', xAxisList)
   const classificationMap = {
     BROAD: '关键词-广泛',
     THEME: '主题',
@@ -243,4 +218,29 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 47 - 47
src/views/adManage/sb/keywords/index.vue

@@ -1,3 +1,50 @@
+<script lang="ts" setup>
+  import { onMounted, ref, watch } from 'vue'
+  import { FsPage, useFs } from '@fast-crud/fast-crud'
+  import { createCrudOptions } from './crud'
+  import { useShopInfo } from '/@/stores/shopInfo'
+  import { usePublicData } from '/@/stores/publicData'
+  import { storeToRefs } from 'pinia'
+  import { useRouter } from 'vue-router'
+  import AdStructChart from './chartComponents/adStruct.vue'
+  import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+  import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+  import { SbBaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+  import DataCompare from '/@/components/dataCompare/index.vue'
+
+  const tabActiveName = ref('dataTendency')
+  const shopInfo = useShopInfo()
+  const publicData = usePublicData()
+  const { dateRange } = storeToRefs(publicData)
+  const { profile } = storeToRefs(shopInfo)
+  const queryParams = ref({
+    profileId: profile.value.profile_id,
+    dateRange,
+  })
+  const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+  const router = useRouter()
+  const showCompare = ref(false)
+
+  const jumpGroup = (row: any) => {
+    router.push({
+      name: 'CampaignDetail',
+      query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+    })
+  }
+
+  onMounted(() => {
+    crudExpose.doRefresh()
+  })
+
+  watch(
+    queryParams,
+    () => {
+      crudExpose.doRefresh()
+    },
+    { deep: true }
+  )
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -74,53 +121,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-  import { onMounted, ref, watch } from 'vue'
-  import { FsPage, useFs } from '@fast-crud/fast-crud'
-  import { createCrudOptions } from './crud'
-  import { useShopInfo } from '/@/stores/shopInfo'
-  import { usePublicData } from '/@/stores/publicData'
-  import { storeToRefs } from 'pinia'
-  import { useRouter } from 'vue-router'
-  import AdStructChart from './chartComponents/adStruct.vue'
-  import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-  import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-  import { SbBaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
-  import DataCompare from '/@/components/dataCompare/index.vue'
-
-  const tabActiveName = ref('dataTendency')
-  const shopInfo = useShopInfo()
-  const publicData = usePublicData()
-  const { dateRange } = storeToRefs(publicData)
-  const { profile } = storeToRefs(shopInfo)
-  const queryParams = ref({
-    profileId: profile.value.profile_id,
-    dateRange,
-  })
-  const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-  const router = useRouter()
-  const showCompare = ref(false)
-
-  const jumpGroup = (row: any) => {
-    router.push({
-      name: 'CampaignDetail',
-      query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-    })
-  }
-
-  onMounted(() => {
-    crudExpose.doRefresh()
-  })
-
-  watch(
-    queryParams,
-    () => {
-      crudExpose.doRefresh()
-    },
-    { deep: true }
-  )
-</script>
-
 <style lang="scss" scoped>
   .campare-switch {
     flex: none;

+ 25 - 25
src/views/adManage/sb/placement/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import { computed, onMounted, ref, watch } from 'vue'
 import * as echarts from 'echarts'
@@ -236,4 +211,29 @@ function resizeChart() {
 }
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 44 - 44
src/views/adManage/sb/placement/index.vue

@@ -1,3 +1,47 @@
+<script lang="ts" setup>
+import {onMounted, ref, watch} from 'vue'
+import {FsPage, useFs} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import {useRouter} from 'vue-router'
+import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
+import {useShopInfo} from '/@/stores/shopInfo'
+import AdStructChart from './chartComponents/adStruct.vue'
+import {getCardData, getLineData, getLineMonthData, getLineWeekData} from '../campaigns/api'
+import {usePublicData} from '/@/stores/publicData'
+import {storeToRefs} from 'pinia'
+import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn'
+import DataCompare from '/@/components/dataCompare/index.vue'
+
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const {dateRange} = storeToRefs(publicData)
+const {profile} = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+const {crudBinding, crudRef, crudExpose} =  useFs({createCrudOptions, context: queryParams})
+const router = useRouter()
+const showCompare = ref(false)
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: {id: row.id, campaignId: row.campaignId, tagsViewName: row.campaignName},
+  })
+}
+
+onMounted(() => {
+  crudExpose.doRefresh()
+})
+
+watch(queryParams, () => {
+  crudExpose.doRefresh()
+}, { deep: true })
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -55,50 +99,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-import {onMounted, ref, watch} from 'vue'
-import {FsPage, useFs} from '@fast-crud/fast-crud'
-import {createCrudOptions} from './crud'
-import {useRouter} from 'vue-router'
-import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
-import {useShopInfo} from '/@/stores/shopInfo'
-import AdStructChart from './chartComponents/adStruct.vue'
-import {getCardData, getLineData, getLineMonthData, getLineWeekData} from '../campaigns/api'
-import {usePublicData} from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
-import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn'
-import DataCompare from '/@/components/dataCompare/index.vue'
-
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const {dateRange} = storeToRefs(publicData)
-const {profile} = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-const {crudBinding, crudRef, crudExpose} =  useFs({createCrudOptions, context: queryParams})
-const router = useRouter()
-const showCompare = ref(false)
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: {id: row.id, campaignId: row.campaignId, tagsViewName: row.campaignName},
-  })
-}
-
-onMounted(() => {
-  crudExpose.doRefresh()
-})
-
-watch(queryParams, () => {
-  crudExpose.doRefresh()
-}, { deep: true })
-
-</script>
-
 <style lang="scss" scoped>
 .chart-tabs {
   margin: 5px 0;

+ 45 - 45
src/views/adManage/sb/searchTerm/index.vue

@@ -1,3 +1,48 @@
+<script lang="ts" setup>
+import {onMounted, ref, watch} from 'vue'
+import {FsPage, useFs} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
+import {getCardData, getLineData, getLineMonthData, getLineWeekData} from './api'
+import {useShopInfo} from '/@/stores/shopInfo'
+import {usePublicData} from '/@/stores/publicData'
+import {storeToRefs} from 'pinia'
+import {BaseColumn} from '/@/views/adManage/utils/commonTabColumn.js'
+import DataCompare from '/@/components/dataCompare/index.vue'
+import router from '/@/router'
+
+const tabActiveName = ref("dataTendency")
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
+const showCompare = ref(false)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+onMounted(async () => {
+	crudExpose.doRefresh()
+})
+watch(
+	queryParams,
+	async () => {
+		crudExpose.doRefresh()
+	},
+  { deep: true }
+)
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -59,51 +104,6 @@
 	</fs-page>
 </template>
 
-<script lang="ts" setup>
-import {onMounted, ref, watch} from 'vue'
-import {FsPage, useFs} from '@fast-crud/fast-crud'
-import {createCrudOptions} from './crud'
-import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
-import {getCardData, getLineData, getLineMonthData, getLineWeekData} from './api'
-import {useShopInfo} from '/@/stores/shopInfo'
-import {usePublicData} from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
-import {BaseColumn} from '/@/views/adManage/utils/commonTabColumn.js'
-import DataCompare from '/@/components/dataCompare/index.vue'
-import router from '/@/router'
-
-const tabActiveName = ref("dataTendency")
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const { dateRange } = storeToRefs(publicData)
-const { profile } = storeToRefs(shopInfo)
-const showCompare = ref(false)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-onMounted(async () => {
-	crudExpose.doRefresh()
-})
-watch(
-	queryParams,
-	async () => {
-		crudExpose.doRefresh()
-	},
-  { deep: true }
-)
-
-</script>
-
 <style scoped>
 .campare-switch {
   flex: none;

+ 25 - 25
src/views/adManage/sb/targets/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import { onMounted, ref, inject, computed, watch } from 'vue'
 import * as echarts from 'echarts'
@@ -234,4 +209,29 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 7 - 7
src/views/adManage/sb/targets/chartComponents/dataTendency.vue

@@ -1,10 +1,3 @@
-<template>
-    <div v-loading="loading">
-        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-        <div style="height: 350px;" ref="chartRef"></div>
-    </div>
-</template>
-
 <script lang="ts" setup>
 import {ref, onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed} from 'vue'
 import * as echarts from 'echarts'
@@ -250,6 +243,13 @@ const removeResize = () => {
 
 </script>
 
+<template>
+    <div v-loading="loading">
+        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+        <div style="height: 350px;" ref="chartRef"></div>
+    </div>
+</template>
+
 <style scoped>
 .metrics-cards {
     display: flex;

+ 66 - 66
src/views/adManage/sb/targets/index.vue

@@ -1,69 +1,3 @@
-<script lang="ts" setup>
-import { Picture as IconPicture } from '@element-plus/icons-vue'
-import { FsPage, useFs } from '@fast-crud/fast-crud'
-import { storeToRefs } from 'pinia'
-import { nextTick, onMounted, ref, watch } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import AdStructChart from './chartComponents/adStruct.vue'
-import { createCrudOptions } from './crud'
-import DataCompare from '/@/components/dataCompare/index.vue'
-import { usePublicData } from '/@/stores/publicData'
-import { useShopInfo } from '/@/stores/shopInfo'
-import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
-import { SbBaseColumn } from '/@/views/adManage/utils/commonTabColumn'
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const { dateRange } = storeToRefs(publicData)
-const { profile } = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange,
-})
-
-const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-const route = useRoute()
-const router = useRouter()
-const adStructChartRef = ref()
-const dataTendencyRef = ref()
-const showCompare = ref(false)
-
-onMounted(() => {
-  crudExpose.doRefresh()
-})
-
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-const resizeTabChart = () => {
-  if (tabActiveName.value === 'dataTendency') {
-    dataTendencyRef.value.resizeChart()
-  } else if (tabActiveName.value === 'adStruct') {
-    adStructChartRef.value.resizeChart()
-  }
-}
-const changeTab = () => {
-  nextTick(() => {
-    resizeTabChart()
-  })
-}
-defineExpose({ resizeTabChart })
-
-watch(
-  queryParams,
-  async () => {
-    crudExpose.doRefresh()
-  },
-  { deep: true }
-)
-</script>
-
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -165,6 +99,72 @@ watch(
   </fs-page>
 </template>
 
+<script lang="ts" setup>
+import { Picture as IconPicture } from '@element-plus/icons-vue'
+import { FsPage, useFs } from '@fast-crud/fast-crud'
+import { storeToRefs } from 'pinia'
+import { nextTick, onMounted, ref, watch } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+import AdStructChart from './chartComponents/adStruct.vue'
+import { createCrudOptions } from './crud'
+import DataCompare from '/@/components/dataCompare/index.vue'
+import { usePublicData } from '/@/stores/publicData'
+import { useShopInfo } from '/@/stores/shopInfo'
+import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
+import { SbBaseColumn } from '/@/views/adManage/utils/commonTabColumn'
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange,
+})
+
+const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+const route = useRoute()
+const router = useRouter()
+const adStructChartRef = ref()
+const dataTendencyRef = ref()
+const showCompare = ref(false)
+
+onMounted(() => {
+  crudExpose.doRefresh()
+})
+
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+const resizeTabChart = () => {
+  if (tabActiveName.value === 'dataTendency') {
+    dataTendencyRef.value.resizeChart()
+  } else if (tabActiveName.value === 'adStruct') {
+    adStructChartRef.value.resizeChart()
+  }
+}
+const changeTab = () => {
+  nextTick(() => {
+    resizeTabChart()
+  })
+}
+defineExpose({ resizeTabChart })
+
+watch(
+  queryParams,
+  async () => {
+    crudExpose.doRefresh()
+  },
+  { deep: true }
+)
+</script>
+
 <style lang="scss" scoped>
 .campare-switch {
   flex: none;

+ 113 - 107
src/views/adManage/sd/chartComponents/dataTendency.vue

@@ -1,50 +1,37 @@
-<template>
-  <div v-loading="loading">
-    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
-      <el-radio-button label="hour" :disabled="!props.fetchLineHour">时</el-radio-button>
-      <el-radio-button label="day">日</el-radio-button>
-      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
-      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
-    </el-radio-group>
-    <div style="height: 350px;" ref="chartRef"></div>
-</div>
-</template>
-
 <script lang="ts" setup>
-import {computed, onBeforeUnmount, onMounted, Ref, ref, watch} from 'vue'
+import { computed, onBeforeUnmount, onMounted, Ref, ref, watch } from 'vue'
 import * as echarts from 'echarts'
-import {sdCampaignMetricsEnum} from '/@/views/adManage/utils/enum.js'
+import { sdCampaignMetricsEnum } from '/@/views/adManage/utils/enum.js'
 import MetricsCards from '/@/components/MetricsCards/index.vue'
 import XEUtils from 'xe-utils'
-import {buildChartOpt, parseQueryParams} from '/@/views/adManage/utils/tools.js'
+import { buildChartOpt, parseQueryParams } from '/@/views/adManage/utils/tools.js'
 
 // import { useShopInfo } from '/@/stores/shopInfo'
 // import { usePublicData } from '/@/stores/publicData'
 // import { storeToRefs } from 'pinia'
 
 defineOptions({
-  name: "DataTendencyChart"
+  name: 'DataTendencyChart',
 })
 
 interface Props {
-  fetchCard: Function,
-  fetchLine: Function,
-  fetchLineMonth?: Function,
-  fetchLineWeek?: Function,
-  fetchLineHour?: Function,
-  query: {[key: string]: any},
-  initMetric?: ShowMetric[],
-  metricEnum?: {[key: string]: string}[]
+  fetchCard: Function
+  fetchLine: Function
+  fetchLineMonth?: Function
+  fetchLineWeek?: Function
+  fetchLineHour?: Function
+  query: { [key: string]: any }
+  initMetric?: ShowMetric[]
+  metricEnum?: { [key: string]: string }[]
 }
 
 const props = withDefaults(defineProps<Props>(), {
   initMetric: () => [
-    {metric: 'Impression', color: '#0085ff', 'label': '曝光量'},
-    {metric: 'Click', color: '#3fd4cf', 'label': '点击量'},
-    {metric: 'Spend', color: '#ff9500', 'label': '花费'},
+    { metric: 'Impression', color: '#0085ff', label: '曝光量' },
+    { metric: 'Click', color: '#3fd4cf', label: '点击量' },
+    { metric: 'Spend', color: '#ff9500', label: '花费' },
   ],
-  metricEnum: () => sdCampaignMetricsEnum
+  metricEnum: () => sdCampaignMetricsEnum,
 })
 
 const metrics = ref(props.initMetric)
@@ -52,30 +39,33 @@ const metrics = ref(props.initMetric)
 // const publicData = usePublicData()
 // const { dateRange } = storeToRefs(publicData)
 const metricsItems: Ref<MetricData[]> = ref([])
-let chartObj:any
+let chartObj: any
 const chartRef = ref()
 const statDim = ref('day')
 const option: any = {
   dataset: {
-    source: []
+    source: [],
   },
   tooltip: {
     trigger: 'axis',
     axisPointer: {
       label: {
-        backgroundColor: '#6a7985'
-      }
-    }
+        backgroundColor: '#6a7985',
+      },
+    },
   },
   legend: {
-    selected: {},  // 控制显隐
-    show: false
+    selected: {}, // 控制显隐
+    show: false,
   },
   grid: {
-    top: 50, right: 150, bottom: 30, left: 65,
+    top: 50,
+    right: 150,
+    bottom: 30,
+    left: 65,
   },
   xAxis: {
-    type: 'category'
+    type: 'category',
   },
   yAxis: [
     {
@@ -84,13 +74,13 @@ const option: any = {
       type: 'value',
       name: '',
       splitLine: {
-        show: true // 设置显示分割线
+        show: true, // 设置显示分割线
       },
       axisLine: {
         show: true,
-				lineStyle: { color: '' }
+        lineStyle: { color: '' },
       },
-      show: true
+      show: true,
     },
     {
       id: 1,
@@ -99,15 +89,15 @@ const option: any = {
       name: '',
       position: 'right',
       splitLine: {
-        show: false
+        show: false,
       },
       axisLine: {
         show: true,
-				lineStyle: {
-					color: ''
-				}
+        lineStyle: {
+          color: '',
+        },
       },
-      show: true
+      show: true,
     },
     {
       id: 2,
@@ -117,16 +107,16 @@ const option: any = {
       offset: 90,
       name: '',
       splitLine: {
-        show: false
+        show: false,
       },
       axisLine: {
         show: true,
-				lineStyle: {
-					color: ''
-				}
+        lineStyle: {
+          color: '',
+        },
       },
-      show: true
-    }
+      show: true,
+    },
   ],
   series: [
     {
@@ -135,14 +125,14 @@ const option: any = {
       type: 'bar',
       encode: {
         x: 'Name',
-        y: ''
+        y: '',
       },
       barWidth: '18px',
       yAxisIndex: 0,
       itemStyle: {
         color: '',
         borderRadius: 4,
-      }
+      },
     },
     {
       id: 1,
@@ -150,7 +140,7 @@ const option: any = {
       type: 'line',
       encode: {
         x: 'Name',
-        y: ''
+        y: '',
       },
       symbolSize: 6,
       symbol: 'circle',
@@ -167,8 +157,8 @@ const option: any = {
         // ]),
       },
       emphasis: {
-        focus:'series'
-      }
+        focus: 'series',
+      },
     },
     {
       id: 2,
@@ -176,7 +166,7 @@ const option: any = {
       type: 'line',
       encode: {
         x: 'Name',
-        y: ''
+        y: '',
       },
       symbolSize: 6,
       symbol: 'circle',
@@ -185,34 +175,36 @@ const option: any = {
       itemStyle: {},
       areaStyle: {},
       emphasis: {
-        focus:'series'
-      }
-    }
-  ]
+        focus: 'series',
+      },
+    },
+  ],
 }
 const loading = ref(true)
 const queryParams = computed(() => parseQueryParams(props.query))
 
 onMounted(() => {
   getMetricsItems()
-	addResize()
+  addResize()
   // initLine()
-  setTimeout(() => { initLine() }, 0)
+  setTimeout(() => {
+    initLine()
+  }, 0)
 })
 onBeforeUnmount(() => {
-	if(chartObj) {
-		chartObj.dispose()
+  if (chartObj) {
+    chartObj.dispose()
     chartObj = null
-	}
+  }
   removeResize()
 })
 
 const initLine = async () => {
-	chartObj = echarts.init(chartRef.value)
-	const items = await getDataset()
-	option.dataset.source = items
+  chartObj = echarts.init(chartRef.value)
+  const items = await getDataset()
+  option.dataset.source = items
 
-  XEUtils.arrayEach(option.series, (info:any, index) => {
+  XEUtils.arrayEach(option.series, (info: any, index) => {
     const color = metrics.value[index].color
     info.name = metrics.value[index].label
     info.encode.y = metrics.value[index].metric
@@ -224,27 +216,27 @@ const initLine = async () => {
         color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
           { offset: 0, color: color + '53' },
           { offset: 1, color: color + '03' },
-        ])
+        ]),
       }
     }
   })
-  XEUtils.arrayEach(option.yAxis, (info:any, index) => {
+  XEUtils.arrayEach(option.yAxis, (info: any, index) => {
     info.name = metrics.value[index].label
     info.axisLine.lineStyle.color = metrics.value[index].color
   })
 
-  XEUtils.arrayEach(props.metricEnum, info => {
+  XEUtils.arrayEach(props.metricEnum, (info) => {
     option.legend.selected[info.label] = false
   })
-  for(const info of metrics.value) {
+  for (const info of metrics.value) {
     option.legend.selected[info.label] = true
   }
   // console.log(option)
-	chartObj.setOption(option)
+  chartObj.setOption(option)
   loading.value = false
 }
 const getDataset = async () => {
-	if (statDim.value === 'week') {
+  if (statDim.value === 'week') {
     if (props.fetchLineWeek) {
       const resp = await props.fetchLineWeek(queryParams.value)
       return resp.data
@@ -265,19 +257,19 @@ const getDataset = async () => {
   }
 }
 const getMetricsItems = async () => {
-	const resp = await props.fetchCard(queryParams.value)
-	const data = resp.data
+  const resp = await props.fetchCard(queryParams.value)
+  const data = resp.data
   metricsItems.value.length = 0
-	XEUtils.arrayEach(props.metricEnum, info => {
-		const tmp:MetricData = {
-			label: info.label,
-			value: info.value,
-			metricVal: data[info.value],
-			gapVal: data[`gap${info.value}`],
-			preVal: data[`prev${info.value}`],
-		}
-		metricsItems.value.push(tmp)
-	})
+  XEUtils.arrayEach(props.metricEnum, (info) => {
+    const tmp: MetricData = {
+      label: info.label,
+      value: info.value,
+      metricVal: data[info.value],
+      gapVal: data[`gap${info.value}`],
+      preVal: data[`prev${info.value}`],
+    }
+    metricsItems.value.push(tmp)
+  })
 }
 
 const changeMetric = () => {
@@ -289,31 +281,45 @@ const changeStatDim = async () => {
   loading.value = true
   let source = await getDataset()
   if (source.length > 0) {
-    chartObj.setOption({dataset: {source: source}})
+    chartObj.setOption({ dataset: { source: source } })
   }
   loading.value = false
 }
 
-watch(
-  props.query,
-  async () => {
-    // console.log("------watch-----queryParams", props.query)
-    loading.value = true
-    await getMetricsItems()
-    const items = await getDataset()
-    const opt = { dataset: { source: items } }
-    chartObj.setOption(opt)
-    loading.value = false
-  }
-)
-
-const resizeChart = () => { chartObj.resize() }
-const addResize = () => { window.addEventListener('resize', resizeChart) }
-const removeResize = () => { window.removeEventListener('resize', resizeChart) }
-
+watch(props.query, async () => {
+  // console.log("------watch-----queryParams", props.query)
+  loading.value = true
+  await getMetricsItems()
+  const items = await getDataset()
+  const opt = { dataset: { source: items } }
+  chartObj.setOption(opt)
+  loading.value = false
+})
 
+const resizeChart = () => {
+  chartObj.resize()
+}
+const addResize = () => {
+  window.addEventListener('resize', resizeChart)
+}
+const removeResize = () => {
+  window.removeEventListener('resize', resizeChart)
+}
 </script>
 
+<template>
+  <div v-loading="loading">
+    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
+      <el-radio-button label="hour" :disabled="!props.fetchLineHour">时</el-radio-button>
+      <el-radio-button label="day">日</el-radio-button>
+      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
+      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
+    </el-radio-group>
+    <div style="height: 350px" ref="chartRef"></div>
+  </div>
+</template>
+
 <style scoped>
 .metrics-cards {
   display: flex;

+ 27 - 27
src/views/adManage/sd/index.vue

@@ -1,30 +1,3 @@
-<template>
-  <div class="asj-container">
-    <div class="public-search">
-      <DateRangePicker v-model="dateRange"></DateRangePicker>
-      <el-select
-        v-model="selectedPortfolios"
-        placeholder="广告组合"
-        clearable
-        multiple
-        style="width: 400px"
-        collapse-tags
-        collapse-tags-tooltip
-        :max-collapse-tags="3"
-        disabled="true"
-        >
-        <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
-      </el-select>
-    </div>
-    <div class="asj-tabs">
-      <div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
-        {{ tab.label }}
-      </div>
-    </div>
-    <component :is="tabsComponents[tabActiveName]"></component>
-  </div>
-</template>
-
 <script lang="ts" setup>
 import { storeToRefs } from 'pinia'
 import { Ref, onBeforeMount, provide, ref } from 'vue'
@@ -72,6 +45,33 @@ onBeforeMount(async () => {
 })
 </script>
 
+<template>
+  <div class="asj-container">
+    <div class="public-search">
+      <DateRangePicker v-model="dateRange"></DateRangePicker>
+      <el-select
+        v-model="selectedPortfolios"
+        placeholder="广告组合"
+        clearable
+        multiple
+        style="width: 400px"
+        collapse-tags
+        collapse-tags-tooltip
+        :max-collapse-tags="3"
+        disabled="true"
+        >
+        <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
+      </el-select>
+    </div>
+    <div class="asj-tabs">
+      <div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
+        {{ tab.label }}
+      </div>
+    </div>
+    <component :is="tabsComponents[tabActiveName]"></component>
+  </div>
+</template>
+
 <style scoped>
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);

+ 25 - 25
src/views/adManage/sd/matchedDelivery/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import { onMounted, ref, inject, computed, watch } from 'vue'
 import * as echarts from 'echarts'
@@ -242,4 +217,29 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 206 - 208
src/views/adManage/sd/matchedDelivery/chartComponents/dataTendency.vue

@@ -1,261 +1,259 @@
-<template>
-    <div v-loading="loading">
-        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-        <div style="height: 350px;" ref="chartRef"></div>
-    </div>
-</template>
-
 <script lang="ts" setup>
-import {ref, onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed} from 'vue'
+import { ref, onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed } from 'vue'
 import * as echarts from 'echarts'
-import {useShopInfo} from '/@/stores/shopInfo'
-import {getLineData, getCardData} from '../api'
-import {spCampaignMetricsEnum} from '/@/views/adManage/utils/enum.js'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { getLineData, getCardData } from '../api'
+import { spCampaignMetricsEnum } from '/@/views/adManage/utils/enum.js'
 import MetricsCards from '/@/components/MetricsCards/index.vue'
 import XEUtils from 'xe-utils'
-import {buildChartOpt} from '/@/views/adManage/utils/tools.js'
-import {usePublicData} from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
+import { buildChartOpt } from '/@/views/adManage/utils/tools.js'
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
 
 defineOptions({
-    name: 'DataTendencyChart'
+  name: 'DataTendencyChart',
 })
 
 onMounted(() => {
-    getMetricsItems()
-    addResize()
-    // initLine()
-    setTimeout(() => {
-        initLine()
-    }, 0)
+  getMetricsItems()
+  addResize()
+  // initLine()
+  setTimeout(() => {
+    initLine()
+  }, 0)
 })
 onBeforeUnmount(() => {
-    if (chartObj) {
-        chartObj.dispose()
-        chartObj = null
-    }
-    removeResize()
+  if (chartObj) {
+    chartObj.dispose()
+    chartObj = null
+  }
+  removeResize()
 })
 
 const publicData = usePublicData()
 const metrics = ref([
-    {metric: 'Impression', color: '#0085ff', 'label': '曝光量'},
-    {metric: 'Click', color: '#3fd4cf', 'label': '点击量'},
-    {metric: 'Spend', color: '#ff9500', 'label': '花费'},
+  { metric: 'Impression', color: '#0085ff', label: '曝光量' },
+  { metric: 'Click', color: '#3fd4cf', label: '点击量' },
+  { metric: 'Spend', color: '#ff9500', label: '花费' },
 ])
 const shopInfo = useShopInfo()
 const metricsItems: Ref<MetricData[]> = ref([])
 let chartObj: any
 const chartRef = ref()
 const option: any = {
-    dataset: {
-        source: []
+  dataset: {
+    source: [],
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      label: {
+        backgroundColor: '#6a7985',
+      },
     },
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            label: {
-                backgroundColor: '#6a7985'
-            }
-        }
+  },
+  legend: {
+    selected: {}, // 控制显隐
+    show: false,
+  },
+  grid: {
+    top: 50,
+    right: 150,
+    bottom: 30,
+    left: 55,
+  },
+  xAxis: {
+    type: 'category',
+  },
+  yAxis: [
+    {
+      id: 0,
+      type: 'value',
+      name: '曝光量',
+      splitLine: {
+        show: true, // 设置显示分割线
+      },
+      axisLine: {
+        show: true,
+        lineStyle: {
+          color: '#0085ff',
+        },
+      },
+      show: true,
     },
-    legend: {
-        selected: {},  // 控制显隐
-        show: false
+    {
+      id: 1,
+      type: 'value',
+      name: '点击量',
+      position: 'right',
+      splitLine: {
+        show: false,
+      },
+      axisLine: {
+        show: true,
+        lineStyle: {
+          color: '#3fd4cf',
+        },
+      },
+      show: true,
     },
-    grid: {
-        top: 50, right: 150, bottom: 30, left: 55,
+    {
+      id: 2,
+      type: 'value',
+      position: 'right',
+      offset: 90,
+      name: '花费',
+      splitLine: {
+        show: false,
+      },
+      axisLine: {
+        show: true,
+        lineStyle: {
+          color: '#ff9500',
+        },
+      },
+      show: true,
     },
-    xAxis: {
-        type: 'category'
+  ],
+  series: [
+    {
+      id: 0,
+      name: '曝光量',
+      type: 'bar',
+      encode: {
+        x: 'date',
+        y: 'Impression',
+      },
+      barWidth: '20px',
+      yAxisIndex: 0,
+      itemStyle: {
+        color: '#0085ff',
+        borderRadius: [6, 6, 6, 6],
+      },
     },
-    yAxis: [
-        {
-            id: 0,
-            type: 'value',
-            name: '曝光量',
-            splitLine: {
-                show: true // 设置显示分割线
-            },
-            axisLine: {
-                show: true,
-                lineStyle: {
-                    color: '#0085ff'
-                }
-            },
-            show: true
-        },
-        {
-            id: 1,
-            type: 'value',
-            name: '点击量',
-            position: 'right',
-            splitLine: {
-                show: false
-            },
-            axisLine: {
-                show: true,
-                lineStyle: {
-                    color: '#3fd4cf'
-                }
-            },
-            show: true
-        },
-        {
-            id: 2,
-            type: 'value',
-            position: 'right',
-            offset: 90,
-            name: '花费',
-            splitLine: {
-                show: false
-            },
-            axisLine: {
-                show: true,
-                lineStyle: {
-                    color: '#ff9500'
-                }
-            },
-            show: true
-        }
-    ],
-    series: [
-        {
-            id: 0,
-            name: '曝光量',
-            type: 'bar',
-            encode: {
-                x: 'date',
-                y: 'Impression'
-            },
-            barWidth: '20px',
-            yAxisIndex: 0,
-            itemStyle: {
-                color: '#0085ff',
-                borderRadius: [6, 6, 6, 6],
-            }
-        },
-        {
-            id: 1,
-            name: '点击量',
-            type: 'line',
-            encode: {
-                x: 'date',
-                y: 'Click'
-            },
-            symbolSize: 6,
-            symbol: 'circle',
-            smooth: true,
-            yAxisIndex: 1,
-            itemStyle: {color: '#3fd4cf', borderColor: '#3fd4cf'},
-            areaStyle: {
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                    {offset: 0, color: '#3fd4cf53'},
-                    {offset: 1, color: '#3fd4cf03'},
-                ]),
-            },
-            emphasis: {
-                focus: 'series'
-            }
-        },
-        {
-            id: 2,
-            name: '花费',
-            type: 'line',
-            encode: {
-                x: 'date',
-                y: 'Spend'
-            },
-            symbolSize: 6,
-            symbol: 'circle',
-            smooth: true,
-            yAxisIndex: 2,
-            itemStyle: {color: '#ff9500', borderColor: '#ff9500'},
-            areaStyle: {
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                    {offset: 0, color: '#ff950053'},
-                    {offset: 1, color: '#ff950003'},
-                ]),
-            },
-            emphasis: {
-                focus: 'series'
-            }
-        }
-    ]
+    {
+      id: 1,
+      name: '点击量',
+      type: 'line',
+      encode: {
+        x: 'date',
+        y: 'Click',
+      },
+      symbolSize: 6,
+      symbol: 'circle',
+      smooth: true,
+      yAxisIndex: 1,
+      itemStyle: { color: '#3fd4cf', borderColor: '#3fd4cf' },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          { offset: 0, color: '#3fd4cf53' },
+          { offset: 1, color: '#3fd4cf03' },
+        ]),
+      },
+      emphasis: {
+        focus: 'series',
+      },
+    },
+    {
+      id: 2,
+      name: '花费',
+      type: 'line',
+      encode: {
+        x: 'date',
+        y: 'Spend',
+      },
+      symbolSize: 6,
+      symbol: 'circle',
+      smooth: true,
+      yAxisIndex: 2,
+      itemStyle: { color: '#ff9500', borderColor: '#ff9500' },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          { offset: 0, color: '#ff950053' },
+          { offset: 1, color: '#ff950003' },
+        ]),
+      },
+      emphasis: {
+        focus: 'series',
+      },
+    },
+  ],
 }
-const {dateRange} = storeToRefs(publicData)
+const { dateRange } = storeToRefs(publicData)
 const loading = ref(true)
 
 const getDataset = async () => {
-    const resp = await getLineData({profile: shopInfo.profile.profile_id, start: dateRange.value[0], end: dateRange.value[1]})
-    return resp.data
+  const resp = await getLineData({ profile: shopInfo.profile.profile_id, start: dateRange.value[0], end: dateRange.value[1] })
+  return resp.data
 }
 const initLine = async () => {
-    chartObj = echarts.init(chartRef.value)
-    const items = await getDataset()
-    option.dataset.source = items
-    XEUtils.arrayEach(metricsItems.value, info => {
-        option.legend.selected[info.label] = false
-    })
-    for (const info of metrics.value) {
-        option.legend.selected[info.label] = true
-    }
-    chartObj.setOption(option)
-    loading.value = false
+  chartObj = echarts.init(chartRef.value)
+  const items = await getDataset()
+  option.dataset.source = items
+  XEUtils.arrayEach(metricsItems.value, (info) => {
+    option.legend.selected[info.label] = false
+  })
+  for (const info of metrics.value) {
+    option.legend.selected[info.label] = true
+  }
+  chartObj.setOption(option)
+  loading.value = false
 }
 
 const getMetricsItems = async () => {
-    const resp = await getCardData({start: dateRange.value[0], end: dateRange.value[1], profile: shopInfo.profile.profile_id})
-    const data = resp.data
-    metricsItems.value.length = 0
-    XEUtils.arrayEach(spCampaignMetricsEnum, info => {
-        const tmp: MetricData = {
-            label: info.label,
-            value: info.value,
-            metricVal: data[info.value],
-            gapVal: data[`gap${info.value}`],
-            preVal: data[`prev${info.value}`],
-        }
-        metricsItems.value.push(tmp)
-    })
+  const resp = await getCardData({ start: dateRange.value[0], end: dateRange.value[1], profile: shopInfo.profile.profile_id })
+  const data = resp.data
+  metricsItems.value.length = 0
+  XEUtils.arrayEach(spCampaignMetricsEnum, (info) => {
+    const tmp: MetricData = {
+      label: info.label,
+      value: info.value,
+      metricVal: data[info.value],
+      gapVal: data[`gap${info.value}`],
+      preVal: data[`prev${info.value}`],
+    }
+    metricsItems.value.push(tmp)
+  })
 }
 
 const changeMetric = () => {
-    const opt = buildChartOpt(option, metrics.value)
-    chartObj.setOption(opt)
+  const opt = buildChartOpt(option, metrics.value)
+  chartObj.setOption(opt)
 }
 
-watch(
-        dateRange,
-        async () => {
-            loading.value = true
-            await getMetricsItems()
-            const items = await getDataset()
-            const opt = {dataset: {source: items}}
-            chartObj.setOption(opt)
-            loading.value = false
-        }
-)
+watch(dateRange, async () => {
+  loading.value = true
+  await getMetricsItems()
+  const items = await getDataset()
+  const opt = { dataset: { source: items } }
+  chartObj.setOption(opt)
+  loading.value = false
+})
 
 const resizeChart = () => {
-    chartObj.resize()
+  chartObj.resize()
 }
 const addResize = () => {
-    window.addEventListener('resize', resizeChart)
+  window.addEventListener('resize', resizeChart)
 }
 const removeResize = () => {
-    window.removeEventListener('resize', resizeChart)
+  window.removeEventListener('resize', resizeChart)
 }
-
-
 </script>
 
+<template>
+  <div v-loading="loading">
+    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+    <div style="height: 350px" ref="chartRef"></div>
+  </div>
+</template>
+
 <style scoped>
 .metrics-cards {
-    display: flex;
-    justify-content: space-between;
-    align-items: flex-start;
-    gap: 12px;
-    width: 100%;
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  gap: 12px;
+  width: 100%;
 }
 </style>

+ 25 - 25
src/views/adManage/sd/promoteProducts/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import { onMounted, ref, inject, computed, watch } from 'vue'
 import * as echarts from 'echarts'
@@ -242,4 +217,29 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 15 - 16
src/views/adManage/sd/targets/chartComponents/adStruct.vue

@@ -1,19 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span style="background: #f19a37; width: 18px; height: 10px; margin-top: 8px; margin-left: 20px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import * as echarts from 'echarts'
 import { computed, inject, onMounted, ref, watch } from 'vue'
@@ -238,4 +222,19 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span style="background: #f19a37; width: 18px; height: 10px; margin-top: 8px; margin-left: 20px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
 <style scoped></style>

+ 7 - 7
src/views/adManage/sd/targets/chartComponents/dataTendency.vue

@@ -1,10 +1,3 @@
-<template>
-    <div v-loading="loading">
-        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-        <div style="height: 350px;" ref="chartRef"></div>
-    </div>
-</template>
-
 <script lang="ts" setup>
 import {ref, onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed} from 'vue'
 import * as echarts from 'echarts'
@@ -250,6 +243,13 @@ const removeResize = () => {
 
 </script>
 
+<template>
+    <div v-loading="loading">
+        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+        <div style="height: 350px;" ref="chartRef"></div>
+    </div>
+</template>
+
 <style scoped>
 .metrics-cards {
     display: flex;

+ 59 - 59
src/views/adManage/sp/advertisedProducts/index.vue

@@ -1,62 +1,3 @@
-<template>
-  <fs-page class="fs-page-custom">
-    <fs-crud ref="crudRef" v-bind="crudBinding">
-      <template #header-middle>
-        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card" @tab-change="changeTab">
-          <el-tab-pane label="数据趋势" name="dataTendency">
-            <DataTendencyChart
-                v-if="tabActiveName === 'dataTendency'"
-                :query="queryParams"
-                :fetchCard="getCardData"
-                :fetch-line-month="getLineMonthData"
-							  :fetch-line-week="getLineWeekData"
-                :fetchLine="getLineData">
-            </DataTendencyChart>
-          </el-tab-pane>
-          <el-tab-pane label="散点视图" name="scatterView" :lazy="true"></el-tab-pane>
-        </el-tabs>
-      </template>
-
-      <template #cell_asin="scope">
-        <el-tooltip  effect="dark" :content="scope.row.asin" placement="top">
-          <el-link :underline="false" @click="jumpGroup(scope.row)">
-            <div class="en-text">{{ scope.row.asin }}</div>
-          </el-link>
-        </el-tooltip>
-      </template>
-      <template #cell_campaignName="scope">
-        <el-tooltip  effect="dark" :content="scope.row.campaignName" placement="top">
-          <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">
-            <div class="en-text">{{ scope.row.campaignName }}</div>
-          </el-link>
-        </el-tooltip>
-      </template>
-      <template #cell_adGroupName="scope">
-        <el-tooltip  effect="dark" :content="scope.row.adGroupName" placement="top">
-          <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">
-            <div class="en-text">{{ scope.row.adGroupName }}</div>
-          </el-link>
-        </el-tooltip>
-      </template>
-      <template v-for="field of Object.keys(SbBaseColumn)" #[`cell_${field}`]="scope">
-        <DataCompare
-            :field="field"
-            :value="scope.row[field]"
-            :prev-val="scope.row[`prev${field}`]"
-            :gap-val="scope.row[`gap${field}`]"
-            :date-range="dateRange"
-            :show-compare="showCompare"/>
-      </template>
-      <template #toolbar-left>
-        <div class="campare-switch">
-          <span>数据对比 </span>
-          <el-switch v-model="showCompare" size="small" />
-        </div>
-      </template>
-    </fs-crud>
-  </fs-page>
-</template>
-
 <script lang="ts" setup>
 import {nextTick, onMounted, ref, watch} from 'vue'
 import {FsPage, useFs} from '@fast-crud/fast-crud'
@@ -117,6 +58,65 @@ watch(queryParams, async () => {
 
 </script>
 
+<template>
+  <fs-page class="fs-page-custom">
+    <fs-crud ref="crudRef" v-bind="crudBinding">
+      <template #header-middle>
+        <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card" @tab-change="changeTab">
+          <el-tab-pane label="数据趋势" name="dataTendency">
+            <DataTendencyChart
+                v-if="tabActiveName === 'dataTendency'"
+                :query="queryParams"
+                :fetchCard="getCardData"
+                :fetch-line-month="getLineMonthData"
+							  :fetch-line-week="getLineWeekData"
+                :fetchLine="getLineData">
+            </DataTendencyChart>
+          </el-tab-pane>
+          <el-tab-pane label="散点视图" name="scatterView" :lazy="true"></el-tab-pane>
+        </el-tabs>
+      </template>
+
+      <template #cell_asin="scope">
+        <el-tooltip  effect="dark" :content="scope.row.asin" placement="top">
+          <el-link :underline="false" @click="jumpGroup(scope.row)">
+            <div class="en-text">{{ scope.row.asin }}</div>
+          </el-link>
+        </el-tooltip>
+      </template>
+      <template #cell_campaignName="scope">
+        <el-tooltip  effect="dark" :content="scope.row.campaignName" placement="top">
+          <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">
+            <div class="en-text">{{ scope.row.campaignName }}</div>
+          </el-link>
+        </el-tooltip>
+      </template>
+      <template #cell_adGroupName="scope">
+        <el-tooltip  effect="dark" :content="scope.row.adGroupName" placement="top">
+          <el-link type="primary" :underline="false" @click="jumpGroup(scope.row)">
+            <div class="en-text">{{ scope.row.adGroupName }}</div>
+          </el-link>
+        </el-tooltip>
+      </template>
+      <template v-for="field of Object.keys(SbBaseColumn)" #[`cell_${field}`]="scope">
+        <DataCompare
+            :field="field"
+            :value="scope.row[field]"
+            :prev-val="scope.row[`prev${field}`]"
+            :gap-val="scope.row[`gap${field}`]"
+            :date-range="dateRange"
+            :show-compare="showCompare"/>
+      </template>
+      <template #toolbar-left>
+        <div class="campare-switch">
+          <span>数据对比 </span>
+          <el-switch v-model="showCompare" size="small" />
+        </div>
+      </template>
+    </fs-crud>
+  </fs-page>
+</template>
+
 <style lang="scss" scoped>
 .chart-tabs {
   margin: 5px 0;

+ 1005 - 1005
src/views/adManage/sp/campaigns/CreateCampaigns/index.vue

@@ -1,899 +1,3 @@
-<template>
-  <div>
-    <el-card>
-      <div style="padding-left: 5px">
-        <!-- 广告活动 -->
-        <el-form
-          :label-position="labelPosition"
-          ref="campaignFormRef"
-          :model="campaignRuleForm"
-          :rules="campaignRules"
-          label-width="120px"
-          class="demo-ruleForm"
-          :size="formSize"
-          status-icon>
-          <el-card shadow="never" body-style="padding-bottom: 0 !important;" v-loading="campaignLoading">
-            <div style="font-size: 24px; font-weight: bold">广告活动</div>
-            <hr />
-            <br />
-            <el-form-item label="广告活动名称" prop="name" style="width: 350px">
-              <el-input v-model="campaignRuleForm.name" placeholder="请输入广告活动名称" />
-            </el-form-item>
-            <el-form-item label="广告组合" prop="adMix">
-              <el-select v-model="campaignRuleForm.adMix" clearable placeholder="请选择">
-                <el-option v-for="item in adMixOptions" :key="item.portfolioId" :label="item.name" :value="item.portfolioId" />
-              </el-select>
-            </el-form-item>
-            <el-form-item prop="startDate" label="开始日期" style="width: 350px">
-              <el-date-picker
-                v-model="campaignRuleForm.startDate"
-                type="date"
-                format="YYYY-MM-DD"
-                value-format="YYYY-MM-DD"
-                label="开始日期"
-                placeholder="开始日期"
-                style="width: 100%" />
-            </el-form-item>
-            <el-form-item prop="date2" label="结束日期" style="width: 350px">
-              <el-date-picker
-                v-model="campaignRuleForm.date2"
-                type="date"
-                format="YYYY-MM-DD"
-                value-format="YYYY-MM-DD"
-                label="结束日期"
-                placeholder="结束日期"
-                style="width: 100%" />
-            </el-form-item>
-            <el-form-item prop="budget" label="每日预算" style="width: 300px">
-              <el-input
-                v-model="campaignRuleForm.budget"
-                maxlength="7"
-                oninput="value=value.indexOf('.') > -1?value.slice(0, value.indexOf('.') + 3):value">
-                <template #prepend>$</template>
-              </el-input>
-            </el-form-item>
-            <el-form-item label="投放类型" prop="type" class="column-item">
-              <el-radio-group v-model="campaignRuleForm.type" @click="changeType">
-                <div>
-                  <el-radio label="AUTO">自动</el-radio>
-                  <div class="radio-description">定向与您推广商品相似的关键词和商品</div>
-                </div>
-                <div>
-                  <el-radio label="MANUAL">手动</el-radio>
-                  <div class="radio-description">选择关键词或商品以定向购物者搜索并设置自定义出价</div>
-                </div>
-              </el-radio-group>
-            </el-form-item>
-            <el-form-item label="竞价策略" prop="bidStrategy" class="column-item column-margin-bottom">
-              <el-radio-group v-model="campaignRuleForm.bidStrategy">
-                <div>
-                  <el-radio label="LEGACY_FOR_SALES" border>
-                    动态竞价-仅降低
-                    <div class="radio-description-2">当您的广告不太可能带来销售时,我们将实时降低您的竞价</div>
-                  </el-radio>
-                </div>
-                <div>
-                  <el-radio label="AUTO_FOR_SALES" border>
-                    动态竞价-提高和降低
-                    <div class="radio-description-2">
-                      当您的广告很有可能带来销售时,我们将实时提高您的竞价(最高可达 100%),并在您的广告不太可能带来销售时降低您的竞价
-                    </div>
-                  </el-radio>
-                </div>
-                <el-radio label="MANUAL" border>
-                  固定竞价
-                  <div class="radio-description-2">我们将使用您的确切竞价和您设置的任何手动调整,而不会根据售出可能性对您的竞价进行更改</div>
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-            <el-form-item label="按展示位置调整出价" prop="placeBid">
-              <p style="color: #8e9196">除了出价策略外,您还可以将出价提高多达900%</p>
-              <div class="gap-items">
-                <div class="gap-item">搜索结果顶部(首页)</div>
-                <el-input v-model="campaignRuleForm.placeBid" class="gap-item">
-                  <template #append>%</template>
-                </el-input>
-              </div>
-              <div class="gap-items">
-                <div class="gap-item">商品首页</div>
-                <el-input v-model="campaignRuleForm.firstPage" class="gap-item">
-                  <template #append>%</template>
-                </el-input>
-              </div>
-              <div class="gap-items" style="margin-bottom: 0">
-                <div class="gap-item">搜索结果的其余位置</div>
-                <el-input v-model="campaignRuleForm.other" class="gap-item">
-                  <template #append>%</template>
-                </el-input>
-              </div>
-            </el-form-item>
-            <el-form-item style="margin-left: 48%">
-              <el-button type="primary" plain @click="submitCampaignForm(campaignFormRef)">保存</el-button>
-            </el-form-item>
-          </el-card>
-          <br />
-          <!-- 广告组 -->
-          <el-card shadow="never" body-style="padding-bottom: 0 !important;" v-loading="adGroupLoading">
-            <div style="font-size: 20px; font-weight: bold">广告组</div>
-            <hr />
-            <br />
-            <el-form ref="adGroupRuleFormRef" :model="adGroupRuleForm" :rules="adGroupRules">
-              <el-form-item required label="广告组名称" prop="adGroupName" style="width: 350px; margin-top: 20px">
-                <el-input v-model="adGroupRuleForm.adGroupName" placeholder="请输入广告组名称" />
-              </el-form-item>
-              <el-form-item required label="默认竞价" prop="defaultBidInp">
-                <el-input v-model="adGroupRuleForm.defaultBidInp" minlength="3" maxlength="4" style="width: 200px">
-                  <template #prepend>$</template>
-                </el-input>
-              </el-form-item>
-              <el-form-item style="margin-left: 48%">
-                <el-button type="primary" plain @click="submitGroupsForm(adGroupRuleFormRef)" :disabled="adGroupSave">保存</el-button>
-              </el-form-item>
-            </el-form>
-          </el-card>
-          <!-- 商品表格 -->
-          <div style="margin-top: 20px; font-size: 24px; font-weight: bold">商品</div>
-          <hr />
-          <br />
-          <el-form-item prop="commodity" style="width: 100%" v-loading="commodityLoading">
-            <div style="width: 100%; height: 620px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px">
-              <div style="width: 50%; border-right: 1px solid #e5e7ec">
-                <el-tabs v-model="activeName" class="demo-tabs">
-                  <el-tab-pane label="搜索" name="first">
-                    <div style="margin-bottom: 10px">
-                      <el-input v-model="searchInp" placeholder="Please input" class="input-with-select" @change="inpChange" clearable>
-                        <template #prepend>
-                          <el-select v-model="select" style="width: 100px" @change="selChange">
-                            <el-option label="名称" value="name" />
-                            <el-option label="ASIN" value="asin" />
-                            <el-option label="SKU" value="sku" />
-                          </el-select>
-                        </template>
-                        <template #append>
-                          <el-select v-model="select2" style="width: 100px">
-                            <el-option label="最新优先" value="latest" />
-                            <el-option label="最早优先" value="earliest" />
-                            <el-option label="优选广告" value="optimal" />
-                          </el-select>
-                        </template>
-                      </el-input>
-                    </div>
-                    <el-table
-                      height="490"
-                      style="width: 100%"
-                      v-loading="loading"
-                      :data="fullTableData"
-                      :header-cell-style="headerCellStyle"
-                      @selection-change="handleSelectionChange">
-                      <el-table-column type="selection" width="50" />
-                      <el-table-column prop="asin" label="商品">
-                        <template #default="scope">
-                          <div style="display: flex; align-items: center">
-                            <div style="margin-right: 8px; line-height: normal">
-                              <el-image class="img-box" :src="scope.row.image_link" />
-                            </div>
-                            <div>
-                              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                                <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                              </el-tooltip>
-                              <div class="data-color">
-                                <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
-                                <span style="margin: 0 5px; color: #cacdd4">|</span>
-                                <span style="color: #6d7784">{{ scope.row.quantity }}</span>
-                              </div>
-                              <span>
-                                ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                              </span>
-                              <span>
-                                SKU: <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
-                              </span>
-                            </div>
-                          </div>
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="name" label="Name" width="120" align="right">
-                        <template #header>
-                          <el-button type="primary" size="normal" link @click="handleGoodsAdd">添加已选中</el-button>
-                        </template>
-                        <template #default="scope">
-                          <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
-                        </template>
-                      </el-table-column>
-                    </el-table>
-                    <el-pagination
-                      @current-change="handleCurrentChange"
-                      @size-change="handleSizeChange"
-                      :current-page="currentPage"
-                      :page-size="pageSize"
-                      :total="totalItems"
-                      layout="prev, pager, next" />
-                  </el-tab-pane>
-                  <el-tab-pane label="输入" name="second">
-                    <el-input
-                      style="padding: 10px"
-                      v-model="goodsTextarea"
-                      :rows="20"
-                      type="textarea"
-                      placeholder="请输入ASIN,多个ASIN使用逗号、空格或换行符分隔。(未完成)"
-                      maxlength="11000" />
-                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-                      <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="addGods">{{ button.text }}</el-button>
-                    </div>
-                  </el-tab-pane>
-                </el-tabs>
-              </div>
-              <div style="width: 50%">
-                <el-card class="box-card" shadow="never" style="border: 0">
-                  <template #header>
-                    <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ adsTableData.length }}</span>
-                      <el-button class="button" type="danger" text bg @click="delAllGoods">全部删除</el-button>
-                    </div>
-                  </template>
-                  <div class="card-body"></div>
-                </el-card>
-                <div style="padding: 0 10px 0 10px; margin-top: -12px">
-                  <el-table
-                    :data="adsTableData"
-                    height="475"
-                    style="width: 100%"
-                    :header-cell-style="headerCellStyle"
-                    @selection-change="handleAddedGoodsChange">
-                    <el-table-column type="selection" width="50" />
-                    <el-table-column prop="asin" label="ASIN">
-                      <template #default="scope">
-                        <div style="display: flex; align-items: center">
-                          <div style="margin-right: 8px; line-height: normal">
-                            <el-image class="img-box" :src="scope.row.image_link" />
-                          </div>
-                          <div>
-                            <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                              <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                            </el-tooltip>
-                            <div class="data-color">
-                              <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
-                              <span style="margin: 0 5px; color: #cacdd4">|</span>
-                              <span style="color: #6d7784">{{ scope.row.quantity }}</span>
-                            </div>
-                            <span
-                              >ASIN:
-                              <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                            </span>
-                            <span
-                              >SKU:
-                              <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
-                            </span>
-                          </div>
-                        </div>
-                      </template>
-                    </el-table-column>
-                    <el-table-column prop="name" label="Name" width="120" align="right">
-                      <template #header>
-                        <el-button type="danger" size="normal" link @click="delSelectedGoods">删除已选中</el-button>
-                      </template>
-                      <template #default="scope">
-                        <el-button type="danger" size="small" @click="delSingleGoods(scope)" text>删除</el-button>
-                      </template>
-                    </el-table-column>
-                  </el-table>
-                </div>
-                <div style="display: flex; justify-content: space-around; padding-top: 10px">
-                  <el-button type="primary" plain :disabled="adsSave" @click="submitAdsForm">保存</el-button>
-                </div>
-              </div>
-            </div>
-          </el-form-item>
-          <!-- 按目标组设置出价 -->
-          <el-form
-            :label-position="labelPosition"
-            ref="targetGroupFormRef"
-            :model="targetGroupRuleForm"
-            :rules="targetGroupRules"
-            label-width="120px"
-            class="demo-ruleForm"
-            :size="formSize"
-            status-icon>
-            <div class="column-item" v-if="campaignRuleForm.type == 'AUTO'">
-              <div style="margin-top: 20px; font-size: 24px; font-weight: bold">按目标组设置出价</div>
-              <hr />
-              <br />
-              <el-card shadow="never" v-if="campaignRuleForm.type == 'AUTO'" class="box-card" v-loading="targetGroupLoading">
-                <div>
-                  <div style="color: #8e9095">
-                    <span>目标群体</span>
-                    <span class="suggested-bid-item">建议竞价</span>
-                    <span>竞价</span>
-                  </div>
-                  <div style="display: flex">
-                    <el-switch v-model="targetGroupRuleForm.closeMatch" size="small" active-text="紧密匹配" @change="closeMatchChange" />
-                    <span class="suggested-bid-item">--</span>
-                    <el-form-item prop="closeMatchInp">
-                      <el-input
-                        :disabled="!targetGroupRuleForm.closeMatch"
-                        v-model="targetGroupRuleForm.closeMatchInp"
-                        minlength="3"
-                        maxlength="4"
-                        class="bid-input">
-                        <template #prepend>$</template>
-                      </el-input>
-                    </el-form-item>
-                  </div>
-                  <div>
-                    <div style="display: flex">
-                      <el-switch v-model="targetGroupRuleForm.broadMatch" size="small" active-text="广泛匹配" @change="broadMatchChange" />
-                      <span class="suggested-bid-item">--</span>
-                      <el-form-item prop="broadMatchInp">
-                        <el-input
-                          :disabled="!targetGroupRuleForm.broadMatch"
-                          v-model="targetGroupRuleForm.broadMatchInp"
-                          minlength="3"
-                          maxlength="4"
-                          class="bid-input">
-                          <template #prepend>$</template>
-                        </el-input>
-                      </el-form-item>
-                    </div>
-                  </div>
-                  <div>
-                    <div style="display: flex">
-                      <el-switch v-model="targetGroupRuleForm.similarProducts" size="small" active-text="同类商品" @change="similarProductsChange" />
-                      <span class="suggested-bid-item">--</span>
-                      <el-form-item prop="similarProductsInp">
-                        <el-input
-                          :disabled="!targetGroupRuleForm.similarProducts"
-                          v-model="targetGroupRuleForm.similarProductsInp"
-                          minlength="3"
-                          maxlength="4"
-                          class="bid-input">
-                          <template #prepend>$</template>
-                        </el-input>
-                      </el-form-item>
-                    </div>
-                  </div>
-                  <div>
-                    <div style="display: flex">
-                      <el-switch v-model="targetGroupRuleForm.relatedProducts" size="small" active-text="关联商品" @change="relatedProductsChange" />
-                      <span class="suggested-bid-item">--</span>
-                      <el-form-item prop="relatedProductsInp">
-                        <el-input
-                          :disabled="!targetGroupRuleForm.relatedProducts"
-                          v-model="targetGroupRuleForm.relatedProductsInp"
-                          minlength="3"
-                          maxlength="4"
-                          class="bid-input">
-                          <template #prepend>$</template>
-                        </el-input>
-                      </el-form-item>
-                    </div>
-                  </div>
-                </div>
-                <div style="display: flex; justify-content: space-around">
-                  <el-button type="primary" plain :disabled="targetGroupBidSave" @click="submitTargetGroupForm">保存</el-button>
-                </div>
-              </el-card>
-            </div>
-          </el-form>
-
-          <!-- 投放类型 -->
-          <div class="column-item" v-if="campaignRuleForm.type == 'MANUAL'">
-            <p style="color: #606266; font-weight: 450"><span style="color: #e47470">*</span> 投放类型</p>
-            <el-radio-group v-model="ruleForm.targetType" @change="changeTargetType">
-              <div style="display: flex">
-                <el-radio label="keyWords" style="align-items: flex-start; margin-top: 5px">
-                  <div style="margin-top: -4px">关键词投放</div>
-                  <div>选择关键词以帮助您的商品出现在购物者搜索中</div>
-                </el-radio>
-              </div>
-              <div>
-                <el-radio label="Goods" style="align-items: flex-start; margin-top: 20px">
-                  <div style="margin-top: -4px">商品投放</div>
-                  <div>选择特定的商品, 分类, 品牌或者其他商品功能来定向您的广告</div>
-                </el-radio>
-              </div>
-            </el-radio-group>
-          </div>
-          <!-- 关键词定向 -->
-          <div
-            style="font-size: 20px; font-weight: bold; margin-top: 30px"
-            v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'">
-            关键词定向
-          </div>
-          <hr v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'" />
-          <el-form-item style="width: 100%; margin-top: 20px" v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'">
-            <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px" v-loading="keywordsLoading">
-              <div style="width: 50%; border-right: 1px solid #e5e7eb">
-                <el-tabs v-model="keyWordsTabs" class="demo-tabs" @tab-click="handleGoodsTabs">
-                  <div style="margin: 8px">
-                    <p style="margin-left: 8px; margin-bottom: -8px; font-weight: 500; color: #616266">竞价:</p>
-                    <div style="display: flex; align-items: center">
-                      <el-select v-model="bidType" class="m-2" placeholder="Select" style="width: 450px">
-                        <el-option v-for="item in bidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
-                      </el-select>
-                      <el-input v-model="bidInput" :disabled="!(bidType == 'customBid')" placeholder="Please input">
-                        <template #prepend>$</template>
-                      </el-input>
-                    </div>
-                    <div style="display: flex">
-                      <span style="margin: 0 10px 0 8px; font-weight: 500; color: #616266">匹配类型: </span>
-                      <el-checkbox v-model="broadType" label="广泛" />
-                      <el-checkbox v-model="phraseType" label="词组" />
-                      <el-checkbox v-model="exactType" label="精确" />
-                    </div>
-                  </div>
-                  <el-tab-pane label="建议" name="first">
-                    <el-table
-                      height="425"
-                      style="width: 100%; padding-left: 5px"
-                      v-loading="loading"
-                      :data="keyWordsTableData"
-                      :header-cell-style="headerCellStyle"
-                      :header-row-style="changeKeyWordsTableHeader">
-                      <el-table-column prop="asin" label="关键词"> </el-table-column>
-                      <el-table-column prop="name" label="匹配类型"> </el-table-column>
-                      <el-table-column prop="name" label="建议出价" width="120"> </el-table-column>
-                    </el-table>
-                  </el-tab-pane>
-                  <el-tab-pane label="输入" name="second">
-                    <el-input v-model="keyWordsTextarea" :rows="10" type="textarea" style="padding-left: 5px" />
-                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-                      <el-button type="primary" text bg @click="addKeyWords">添加</el-button>
-                    </div>
-                  </el-tab-pane>
-                </el-tabs>
-              </div>
-              <div style="width: 50%">
-                <el-card class="box-card" shadow="never" style="border: none">
-                  <template #header>
-                    <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedKeyWordsTableData.length }}</span>
-                      <span style="color: #529b2e">成功: {{ successCount }}</span>
-                      <span style="color: #c45656">失败: {{ errorCount }}</span>
-                      <el-button class="button" type="danger" text bg @click="delAllKeyWords">全部删除</el-button>
-                    </div>
-                  </template>
-                  <div class="card-body" body-style="padding-bottom: -20px;">
-                    <el-table
-                      :data="addedKeyWordsTableData"
-                      style="width: 100%; height: 450px"
-                      :header-row-style="changeKeyWordsTableHeader"
-                      :header-cell-style="headerCellStyle">
-                      <el-table-column prop="keyword" label="关键词" width="auto" />
-                      <el-table-column prop="matchType" label="匹配类型" />
-                      <el-table-column prop="bid" label="出价">
-                        <template #default="scope">
-                          <el-input v-model="scope.row.bid" placeholder="Please input bid" />
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="suggestBid" label="建议出价" />
-                      <el-table-column prop="operate" label="操作" width="60" align="right">
-                        <template #default="scope">
-                          <el-button type="danger" size="small" link @click="delSingleKeyWord(scope)">删除</el-button>
-                        </template>
-                      </el-table-column>
-                    </el-table>
-                  </div>
-                </el-card>
-                <div style="display: flex; justify-content: space-around; padding-top: 0px">
-                  <el-button type="primary" plain @click="keyWordsSave" :disabled="!addedKeyWordsTableData.length">保存</el-button>
-                </div>
-              </div>
-            </div>
-          </el-form-item>
-
-          <div
-            style="font-size: 20px; font-weight: bold; margin-top: 30px"
-            v-if="campaignRuleForm.type === 'AUTO' || (ruleForm.targetType === 'keyWords' && campaignRuleForm.type === 'MANUAL')">
-            否定词
-          </div>
-          <hr v-if="campaignRuleForm.type === 'AUTO' || (ruleForm.targetType === 'keyWords' && campaignRuleForm.type === 'MANUAL')" />
-          <!-- 否定词表格 -->
-          <el-form-item
-            style="width: 100%; margin-top: 20px"
-            v-if="campaignRuleForm.type === 'AUTO' || (ruleForm.targetType === 'keyWords' && campaignRuleForm.type === 'MANUAL')">
-            <div style="width: 100%; height: 520px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px" v-loading="negativeWordsLoading">
-              <div style="width: 50%; border-right: 1px solid #e5e7ec">
-                <div style="margin: 10px 0">
-                  <span style="margin-left: 25px; color: #e47470">*</span>
-                  <span style="color: #666666; margin-right: 10px">匹配类型: </span>
-                  <el-checkbox v-model="NEGATIVE_PHRASE" label="词组否定" />
-                  <el-checkbox v-model="NEGATIVE_EXACT" label="精确否定" />
-                </div>
-                <el-input
-                  v-model="negativeWordsTextarea"
-                  :rows="17"
-                  type="textarea"
-                  placeholder="请输入关键词,多个关键词使用逗号或者换行符分隔。(最多添加1000个关键词)"
-                  maxlength="11000"
-                  style="padding: 0 20px" />
-                <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-                  <el-button style="margin-right: 18px" type="primary" text bg @click="addNegative">添加</el-button>
-                </div>
-              </div>
-              <div style="width: 50%">
-                <el-card class="box-card" shadow="never" style="border: none">
-                  <template #header>
-                    <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedData.length }}</span>
-                      <el-button class="button" text bg :disabled="!tableData.length" @click="delAllNegative">全部删除</el-button>
-                    </div>
-                  </template>
-                  <div class="card-body">
-                    <el-table :data="tableData" style="width: 100%; height: 370px; padding-bottom: 0" :header-row-style="changeNegTableHeader">
-                      <el-table-column prop="negativeWords" label="否定词" width="auto" />
-                      <el-table-column prop="operate" label="操作" width="60" align="right">
-                        <template #default="scope">
-                          <el-button type="primary" size="small" @click="delSingleNegative(scope)" text>删除</el-button>
-                        </template>
-                      </el-table-column>
-                    </el-table>
-                  </div>
-                </el-card>
-                <div style="display: flex; justify-content: space-around">
-                  <el-button type="primary" plain @click="negativeWordsSave" :disabled="!negativeList.length">保存</el-button>
-                </div>
-              </div>
-            </div>
-          </el-form-item>
-
-          <!-- 商品定向 -->
-          <div style="font-size: 20px; font-weight: bold; margin-top: 30px" v-if="ruleForm.targetType == 'Goods'">商品定向</div>
-          <hr v-if="ruleForm.targetType == 'Goods'" />
-          <el-form-item style="width: 100%; margin-top: 20px" v-if="ruleForm.targetType == 'Goods'">
-            <div
-              style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px"
-              v-loading="productOrientationLoading">
-              <div style="width: 50%; border-right: 1px solid #e5e7eb">
-                <el-tabs
-                  type="border-card"
-                  stretch
-                  class="goods-orientation-tabs"
-                  style="border: 0; border-right: 0; border-bottom-left-radius: 6px; border-top-left-radius: 5px; overflow: hidden">
-                  <el-tab-pane label="品类" style="border-top-left-radius: 6px">
-                    <div style="display: flex; align-items: center">
-                      <span style="width: 40px">竞价:</span>
-                      <el-select v-model="categoryBiddingType" @change="singleGoodsBidSelectChanged" class="m-2" placeholder="Select">
-                        <el-option v-for="item in categoryBiddingTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
-                      </el-select>
-                      <el-input v-model="singleGoodsBidInput" :disabled="categoryBiddingType === 'defaultBid'" style="width: 200px">
-                        <template #prepend>$</template>
-                      </el-input>
-                    </div>
-
-                    <el-tabs v-model="categoryTabs" class="category-tabs">
-                      <el-tab-pane label="建议" name="first">
-                        <el-table :data="proposalTableData" style="width: 100%" height="422">
-                          <el-table-column prop="proposal" label="建议" width="520">
-                            <template #header> 0建议 </template>
-                          </el-table-column>
-                          <el-table-column prop="address" label="Address">
-                            <template #header>
-                              <el-button type="primary" size="normal" link @click="handleGoodsAdd">全部添加</el-button>
-                            </template>
-                            <template #default="scope">
-                              <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
-                            </template>
-                          </el-table-column>
-                        </el-table>
-                      </el-tab-pane>
-                      <el-tab-pane label="搜索" name="second">
-                        <el-input placeholder="请输入关键词过滤" />
-                        <el-scrollbar height="390px">
-                          <el-tree :data="searchClassifyTableData" :props="defaultProps" :expand-on-click-node="false">
-                            <template #default="{ node, data }">
-                              <span class="custom-tree-node">
-                                <span style="width: 75%">{{ node.label }}</span>
-                                <span style="color: rgb(50, 108, 216)" v-if="data.ta == true">
-                                  <a @click="refine(data)"> 细化 </a>
-                                  <a style="margin-left: 8px" @click="orientate(node, data)"> 定向 </a>
-                                </span>
-                              </span>
-                            </template>
-                          </el-tree>
-                        </el-scrollbar>
-                        <el-dialog v-model="visible" :title="`细化分类: ${dialogTitle}`" @close="dialogClose" destroy-on-close>
-                          <div style="display: flex; justify-content: space-between">
-                            <span>根据特定品牌、价格范围、星级和Prime配送资格,细化分类</span>
-                            <span>
-                              <el-checkbox v-model="dialogForm.isCount" label="显示商品数量" @change="isCountChanged" />
-                            </span>
-                          </div>
-                          <el-form :model="dialogForm" :rules="dialogRules" ref="dialogFormRef" style="margin-top: 20px">
-                            <el-form-item style="padding-left: 140px">
-                              <span style="margin-right: 10px; color: #616266; font-weight: 500">品牌</span>
-                              <el-select
-                                v-model="dialogForm.dialogselectValue"
-                                @change="dialogSelectChange"
-                                multiple
-                                placeholder="请选择"
-                                :loading="dialogSelectLoading">
-                                <el-option v-for="item in dialogForm.dialogOptions" :key="item.value" :label="item.label" :value="item.value" />
-                              </el-select>
-                            </el-form-item>
-                            <el-form-item prop="prices" style="padding-left: 112px; margin-top: 10px">
-                              <span style="margin-right: 10px; color: #616266; font-weight: 500">价格范围</span>
-                              <el-input-number v-model="dialogForm.prices.lowest" :min="1" :controls="false" placeholder="无最低商品价格" />
-                              --
-                              <el-input-number v-model="dialogForm.prices.highest" :min="1" :controls="false" placeholder="无最高商品价格" />
-                            </el-form-item>
-                            <el-form-item prop="starRating" style="padding-left: 85px; margin-top: 10px">
-                              <span style="margin-right: 15px; color: #616266; font-weight: 500">查看星级评定</span>
-                              <el-slider v-model="dialogForm.starRating" range show-stops :max="5" :marks="marks" style="width: 70%" />
-                            </el-form-item>
-                            <el-form-item prop="delivery" style="padding-left: 140px; margin-top: 30px">
-                              <span style="margin-right: 10px; color: #616266; font-weight: 500">配送</span>
-                              <el-radio-group v-model="dialogForm.delivery">
-                                <el-radio label="all" style="font-weight: 400">所有</el-radio>
-                                <el-radio label="eligible" style="font-weight: 400">具备Prime资格</el-radio>
-                                <el-radio label="diseligible" style="font-weight: 400">不具备Prime资格</el-radio>
-                              </el-radio-group>
-                            </el-form-item>
-                          </el-form>
-                          <template #footer>
-                            <div style="display: flex; justify-content: space-between">
-                              <span v-loading="countLoadig"
-                                >定位到的商品数量:
-                                <span v-if="dialogForm.isCount == true">{{ commodityCount[0]?.min }} - {{ commodityCount[0]?.max }}</span></span
-                              >
-                              <span class="dialog-footer">
-                                <el-button @click="visible = false">取消</el-button>
-                                <el-button type="primary" @click="dialogFormSubmit">确定</el-button>
-                              </span>
-                            </div>
-                          </template>
-                        </el-dialog>
-                      </el-tab-pane>
-                    </el-tabs>
-                  </el-tab-pane>
-                  <el-tab-pane label="单个商品">
-                    <div style="display: flex; align-items: center">
-                      <span style="width: 40px">竞价:</span>
-                      <el-select class="m-2" v-model="singleGoodsBidSelect" @change="singleGoodsBidSelectChanged">
-                        <el-option v-for="item in singleGoodsBidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
-                      </el-select>
-                      <el-input v-model="singleGoodsBidInput" :disabled="singleGoodsBidSelect == 'defaultBid'" style="width: 200px">
-                        <template #prepend>$</template>
-                      </el-input>
-                      <div style="margin-left: 20px">
-                        <span style="margin-right: 10px">类型:</span>
-                        <el-checkbox v-model="expand" label="扩展" />
-                        <el-checkbox v-model="accurate" label="精准" />
-                      </div>
-                    </div>
-                    <el-tabs v-model="singleGoodsTabs" class="category-tabs">
-                      <el-tab-pane label="建议" name="first">
-                        <el-table :data="proposalTableData" style="width: 100%" height="342">
-                          <el-table-column prop="proposal" label="商品" width="520" />
-                          <el-table-column prop="address" label="类型" />
-                          <el-table-column prop="operational" label="操作" />
-                        </el-table>
-                      </el-tab-pane>
-                      <el-tab-pane label="搜索" name="second">
-                        <el-input v-model="singleGoodsSearchInp" @change="singleGoodsSearchChaneged" placeholder="按ASIN搜索"></el-input>
-                        <el-table :data="searchTableData" style="width: 100%" height="309">
-                          <el-table-column prop="asin" label="商品" width="520">
-                            <template #default="{ row }">
-                              <div style="display: flex; align-items: center">
-                                <img :src="row.image_link" style="width: 40px; height: 40px; margin-right: 10px" />
-                                <span>{{ row.title }}</span>
-                              </div>
-                            </template>
-                          </el-table-column>
-                          <el-table-column prop="productTypes" label="类型">
-                            <template #default="scope">
-                              <div v-if="expand">扩展</div>
-                              <div v-if="accurate">精准</div>
-                            </template>
-                          </el-table-column>
-                          <el-table-column prop="operational" label="操作">
-                            <template #default="scope">
-                              <el-button class="button" type="primary" text @click="addSingleSearch(scope)">添加</el-button>
-                            </template>
-                          </el-table-column>
-                        </el-table>
-                      </el-tab-pane>
-                      <!-- TODO: 商品定向TextArea -->
-                      <!-- <el-tab-pane label="输入" name="third">暂无此功能</el-tab-pane> -->
-                    </el-tabs>
-                  </el-tab-pane>
-                </el-tabs>
-              </div>
-              <div style="width: 50%">
-                <el-card class="box-card" shadow="never" style="border: none">
-                  <template #header>
-                    <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ productOrientationTableData.length }}</span>
-                      <el-button class="button" type="danger" text bg @click="delAllCna">全部删除</el-button>
-                    </div>
-                  </template>
-                  <div class="card-body">
-                    <el-table
-                      height="460"
-                      :data="productOrientationTableData"
-                      style="width: 100%"
-                      :header-row-style="changeKeyWordsTableHeader"
-                      :header-cell-style="headerCellStyle">
-                      <el-table-column prop="cna" label="分类 & 商品" width="300">
-                        <template #default="scope">
-                          <div v-if="scope.row.cna || scope.row.classification">
-                            分类: <span style="color: #000000">{{ scope.row.cna ? scope.row.cna : scope.row.classification }}</span>
-                          </div>
-                          <div v-if="scope.row.asin">
-                            {{ scope.row.asin ? scope.row.asin : '--' }}
-                          </div>
-                          <div v-if="scope.row.brand">
-                            品牌: <span style="color: #000000">{{ scope.row.brand }}</span>
-                          </div>
-                          <div v-if="scope.row.low_price || scope.row.high_price">
-                            品牌价格:
-                            <span style="color: #000000">
-                              {{ scope.row.low_price ? '$' + scope.row.low_price : '--' }} -
-                              {{ scope.row.high_price ? '$' + scope.row.high_price : '--' }}
-                            </span>
-                          </div>
-                          <div v-if="scope.row.low_rating || scope.row.high_rating">
-                            评分: <span style="color: #000000">{{ scope.row.low_rating }} - {{ scope.row.high_rating }}</span>
-                          </div>
-                          <div v-if="scope.row.deliveryText">
-                            配送: <span style="color: #000000">{{ scope.row.deliveryText }}</span>
-                          </div>
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="type" label="类型">
-                        <template #default="scope">
-                          {{ scope.row.productTypeText ? scope.row.productTypeText : '--' }}
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="bid" label="竞价">
-                        <template #default="scope">
-                          <el-input-number v-model="scope.row.bid" :min="0.02" :max="1000000" :controls="false" size="small" />
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="operate" label="操作" width="60" align="right">
-                        <template #default="scope">
-                          <el-button type="danger" text size="small" @click="delCna(scope.$index)">删除</el-button>
-                        </template>
-                      </el-table-column>
-                    </el-table>
-                  </div>
-                </el-card>
-                <div style="display: flex; justify-content: space-around; margin-top: -8px">
-                  <el-button type="primary" plain @click="productTagetSave">保存</el-button>
-                </div>
-              </div>
-            </div>
-          </el-form-item>
-
-          <div
-            style="font-size: 20px; font-weight: bold; margin-top: 30px"
-            v-if="campaignRuleForm.type == 'AUTO' || (ruleForm.targetType == 'Goods' && campaignRuleForm.type === 'MANUAL')">
-            否定商品
-          </div>
-          <hr v-if="campaignRuleForm.type == 'AUTO' || (ruleForm.targetType == 'Goods' && campaignRuleForm.type === 'MANUAL')" />
-          <el-form-item
-            prop="matchType"
-            style="width: 100%; margin-top: 20px"
-            v-if="campaignRuleForm.type == 'AUTO' || (ruleForm.targetType == 'Goods' && campaignRuleForm.type === 'MANUAL')">
-            <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px" v-loading="negativeGoodsLoading">
-              <div style="width: 50%; border-right: 1px solid #e5e7ec">
-                <el-tabs v-model="negativeTabs" class="demo-tabs" @tab-click="handleNegGoodsTabs">
-                  <el-tab-pane label="搜索" name="first">
-                    <div style="margin-bottom: 10px">
-                      <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegativeGoods" clearable />
-                    </div>
-                    <el-table
-                      height="495"
-                      style="width: 100%"
-                      v-loading="loading"
-                      :data="negativeTableData"
-                      :header-cell-style="headerCellStyle"
-                      :show-header="false">
-                      <el-table-column prop="asin" label="商品">
-                        <template #default="scope">
-                          <div style="display: flex; align-items: center">
-                            <div style="margin-right: 8px; line-height: normal">
-                              <el-image class="img-box" :src="scope.row.image_link" />
-                            </div>
-                            <div>
-                              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                                <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                              </el-tooltip>
-                              <span>
-                                ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                              </span>
-                            </div>
-                          </div>
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="name" label="Name" width="120" align="right">
-                        <template #header> </template>
-                        <template #default="scope">
-                          <el-button type="primary" size="small" @click="addSingleNegativeGoods(scope)" text>添加</el-button>
-                        </template>
-                      </el-table-column>
-                    </el-table>
-                  </el-tab-pane>
-                  <el-tab-pane label="输入" name="second">
-                    <el-input
-                      v-model="ruleForm.negativeGoodsTextarea"
-                      :disabled="true"
-                      :rows="17"
-                      type="textarea"
-                      maxlength="11000"
-                      style="padding: 10px 10px" />
-                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-                      <el-button
-                        style="margin-right: 10px"
-                        type="primary"
-                        text
-                        bg
-                        :disabled="!ruleForm.negativeGoodsTextarea"
-                        @click="addNegativeGoods"
-                        >添加</el-button
-                      >
-                    </div>
-                  </el-tab-pane>
-                </el-tabs>
-              </div>
-              <div style="width: 50%">
-                <el-card class="box-card" shadow="never" style="border: none">
-                  <template #header>
-                    <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
-                      <el-button class="button" text bg @click="delAllNegativeGoods">全部删除</el-button>
-                    </div>
-                  </template>
-                  <div class="card-body"></div>
-                </el-card>
-                <div style="padding: 0 10px 0 10px; margin-top: -30px">
-                  <el-table
-                    :data="addedNegetiveTableData"
-                    height="473"
-                    style="width: 100%"
-                    :header-cell-style="headerCellStyle"
-                    @selection-change="handleAddedNegGoods">
-                    <el-table-column prop="asin" label="商品">
-                      <template #default="scope">
-                        <div style="display: flex; align-items: center">
-                          <div style="margin-right: 8px; line-height: normal">
-                            <el-image class="img-box" :src="scope.row.image_link" />
-                          </div>
-                          <div>
-                            <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                              <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                            </el-tooltip>
-                            <span
-                              >ASIN:
-                              <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                            </span>
-                          </div>
-                        </div>
-                      </template>
-                    </el-table-column>
-                    <el-table-column label="操作" width="120" align="right">
-                      <template #default="scope">
-                        <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
-                      </template>
-                    </el-table-column>
-                  </el-table>
-                </div>
-                <div style="display: flex; justify-content: space-around; padding-top: 10px">
-                  <el-button plain type="primary" @click="negativeGoodsSave" :disabled="!addedNegetiveTableData.length">保存</el-button>
-                </div>
-              </div>
-            </div>
-          </el-form-item>
-
-          <!-- <br />
-          <el-form-item>
-            <el-button size="large" @click="resetForm(ruleFormRef)">取消</el-button>
-            <el-button size="large" type="primary" plain @click="submitForm(ruleFormRef)">保存</el-button>
-          </el-form-item> -->
-        </el-form>
-      </div>
-    </el-card>
-  </div>
-</template>
-
 <script lang="ts" setup>
 import { onMounted, reactive, ref, computed, watch } from 'vue'
 import type { CSSProperties } from 'vue'
@@ -2315,124 +1419,1020 @@ async function negativeGoodsSave() {
   }
 }
 
-// ------------------------------------------自定义校验模块------------------------------------------
-function checkBid(value, callback, bidField) {
-  const bid = parseFloat(value)
-  const budget = parseFloat(campaignRuleForm.budget)
-  // 检查值是否为最多两位小数的普通数字格式
-  const isNormalNumberWithTwoDecimals = /^-?\d+(\.\d{1,2})?$/.test(value)
+// ------------------------------------------自定义校验模块------------------------------------------
+function checkBid(value, callback, bidField) {
+  const bid = parseFloat(value)
+  const budget = parseFloat(campaignRuleForm.budget)
+  // 检查值是否为最多两位小数的普通数字格式
+  const isNormalNumberWithTwoDecimals = /^-?\d+(\.\d{1,2})?$/.test(value)
+
+  if (!isNormalNumberWithTwoDecimals) {
+    callback(new Error('请输入数字值(最多两位小数)'))
+  } else if (isNaN(bid)) {
+    callback(new Error('请输入有效的数字'))
+  } else if (bid < 0.02 || bid > 1000) {
+    callback(new Error('值必须在0.02到1000之间'))
+  } else if (bid >= budget) {
+    callback(new Error('出价必须小于预算'))
+  } else {
+    callback()
+  }
+}
+// 自定义校验规则---自动定价和按目标设置出价模块
+// function getValidationRules(fieldName) {
+//   // 默认校验规则
+//   const commonRules = [
+//     { required: true, message: '此项为必填项', trigger: 'blur' },
+//     { validator: (rule, value, callback) => checkBid(value, callback, fieldName), trigger: 'blur' },
+//   ]
+
+//   // 根据不同字段和状态返回特定的校验规则
+//   switch (fieldName) {
+//     case 'defaultBidInp':
+//       if (ruleForm.autoRedirect === 'defaultBid') {
+//         return commonRules
+//       }
+//       break
+//     case 'similarProductsInp':
+//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.similarProducts) {
+//         return commonRules
+//       } else if (ruleForm.similarProducts == false) {
+//         ruleFormRef.value?.clearValidate(fieldName)
+//       }
+//       break
+//     case 'relatedProductsInp':
+//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.relatedProducts) {
+//         return commonRules
+//       } else if (ruleForm.relatedProducts == false) {
+//         ruleFormRef.value?.clearValidate(fieldName)
+//       }
+//       break
+//     case 'broadMatchInp':
+//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.broadMatch) {
+//         return commonRules
+//       } else if (ruleForm.broadMatch == false) {
+//         ruleFormRef.value?.clearValidate(fieldName)
+//       }
+//       break
+//     case 'closeMatchInp':
+//       // 仅当autoRedirect为'targetBid'且closeMatch开启时校验closeMatchInp
+//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.closeMatch) {
+//         return commonRules
+//       } else if (ruleForm.closeMatch == false) {
+//         ruleFormRef.value?.clearValidate(fieldName)
+//       }
+//       break
+//     default:
+//       return []
+//   }
+//   // 如果不满足上述条件,则无需校验
+//   return []
+// }
+// 监听表单字段变化,根据不同字段和状态返回特定的校验规则
+// watch(
+//   [() => ruleForm.autoRedirect, () => ruleForm.closeMatch, () => ruleForm.broadMatch, () => ruleForm.similarProducts, () => ruleForm.relatedProducts],
+//   () => {
+//     // 定义需要更新校验规则的字段
+//     const fields = ['defaultBidInp', 'closeMatchInp', 'broadMatchInp', 'similarProductsInp', 'relatedProductsInp']
+//     fields.forEach((field) => {
+//       rules.value[field] = getValidationRules(field)
+//     })
+//   }
+// )
+
+// 修改表头样式
+const headerCellStyle = (args) => {
+  if (args.rowIndex === 0) {
+    return {
+      backgroundColor: 'rgba(245, 245, 245, 0.9)',
+    }
+  }
+}
+
+function changeNegTableHeader(args) {
+  if (args.rowIndex === 0) {
+    return {
+      color: '#505968',
+    }
+  }
+}
 
-  if (!isNormalNumberWithTwoDecimals) {
-    callback(new Error('请输入数字值(最多两位小数)'))
-  } else if (isNaN(bid)) {
-    callback(new Error('请输入有效的数字'))
-  } else if (bid < 0.02 || bid > 1000) {
-    callback(new Error('值必须在0.02到1000之间'))
-  } else if (bid >= budget) {
-    callback(new Error('出价必须小于预算'))
-  } else {
-    callback()
+function changeKeyWordsTableHeader(args) {
+  if (args.rowIndex === 0) {
+    return {
+      color: '#505968',
+      backgroundColor: 'rgba(245, 245, 245, 0.9)',
+    }
   }
 }
-// 自定义校验规则---自动定价和按目标设置出价模块
-// function getValidationRules(fieldName) {
-//   // 默认校验规则
-//   const commonRules = [
-//     { required: true, message: '此项为必填项', trigger: 'blur' },
-//     { validator: (rule, value, callback) => checkBid(value, callback, fieldName), trigger: 'blur' },
-//   ]
 
-//   // 根据不同字段和状态返回特定的校验规则
-//   switch (fieldName) {
-//     case 'defaultBidInp':
-//       if (ruleForm.autoRedirect === 'defaultBid') {
-//         return commonRules
-//       }
-//       break
-//     case 'similarProductsInp':
-//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.similarProducts) {
-//         return commonRules
-//       } else if (ruleForm.similarProducts == false) {
-//         ruleFormRef.value?.clearValidate(fieldName)
-//       }
-//       break
-//     case 'relatedProductsInp':
-//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.relatedProducts) {
-//         return commonRules
-//       } else if (ruleForm.relatedProducts == false) {
-//         ruleFormRef.value?.clearValidate(fieldName)
-//       }
-//       break
-//     case 'broadMatchInp':
-//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.broadMatch) {
-//         return commonRules
-//       } else if (ruleForm.broadMatch == false) {
-//         ruleFormRef.value?.clearValidate(fieldName)
-//       }
-//       break
-//     case 'closeMatchInp':
-//       // 仅当autoRedirect为'targetBid'且closeMatch开启时校验closeMatchInp
-//       if (ruleForm.autoRedirect === 'targetBid' && ruleForm.closeMatch) {
-//         return commonRules
-//       } else if (ruleForm.closeMatch == false) {
-//         ruleFormRef.value?.clearValidate(fieldName)
-//       }
-//       break
-//     default:
-//       return []
-//   }
-//   // 如果不满足上述条件,则无需校验
-//   return []
-// }
-// 监听表单字段变化,根据不同字段和状态返回特定的校验规则
-// watch(
-//   [() => ruleForm.autoRedirect, () => ruleForm.closeMatch, () => ruleForm.broadMatch, () => ruleForm.similarProducts, () => ruleForm.relatedProducts],
-//   () => {
-//     // 定义需要更新校验规则的字段
-//     const fields = ['defaultBidInp', 'closeMatchInp', 'broadMatchInp', 'similarProductsInp', 'relatedProductsInp']
-//     fields.forEach((field) => {
-//       rules.value[field] = getValidationRules(field)
-//     })
-//   }
-// )
+onMounted(() => {
+  setTableData()
+  getAdMix()
+  // const myTest = route.query
+  // console.log('myTest', myTest)
+})
+
+defineOptions({
+  name: 'SpCreateCampaigns',
+})
+</script>
+
+<template>
+  <div>
+    <el-card>
+      <div style="padding-left: 5px">
+        <!-- 广告活动 -->
+        <el-form
+          :label-position="labelPosition"
+          ref="campaignFormRef"
+          :model="campaignRuleForm"
+          :rules="campaignRules"
+          label-width="120px"
+          class="demo-ruleForm"
+          :size="formSize"
+          status-icon>
+          <el-card shadow="never" body-style="padding-bottom: 0 !important;" v-loading="campaignLoading">
+            <div style="font-size: 24px; font-weight: bold">广告活动</div>
+            <hr />
+            <br />
+            <el-form-item label="广告活动名称" prop="name" style="width: 350px">
+              <el-input v-model="campaignRuleForm.name" placeholder="请输入广告活动名称" />
+            </el-form-item>
+            <el-form-item label="广告组合" prop="adMix">
+              <el-select v-model="campaignRuleForm.adMix" clearable placeholder="请选择">
+                <el-option v-for="item in adMixOptions" :key="item.portfolioId" :label="item.name" :value="item.portfolioId" />
+              </el-select>
+            </el-form-item>
+            <el-form-item prop="startDate" label="开始日期" style="width: 350px">
+              <el-date-picker
+                v-model="campaignRuleForm.startDate"
+                type="date"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+                label="开始日期"
+                placeholder="开始日期"
+                style="width: 100%" />
+            </el-form-item>
+            <el-form-item prop="date2" label="结束日期" style="width: 350px">
+              <el-date-picker
+                v-model="campaignRuleForm.date2"
+                type="date"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+                label="结束日期"
+                placeholder="结束日期"
+                style="width: 100%" />
+            </el-form-item>
+            <el-form-item prop="budget" label="每日预算" style="width: 300px">
+              <el-input
+                v-model="campaignRuleForm.budget"
+                maxlength="7"
+                oninput="value=value.indexOf('.') > -1?value.slice(0, value.indexOf('.') + 3):value">
+                <template #prepend>$</template>
+              </el-input>
+            </el-form-item>
+            <el-form-item label="投放类型" prop="type" class="column-item">
+              <el-radio-group v-model="campaignRuleForm.type" @click="changeType">
+                <div>
+                  <el-radio label="AUTO">自动</el-radio>
+                  <div class="radio-description">定向与您推广商品相似的关键词和商品</div>
+                </div>
+                <div>
+                  <el-radio label="MANUAL">手动</el-radio>
+                  <div class="radio-description">选择关键词或商品以定向购物者搜索并设置自定义出价</div>
+                </div>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="竞价策略" prop="bidStrategy" class="column-item column-margin-bottom">
+              <el-radio-group v-model="campaignRuleForm.bidStrategy">
+                <div>
+                  <el-radio label="LEGACY_FOR_SALES" border>
+                    动态竞价-仅降低
+                    <div class="radio-description-2">当您的广告不太可能带来销售时,我们将实时降低您的竞价</div>
+                  </el-radio>
+                </div>
+                <div>
+                  <el-radio label="AUTO_FOR_SALES" border>
+                    动态竞价-提高和降低
+                    <div class="radio-description-2">
+                      当您的广告很有可能带来销售时,我们将实时提高您的竞价(最高可达 100%),并在您的广告不太可能带来销售时降低您的竞价
+                    </div>
+                  </el-radio>
+                </div>
+                <el-radio label="MANUAL" border>
+                  固定竞价
+                  <div class="radio-description-2">我们将使用您的确切竞价和您设置的任何手动调整,而不会根据售出可能性对您的竞价进行更改</div>
+                </el-radio>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="按展示位置调整出价" prop="placeBid">
+              <p style="color: #8e9196">除了出价策略外,您还可以将出价提高多达900%</p>
+              <div class="gap-items">
+                <div class="gap-item">搜索结果顶部(首页)</div>
+                <el-input v-model="campaignRuleForm.placeBid" class="gap-item">
+                  <template #append>%</template>
+                </el-input>
+              </div>
+              <div class="gap-items">
+                <div class="gap-item">商品首页</div>
+                <el-input v-model="campaignRuleForm.firstPage" class="gap-item">
+                  <template #append>%</template>
+                </el-input>
+              </div>
+              <div class="gap-items" style="margin-bottom: 0">
+                <div class="gap-item">搜索结果的其余位置</div>
+                <el-input v-model="campaignRuleForm.other" class="gap-item">
+                  <template #append>%</template>
+                </el-input>
+              </div>
+            </el-form-item>
+            <el-form-item style="margin-left: 48%">
+              <el-button type="primary" plain @click="submitCampaignForm(campaignFormRef)">保存</el-button>
+            </el-form-item>
+          </el-card>
+          <br />
+          <!-- 广告组 -->
+          <el-card shadow="never" body-style="padding-bottom: 0 !important;" v-loading="adGroupLoading">
+            <div style="font-size: 20px; font-weight: bold">广告组</div>
+            <hr />
+            <br />
+            <el-form ref="adGroupRuleFormRef" :model="adGroupRuleForm" :rules="adGroupRules">
+              <el-form-item required label="广告组名称" prop="adGroupName" style="width: 350px; margin-top: 20px">
+                <el-input v-model="adGroupRuleForm.adGroupName" placeholder="请输入广告组名称" />
+              </el-form-item>
+              <el-form-item required label="默认竞价" prop="defaultBidInp">
+                <el-input v-model="adGroupRuleForm.defaultBidInp" minlength="3" maxlength="4" style="width: 200px">
+                  <template #prepend>$</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item style="margin-left: 48%">
+                <el-button type="primary" plain @click="submitGroupsForm(adGroupRuleFormRef)" :disabled="adGroupSave">保存</el-button>
+              </el-form-item>
+            </el-form>
+          </el-card>
+          <!-- 商品表格 -->
+          <div style="margin-top: 20px; font-size: 24px; font-weight: bold">商品</div>
+          <hr />
+          <br />
+          <el-form-item prop="commodity" style="width: 100%" v-loading="commodityLoading">
+            <div style="width: 100%; height: 620px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px">
+              <div style="width: 50%; border-right: 1px solid #e5e7ec">
+                <el-tabs v-model="activeName" class="demo-tabs">
+                  <el-tab-pane label="搜索" name="first">
+                    <div style="margin-bottom: 10px">
+                      <el-input v-model="searchInp" placeholder="Please input" class="input-with-select" @change="inpChange" clearable>
+                        <template #prepend>
+                          <el-select v-model="select" style="width: 100px" @change="selChange">
+                            <el-option label="名称" value="name" />
+                            <el-option label="ASIN" value="asin" />
+                            <el-option label="SKU" value="sku" />
+                          </el-select>
+                        </template>
+                        <template #append>
+                          <el-select v-model="select2" style="width: 100px">
+                            <el-option label="最新优先" value="latest" />
+                            <el-option label="最早优先" value="earliest" />
+                            <el-option label="优选广告" value="optimal" />
+                          </el-select>
+                        </template>
+                      </el-input>
+                    </div>
+                    <el-table
+                      height="490"
+                      style="width: 100%"
+                      v-loading="loading"
+                      :data="fullTableData"
+                      :header-cell-style="headerCellStyle"
+                      @selection-change="handleSelectionChange">
+                      <el-table-column type="selection" width="50" />
+                      <el-table-column prop="asin" label="商品">
+                        <template #default="scope">
+                          <div style="display: flex; align-items: center">
+                            <div style="margin-right: 8px; line-height: normal">
+                              <el-image class="img-box" :src="scope.row.image_link" />
+                            </div>
+                            <div>
+                              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                                <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                              </el-tooltip>
+                              <div class="data-color">
+                                <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
+                                <span style="margin: 0 5px; color: #cacdd4">|</span>
+                                <span style="color: #6d7784">{{ scope.row.quantity }}</span>
+                              </div>
+                              <span>
+                                ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                              </span>
+                              <span>
+                                SKU: <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
+                              </span>
+                            </div>
+                          </div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="name" label="Name" width="120" align="right">
+                        <template #header>
+                          <el-button type="primary" size="normal" link @click="handleGoodsAdd">添加已选中</el-button>
+                        </template>
+                        <template #default="scope">
+                          <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                    <el-pagination
+                      @current-change="handleCurrentChange"
+                      @size-change="handleSizeChange"
+                      :current-page="currentPage"
+                      :page-size="pageSize"
+                      :total="totalItems"
+                      layout="prev, pager, next" />
+                  </el-tab-pane>
+                  <el-tab-pane label="输入" name="second">
+                    <el-input
+                      style="padding: 10px"
+                      v-model="goodsTextarea"
+                      :rows="20"
+                      type="textarea"
+                      placeholder="请输入ASIN,多个ASIN使用逗号、空格或换行符分隔。(未完成)"
+                      maxlength="11000" />
+                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                      <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="addGods">{{ button.text }}</el-button>
+                    </div>
+                  </el-tab-pane>
+                </el-tabs>
+              </div>
+              <div style="width: 50%">
+                <el-card class="box-card" shadow="never" style="border: 0">
+                  <template #header>
+                    <div class="card-header">
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ adsTableData.length }}</span>
+                      <el-button class="button" type="danger" text bg @click="delAllGoods">全部删除</el-button>
+                    </div>
+                  </template>
+                  <div class="card-body"></div>
+                </el-card>
+                <div style="padding: 0 10px 0 10px; margin-top: -12px">
+                  <el-table
+                    :data="adsTableData"
+                    height="475"
+                    style="width: 100%"
+                    :header-cell-style="headerCellStyle"
+                    @selection-change="handleAddedGoodsChange">
+                    <el-table-column type="selection" width="50" />
+                    <el-table-column prop="asin" label="ASIN">
+                      <template #default="scope">
+                        <div style="display: flex; align-items: center">
+                          <div style="margin-right: 8px; line-height: normal">
+                            <el-image class="img-box" :src="scope.row.image_link" />
+                          </div>
+                          <div>
+                            <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                              <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                            </el-tooltip>
+                            <div class="data-color">
+                              <span style="font-weight: 500; color: rgb(30, 33, 41)">${{ scope.row.price ? scope.row.price : '--' }}</span>
+                              <span style="margin: 0 5px; color: #cacdd4">|</span>
+                              <span style="color: #6d7784">{{ scope.row.quantity }}</span>
+                            </div>
+                            <span
+                              >ASIN:
+                              <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                            </span>
+                            <span
+                              >SKU:
+                              <span class="data-color">{{ scope.row.sku ? scope.row.sku : '--' }}</span>
+                            </span>
+                          </div>
+                        </div>
+                      </template>
+                    </el-table-column>
+                    <el-table-column prop="name" label="Name" width="120" align="right">
+                      <template #header>
+                        <el-button type="danger" size="normal" link @click="delSelectedGoods">删除已选中</el-button>
+                      </template>
+                      <template #default="scope">
+                        <el-button type="danger" size="small" @click="delSingleGoods(scope)" text>删除</el-button>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </div>
+                <div style="display: flex; justify-content: space-around; padding-top: 10px">
+                  <el-button type="primary" plain :disabled="adsSave" @click="submitAdsForm">保存</el-button>
+                </div>
+              </div>
+            </div>
+          </el-form-item>
+          <!-- 按目标组设置出价 -->
+          <el-form
+            :label-position="labelPosition"
+            ref="targetGroupFormRef"
+            :model="targetGroupRuleForm"
+            :rules="targetGroupRules"
+            label-width="120px"
+            class="demo-ruleForm"
+            :size="formSize"
+            status-icon>
+            <div class="column-item" v-if="campaignRuleForm.type == 'AUTO'">
+              <div style="margin-top: 20px; font-size: 24px; font-weight: bold">按目标组设置出价</div>
+              <hr />
+              <br />
+              <el-card shadow="never" v-if="campaignRuleForm.type == 'AUTO'" class="box-card" v-loading="targetGroupLoading">
+                <div>
+                  <div style="color: #8e9095">
+                    <span>目标群体</span>
+                    <span class="suggested-bid-item">建议竞价</span>
+                    <span>竞价</span>
+                  </div>
+                  <div style="display: flex">
+                    <el-switch v-model="targetGroupRuleForm.closeMatch" size="small" active-text="紧密匹配" @change="closeMatchChange" />
+                    <span class="suggested-bid-item">--</span>
+                    <el-form-item prop="closeMatchInp">
+                      <el-input
+                        :disabled="!targetGroupRuleForm.closeMatch"
+                        v-model="targetGroupRuleForm.closeMatchInp"
+                        minlength="3"
+                        maxlength="4"
+                        class="bid-input">
+                        <template #prepend>$</template>
+                      </el-input>
+                    </el-form-item>
+                  </div>
+                  <div>
+                    <div style="display: flex">
+                      <el-switch v-model="targetGroupRuleForm.broadMatch" size="small" active-text="广泛匹配" @change="broadMatchChange" />
+                      <span class="suggested-bid-item">--</span>
+                      <el-form-item prop="broadMatchInp">
+                        <el-input
+                          :disabled="!targetGroupRuleForm.broadMatch"
+                          v-model="targetGroupRuleForm.broadMatchInp"
+                          minlength="3"
+                          maxlength="4"
+                          class="bid-input">
+                          <template #prepend>$</template>
+                        </el-input>
+                      </el-form-item>
+                    </div>
+                  </div>
+                  <div>
+                    <div style="display: flex">
+                      <el-switch v-model="targetGroupRuleForm.similarProducts" size="small" active-text="同类商品" @change="similarProductsChange" />
+                      <span class="suggested-bid-item">--</span>
+                      <el-form-item prop="similarProductsInp">
+                        <el-input
+                          :disabled="!targetGroupRuleForm.similarProducts"
+                          v-model="targetGroupRuleForm.similarProductsInp"
+                          minlength="3"
+                          maxlength="4"
+                          class="bid-input">
+                          <template #prepend>$</template>
+                        </el-input>
+                      </el-form-item>
+                    </div>
+                  </div>
+                  <div>
+                    <div style="display: flex">
+                      <el-switch v-model="targetGroupRuleForm.relatedProducts" size="small" active-text="关联商品" @change="relatedProductsChange" />
+                      <span class="suggested-bid-item">--</span>
+                      <el-form-item prop="relatedProductsInp">
+                        <el-input
+                          :disabled="!targetGroupRuleForm.relatedProducts"
+                          v-model="targetGroupRuleForm.relatedProductsInp"
+                          minlength="3"
+                          maxlength="4"
+                          class="bid-input">
+                          <template #prepend>$</template>
+                        </el-input>
+                      </el-form-item>
+                    </div>
+                  </div>
+                </div>
+                <div style="display: flex; justify-content: space-around">
+                  <el-button type="primary" plain :disabled="targetGroupBidSave" @click="submitTargetGroupForm">保存</el-button>
+                </div>
+              </el-card>
+            </div>
+          </el-form>
+
+          <!-- 投放类型 -->
+          <div class="column-item" v-if="campaignRuleForm.type == 'MANUAL'">
+            <p style="color: #606266; font-weight: 450"><span style="color: #e47470">*</span> 投放类型</p>
+            <el-radio-group v-model="ruleForm.targetType" @change="changeTargetType">
+              <div style="display: flex">
+                <el-radio label="keyWords" style="align-items: flex-start; margin-top: 5px">
+                  <div style="margin-top: -4px">关键词投放</div>
+                  <div>选择关键词以帮助您的商品出现在购物者搜索中</div>
+                </el-radio>
+              </div>
+              <div>
+                <el-radio label="Goods" style="align-items: flex-start; margin-top: 20px">
+                  <div style="margin-top: -4px">商品投放</div>
+                  <div>选择特定的商品, 分类, 品牌或者其他商品功能来定向您的广告</div>
+                </el-radio>
+              </div>
+            </el-radio-group>
+          </div>
+          <!-- 关键词定向 -->
+          <div
+            style="font-size: 20px; font-weight: bold; margin-top: 30px"
+            v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'">
+            关键词定向
+          </div>
+          <hr v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'" />
+          <el-form-item style="width: 100%; margin-top: 20px" v-if="ruleForm.targetType == 'keyWords' && campaignRuleForm.type == 'MANUAL'">
+            <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px" v-loading="keywordsLoading">
+              <div style="width: 50%; border-right: 1px solid #e5e7eb">
+                <el-tabs v-model="keyWordsTabs" class="demo-tabs" @tab-click="handleGoodsTabs">
+                  <div style="margin: 8px">
+                    <p style="margin-left: 8px; margin-bottom: -8px; font-weight: 500; color: #616266">竞价:</p>
+                    <div style="display: flex; align-items: center">
+                      <el-select v-model="bidType" class="m-2" placeholder="Select" style="width: 450px">
+                        <el-option v-for="item in bidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
+                      </el-select>
+                      <el-input v-model="bidInput" :disabled="!(bidType == 'customBid')" placeholder="Please input">
+                        <template #prepend>$</template>
+                      </el-input>
+                    </div>
+                    <div style="display: flex">
+                      <span style="margin: 0 10px 0 8px; font-weight: 500; color: #616266">匹配类型: </span>
+                      <el-checkbox v-model="broadType" label="广泛" />
+                      <el-checkbox v-model="phraseType" label="词组" />
+                      <el-checkbox v-model="exactType" label="精确" />
+                    </div>
+                  </div>
+                  <el-tab-pane label="建议" name="first">
+                    <el-table
+                      height="425"
+                      style="width: 100%; padding-left: 5px"
+                      v-loading="loading"
+                      :data="keyWordsTableData"
+                      :header-cell-style="headerCellStyle"
+                      :header-row-style="changeKeyWordsTableHeader">
+                      <el-table-column prop="asin" label="关键词"> </el-table-column>
+                      <el-table-column prop="name" label="匹配类型"> </el-table-column>
+                      <el-table-column prop="name" label="建议出价" width="120"> </el-table-column>
+                    </el-table>
+                  </el-tab-pane>
+                  <el-tab-pane label="输入" name="second">
+                    <el-input v-model="keyWordsTextarea" :rows="10" type="textarea" style="padding-left: 5px" />
+                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                      <el-button type="primary" text bg @click="addKeyWords">添加</el-button>
+                    </div>
+                  </el-tab-pane>
+                </el-tabs>
+              </div>
+              <div style="width: 50%">
+                <el-card class="box-card" shadow="never" style="border: none">
+                  <template #header>
+                    <div class="card-header">
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedKeyWordsTableData.length }}</span>
+                      <span style="color: #529b2e">成功: {{ successCount }}</span>
+                      <span style="color: #c45656">失败: {{ errorCount }}</span>
+                      <el-button class="button" type="danger" text bg @click="delAllKeyWords">全部删除</el-button>
+                    </div>
+                  </template>
+                  <div class="card-body" body-style="padding-bottom: -20px;">
+                    <el-table
+                      :data="addedKeyWordsTableData"
+                      style="width: 100%; height: 450px"
+                      :header-row-style="changeKeyWordsTableHeader"
+                      :header-cell-style="headerCellStyle">
+                      <el-table-column prop="keyword" label="关键词" width="auto" />
+                      <el-table-column prop="matchType" label="匹配类型" />
+                      <el-table-column prop="bid" label="出价">
+                        <template #default="scope">
+                          <el-input v-model="scope.row.bid" placeholder="Please input bid" />
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="suggestBid" label="建议出价" />
+                      <el-table-column prop="operate" label="操作" width="60" align="right">
+                        <template #default="scope">
+                          <el-button type="danger" size="small" link @click="delSingleKeyWord(scope)">删除</el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </el-card>
+                <div style="display: flex; justify-content: space-around; padding-top: 0px">
+                  <el-button type="primary" plain @click="keyWordsSave" :disabled="!addedKeyWordsTableData.length">保存</el-button>
+                </div>
+              </div>
+            </div>
+          </el-form-item>
 
-// 修改表头样式
-const headerCellStyle = (args) => {
-  if (args.rowIndex === 0) {
-    return {
-      backgroundColor: 'rgba(245, 245, 245, 0.9)',
-    }
-  }
-}
+          <div
+            style="font-size: 20px; font-weight: bold; margin-top: 30px"
+            v-if="campaignRuleForm.type === 'AUTO' || (ruleForm.targetType === 'keyWords' && campaignRuleForm.type === 'MANUAL')">
+            否定词
+          </div>
+          <hr v-if="campaignRuleForm.type === 'AUTO' || (ruleForm.targetType === 'keyWords' && campaignRuleForm.type === 'MANUAL')" />
+          <!-- 否定词表格 -->
+          <el-form-item
+            style="width: 100%; margin-top: 20px"
+            v-if="campaignRuleForm.type === 'AUTO' || (ruleForm.targetType === 'keyWords' && campaignRuleForm.type === 'MANUAL')">
+            <div style="width: 100%; height: 520px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px" v-loading="negativeWordsLoading">
+              <div style="width: 50%; border-right: 1px solid #e5e7ec">
+                <div style="margin: 10px 0">
+                  <span style="margin-left: 25px; color: #e47470">*</span>
+                  <span style="color: #666666; margin-right: 10px">匹配类型: </span>
+                  <el-checkbox v-model="NEGATIVE_PHRASE" label="词组否定" />
+                  <el-checkbox v-model="NEGATIVE_EXACT" label="精确否定" />
+                </div>
+                <el-input
+                  v-model="negativeWordsTextarea"
+                  :rows="17"
+                  type="textarea"
+                  placeholder="请输入关键词,多个关键词使用逗号或者换行符分隔。(最多添加1000个关键词)"
+                  maxlength="11000"
+                  style="padding: 0 20px" />
+                <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                  <el-button style="margin-right: 18px" type="primary" text bg @click="addNegative">添加</el-button>
+                </div>
+              </div>
+              <div style="width: 50%">
+                <el-card class="box-card" shadow="never" style="border: none">
+                  <template #header>
+                    <div class="card-header">
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedData.length }}</span>
+                      <el-button class="button" text bg :disabled="!tableData.length" @click="delAllNegative">全部删除</el-button>
+                    </div>
+                  </template>
+                  <div class="card-body">
+                    <el-table :data="tableData" style="width: 100%; height: 370px; padding-bottom: 0" :header-row-style="changeNegTableHeader">
+                      <el-table-column prop="negativeWords" label="否定词" width="auto" />
+                      <el-table-column prop="operate" label="操作" width="60" align="right">
+                        <template #default="scope">
+                          <el-button type="primary" size="small" @click="delSingleNegative(scope)" text>删除</el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </el-card>
+                <div style="display: flex; justify-content: space-around">
+                  <el-button type="primary" plain @click="negativeWordsSave" :disabled="!negativeList.length">保存</el-button>
+                </div>
+              </div>
+            </div>
+          </el-form-item>
 
-function changeNegTableHeader(args) {
-  if (args.rowIndex === 0) {
-    return {
-      color: '#505968',
-    }
-  }
-}
+          <!-- 商品定向 -->
+          <div style="font-size: 20px; font-weight: bold; margin-top: 30px" v-if="ruleForm.targetType == 'Goods'">商品定向</div>
+          <hr v-if="ruleForm.targetType == 'Goods'" />
+          <el-form-item style="width: 100%; margin-top: 20px" v-if="ruleForm.targetType == 'Goods'">
+            <div
+              style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7eb; border-radius: 6px"
+              v-loading="productOrientationLoading">
+              <div style="width: 50%; border-right: 1px solid #e5e7eb">
+                <el-tabs
+                  type="border-card"
+                  stretch
+                  class="goods-orientation-tabs"
+                  style="border: 0; border-right: 0; border-bottom-left-radius: 6px; border-top-left-radius: 5px; overflow: hidden">
+                  <el-tab-pane label="品类" style="border-top-left-radius: 6px">
+                    <div style="display: flex; align-items: center">
+                      <span style="width: 40px">竞价:</span>
+                      <el-select v-model="categoryBiddingType" @change="singleGoodsBidSelectChanged" class="m-2" placeholder="Select">
+                        <el-option v-for="item in categoryBiddingTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
+                      </el-select>
+                      <el-input v-model="singleGoodsBidInput" :disabled="categoryBiddingType === 'defaultBid'" style="width: 200px">
+                        <template #prepend>$</template>
+                      </el-input>
+                    </div>
 
-function changeKeyWordsTableHeader(args) {
-  if (args.rowIndex === 0) {
-    return {
-      color: '#505968',
-      backgroundColor: 'rgba(245, 245, 245, 0.9)',
-    }
-  }
-}
+                    <el-tabs v-model="categoryTabs" class="category-tabs">
+                      <el-tab-pane label="建议" name="first">
+                        <el-table :data="proposalTableData" style="width: 100%" height="422">
+                          <el-table-column prop="proposal" label="建议" width="520">
+                            <template #header> 0建议 </template>
+                          </el-table-column>
+                          <el-table-column prop="address" label="Address">
+                            <template #header>
+                              <el-button type="primary" size="normal" link @click="handleGoodsAdd">全部添加</el-button>
+                            </template>
+                            <template #default="scope">
+                              <el-button type="primary" size="small" @click="addSingleGoods(scope)" text>添加</el-button>
+                            </template>
+                          </el-table-column>
+                        </el-table>
+                      </el-tab-pane>
+                      <el-tab-pane label="搜索" name="second">
+                        <el-input placeholder="请输入关键词过滤" />
+                        <el-scrollbar height="390px">
+                          <el-tree :data="searchClassifyTableData" :props="defaultProps" :expand-on-click-node="false">
+                            <template #default="{ node, data }">
+                              <span class="custom-tree-node">
+                                <span style="width: 75%">{{ node.label }}</span>
+                                <span style="color: rgb(50, 108, 216)" v-if="data.ta == true">
+                                  <a @click="refine(data)"> 细化 </a>
+                                  <a style="margin-left: 8px" @click="orientate(node, data)"> 定向 </a>
+                                </span>
+                              </span>
+                            </template>
+                          </el-tree>
+                        </el-scrollbar>
+                        <el-dialog v-model="visible" :title="`细化分类: ${dialogTitle}`" @close="dialogClose" destroy-on-close>
+                          <div style="display: flex; justify-content: space-between">
+                            <span>根据特定品牌、价格范围、星级和Prime配送资格,细化分类</span>
+                            <span>
+                              <el-checkbox v-model="dialogForm.isCount" label="显示商品数量" @change="isCountChanged" />
+                            </span>
+                          </div>
+                          <el-form :model="dialogForm" :rules="dialogRules" ref="dialogFormRef" style="margin-top: 20px">
+                            <el-form-item style="padding-left: 140px">
+                              <span style="margin-right: 10px; color: #616266; font-weight: 500">品牌</span>
+                              <el-select
+                                v-model="dialogForm.dialogselectValue"
+                                @change="dialogSelectChange"
+                                multiple
+                                placeholder="请选择"
+                                :loading="dialogSelectLoading">
+                                <el-option v-for="item in dialogForm.dialogOptions" :key="item.value" :label="item.label" :value="item.value" />
+                              </el-select>
+                            </el-form-item>
+                            <el-form-item prop="prices" style="padding-left: 112px; margin-top: 10px">
+                              <span style="margin-right: 10px; color: #616266; font-weight: 500">价格范围</span>
+                              <el-input-number v-model="dialogForm.prices.lowest" :min="1" :controls="false" placeholder="无最低商品价格" />
+                              --
+                              <el-input-number v-model="dialogForm.prices.highest" :min="1" :controls="false" placeholder="无最高商品价格" />
+                            </el-form-item>
+                            <el-form-item prop="starRating" style="padding-left: 85px; margin-top: 10px">
+                              <span style="margin-right: 15px; color: #616266; font-weight: 500">查看星级评定</span>
+                              <el-slider v-model="dialogForm.starRating" range show-stops :max="5" :marks="marks" style="width: 70%" />
+                            </el-form-item>
+                            <el-form-item prop="delivery" style="padding-left: 140px; margin-top: 30px">
+                              <span style="margin-right: 10px; color: #616266; font-weight: 500">配送</span>
+                              <el-radio-group v-model="dialogForm.delivery">
+                                <el-radio label="all" style="font-weight: 400">所有</el-radio>
+                                <el-radio label="eligible" style="font-weight: 400">具备Prime资格</el-radio>
+                                <el-radio label="diseligible" style="font-weight: 400">不具备Prime资格</el-radio>
+                              </el-radio-group>
+                            </el-form-item>
+                          </el-form>
+                          <template #footer>
+                            <div style="display: flex; justify-content: space-between">
+                              <span v-loading="countLoadig"
+                                >定位到的商品数量:
+                                <span v-if="dialogForm.isCount == true">{{ commodityCount[0]?.min }} - {{ commodityCount[0]?.max }}</span></span
+                              >
+                              <span class="dialog-footer">
+                                <el-button @click="visible = false">取消</el-button>
+                                <el-button type="primary" @click="dialogFormSubmit">确定</el-button>
+                              </span>
+                            </div>
+                          </template>
+                        </el-dialog>
+                      </el-tab-pane>
+                    </el-tabs>
+                  </el-tab-pane>
+                  <el-tab-pane label="单个商品">
+                    <div style="display: flex; align-items: center">
+                      <span style="width: 40px">竞价:</span>
+                      <el-select class="m-2" v-model="singleGoodsBidSelect" @change="singleGoodsBidSelectChanged">
+                        <el-option v-for="item in singleGoodsBidTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
+                      </el-select>
+                      <el-input v-model="singleGoodsBidInput" :disabled="singleGoodsBidSelect == 'defaultBid'" style="width: 200px">
+                        <template #prepend>$</template>
+                      </el-input>
+                      <div style="margin-left: 20px">
+                        <span style="margin-right: 10px">类型:</span>
+                        <el-checkbox v-model="expand" label="扩展" />
+                        <el-checkbox v-model="accurate" label="精准" />
+                      </div>
+                    </div>
+                    <el-tabs v-model="singleGoodsTabs" class="category-tabs">
+                      <el-tab-pane label="建议" name="first">
+                        <el-table :data="proposalTableData" style="width: 100%" height="342">
+                          <el-table-column prop="proposal" label="商品" width="520" />
+                          <el-table-column prop="address" label="类型" />
+                          <el-table-column prop="operational" label="操作" />
+                        </el-table>
+                      </el-tab-pane>
+                      <el-tab-pane label="搜索" name="second">
+                        <el-input v-model="singleGoodsSearchInp" @change="singleGoodsSearchChaneged" placeholder="按ASIN搜索"></el-input>
+                        <el-table :data="searchTableData" style="width: 100%" height="309">
+                          <el-table-column prop="asin" label="商品" width="520">
+                            <template #default="{ row }">
+                              <div style="display: flex; align-items: center">
+                                <img :src="row.image_link" style="width: 40px; height: 40px; margin-right: 10px" />
+                                <span>{{ row.title }}</span>
+                              </div>
+                            </template>
+                          </el-table-column>
+                          <el-table-column prop="productTypes" label="类型">
+                            <template #default="scope">
+                              <div v-if="expand">扩展</div>
+                              <div v-if="accurate">精准</div>
+                            </template>
+                          </el-table-column>
+                          <el-table-column prop="operational" label="操作">
+                            <template #default="scope">
+                              <el-button class="button" type="primary" text @click="addSingleSearch(scope)">添加</el-button>
+                            </template>
+                          </el-table-column>
+                        </el-table>
+                      </el-tab-pane>
+                      <!-- TODO: 商品定向TextArea -->
+                      <!-- <el-tab-pane label="输入" name="third">暂无此功能</el-tab-pane> -->
+                    </el-tabs>
+                  </el-tab-pane>
+                </el-tabs>
+              </div>
+              <div style="width: 50%">
+                <el-card class="box-card" shadow="never" style="border: none">
+                  <template #header>
+                    <div class="card-header">
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ productOrientationTableData.length }}</span>
+                      <el-button class="button" type="danger" text bg @click="delAllCna">全部删除</el-button>
+                    </div>
+                  </template>
+                  <div class="card-body">
+                    <el-table
+                      height="460"
+                      :data="productOrientationTableData"
+                      style="width: 100%"
+                      :header-row-style="changeKeyWordsTableHeader"
+                      :header-cell-style="headerCellStyle">
+                      <el-table-column prop="cna" label="分类 & 商品" width="300">
+                        <template #default="scope">
+                          <div v-if="scope.row.cna || scope.row.classification">
+                            分类: <span style="color: #000000">{{ scope.row.cna ? scope.row.cna : scope.row.classification }}</span>
+                          </div>
+                          <div v-if="scope.row.asin">
+                            {{ scope.row.asin ? scope.row.asin : '--' }}
+                          </div>
+                          <div v-if="scope.row.brand">
+                            品牌: <span style="color: #000000">{{ scope.row.brand }}</span>
+                          </div>
+                          <div v-if="scope.row.low_price || scope.row.high_price">
+                            品牌价格:
+                            <span style="color: #000000">
+                              {{ scope.row.low_price ? '$' + scope.row.low_price : '--' }} -
+                              {{ scope.row.high_price ? '$' + scope.row.high_price : '--' }}
+                            </span>
+                          </div>
+                          <div v-if="scope.row.low_rating || scope.row.high_rating">
+                            评分: <span style="color: #000000">{{ scope.row.low_rating }} - {{ scope.row.high_rating }}</span>
+                          </div>
+                          <div v-if="scope.row.deliveryText">
+                            配送: <span style="color: #000000">{{ scope.row.deliveryText }}</span>
+                          </div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="type" label="类型">
+                        <template #default="scope">
+                          {{ scope.row.productTypeText ? scope.row.productTypeText : '--' }}
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="bid" label="竞价">
+                        <template #default="scope">
+                          <el-input-number v-model="scope.row.bid" :min="0.02" :max="1000000" :controls="false" size="small" />
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="operate" label="操作" width="60" align="right">
+                        <template #default="scope">
+                          <el-button type="danger" text size="small" @click="delCna(scope.$index)">删除</el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </el-card>
+                <div style="display: flex; justify-content: space-around; margin-top: -8px">
+                  <el-button type="primary" plain @click="productTagetSave">保存</el-button>
+                </div>
+              </div>
+            </div>
+          </el-form-item>
 
-onMounted(() => {
-  setTableData()
-  getAdMix()
-  // const myTest = route.query
-  // console.log('myTest', myTest)
-})
+          <div
+            style="font-size: 20px; font-weight: bold; margin-top: 30px"
+            v-if="campaignRuleForm.type == 'AUTO' || (ruleForm.targetType == 'Goods' && campaignRuleForm.type === 'MANUAL')">
+            否定商品
+          </div>
+          <hr v-if="campaignRuleForm.type == 'AUTO' || (ruleForm.targetType == 'Goods' && campaignRuleForm.type === 'MANUAL')" />
+          <el-form-item
+            prop="matchType"
+            style="width: 100%; margin-top: 20px"
+            v-if="campaignRuleForm.type == 'AUTO' || (ruleForm.targetType == 'Goods' && campaignRuleForm.type === 'MANUAL')">
+            <div style="width: 100%; height: 600px; display: flex; border: 1px solid #e5e7ec; border-radius: 6px" v-loading="negativeGoodsLoading">
+              <div style="width: 50%; border-right: 1px solid #e5e7ec">
+                <el-tabs v-model="negativeTabs" class="demo-tabs" @tab-click="handleNegGoodsTabs">
+                  <el-tab-pane label="搜索" name="first">
+                    <div style="margin-bottom: 10px">
+                      <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegativeGoods" clearable />
+                    </div>
+                    <el-table
+                      height="495"
+                      style="width: 100%"
+                      v-loading="loading"
+                      :data="negativeTableData"
+                      :header-cell-style="headerCellStyle"
+                      :show-header="false">
+                      <el-table-column prop="asin" label="商品">
+                        <template #default="scope">
+                          <div style="display: flex; align-items: center">
+                            <div style="margin-right: 8px; line-height: normal">
+                              <el-image class="img-box" :src="scope.row.image_link" />
+                            </div>
+                            <div>
+                              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                                <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                              </el-tooltip>
+                              <span>
+                                ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                              </span>
+                            </div>
+                          </div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="name" label="Name" width="120" align="right">
+                        <template #header> </template>
+                        <template #default="scope">
+                          <el-button type="primary" size="small" @click="addSingleNegativeGoods(scope)" text>添加</el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </el-tab-pane>
+                  <el-tab-pane label="输入" name="second">
+                    <el-input
+                      v-model="ruleForm.negativeGoodsTextarea"
+                      :disabled="true"
+                      :rows="17"
+                      type="textarea"
+                      maxlength="11000"
+                      style="padding: 10px 10px" />
+                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                      <el-button
+                        style="margin-right: 10px"
+                        type="primary"
+                        text
+                        bg
+                        :disabled="!ruleForm.negativeGoodsTextarea"
+                        @click="addNegativeGoods"
+                        >添加</el-button
+                      >
+                    </div>
+                  </el-tab-pane>
+                </el-tabs>
+              </div>
+              <div style="width: 50%">
+                <el-card class="box-card" shadow="never" style="border: none">
+                  <template #header>
+                    <div class="card-header">
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
+                      <el-button class="button" text bg @click="delAllNegativeGoods">全部删除</el-button>
+                    </div>
+                  </template>
+                  <div class="card-body"></div>
+                </el-card>
+                <div style="padding: 0 10px 0 10px; margin-top: -30px">
+                  <el-table
+                    :data="addedNegetiveTableData"
+                    height="473"
+                    style="width: 100%"
+                    :header-cell-style="headerCellStyle"
+                    @selection-change="handleAddedNegGoods">
+                    <el-table-column prop="asin" label="商品">
+                      <template #default="scope">
+                        <div style="display: flex; align-items: center">
+                          <div style="margin-right: 8px; line-height: normal">
+                            <el-image class="img-box" :src="scope.row.image_link" />
+                          </div>
+                          <div>
+                            <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                              <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                            </el-tooltip>
+                            <span
+                              >ASIN:
+                              <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                            </span>
+                          </div>
+                        </div>
+                      </template>
+                    </el-table-column>
+                    <el-table-column label="操作" width="120" align="right">
+                      <template #default="scope">
+                        <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </div>
+                <div style="display: flex; justify-content: space-around; padding-top: 10px">
+                  <el-button plain type="primary" @click="negativeGoodsSave" :disabled="!addedNegetiveTableData.length">保存</el-button>
+                </div>
+              </div>
+            </div>
+          </el-form-item>
 
-defineOptions({
-  name: 'SpCreateCampaigns',
-})
-</script>
+          <!-- <br />
+          <el-form-item>
+            <el-button size="large" @click="resetForm(ruleFormRef)">取消</el-button>
+            <el-button size="large" type="primary" plain @click="submitForm(ruleFormRef)">保存</el-button>
+          </el-form-item> -->
+        </el-form>
+      </div>
+    </el-card>
+  </div>
+</template>
 
 <style lang="scss" scoped>
 :deep(.el-form--default.el-form--label-top .el-form-item .el-form-item__label) {

+ 113 - 113
src/views/adManage/sp/campaigns/CreateCampaigns/negativeGoods/index.vue

@@ -1,116 +1,3 @@
-<template>
-  <el-form
-    :label-position="labelPosition"
-    ref="ruleFormRef"
-    :model="ruleForm"
-    :rules="rules"
-    label-width="120px"
-    class="demo-ruleForm"
-    :size="formSize"
-    status-icon>
-
-    <el-form-item prop="matchType" style="width: 100%; margin-top: 20px">
-            <div style="width: 100%; height: 520px; display: flex; border: 1px solid #c2c7cf; border-radius: 6px">
-              <div style="width: 50%; border-right: 1px solid #c2c7cf">
-                <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
-                  <el-tab-pane label="搜索" name="first">
-                    <div style="margin-bottom: 10px">
-                      <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegative" clearable />
-                    </div>
-                    <el-table
-                      height="415"
-                      style="width: 100%"
-                      v-loading="loading"
-                      :data="negativeTableData"
-                      :header-cell-style="headerCellStyle"
-                      :show-header="false">
-                      <el-table-column prop="asin" label="商品">
-                        <template #default="scope">
-                          <div style="display: flex; align-items: center">
-                            <div style="margin-right: 8px; line-height: normal">
-                              <el-image class="img-box" :src="scope.row.image_link" />
-                            </div>
-                            <div>
-                              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                                <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                              </el-tooltip>
-                              <span>
-                                ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                              </span>
-                            </div>
-                          </div>
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="name" label="Name" width="120" align="right">
-                        <template #header> </template>
-                        <template #default="scope">
-                          <el-button type="primary" size="small" @click="addSingleNegative(scope)" text>添加</el-button>
-                        </template>
-                      </el-table-column>
-                    </el-table>
-                  </el-tab-pane>
-                  <el-tab-pane label="输入" name="second">
-                    <el-input
-                      v-model="ruleForm.negativeGoodsTextarea"
-                      :rows="17"
-                      type="textarea"
-                      placeholder="请输入关键词,多个关键词使用逗号或者换行符分隔。(最多添加1000个关键词)"
-                      maxlength="11000"
-                      style="padding: 10px 10px" />
-                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
-                      <el-button style="margin-right: 10px" type="primary" text bg @click="addNegativeGoods">添加</el-button>
-                    </div>
-                  </el-tab-pane>
-                </el-tabs>
-              </div>
-              <div style="width: 50%">
-                <el-card class="box-card" shadow="never">
-                  <template #header>
-                    <div class="card-header">
-                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
-                      <el-button class="button" text bg @click="delAllNegativeGoods">全部删除</el-button>
-                    </div>
-                  </template>
-                  <div class="card-body"></div>
-                </el-card>
-                <div style="padding: 0 10px 0 10px; margin-top: -12px">
-                  <el-table
-                    :data="addedNegetiveTableData"
-                    height="415"
-                    style="width: 100%"
-                    :header-cell-style="headerCellStyle"
-                    @selection-change="handleAddedChange">
-                    <el-table-column prop="asin" label="商品">
-                      <template #default="scope">
-                        <div style="display: flex; align-items: center">
-                          <div style="margin-right: 8px; line-height: normal">
-                            <el-image class="img-box" :src="scope.row.image_link" />
-                          </div>
-                          <div>
-                            <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
-                              <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
-                            </el-tooltip>
-                            <span
-                              >ASIN:
-                              <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
-                            </span>
-                          </div>
-                        </div>
-                      </template>
-                    </el-table-column>
-                    <el-table-column label="操作" width="120" align="right">
-                      <template #default="scope">
-                        <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
-                      </template>
-                    </el-table-column>
-                  </el-table>
-                </div>
-              </div>
-            </div>
-          </el-form-item>
-  </el-form>
-</template>
-
 <script lang="ts" setup>
 import { onMounted, reactive, ref, computed, watch } from 'vue'
 import { useRoute } from 'vue-router'
@@ -224,4 +111,117 @@ const headerCellStyle = (args) => {
 
 </script>
 
+<template>
+  <el-form
+    :label-position="labelPosition"
+    ref="ruleFormRef"
+    :model="ruleForm"
+    :rules="rules"
+    label-width="120px"
+    class="demo-ruleForm"
+    :size="formSize"
+    status-icon>
+
+    <el-form-item prop="matchType" style="width: 100%; margin-top: 20px">
+            <div style="width: 100%; height: 520px; display: flex; border: 1px solid #c2c7cf; border-radius: 6px">
+              <div style="width: 50%; border-right: 1px solid #c2c7cf">
+                <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+                  <el-tab-pane label="搜索" name="first">
+                    <div style="margin-bottom: 10px">
+                      <el-input placeholder="按ASIN搜索" v-model="negativeInput" @change="searchNegative" clearable />
+                    </div>
+                    <el-table
+                      height="415"
+                      style="width: 100%"
+                      v-loading="loading"
+                      :data="negativeTableData"
+                      :header-cell-style="headerCellStyle"
+                      :show-header="false">
+                      <el-table-column prop="asin" label="商品">
+                        <template #default="scope">
+                          <div style="display: flex; align-items: center">
+                            <div style="margin-right: 8px; line-height: normal">
+                              <el-image class="img-box" :src="scope.row.image_link" />
+                            </div>
+                            <div>
+                              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                                <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                              </el-tooltip>
+                              <span>
+                                ASIN: <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                              </span>
+                            </div>
+                          </div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="name" label="Name" width="120" align="right">
+                        <template #header> </template>
+                        <template #default="scope">
+                          <el-button type="primary" size="small" @click="addSingleNegative(scope)" text>添加</el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </el-tab-pane>
+                  <el-tab-pane label="输入" name="second">
+                    <el-input
+                      v-model="ruleForm.negativeGoodsTextarea"
+                      :rows="17"
+                      type="textarea"
+                      placeholder="请输入关键词,多个关键词使用逗号或者换行符分隔。(最多添加1000个关键词)"
+                      maxlength="11000"
+                      style="padding: 10px 10px" />
+                    <div style="display: flex; flex-direction: row-reverse; margin-top: 10px">
+                      <el-button style="margin-right: 10px" type="primary" text bg @click="addNegativeGoods">添加</el-button>
+                    </div>
+                  </el-tab-pane>
+                </el-tabs>
+              </div>
+              <div style="width: 50%">
+                <el-card class="box-card" shadow="never">
+                  <template #header>
+                    <div class="card-header">
+                      <span style="font-weight: 550; font-size: 15px; color: #1f2128">已添加: {{ addedNegetiveTableData.length }}</span>
+                      <el-button class="button" text bg @click="delAllNegativeGoods">全部删除</el-button>
+                    </div>
+                  </template>
+                  <div class="card-body"></div>
+                </el-card>
+                <div style="padding: 0 10px 0 10px; margin-top: -12px">
+                  <el-table
+                    :data="addedNegetiveTableData"
+                    height="415"
+                    style="width: 100%"
+                    :header-cell-style="headerCellStyle"
+                    @selection-change="handleAddedChange">
+                    <el-table-column prop="asin" label="商品">
+                      <template #default="scope">
+                        <div style="display: flex; align-items: center">
+                          <div style="margin-right: 8px; line-height: normal">
+                            <el-image class="img-box" :src="scope.row.image_link" />
+                          </div>
+                          <div>
+                            <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                              <div class="single-line">{{ scope.row.title ? scope.row.title : '--' }}</div>
+                            </el-tooltip>
+                            <span
+                              >ASIN:
+                              <span class="data-color" style="margin-right: 8px">{{ scope.row.asin ? scope.row.asin : '--' }}</span>
+                            </span>
+                          </div>
+                        </div>
+                      </template>
+                    </el-table-column>
+                    <el-table-column label="操作" width="120" align="right">
+                      <template #default="scope">
+                        <el-button type="primary" size="small" @click="delSingleNegativeGoods(scope)" text>删除</el-button>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </div>
+              </div>
+            </div>
+          </el-form-item>
+  </el-form>
+</template>
+
 <style></style>

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

@@ -1,3 +1,34 @@
+<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 Automation from './automation/index.vue'
+import {getEnumLabel} from '/@/views/adManage/utils/tools.js'
+import {dynBidStrategyEnum} from '/@/views/adManage/utils/enum.js'
+import {useShopInfo} from '/@/stores/shopInfo'
+// import { usePublicData } from '/@/stores/publicData'
+import {storeToRefs} from 'pinia'
+
+import {GetObj} from './api'
+
+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 () => {
+  const resp = await GetObj(route.query.campaignId)
+  campaignInfo.value = resp.data
+})
+
+
+</script>
+
 <template>
   <div class="asj-container">
     <div class="asj-detail-header">
@@ -52,37 +83,6 @@
   </div>
 </template>
 
-<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 Automation from './automation/index.vue'
-import {getEnumLabel} from '/@/views/adManage/utils/tools.js'
-import {dynBidStrategyEnum} from '/@/views/adManage/utils/enum.js'
-import {useShopInfo} from '/@/stores/shopInfo'
-// import { usePublicData } from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
-
-import {GetObj} from './api'
-
-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 () => {
-  const resp = await GetObj(route.query.campaignId)
-  campaignInfo.value = resp.data
-})
-
-
-</script>
-
 <style>
 /* .el-tabs--card {
   height: calc(100vh - 80px);

+ 31 - 31
src/views/adManage/sp/campaigns/chartComponents/adStruct.vue

@@ -1,34 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="9">
-        <div>
-          <TextSelector v-model="modelValue" :options="computedPieOptions" @change="changePie" style="margin-top: 5px" />
-        </div>
-        <div ref="pie" style="height: 400px"></div>
-      </el-col>
-      <el-col :span="15">
-        <div style="margin-left: 40%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import { computed, inject, onMounted, ref, watch } from 'vue'
 import * as echarts from 'echarts'
@@ -530,4 +499,35 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="9">
+        <div>
+          <TextSelector v-model="modelValue" :options="computedPieOptions" @change="changePie" style="margin-top: 5px" />
+        </div>
+        <div ref="pie" style="height: 400px"></div>
+      </el-col>
+      <el-col :span="15">
+        <div style="margin-left: 40%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 7 - 7
src/views/adManage/sp/campaigns/chartComponents/dataTendency.vue

@@ -1,10 +1,3 @@
-<template>
-    <div v-loading="loading">
-        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-        <div style="height: 350px;" ref="chartRef"></div>
-    </div>
-</template>
-
 <script lang="ts" setup>
 import {ref, onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed} from 'vue'
 import * as echarts from 'echarts'
@@ -250,6 +243,13 @@ const removeResize = () => {
 
 </script>
 
+<template>
+    <div v-loading="loading">
+        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+        <div style="height: 350px;" ref="chartRef"></div>
+    </div>
+</template>
+
 <style scoped>
 .metrics-cards {
     display: flex;

+ 47 - 47
src/views/adManage/sp/campaigns/index.vue

@@ -1,3 +1,50 @@
+<script lang="ts" setup>
+import { onMounted, ref, watch } from 'vue'
+import { FsPage, useFs } from '@fast-crud/fast-crud'
+import { createCrudOptions } from './crud'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
+import { useRouter } from 'vue-router'
+import AdStructChart from './chartComponents/adStruct.vue'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+import DataCompare from '/@/components/dataCompare/index.vue'
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange,
+})
+const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+const router = useRouter()
+const showCompare = ref(false)
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'SpCampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+onMounted(async () => {
+  crudExpose.doRefresh()
+})
+
+watch(
+  queryParams,
+  async () => {
+    crudExpose.doRefresh()
+  },
+  { deep: true }
+)
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -55,53 +102,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-import { onMounted, ref, watch } from 'vue'
-import { FsPage, useFs } from '@fast-crud/fast-crud'
-import { createCrudOptions } from './crud'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from '/@/stores/publicData'
-import { storeToRefs } from 'pinia'
-import { useRouter } from 'vue-router'
-import AdStructChart from './chartComponents/adStruct.vue'
-import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
-import DataCompare from '/@/components/dataCompare/index.vue'
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const { dateRange } = storeToRefs(publicData)
-const { profile } = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange,
-})
-const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-const router = useRouter()
-const showCompare = ref(false)
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'SpCampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-onMounted(async () => {
-  crudExpose.doRefresh()
-})
-
-watch(
-  queryParams,
-  async () => {
-    crudExpose.doRefresh()
-  },
-  { deep: true }
-)
-
-</script>
-
 <style lang="scss" scoped>
 .campare-switch {
   flex: none;

+ 12 - 12
src/views/adManage/sp/chartComponents/dataTendency.vue

@@ -1,15 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
-      <el-radio-button label="day">日</el-radio-button>
-      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
-      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
-    </el-radio-group>
-    <div style="height: 350px;" ref="chartRef"></div>
-</div>
-</template>
-
 <script lang="ts" setup>
 import {computed, onBeforeUnmount, onMounted, Ref, ref, watch} from 'vue'
 import * as echarts from 'echarts'
@@ -304,6 +292,18 @@ const removeResize = () => { window.removeEventListener('resize', resizeChart) }
 
 </script>
 
+<template>
+  <div v-loading="loading">
+    <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
+      <el-radio-button label="day">日</el-radio-button>
+      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
+      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
+    </el-radio-group>
+    <div style="height: 350px;" ref="chartRef"></div>
+</div>
+</template>
+
 <style scoped>
 .metrics-cards {
   display: flex;

+ 28 - 28
src/views/adManage/sp/index.vue

@@ -1,31 +1,3 @@
-<template>
-	<div class="asj-container">
-		<div class="public-search">
-			<DateRangePicker v-model="dateRange"></DateRangePicker>
-			<el-select
-				v-model="selectedPortfolios"
-				placeholder="广告组合"
-				clearable
-				multiple
-				style="width: 400px"
-				collapse-tags
-				collapse-tags-tooltip
-				:max-collapse-tags="3"
-				disabled="true"
-			>
-				<el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
-			</el-select>
-		</div>
-
-		<div class="asj-tabs">
-			<div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
-				{{ tab.label }}
-			</div>
-		</div>
-		<component :is="tabsComponents[tabActiveName]"></component>
-	</div>
-</template>
-
 <script lang="ts" setup>
 import { ref, onBeforeMount, Ref, watch, provide } from 'vue'
 import { useShopInfo } from '/@/stores/shopInfo'
@@ -75,6 +47,34 @@ onBeforeMount(async () => {
 
 </script>
 
+<template>
+	<div class="asj-container">
+		<div class="public-search">
+			<DateRangePicker v-model="dateRange"></DateRangePicker>
+			<el-select
+				v-model="selectedPortfolios"
+				placeholder="广告组合"
+				clearable
+				multiple
+				style="width: 400px"
+				collapse-tags
+				collapse-tags-tooltip
+				:max-collapse-tags="3"
+				disabled="true"
+			>
+				<el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
+			</el-select>
+		</div>
+
+		<div class="asj-tabs">
+			<div v-for="tab of tabs" :key="tab.name" :class="['asj-tab', { active: tabActiveName === tab.name }]" @click="tabActiveName = tab.name">
+				{{ tab.label }}
+			</div>
+		</div>
+		<component :is="tabsComponents[tabActiveName]"></component>
+	</div>
+</template>
+
 <style scoped>
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);

+ 25 - 25
src/views/adManage/sp/keywords/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import { onMounted, ref, inject, computed, watch } from 'vue'
 import * as echarts from 'echarts'
@@ -404,4 +379,29 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 43 - 43
src/views/adManage/sp/keywords/index.vue

@@ -1,3 +1,46 @@
+<script lang="ts" setup>
+import {onMounted, ref, watch} from 'vue'
+import {FsPage, useFs} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import {useShopInfo} from '/@/stores/shopInfo'
+import AdStructChart from './chartComponents/adStruct.vue'
+import {getCardData, getLineData, getLineMonthData, getLineWeekData} from './api'
+import {usePublicData} from '/@/stores/publicData'
+import {storeToRefs} from 'pinia'
+import router from '/@/router'
+import {BaseColumn} from '/@/views/adManage/utils/commonTabColumn'
+import DataCompare from '/@/components/dataCompare/index.vue'
+
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const {dateRange} = storeToRefs(publicData)
+const {profile} = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: queryParams})
+const showCompare = ref(false)
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+onMounted(async () => {
+  crudExpose.doRefresh()
+})
+
+watch(queryParams, async () => {
+  crudExpose.doRefresh()
+}, { deep: true })
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -69,49 +112,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-import {onMounted, ref, watch} from 'vue'
-import {FsPage, useFs} from '@fast-crud/fast-crud'
-import {createCrudOptions} from './crud'
-import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-import {useShopInfo} from '/@/stores/shopInfo'
-import AdStructChart from './chartComponents/adStruct.vue'
-import {getCardData, getLineData, getLineMonthData, getLineWeekData} from './api'
-import {usePublicData} from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
-import router from '/@/router'
-import {BaseColumn} from '/@/views/adManage/utils/commonTabColumn'
-import DataCompare from '/@/components/dataCompare/index.vue'
-
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const {dateRange} = storeToRefs(publicData)
-const {profile} = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: queryParams})
-const showCompare = ref(false)
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-onMounted(async () => {
-  crudExpose.doRefresh()
-})
-
-watch(queryParams, async () => {
-  crudExpose.doRefresh()
-}, { deep: true })
-
-</script>
-
 <style lang="scss" scoped>
 .chart-tabs {
   margin: 5px 0;

+ 25 - 25
src/views/adManage/sp/placement/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import * as echarts from 'echarts'
 import { storeToRefs } from 'pinia'
@@ -402,4 +377,29 @@ function resizeChart() {
 }
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 44 - 44
src/views/adManage/sp/placement/index.vue

@@ -1,3 +1,47 @@
+<script lang="ts" setup>
+import {onMounted, ref, watch} from 'vue'
+import {FsPage, useFs} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import {useRouter} from 'vue-router'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import {useShopInfo} from '/@/stores/shopInfo'
+import AdStructChart from './chartComponents/adStruct.vue'
+import {getCardData, getLineData, getLineMonthData, getLineWeekData} from '../campaigns/api'
+import {usePublicData} from '/@/stores/publicData'
+import {storeToRefs} from 'pinia'
+import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn'
+import DataCompare from '/@/components/dataCompare/index.vue'
+
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const {dateRange} = storeToRefs(publicData)
+const {profile} = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+const {crudBinding, crudRef, crudExpose} =  useFs({createCrudOptions, context: queryParams})
+const router = useRouter()
+const showCompare = ref(false)
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: {id: row.id, campaignId: row.campaignId, tagsViewName: row.campaignName},
+  })
+}
+
+onMounted(async () => {
+  crudExpose.doRefresh()
+})
+
+watch(queryParams, async () => {
+  crudExpose.doRefresh()
+}, { deep: true })
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -55,50 +99,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-import {onMounted, ref, watch} from 'vue'
-import {FsPage, useFs} from '@fast-crud/fast-crud'
-import {createCrudOptions} from './crud'
-import {useRouter} from 'vue-router'
-import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-import {useShopInfo} from '/@/stores/shopInfo'
-import AdStructChart from './chartComponents/adStruct.vue'
-import {getCardData, getLineData, getLineMonthData, getLineWeekData} from '../campaigns/api'
-import {usePublicData} from '/@/stores/publicData'
-import {storeToRefs} from 'pinia'
-import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn'
-import DataCompare from '/@/components/dataCompare/index.vue'
-
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const {dateRange} = storeToRefs(publicData)
-const {profile} = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-const {crudBinding, crudRef, crudExpose} =  useFs({createCrudOptions, context: queryParams})
-const router = useRouter()
-const showCompare = ref(false)
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: {id: row.id, campaignId: row.campaignId, tagsViewName: row.campaignName},
-  })
-}
-
-onMounted(async () => {
-  crudExpose.doRefresh()
-})
-
-watch(queryParams, async () => {
-  crudExpose.doRefresh()
-}, { deep: true })
-
-</script>
-
 <style lang="scss" scoped>
 .chart-tabs {
   margin: 5px 0;

+ 46 - 46
src/views/adManage/sp/purchasedOtherProducts/index.vue

@@ -1,3 +1,49 @@
+<script lang="ts" setup>
+import { ref, onMounted, computed, watch } from 'vue'
+import { useFs, FsPage } from '@fast-crud/fast-crud';
+import { createCrudOptions } from './crud'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
+import { spCampaignPuchasedOtherProductsMetricsEnum } from '/@/views/adManage/utils/enum.js'
+import { SpCampaignPuchasedOtherProductsColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+import DataCompare from '/@/components/dataCompare/index.vue'
+import router from '/@/router'
+
+const tabActiveName = ref("dataTendency")
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
+const initMetric = [
+  {metric: 'TotalPurchasesOtherSKU', color: '#0085ff', 'label': '其它商品订单数'},
+  {metric: 'TotalSalesOtherSKU', color: '#3fd4cf', 'label': '其它商品销售额'},
+  {metric: 'TotalUnitOrderedOtherSKU', color: '#ff9500', 'label': '其它商品销量'},
+]
+const showCompare = ref(false)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+onMounted(async () => {
+	crudExpose.doRefresh()
+})
+watch(queryParams, async () => {
+	crudExpose.doRefresh()
+}, { deep: true })
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -57,52 +103,6 @@
 	</fs-page>
 </template>
 
-<script lang="ts" setup>
-import { ref, onMounted, computed, watch } from 'vue'
-import { useFs, FsPage } from '@fast-crud/fast-crud';
-import { createCrudOptions } from './crud'
-import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from '/@/stores/publicData'
-import { storeToRefs } from 'pinia'
-import { spCampaignPuchasedOtherProductsMetricsEnum } from '/@/views/adManage/utils/enum.js'
-import { SpCampaignPuchasedOtherProductsColumn } from '/@/views/adManage/utils/commonTabColumn.js'
-import DataCompare from '/@/components/dataCompare/index.vue'
-import router from '/@/router'
-
-const tabActiveName = ref("dataTendency")
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const { dateRange } = storeToRefs(publicData)
-const { profile } = storeToRefs(shopInfo)
-const initMetric = [
-  {metric: 'TotalPurchasesOtherSKU', color: '#0085ff', 'label': '其它商品订单数'},
-  {metric: 'TotalSalesOtherSKU', color: '#3fd4cf', 'label': '其它商品销售额'},
-  {metric: 'TotalUnitOrderedOtherSKU', color: '#ff9500', 'label': '其它商品销量'},
-]
-const showCompare = ref(false)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-onMounted(async () => {
-	crudExpose.doRefresh()
-})
-watch(queryParams, async () => {
-	crudExpose.doRefresh()
-}, { deep: true })
-
-</script>
-
 <style scoped>
 .campare-switch {
   flex: none;

+ 46 - 46
src/views/adManage/sp/searchTerm/index.vue

@@ -1,3 +1,49 @@
+<script lang="ts" setup>
+import { ref, onMounted, watch, computed } from 'vue'
+import { useFs, FsPage } from '@fast-crud/fast-crud';
+import { createCrudOptions } from './crud'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
+import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+import DataCompare from '/@/components/dataCompare/index.vue'
+import {useRouter} from 'vue-router'
+
+
+const tabActiveName = ref("dataTendency")
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
+const router = useRouter()
+const showCompare = ref(false)
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'SpCampaignDetail',
+    query: {campaignId: row.campaignId, tagsViewName: row.campaignName},
+  })
+}
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
+
+onMounted(async () => {
+	crudExpose.doRefresh()
+})
+watch(
+	queryParams, 
+	async () => {
+		crudExpose.doRefresh()
+	},
+  { deep: true }
+)
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -60,52 +106,6 @@
 	</fs-page>
 </template>
 
-<script lang="ts" setup>
-import { ref, onMounted, watch, computed } from 'vue'
-import { useFs, FsPage } from '@fast-crud/fast-crud';
-import { createCrudOptions } from './crud'
-import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from '/@/stores/publicData'
-import { storeToRefs } from 'pinia'
-import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
-import DataCompare from '/@/components/dataCompare/index.vue'
-import {useRouter} from 'vue-router'
-
-
-const tabActiveName = ref("dataTendency")
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const { dateRange } = storeToRefs(publicData)
-const { profile } = storeToRefs(shopInfo)
-const router = useRouter()
-const showCompare = ref(false)
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'SpCampaignDetail',
-    query: {campaignId: row.campaignId, tagsViewName: row.campaignName},
-  })
-}
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: queryParams })
-
-onMounted(async () => {
-	crudExpose.doRefresh()
-})
-watch(
-	queryParams, 
-	async () => {
-		crudExpose.doRefresh()
-	},
-  { deep: true }
-)
-
-</script>
-
 <style scoped>
 .en-text {
   max-width: 100%;

+ 25 - 25
src/views/adManage/sp/targets/chartComponents/adStruct.vue

@@ -1,28 +1,3 @@
-<template>
-  <div v-loading="loading">
-    <el-row :gutter="5">
-      <el-col :span="24">
-        <div style="margin-left: 45%">
-          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
-          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
-          <span
-            style="
-              background: #f19a37;
-              width: 18px;
-              height: 10px;
-              margin-top: 8px;
-              margin-left: 20px;
-              display: inline-block;
-              border-radius: 3px;
-            "></span>
-          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
-        </div>
-        <div ref="bar" style="height: 400px"></div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
 <script setup>
 import * as echarts from 'echarts'
 import { computed, inject, onMounted, ref, watch } from 'vue'
@@ -399,4 +374,29 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
+<template>
+  <div v-loading="loading">
+    <el-row :gutter="5">
+      <el-col :span="24">
+        <div style="margin-left: 45%">
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedBarOptions1" @change="changeBarOne" style="margin-top: 5px; margin-left: 8px" />
+          <span
+            style="
+              background: #f19a37;
+              width: 18px;
+              height: 10px;
+              margin-top: 8px;
+              margin-left: 20px;
+              display: inline-block;
+              border-radius: 3px;
+            "></span>
+          <TextSelector v-model="barModelValue2" :options="computedBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
+        </div>
+        <div ref="bar" style="height: 400px"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
 <style scoped></style>

+ 7 - 7
src/views/adManage/sp/targets/chartComponents/dataTendency.vue

@@ -1,10 +1,3 @@
-<template>
-    <div v-loading="loading">
-        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
-        <div style="height: 350px;" ref="chartRef"></div>
-    </div>
-</template>
-
 <script lang="ts" setup>
 import {ref, onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed} from 'vue'
 import * as echarts from 'echarts'
@@ -250,6 +243,13 @@ const removeResize = () => {
 
 </script>
 
+<template>
+    <div v-loading="loading">
+        <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+        <div style="height: 350px;" ref="chartRef"></div>
+    </div>
+</template>
+
 <style scoped>
 .metrics-cards {
     display: flex;

+ 46 - 46
src/views/adManage/sp/targets/index.vue

@@ -1,3 +1,49 @@
+<script lang="ts" setup>
+import {nextTick, onMounted, ref, watch} from 'vue'
+import {FsPage, useFs} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import {useRoute, useRouter} from 'vue-router'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import {useShopInfo} from '/@/stores/shopInfo'
+import {usePublicData} from '/@/stores/publicData'
+import AdStructChart from './chartComponents/adStruct.vue'
+import {getCardData, getLineData, getLineMonthData, getLineWeekData} from '/@/views/adManage/sp/targets/api'
+import {storeToRefs} from 'pinia'
+import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn'
+import DataCompare from '/@/components/dataCompare/index.vue'
+
+
+const tabActiveName = ref('dataTendency')
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const {dateRange} = storeToRefs(publicData)
+const {profile} = storeToRefs(shopInfo)
+const queryParams = ref({
+  profileId: profile.value.profile_id,
+  dateRange
+})
+
+const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: queryParams})
+const route = useRoute()
+const router = useRouter()
+const showCompare = ref(false)
+const jumpGroup = (row: any) => {
+  router.push({
+    name: 'CampaignDetail',
+    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
+  })
+}
+
+onMounted(() => {
+  crudExpose.doRefresh()
+})
+
+watch(queryParams, async () => {
+  crudExpose.doRefresh()
+}, {deep: true})
+
+</script>
+
 <template>
   <fs-page class="fs-page-custom">
     <fs-crud ref="crudRef" v-bind="crudBinding">
@@ -57,52 +103,6 @@
   </fs-page>
 </template>
 
-<script lang="ts" setup>
-import {nextTick, onMounted, ref, watch} from 'vue'
-import {FsPage, useFs} from '@fast-crud/fast-crud'
-import {createCrudOptions} from './crud'
-import {useRoute, useRouter} from 'vue-router'
-import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
-import {useShopInfo} from '/@/stores/shopInfo'
-import {usePublicData} from '/@/stores/publicData'
-import AdStructChart from './chartComponents/adStruct.vue'
-import {getCardData, getLineData, getLineMonthData, getLineWeekData} from '/@/views/adManage/sp/targets/api'
-import {storeToRefs} from 'pinia'
-import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn'
-import DataCompare from '/@/components/dataCompare/index.vue'
-
-
-const tabActiveName = ref('dataTendency')
-const shopInfo = useShopInfo()
-const publicData = usePublicData()
-const {dateRange} = storeToRefs(publicData)
-const {profile} = storeToRefs(shopInfo)
-const queryParams = ref({
-  profileId: profile.value.profile_id,
-  dateRange
-})
-
-const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: queryParams})
-const route = useRoute()
-const router = useRouter()
-const showCompare = ref(false)
-const jumpGroup = (row: any) => {
-  router.push({
-    name: 'CampaignDetail',
-    query: { campaignId: row.campaignId, tagsViewName: row.campaignName },
-  })
-}
-
-onMounted(() => {
-  crudExpose.doRefresh()
-})
-
-watch(queryParams, async () => {
-  crudExpose.doRefresh()
-}, {deep: true})
-
-</script>
-
 <style lang="scss" scoped>
 .chart-tabs {
   margin: 5px 0;