Selaa lähdekoodia

Merge branch 'wang' into test

WanGxC 1 vuosi sitten
vanhempi
commit
572370d975

+ 65 - 64
src/views/adManage/sb/campaigns/chartComponents/adStruct.vue

@@ -5,38 +5,41 @@
         <div>
           <!--<TextSelector v-model="modelValue" :options="computedPieOptions" @change="changePie" style="margin-top: 5px"/>-->
           <el-select v-model="modelValue" class="m-2" size="small" @change="changePie" style="width: 120px">
-            <el-option
-                v-for="item in computedPieOptions"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-            />
+            <el-option v-for="item in computedPieOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </div>
-        <div ref="pie" style="height: 400px;"></div>
+        <div ref="pie" style="height: 400px"></div>
       </el-col>
       <el-col :span="17">
         <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;"/>
+          <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>
+        <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"
-import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sb/campaigns/api"
+import * as echarts from 'echarts'
+import { computed, inject, onMounted, ref, watch } from 'vue'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { sbBarOptions1, sbBarOptions2, barOptionsMap, metricMap, pieOptions } from '/@/views/adManage/utils/enum'
+import TextSelector from '/@/components/TextSelector/index.vue'
 import { useShopInfo } from '/@/stores/shopInfo'
-
+import { getAdStructureData } from '/@/views/adManage/sb/campaigns/api'
+import { barOptionsMap, metricMap, pieOptions, sbBarOptions1, sbBarOptions2 } from '/@/views/adManage/utils/enum'
 
 const shopInfo = useShopInfo()
 let pieChart = ref()
@@ -56,7 +59,7 @@ onMounted(async () => {
   barChart = echarts.init(bar.value)
   pieChart = echarts.init(pie.value)
 
-  window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
   setTimeout(() => {
     resizeChart()
   }, 0)
@@ -90,23 +93,21 @@ async function initPieBarData() {
     { value: pieBarData.pie_data[2].Spend, name: '视频' },
   ]
   barData = pieBarData.line_data
+  console.log('🚀 ~ barData', barData)
   // 柱状图初始化数据
-  ACOSList = barData.map(item => item.ACOS)
-  SpendList = barData.map(item => item.Spend)
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
-  xAxisList = barData.map(item => item.Classification)
+  xAxisList = barData.map((item) => item.Classification)
+  console.log('🚀 ~ xAxisList', xAxisList)
   const classificationMap = {
-    'BROAD': '关键词-广泛',
-    'category': '品类',
-    'EXACT': '关键词-精准',
-    'asin': '商品',
-    'PHRASE': '关键词-词组',
-    'close-match': '紧密匹配',
-    'loose-match': '广泛匹配',
-    'substitutes': '同类商品',
-    'complements': '关联商品'
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
   }
-  xAxisMapList = xAxisList.map(item => classificationMap[item])
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
   loading.value = false
 }
 
@@ -139,11 +140,14 @@ function changeBarTwo(newValue) {
 }
 
 function updateBarChart() {
-  const barValues1 = barData.map(item => item[barModelValue1.value])
-  const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
   barChart.setOption(option)
 }
 
@@ -170,8 +174,8 @@ function updatePieChartData(resp) {
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-  const barValues1 = resp.line_data.map(item => item[barModelValue1.value])
-  const barValues2 = resp.line_data.map(item => item[barModelValue2.value])
+  const barValues1 = resp.line_data.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.line_data.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
@@ -196,16 +200,16 @@ function initChart() {
           color: '#4C5058',
           fontSize: 15,
           fontWeight: 'bold',
-          lineHeight: 33
+          lineHeight: 33,
         },
-      }
+      },
     },
     toolbox: {
       feature: {
-        saveAsImage: { yAxisIndex: 'none' }
-      }
+        saveAsImage: { yAxisIndex: 'none' },
+      },
     },
-    grid: { top: 55, right: 60, bottom: 55, left: 55, },
+    grid: { top: 55, right: 60, bottom: 55, left: 55 },
     xAxis: [
       {
         type: 'category',
@@ -215,7 +219,7 @@ function initChart() {
         //   rotate: -30, // 将标签旋转
         //   fontSize: 13
         // }
-      }
+      },
     ],
     yAxis: [
       {
@@ -227,15 +231,15 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#3a83f7' // 第一个 Y 轴的颜色
-          }
-        }
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
+        },
       },
       {
         type: 'value',
         // name: '数据2',
         splitLine: {
-          show: false
+          show: false,
         },
         // axisLabel: {
         //     formatter: '{value} 单位2'
@@ -243,10 +247,10 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#f19a37' // 第一个 Y 轴的颜色
-          }
-        }
-      }
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
     ],
     series: [
       {
@@ -259,7 +263,7 @@ function initChart() {
           color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
             { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
             { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-            { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
           ]),
           // 柱状图圆角
           borderRadius: [4, 4, 4, 4],
@@ -275,7 +279,7 @@ function initChart() {
           color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
             { offset: 0, color: '#f19a37' },
             { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-            { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
           ]),
           // 柱状图圆角
           borderRadius: [4, 4, 4, 4],
@@ -305,7 +309,7 @@ function initChart() {
             show: true,
             // fontSize: 40,
             fontWeight: 'bold',
-          }
+          },
         },
         label: {
           show: true,
@@ -319,18 +323,18 @@ function initChart() {
               color: '#4C5058',
               fontSize: 15,
               fontWeight: 'bold',
-              lineHeight: 33
+              lineHeight: 33,
             },
-          }
+          },
         },
         labelLine: {
           normal: {
-            show: true
-          }
+            show: true,
+          },
         },
-        data: pieData
-      }
-    ]
+        data: pieData,
+      },
+    ],
   }
   pieChart.setOption(option2)
   resizeChart()
@@ -342,9 +346,6 @@ function resizeChart() {
 }
 
 defineExpose({ resizeChart })
-
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -25,19 +25,16 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onBeforeMount, Ref, watch, provide } from 'vue'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
-import { GetAllPortfolios } from '/@/views/adManage/portfolios/api'
+import { Ref, onBeforeMount, provide, ref } from 'vue'
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
+import { usePublicData } from '/@/stores/publicData'
+import { GetAllPortfolios } from '/@/views/adManage/portfolios/api'
 import Campaigns from '/@/views/adManage/sb/campaigns/index.vue'
 import Keywords from '/@/views/adManage/sb/keywords/index.vue'
-import Targets from '/@/views/adManage/sb/targets/index.vue'
-import SearchTerm from '/@/views/adManage/sb/searchTerm/index.vue'
-import AdvertisedProducts from './advertisedProducts/index.vue'
-import PurchasedOtherProducts from './purchasedOtherProducts/index.vue'
 import Placement from '/@/views/adManage/sb/placement/index.vue'
+import SearchTerm from '/@/views/adManage/sb/searchTerm/index.vue'
+import Targets from '/@/views/adManage/sb/targets/index.vue'
 
 // const shopInfo = useShopInfo()
 const publicData = usePublicData()
@@ -77,4 +74,7 @@ onBeforeMount(async () => {
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);
 }
+::v-deep(.el-table__footer-wrapper .el-table__footer tr) {
+  background-color: #f5f7fa;
+}
 </style>

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

@@ -3,33 +3,41 @@
     <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;"/>
+          <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>
+        <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"
+import { computed, onMounted, ref, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sb/keywords/api"
+import { getAdStructureData } from '/@/views/adManage/sb/keywords/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from "/@/stores/publicData"
+import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
 
-
 const shopInfo = useShopInfo()
 const publicData = usePublicData()
-const {dateRange} = storeToRefs(publicData)
-const {profile} = storeToRefs(shopInfo)
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
 let barChart = ref()
 const pie = ref()
 const bar = ref()
@@ -44,7 +52,7 @@ let barModelValue2 = ref(barOptions2[2].value)
 onMounted(async () => {
   barChart = echarts.init(bar.value)
 
-  window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
   setTimeout(() => {
     resizeChart()
   }, 0)
@@ -74,22 +82,22 @@ async function initBarData() {
   responseData = await setAdStructureData()
   barData = responseData
   // 柱状图初始化数据
-  ACOSList = barData.map(item => item.ACOS)
-  SpendList = barData.map(item => item.Spend)
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
-  xAxisList = barData.map(item => item.matchType)
+  xAxisList = barData.map((item) => item.matchType)
   const classificationMap = {
-    'BROAD': '关键词-广泛',
-    'category': '品类',
-    'EXACT': '关键词-精准',
-    'asin': '商品',
-    'PHRASE': '关键词-词组',
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
     'close-match': '紧密匹配',
     'loose-match': '广泛匹配',
-    'substitutes': '同类商品',
-    'complements': '关联商品'
+    substitutes: '同类商品',
+    complements: '关联商品',
   }
-  xAxisMapList = xAxisList.map(item => classificationMap[item])
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
   loading.value = false
 }
 
@@ -110,11 +118,14 @@ function changeBarTwo(newValue) {
 }
 
 function updateBarChart() {
-  const barValues1 = barData.map(item => item[barModelValue1.value])
-  const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
   barChart.setOption(option)
 }
 
@@ -130,8 +141,8 @@ watch(dateRange, async () => {
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-  const barValues1 = resp.map(item => item[barModelValue1.value])
-  const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
@@ -150,15 +161,15 @@ function initChart() {
       axisPointer: {
         type: 'shadow',
         label: {
-          backgroundColor: '#6a7985'
-        }
-      }
+          backgroundColor: '#6a7985',
+        },
+      },
     },
     // legend: {data: ['数据1', '数据2'],},
     toolbox: {
       feature: {
-        saveAsImage: { yAxisIndex: 'none' }
-      }
+        saveAsImage: { yAxisIndex: 'none' },
+      },
     },
     grid: { top: 50, right: 60, bottom: 50, left: 60 },
     xAxis: [
@@ -174,22 +185,22 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#3a83f7' // 第一个 Y 轴的颜色
-          }
-        }
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
+        },
       },
       {
         type: 'value',
         splitLine: {
-          show: false
+          show: false,
         },
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#f19a37' // 第一个 Y 轴的颜色
-          }
-        }
-      }
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
     ],
     series: [
       {
@@ -202,7 +213,7 @@ function initChart() {
           color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
             { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
             { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-            { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
           ]),
           // 柱状图圆角
           borderRadius: [4, 4, 4, 4],
@@ -218,7 +229,7 @@ function initChart() {
           color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
             { offset: 0, color: '#f19a37' },
             { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-            { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
           ]),
           // 柱状图圆角
           borderRadius: [4, 4, 4, 4],
@@ -236,6 +247,4 @@ function resizeChart() {
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -3,30 +3,37 @@
     <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: #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;"/>
+            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>
+        <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"
+import { computed, onMounted, ref, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/placement/api"
+import { getAdStructureData } from '/@/views/adManage/sp/placement/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from "/@/stores/publicData"
+import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
 
-
 const shopInfo = useShopInfo()
 const publicData = usePublicData()
 const { dateRange } = storeToRefs(publicData)
@@ -43,7 +50,7 @@ let barModelValue2 = ref(barOptions2[2].value)
 onMounted(async () => {
   barChart = echarts.init(bar.value)
 
-  window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
   setTimeout(() => {
     resizeChart()
   }, 0)
@@ -73,25 +80,25 @@ async function initBarData() {
   responseData = await setAdStructureData()
   barData = responseData
   // 柱状图初始化数据
-  ACOSList = barData.map(item => item.ACOS)
-  SpendList = barData.map(item => item.Spend)
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
-  xAxisList = barData.map(item => item.placement)
+  xAxisList = barData.map((item) => item.placement)
   const classificationMap = {
-    'BROAD': '关键词-广泛',
-    'category': '品类',
-    'EXACT': '关键词-精准',
-    'asin': '商品',
-    'PHRASE': '关键词-词组',
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
     'close-match': '紧密匹配',
     'loose-match': '广泛匹配',
-    'substitutes': '同类商品',
-    'complements': '关联商品',
-    'top': '首页',
-    'rest_of_search': '其他页面',
-    'product_page': '产品页面'
+    substitutes: '同类商品',
+    complements: '关联商品',
+    top: '首页',
+    rest_of_search: '其他页面',
+    product_page: '产品页面',
   }
-  xAxisMapList = xAxisList.map(item => classificationMap[item])
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
   loading.value = false
 }
 
@@ -112,11 +119,14 @@ function changeBarTwo(newValue) {
 }
 
 function updateBarChart() {
-  const barValues1 = barData.map(item => item[barModelValue1.value])
-  const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
   barChart.setOption(option)
 }
 
@@ -132,8 +142,8 @@ watch(dateRange, async () => {
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-  const barValues1 = resp.map(item => item[barModelValue1.value])
-  const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
@@ -152,15 +162,15 @@ function initChart() {
       axisPointer: {
         type: 'shadow',
         label: {
-          backgroundColor: '#6a7985'
-        }
-      }
+          backgroundColor: '#6a7985',
+        },
+      },
     },
     // legend: {data: ['数据1', '数据2'],},
     toolbox: {
       feature: {
-        saveAsImage: { yAxisIndex: 'none' }
-      }
+        saveAsImage: { yAxisIndex: 'none' },
+      },
     },
     grid: { top: 50, right: 60, bottom: 50, left: 60 },
     xAxis: [
@@ -176,22 +186,22 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#3a83f7' // 第一个 Y 轴的颜色
-          }
-        }
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
+        },
       },
       {
         type: 'value',
         splitLine: {
-          show: false
+          show: false,
         },
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#f19a37' // 第一个 Y 轴的颜色
-          }
-        }
-      }
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
     ],
     series: [
       {
@@ -233,9 +243,6 @@ function initChart() {
 function resizeChart() {
   barChart.resize()
 }
-
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -1,29 +1,37 @@
 <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>
+  <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"
+import { onMounted, ref, inject, computed, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/targets/api"
+import { getAdStructureData } from '/@/views/adManage/sp/targets/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let barChart = ref()
 const pie = ref()
@@ -37,23 +45,23 @@ let barModelValue1 = ref(barOptions1[0].value)
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 柱状图总数据
@@ -66,26 +74,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.Classification)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.Classification)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -95,42 +103,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
-
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
+
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -138,99 +149,97 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
-                      { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-                      { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#f19a37' },
-                      { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-                      { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
+            { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 164 - 155
src/views/adManage/sd/audiences/chartComponents/adStruct.vue

@@ -1,29 +1,37 @@
 <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>
+  <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"
+import { onMounted, ref, inject, computed, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/targets/api"
+import { getAdStructureData } from '/@/views/adManage/sp/targets/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let barChart = ref()
 const pie = ref()
@@ -37,23 +45,23 @@ let barModelValue1 = ref(barOptions1[0].value)
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 柱状图总数据
@@ -66,26 +74,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.Classification)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.Classification)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -95,42 +103,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
-
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
+
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -138,99 +149,97 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
-                      { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-                      { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#f19a37' },
-                      { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-                      { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
+            { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 3 - 6
src/views/adManage/sd/campaigns/CreateCampaigns/component/SingleSearch.vue

@@ -1,5 +1,5 @@
 <template>
-  <div style="height: 490px" v-loading="containerLoading">
+  <div style="height: 525px" v-loading="containerLoading">
     <el-input v-model="searchInput" @change="handleChange" placeholder="按ASIN搜索"></el-input>
     <hr style="margin-top: 5px" />
     <el-table :data="commodityData" :show-header="false" @selection-change="handleSelectionChange" height="450" style="width: 100%">
@@ -30,13 +30,10 @@
 </template>
 
 <script setup lang="ts">
-import { onMounted, ref, watch, reactive, CSSProperties, defineEmits } from 'vue'
-import { request } from '/@/utils/service'
-import type { FormInstance, FormRules, TabsPaneContext } from 'element-plus'
+import { storeToRefs } from 'pinia'
+import { defineEmits, ref } from 'vue'
 import { getCommodityCard } from '../api/index'
 import { useShopInfo } from '/@/stores/shopInfo'
-import { storeToRefs } from 'pinia'
-import emitter from '/@/utils/emitter'
 
 const shopInfo = useShopInfo()
 const { profile } = storeToRefs(shopInfo)

+ 2 - 1
src/views/adManage/sd/campaigns/CreateCampaigns/index.vue

@@ -3,7 +3,8 @@
     <AdCampaign @send-campaign="getCampaign" @send-targetType="getTargetType"></AdCampaign>
     <AdGroup @send-groupId="getGroupId"></AdGroup>
     <component :is="currentComponent"></component>
-    <Creativity v-if="product"></Creativity>
+    <!-- <Creativity v-if="product.length !== 0"></Creativity> -->
+    <Creativity></Creativity>
   </div>
 </template>
 

+ 60 - 55
src/views/adManage/sd/campaigns/chartComponents/adStruct.vue

@@ -5,39 +5,42 @@
         <div>
           <!--<TextSelector v-model="modelValue" :options="computedPieOptions" @change="changePie" style="margin-top: 5px"/>-->
           <el-select v-model="modelValue" class="m-2" size="small" @change="changePie" style="width: 120px">
-            <el-option
-                v-for="item in computedPieOptions"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-            />
+            <el-option v-for="item in computedPieOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </div>
-        <div ref="pie" style="height: 400px;"></div>
+        <div ref="pie" style="height: 400px"></div>
       </el-col>
       <el-col :span="17">
         <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="computedsdBarOptions1" @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="computedsdBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px;"/>
+          <span style="background: #3a83f7; width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px"></span>
+          <TextSelector v-model="barModelValue1" :options="computedsdBarOptions1" @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="computedsdBarOptions2" @change="changeBarTwo" style="margin-top: 5px; margin-left: 8px" />
         </div>
-        <div ref="bar" style="height: 400px;"></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"
+import { computed, inject, onMounted, ref, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sd/campaigns/api"
+import { getAdStructureData } from '/@/views/adManage/sd/campaigns/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
 import { sdBarOptions1, sdBarOptions2, sdBarOptionsMap, metricMap, pieOptions } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let pieChart = ref()
 let barChart = ref()
@@ -56,7 +59,7 @@ onMounted(async () => {
   barChart = echarts.init(bar.value)
   pieChart = echarts.init(pie.value)
 
-  window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
   setTimeout(() => {
     resizeChart()
   }, 0)
@@ -90,18 +93,18 @@ async function initPieBarData() {
   ]
   barData = pieBarData.target_data
   // 柱状图初始化数据
-  ACOSList = barData.map(item => item.ACOS)
-  SpendList = barData.map(item => item.Spend)
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
-  xAxisList = barData.map(item => item.Name)
+  xAxisList = barData.map((item) => item.Name)
   const classificationMap = {
-    'views': '浏览再营销',
-    'audience': '亚马逊人群',
-    'category': '品类',
-    'purchases': '购买再营销',
-    'asin': '商品'
+    views: '浏览再营销',
+    audience: '亚马逊人群',
+    category: '品类',
+    purchases: '购买再营销',
+    asin: '商品',
   }
-  xAxisMapList = xAxisList.map(item => classificationMap[item])
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
   loading.value = false
 }
 
@@ -133,11 +136,14 @@ function changeBarTwo(newValue) {
 }
 
 function updateBarChart() {
-  const barValues1 = barData.map(item => item[barModelValue1.value])
-  const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
+  // 更新柱状图的系列名称以反映当前的指标
+  option.series[0].name = sdBarOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = sdBarOptionsMap[barModelValue2.value] || barModelValue2.value
   barChart.setOption(option)
 }
 
@@ -163,8 +169,8 @@ function updatePieChartData(resp) {
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-  const barValues1 = resp.target_data.map(item => item[barModelValue1.value])
-  const barValues2 = resp.target_data.map(item => item[barModelValue2.value])
+  const barValues1 = resp.target_data.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.target_data.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
@@ -189,16 +195,16 @@ function initChart() {
           color: '#4C5058',
           fontSize: 15,
           fontWeight: 'bold',
-          lineHeight: 33
+          lineHeight: 33,
         },
-      }
+      },
     },
     toolbox: {
       feature: {
-        saveAsImage: { yAxisIndex: 'none' }
-      }
+        saveAsImage: { yAxisIndex: 'none' },
+      },
     },
-    grid: { top: 55, right: 60, bottom: 55, left: 55, },
+    grid: { top: 55, right: 60, bottom: 55, left: 55 },
     xAxis: [
       {
         type: 'category',
@@ -208,7 +214,7 @@ function initChart() {
         //   rotate: -30, // 将标签旋转
         //   fontSize: 13
         // }
-      }
+      },
     ],
     yAxis: [
       {
@@ -220,15 +226,15 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#3a83f7' // 第一个 Y 轴的颜色
-          }
-        }
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
+        },
       },
       {
         type: 'value',
         // name: '数据2',
         splitLine: {
-          show: false
+          show: false,
         },
         // axisLabel: {
         //     formatter: '{value} 单位2'
@@ -236,10 +242,10 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#f19a37' // 第一个 Y 轴的颜色
-          }
-        }
-      }
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
     ],
     series: [
       {
@@ -252,7 +258,7 @@ function initChart() {
           color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
             { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
             { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-            { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
           ]),
           // 柱状图圆角
           borderRadius: [4, 4, 4, 4],
@@ -268,7 +274,7 @@ function initChart() {
           color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
             { offset: 0, color: '#f19a37' },
             { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-            { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
           ]),
           // 柱状图圆角
           borderRadius: [4, 4, 4, 4],
@@ -298,7 +304,7 @@ function initChart() {
             show: true,
             // fontSize: 40,
             fontWeight: 'bold',
-          }
+          },
         },
         label: {
           show: true,
@@ -312,18 +318,18 @@ function initChart() {
               color: '#4C5058',
               fontSize: 15,
               fontWeight: 'bold',
-              lineHeight: 33
+              lineHeight: 33,
             },
-          }
+          },
         },
         labelLine: {
           normal: {
-            show: true
-          }
+            show: true,
+          },
         },
-        data: pieData
-      }
-    ]
+        data: pieData,
+      },
+    ],
   }
   pieChart.setOption(option2)
   resizeChart()
@@ -335,7 +341,6 @@ function resizeChart() {
 }
 
 defineExpose({ resizeChart })
-
 </script>
 
 <style scoped>

+ 17 - 18
src/views/adManage/sd/index.vue

@@ -3,14 +3,14 @@
     <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">
+        v-model="selectedPortfolios"
+        placeholder="广告组合"
+        clearable
+        multiple
+        style="width: 400px"
+        collapse-tags
+        collapse-tags-tooltip
+        :max-collapse-tags="3">
         <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
       </el-select>
     </div>
@@ -24,19 +24,16 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onBeforeMount, Ref, watch, provide } from 'vue'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
-import { GetAllPortfolios } from '/@/views/adManage/portfolios/api'
+import { Ref, onBeforeMount, provide, ref } from 'vue'
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
-import Campaigns from '/@/views/adManage/sd/campaigns/index.vue'
+import { usePublicData } from '/@/stores/publicData'
+import { GetAllPortfolios } from '/@/views/adManage/portfolios/api'
 import Audiences from '/@/views/adManage/sd/audiences/index.vue'
-import Targets from '/@/views/adManage/sd/targets/index.vue'
+import Campaigns from '/@/views/adManage/sd/campaigns/index.vue'
 import MatchedDelivery from '/@/views/adManage/sd/matchedDelivery/index.vue'
 import PromoteProducts from '/@/views/adManage/sd/promoteProducts/index.vue'
-import PurchasedOtherProducts from './purchasedOtherProducts/index.vue'
-import Placement from '/@/views/adManage/sb/placement/index.vue'
+import Targets from '/@/views/adManage/sd/targets/index.vue'
 
 // const shopInfo = useShopInfo()
 const publicData = usePublicData()
@@ -51,7 +48,7 @@ const tabsComponents: any = {
   MatchedDelivery,
   PromoteProducts,
   // PurchasedOtherProducts,
-  
+
   // Placement
 }
 const tabs = [
@@ -71,11 +68,13 @@ onBeforeMount(async () => {
   const resp: APIResponseData = await GetAllPortfolios()
   portfolios.value = resp.data
 })
-
 </script>
 
 <style scoped>
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);
 }
+::v-deep(.el-table__footer-wrapper .el-table__footer tr) {
+  background-color: #f5f7fa;
+}
 </style>

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

@@ -1,29 +1,37 @@
 <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>
+  <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"
+import { onMounted, ref, inject, computed, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/targets/api"
+import { getAdStructureData } from '/@/views/adManage/sp/targets/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let barChart = ref()
 const pie = ref()
@@ -37,23 +45,23 @@ let barModelValue1 = ref(barOptions1[0].value)
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 柱状图总数据
@@ -66,26 +74,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.Classification)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.Classification)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -95,42 +103,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
-
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
+
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -138,99 +149,97 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
-                      { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-                      { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#f19a37' },
-                      { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-                      { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
+            { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -1,29 +1,37 @@
 <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>
+  <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"
+import { onMounted, ref, inject, computed, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/targets/api"
+import { getAdStructureData } from '/@/views/adManage/sp/targets/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let barChart = ref()
 const pie = ref()
@@ -37,23 +45,23 @@ let barModelValue1 = ref(barOptions1[0].value)
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 柱状图总数据
@@ -66,26 +74,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.Classification)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.Classification)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -95,42 +103,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
-
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
+
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -138,99 +149,97 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
-                      { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-                      { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#f19a37' },
-                      { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-                      { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
+            { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 164 - 155
src/views/adManage/sd/targets/chartComponents/adStruct.vue

@@ -1,29 +1,37 @@
 <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>
+  <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"
+import { onMounted, ref, inject, computed, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/targets/api"
+import { getAdStructureData } from '/@/views/adManage/sp/targets/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptions1, barOptions2, barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptions1, barOptions2, barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let barChart = ref()
 const pie = ref()
@@ -37,23 +45,23 @@ let barModelValue1 = ref(barOptions1[0].value)
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 柱状图总数据
@@ -66,26 +74,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.Classification)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.Classification)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -95,42 +103,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
-
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
+
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -138,99 +149,97 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
-                      { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
-                      { offset: 1, color: '#8ab6f1' } // 结束的浅蓝色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                      { offset: 0, color: '#f19a37' },
-                      { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
-                      { offset: 1, color: 'rgb(234, 207, 135)' } // 结束的浅黄色
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' }, // 起始的鲜亮蓝色
+            { offset: 0.5, color: '#5a9ef4' }, // 中间色,中度蓝色
+            { offset: 1, color: '#8ab6f1' }, // 结束的浅蓝色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 0.5, color: '#f7b96c' }, // 中间色,浅橙色
+            { offset: 1, color: 'rgb(234, 207, 135)' }, // 结束的浅黄色
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -3,33 +3,41 @@
     <el-row :gutter="5">
       <el-col :span="9">
         <div>
-          <TextSelector v-model="modelValue" :options="computedPieOptions" @change="changePie" style="margin-top: 5px"/>
+          <TextSelector v-model="modelValue" :options="computedPieOptions" @change="changePie" style="margin-top: 5px" />
         </div>
-        <div ref="pie" style="height: 400px;"></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;"/>
+          <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>
+        <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"
+import { computed, inject, onMounted, ref, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/campaigns/api"
+import { getAdStructureData } from '/@/views/adManage/sp/campaigns/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
 import { barOptionsMap, metricMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
 
-
 const shopInfo = useShopInfo()
 let pieChart = ref()
 let barChart = ref()
@@ -96,11 +104,11 @@ const barOptions1 = [
   },
   {
     value: 'CPC',
-    label: '点击成本'
+    label: '点击成本',
   },
   {
     value: 'CPA',
-    label: '订单成本'
+    label: '订单成本',
   },
   {
     value: 'Impression',
@@ -112,39 +120,39 @@ const barOptions1 = [
   },
   {
     value: 'qwe',
-    label: '点击率'
+    label: '点击率',
   },
   {
     value: '转化率',
-    label: '转化率'
+    label: '转化率',
   },
   {
     value: 'TotalSalesSameSKU',
-    label: '推广商品销售额'
+    label: '推广商品销售额',
   },
   {
     value: 'TotalSalesOtherSKU',
-    label: '其他商品销售额'
+    label: '其他商品销售额',
   },
   {
     value: 'TotalPurchasesSameSKU',
-    label: '推广商品订单数'
+    label: '推广商品订单数',
   },
   {
     value: 'TotalPurchasesOtherSKU',
-    label: '其他商品订单数'
+    label: '其他商品订单数',
   },
   {
     value: 'TotalUnitOrderedSameSKU',
-    label: '推广商品销量'
+    label: '推广商品销量',
   },
   {
     value: 'TotalUnitOrderedOtherSKU',
-    label: '其他商品销量'
+    label: '其他商品销量',
   },
   {
     value: 'TopOfSearchImpressionShare',
-    label: '搜索结果顶部展示份额'
+    label: '搜索结果顶部展示份额',
   },
 ]
 let barModelValue1 = ref(barOptions1[0].value)
@@ -177,11 +185,11 @@ const barOptions2 = [
   },
   {
     value: 'CPC',
-    label: '点击成本'
+    label: '点击成本',
   },
   {
     value: 'CPA',
-    label: '订单成本'
+    label: '订单成本',
   },
   {
     value: 'Impression',
@@ -193,39 +201,39 @@ const barOptions2 = [
   },
   {
     value: 'qwe',
-    label: '点击率'
+    label: '点击率',
   },
   {
     value: '转化率',
-    label: '转化率'
+    label: '转化率',
   },
   {
     value: 'TotalSalesSameSKU',
-    label: '推广商品销售额'
+    label: '推广商品销售额',
   },
   {
     value: 'TotalSalesOtherSKU',
-    label: '其他商品销售额'
+    label: '其他商品销售额',
   },
   {
     value: 'TotalPurchasesSameSKU',
-    label: '推广商品订单数'
+    label: '推广商品订单数',
   },
   {
     value: 'TotalPurchasesOtherSKU',
-    label: '其他商品订单数'
+    label: '其他商品订单数',
   },
   {
     value: 'TotalUnitOrderedSameSKU',
-    label: '推广商品销量'
+    label: '推广商品销量',
   },
   {
     value: 'TotalUnitOrderedOtherSKU',
-    label: '其他商品销量'
+    label: '其他商品销量',
   },
   {
     value: 'TopOfSearchImpressionShare',
-    label: '搜索结果顶部展示份额'
+    label: '搜索结果顶部展示份额',
   },
 ]
 let barModelValue2 = ref(barOptions2[2].value)
@@ -234,7 +242,7 @@ onMounted(async () => {
   barChart = echarts.init(bar.value)
   pieChart = echarts.init(pie.value)
 
-  window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
   setTimeout(() => {
     resizeChart()
   }, 0)
@@ -268,22 +276,22 @@ async function initPieBarData() {
   ]
   barData = pieBarData.line_data
   // 柱状图初始化数据
-  ACOSList = barData.map(item => item.ACOS)
-  SpendList = barData.map(item => item.Spend)
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
-  xAxisList = barData.map(item => item.Classification)
+  xAxisList = barData.map((item) => item.Classification)
   const classificationMap = {
-    'BROAD': '关键词-广泛',
-    'category': '品类',
-    'EXACT': '关键词-精准',
-    'asin': '商品',
-    'PHRASE': '关键词-词组',
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
     'close-match': '紧密匹配',
     'loose-match': '广泛匹配',
-    'substitutes': '同类商品',
-    'complements': '关联商品'
+    substitutes: '同类商品',
+    complements: '关联商品',
   }
-  xAxisMapList = xAxisList.map(item => classificationMap[item])
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
   loading.value = false
 }
 
@@ -315,11 +323,16 @@ function changeBarTwo(newValue) {
 }
 
 function updateBarChart() {
-  const barValues1 = barData.map(item => item[barModelValue1.value])
-  const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
+
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+
   barChart.setOption(option)
 }
 
@@ -345,8 +358,8 @@ function updatePieChartData(resp) {
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-  const barValues1 = resp.line_data.map(item => item[barModelValue1.value])
-  const barValues2 = resp.line_data.map(item => item[barModelValue2.value])
+  const barValues1 = resp.line_data.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.line_data.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
@@ -371,16 +384,16 @@ function initChart() {
           color: '#4C5058',
           fontSize: 15,
           fontWeight: 'bold',
-          lineHeight: 33
+          lineHeight: 33,
         },
-      }
+      },
     },
     toolbox: {
       feature: {
-        saveAsImage: { yAxisIndex: 'none' }
-      }
+        saveAsImage: { yAxisIndex: 'none' },
+      },
     },
-    grid: { top: 55, right: 60, bottom: 55, left: 55, },
+    grid: { top: 55, right: 60, bottom: 55, left: 55 },
     xAxis: [
       {
         type: 'category',
@@ -388,9 +401,9 @@ function initChart() {
         data: xAxisMapList,
         axisLabel: {
           rotate: -30, // 将标签旋转
-          fontSize: 13
-        }
-      }
+          fontSize: 13,
+        },
+      },
     ],
     yAxis: [
       {
@@ -402,15 +415,15 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#3a83f7' // 第一个 Y 轴的颜色
-          }
-        }
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
+        },
       },
       {
         type: 'value',
         // name: '数据2',
         splitLine: {
-          show: false
+          show: false,
         },
         // axisLabel: {
         //     formatter: '{value} 单位2'
@@ -418,10 +431,10 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#f19a37' // 第一个 Y 轴的颜色
-          }
-        }
-      }
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
     ],
     series: [
       {
@@ -478,7 +491,7 @@ function initChart() {
             show: true,
             // fontSize: 40,
             fontWeight: 'bold',
-          }
+          },
         },
         label: {
           show: true,
@@ -492,18 +505,18 @@ function initChart() {
               color: '#4C5058',
               fontSize: 15,
               fontWeight: 'bold',
-              lineHeight: 33
+              lineHeight: 33,
             },
-          }
+          },
         },
         labelLine: {
           normal: {
-            show: true
-          }
+            show: true,
+          },
         },
-        data: pieData
-      }
-    ]
+        data: pieData,
+      },
+    ],
   }
   pieChart.setOption(option2)
   resizeChart()
@@ -515,9 +528,6 @@ function resizeChart() {
 }
 
 defineExpose({ resizeChart })
-
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 3 - 1
src/views/adManage/sp/campaigns/index.vue

@@ -114,7 +114,9 @@ watch(
 ::v-deep(.el-table--border .el-table__footer-wrapper) {
   border: none;
 }
-
+::v-deep(.el-table__footer-wrapper .el-table__footer tr) {
+  background-color: #f5f7fa;
+}
 .en-text {
   max-width: 100%;
   font-size: 13px;

+ 3 - 0
src/views/adManage/sp/index.vue

@@ -78,4 +78,7 @@ onBeforeMount(async () => {
 ::v-deep(.el-table .el-table__header-wrapper .cell) {
   border-right: 1px solid rgb(218, 221, 223);
 }
+::v-deep(.el-table__footer-wrapper .el-table__footer tr) {
+  background-color: #f5f7fa;
+}
 </style>

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

@@ -1,36 +1,43 @@
 <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>
+  <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"
+import { onMounted, ref, inject, computed, watch } from 'vue'
+import * as echarts from 'echarts'
 import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/keywords/api"
+import { getAdStructureData } from '/@/views/adManage/sp/keywords/api'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptionsMap } from "/@/views/adManage/utils/enum"
+import { barOptionsMap } from '/@/views/adManage/utils/enum'
 import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from "/@/stores/publicData"
-import {storeToRefs} from 'pinia'
-
-
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
 
 const shopInfo = useShopInfo()
 const publicData = usePublicData()
-const {dateRange} = storeToRefs(publicData)
-const {profile} = storeToRefs(shopInfo)
+const { dateRange } = storeToRefs(publicData)
+const { profile } = storeToRefs(shopInfo)
 let barChart = ref()
 const pie = ref()
 const bar = ref()
@@ -40,185 +47,185 @@ const loading = ref(true)
 
 // 下拉框相关
 const barOptions1 = [
-    {
-        value: 'ACOS',
-        label: 'ACOS',
-    },
-    {
-        value: 'ROAS',
-        label: 'ROAS',
-    },
-    {
-        value: 'Spend',
-        label: '花费',
-        units: '$',
-    },
-    {
-        value: 'TotalSales',
-        label: '销售额',
-    },
-    {
-        value: 'TotalPurchases',
-        label: '订单数',
-    },
-    {
-        value: 'TotalUnitOrdered',
-        label: '销量',
-    },
-    {
-        value: 'CPC',
-        label: '点击成本'
-    },
-    {
-        value: 'CPA',
-        label: '订单成本'
-    },
-    {
-        value: 'Impression',
-        label: '曝光量',
-    },
-    {
-        value: 'Click',
-        label: '点击量',
-    },
-    {
-        value: 'qwe',
-        label: '点击率'
-    },
-    {
-        value: '转化率',
-        label: '转化率'
-    },
-    {
-        value: 'TotalSalesSameSKU',
-        label: '推广商品销售额'
-    },
-    {
-        value: 'TotalSalesOtherSKU',
-        label: '其他商品销售额'
-    },
-    {
-        value: 'TotalPurchasesSameSKU',
-        label: '推广商品订单数'
-    },
-    {
-        value: 'TotalPurchasesOtherSKU',
-        label: '其他商品订单数'
-    },
-    {
-        value: 'TotalUnitOrderedSameSKU',
-        label: '推广商品销量'
-    },
-    {
-        value: 'TotalUnitOrderedOtherSKU',
-        label: '其他商品销量'
-    },
-    {
-        value: 'TopOfSearchImpressionShare',
-        label: '搜索结果顶部展示份额'
-    },
+  {
+    value: 'ACOS',
+    label: 'ACOS',
+  },
+  {
+    value: 'ROAS',
+    label: 'ROAS',
+  },
+  {
+    value: 'Spend',
+    label: '花费',
+    units: '$',
+  },
+  {
+    value: 'TotalSales',
+    label: '销售额',
+  },
+  {
+    value: 'TotalPurchases',
+    label: '订单数',
+  },
+  {
+    value: 'TotalUnitOrdered',
+    label: '销量',
+  },
+  {
+    value: 'CPC',
+    label: '点击成本',
+  },
+  {
+    value: 'CPA',
+    label: '订单成本',
+  },
+  {
+    value: 'Impression',
+    label: '曝光量',
+  },
+  {
+    value: 'Click',
+    label: '点击量',
+  },
+  {
+    value: 'qwe',
+    label: '点击率',
+  },
+  {
+    value: '转化率',
+    label: '转化率',
+  },
+  {
+    value: 'TotalSalesSameSKU',
+    label: '推广商品销售额',
+  },
+  {
+    value: 'TotalSalesOtherSKU',
+    label: '其他商品销售额',
+  },
+  {
+    value: 'TotalPurchasesSameSKU',
+    label: '推广商品订单数',
+  },
+  {
+    value: 'TotalPurchasesOtherSKU',
+    label: '其他商品订单数',
+  },
+  {
+    value: 'TotalUnitOrderedSameSKU',
+    label: '推广商品销量',
+  },
+  {
+    value: 'TotalUnitOrderedOtherSKU',
+    label: '其他商品销量',
+  },
+  {
+    value: 'TopOfSearchImpressionShare',
+    label: '搜索结果顶部展示份额',
+  },
 ]
 let barModelValue1 = ref(barOptions1[0].value)
 
 const barOptions2 = [
-    {
-        value: 'ACOS',
-        label: 'ACOS',
-    },
-    {
-        value: 'ROAS',
-        label: 'ROAS',
-    },
-    {
-        value: 'Spend',
-        label: '花费',
-        units: '$',
-    },
-    {
-        value: 'TotalSales',
-        label: '销售额',
-    },
-    {
-        value: 'TotalPurchases',
-        label: '订单数',
-    },
-    {
-        value: 'TotalUnitOrdered',
-        label: '销量',
-    },
-    {
-        value: 'CPC',
-        label: '点击成本'
-    },
-    {
-        value: 'CPA',
-        label: '订单成本'
-    },
-    {
-        value: 'Impression',
-        label: '曝光量',
-    },
-    {
-        value: 'Click',
-        label: '点击量',
-    },
-    {
-        value: 'qwe',
-        label: '点击率'
-    },
-    {
-        value: '转化率',
-        label: '转化率'
-    },
-    {
-        value: 'TotalSalesSameSKU',
-        label: '推广商品销售额'
-    },
-    {
-        value: 'TotalSalesOtherSKU',
-        label: '其他商品销售额'
-    },
-    {
-        value: 'TotalPurchasesSameSKU',
-        label: '推广商品订单数'
-    },
-    {
-        value: 'TotalPurchasesOtherSKU',
-        label: '其他商品订单数'
-    },
-    {
-        value: 'TotalUnitOrderedSameSKU',
-        label: '推广商品销量'
-    },
-    {
-        value: 'TotalUnitOrderedOtherSKU',
-        label: '其他商品销量'
-    },
-    {
-        value: 'TopOfSearchImpressionShare',
-        label: '搜索结果顶部展示份额'
-    },
+  {
+    value: 'ACOS',
+    label: 'ACOS',
+  },
+  {
+    value: 'ROAS',
+    label: 'ROAS',
+  },
+  {
+    value: 'Spend',
+    label: '花费',
+    units: '$',
+  },
+  {
+    value: 'TotalSales',
+    label: '销售额',
+  },
+  {
+    value: 'TotalPurchases',
+    label: '订单数',
+  },
+  {
+    value: 'TotalUnitOrdered',
+    label: '销量',
+  },
+  {
+    value: 'CPC',
+    label: '点击成本',
+  },
+  {
+    value: 'CPA',
+    label: '订单成本',
+  },
+  {
+    value: 'Impression',
+    label: '曝光量',
+  },
+  {
+    value: 'Click',
+    label: '点击量',
+  },
+  {
+    value: 'qwe',
+    label: '点击率',
+  },
+  {
+    value: '转化率',
+    label: '转化率',
+  },
+  {
+    value: 'TotalSalesSameSKU',
+    label: '推广商品销售额',
+  },
+  {
+    value: 'TotalSalesOtherSKU',
+    label: '其他商品销售额',
+  },
+  {
+    value: 'TotalPurchasesSameSKU',
+    label: '推广商品订单数',
+  },
+  {
+    value: 'TotalPurchasesOtherSKU',
+    label: '其他商品订单数',
+  },
+  {
+    value: 'TotalUnitOrderedSameSKU',
+    label: '推广商品销量',
+  },
+  {
+    value: 'TotalUnitOrderedOtherSKU',
+    label: '其他商品销量',
+  },
+  {
+    value: 'TopOfSearchImpressionShare',
+    label: '搜索结果顶部展示份额',
+  },
 ]
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 饼图总数据和柱状图总数据
@@ -231,26 +238,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.matchType)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.matchType)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -260,42 +267,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -303,97 +313,95 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                        { offset: 0, color: '#3a83f7' },
-                        { offset: 1, color: 'rgb(111, 209, 206)' },
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                        { offset: 0, color: '#f19a37' },
-                        { offset: 1, color: 'rgb(234,207,135)' },
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' },
+            { offset: 1, color: 'rgb(111, 209, 206)' },
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 1, color: 'rgb(234,207,135)' },
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -3,28 +3,36 @@
     <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: #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;"/>
+            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>
+        <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"
-import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/placement/api"
+import * as echarts from 'echarts'
+import { storeToRefs } from 'pinia'
+import { computed, onMounted, ref, watch } from 'vue'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptionsMap } from "/@/views/adManage/utils/enum"
+import TextSelector from '/@/components/TextSelector/index.vue'
+import { usePublicData } from '/@/stores/publicData'
 import { useShopInfo } from '/@/stores/shopInfo'
-import { usePublicData } from "/@/stores/publicData"
-import { storeToRefs } from 'pinia'
+import { getAdStructureData } from '/@/views/adManage/sp/placement/api'
+import { barOptionsMap } from '/@/views/adManage/utils/enum'
 
 const shopInfo = useShopInfo()
 const publicData = usePublicData()
@@ -63,11 +71,11 @@ const barOptions1 = [
   },
   {
     value: 'CPC',
-    label: '点击成本'
+    label: '点击成本',
   },
   {
     value: 'CPA',
-    label: '订单成本'
+    label: '订单成本',
   },
   {
     value: 'Impression',
@@ -79,39 +87,39 @@ const barOptions1 = [
   },
   {
     value: 'qwe',
-    label: '点击率'
+    label: '点击率',
   },
   {
     value: '转化率',
-    label: '转化率'
+    label: '转化率',
   },
   {
     value: 'TotalSalesSameSKU',
-    label: '推广商品销售额'
+    label: '推广商品销售额',
   },
   {
     value: 'TotalSalesOtherSKU',
-    label: '其他商品销售额'
+    label: '其他商品销售额',
   },
   {
     value: 'TotalPurchasesSameSKU',
-    label: '推广商品订单数'
+    label: '推广商品订单数',
   },
   {
     value: 'TotalPurchasesOtherSKU',
-    label: '其他商品订单数'
+    label: '其他商品订单数',
   },
   {
     value: 'TotalUnitOrderedSameSKU',
-    label: '推广商品销量'
+    label: '推广商品销量',
   },
   {
     value: 'TotalUnitOrderedOtherSKU',
-    label: '其他商品销量'
+    label: '其他商品销量',
   },
   {
     value: 'TopOfSearchImpressionShare',
-    label: '搜索结果顶部展示份额'
+    label: '搜索结果顶部展示份额',
   },
 ]
 let barModelValue1 = ref(barOptions1[0].value)
@@ -144,11 +152,11 @@ const barOptions2 = [
   },
   {
     value: 'CPC',
-    label: '点击成本'
+    label: '点击成本',
   },
   {
     value: 'CPA',
-    label: '订单成本'
+    label: '订单成本',
   },
   {
     value: 'Impression',
@@ -160,39 +168,39 @@ const barOptions2 = [
   },
   {
     value: 'qwe',
-    label: '点击率'
+    label: '点击率',
   },
   {
     value: '转化率',
-    label: '转化率'
+    label: '转化率',
   },
   {
     value: 'TotalSalesSameSKU',
-    label: '推广商品销售额'
+    label: '推广商品销售额',
   },
   {
     value: 'TotalSalesOtherSKU',
-    label: '其他商品销售额'
+    label: '其他商品销售额',
   },
   {
     value: 'TotalPurchasesSameSKU',
-    label: '推广商品订单数'
+    label: '推广商品订单数',
   },
   {
     value: 'TotalPurchasesOtherSKU',
-    label: '其他商品订单数'
+    label: '其他商品订单数',
   },
   {
     value: 'TotalUnitOrderedSameSKU',
-    label: '推广商品销量'
+    label: '推广商品销量',
   },
   {
     value: 'TotalUnitOrderedOtherSKU',
-    label: '其他商品销量'
+    label: '其他商品销量',
   },
   {
     value: 'TopOfSearchImpressionShare',
-    label: '搜索结果顶部展示份额'
+    label: '搜索结果顶部展示份额',
   },
 ]
 let barModelValue2 = ref(barOptions2[2].value)
@@ -200,7 +208,7 @@ let barModelValue2 = ref(barOptions2[2].value)
 onMounted(async () => {
   barChart = echarts.init(bar.value)
 
-  window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
   setTimeout(() => {
     resizeChart()
   }, 0)
@@ -229,25 +237,25 @@ async function initBarData() {
   responseData = await setAdStructureData()
   barData = responseData
   // 柱状图初始化数据
-  ACOSList = barData.map(item => item.ACOS)
-  SpendList = barData.map(item => item.Spend)
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
   // 将x轴映射为中文
-  xAxisList = barData.map(item => item.placement)
+  xAxisList = barData.map((item) => item.placement)
   const classificationMap = {
-    'BROAD': '关键词-广泛',
-    'category': '品类',
-    'EXACT': '关键词-精准',
-    'asin': '商品',
-    'PHRASE': '关键词-词组',
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
     'close-match': '紧密匹配',
     'loose-match': '广泛匹配',
-    'substitutes': '同类商品',
-    'complements': '关联商品',
-    'top': '搜索结果顶部(首页)',
-    'rest_of_search': '搜索结果的其余位置',
-    'product_page': '商品页面'
+    substitutes: '同类商品',
+    complements: '关联商品',
+    top: '搜索结果顶部(首页)',
+    rest_of_search: '搜索结果的其余位置',
+    product_page: '商品页面',
   }
-  xAxisMapList = xAxisList.map(item => classificationMap[item])
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
   loading.value = false
 }
 
@@ -268,11 +276,14 @@ function changeBarTwo(newValue) {
 }
 
 function updateBarChart() {
-  const barValues1 = barData.map(item => item[barModelValue1.value])
-  const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
   barChart.setOption(option)
 }
 
@@ -288,8 +299,8 @@ watch(dateRange, async () => {
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-  const barValues1 = resp.map(item => item[barModelValue1.value])
-  const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
   option.series[0].data = barValues1
   option.series[1].data = barValues2
@@ -308,15 +319,15 @@ function initChart() {
       axisPointer: {
         type: 'shadow',
         label: {
-          backgroundColor: '#6a7985'
-        }
-      }
+          backgroundColor: '#6a7985',
+        },
+      },
     },
     // legend: {data: ['数据1', '数据2'],},
     toolbox: {
       feature: {
-        saveAsImage: { yAxisIndex: 'none' }
-      }
+        saveAsImage: { yAxisIndex: 'none' },
+      },
     },
     grid: { top: 50, right: 60, bottom: 50, left: 60 },
     xAxis: [
@@ -332,22 +343,22 @@ function initChart() {
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#3a83f7' // 第一个 Y 轴的颜色
-          }
-        }
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
+        },
       },
       {
         type: 'value',
         splitLine: {
-          show: false
+          show: false,
         },
         axisLine: {
           show: true,
           lineStyle: {
-            color: '#f19a37' // 第一个 Y 轴的颜色
-          }
-        }
-      }
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
     ],
     series: [
       {
@@ -389,9 +400,6 @@ function initChart() {
 function resizeChart() {
   barChart.resize()
 }
-
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

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

@@ -1,28 +1,36 @@
 <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>
+  <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"
-import TextSelector from '/@/components/TextSelector/index.vue'
-import { getAdStructureData } from "/@/views/adManage/sp/targets/api"
+import * as echarts from 'echarts'
+import { computed, inject, onMounted, ref, watch } from 'vue'
 import { createDisabledOptions } from '../../../utils/dropdowndisable'
-import { barOptionsMap } from "/@/views/adManage/utils/enum"
+import TextSelector from '/@/components/TextSelector/index.vue'
 import { useShopInfo } from '/@/stores/shopInfo'
-
+import { getAdStructureData } from '/@/views/adManage/sp/targets/api'
+import { barOptionsMap } from '/@/views/adManage/utils/enum'
 
 const shopInfo = useShopInfo()
 let barChart = ref()
@@ -34,185 +42,185 @@ const dateRange = inject('dateRange')
 
 // 下拉框相关
 const barOptions1 = [
-    {
-        value: 'ACOS',
-        label: 'ACOS',
-    },
-    {
-        value: 'ROAS',
-        label: 'ROAS',
-    },
-    {
-        value: 'Spend',
-        label: '花费',
-        units: '$',
-    },
-    {
-        value: 'TotalSales',
-        label: '销售额',
-    },
-    {
-        value: 'TotalPurchases',
-        label: '订单数',
-    },
-    {
-        value: 'TotalUnitOrdered',
-        label: '销量',
-    },
-    {
-        value: 'CPC',
-        label: '点击成本'
-    },
-    {
-        value: 'CPA',
-        label: '订单成本'
-    },
-    {
-        value: 'Impression',
-        label: '曝光量',
-    },
-    {
-        value: 'Click',
-        label: '点击量',
-    },
-    {
-        value: 'qwe',
-        label: '点击率'
-    },
-    {
-        value: '转化率',
-        label: '转化率'
-    },
-    {
-        value: 'TotalSalesSameSKU',
-        label: '推广商品销售额'
-    },
-    {
-        value: 'TotalSalesOtherSKU',
-        label: '其他商品销售额'
-    },
-    {
-        value: 'TotalPurchasesSameSKU',
-        label: '推广商品订单数'
-    },
-    {
-        value: 'TotalPurchasesOtherSKU',
-        label: '其他商品订单数'
-    },
-    {
-        value: 'TotalUnitOrderedSameSKU',
-        label: '推广商品销量'
-    },
-    {
-        value: 'TotalUnitOrderedOtherSKU',
-        label: '其他商品销量'
-    },
-    {
-        value: 'TopOfSearchImpressionShare',
-        label: '搜索结果顶部展示份额'
-    },
+  {
+    value: 'ACOS',
+    label: 'ACOS',
+  },
+  {
+    value: 'ROAS',
+    label: 'ROAS',
+  },
+  {
+    value: 'Spend',
+    label: '花费',
+    units: '$',
+  },
+  {
+    value: 'TotalSales',
+    label: '销售额',
+  },
+  {
+    value: 'TotalPurchases',
+    label: '订单数',
+  },
+  {
+    value: 'TotalUnitOrdered',
+    label: '销量',
+  },
+  {
+    value: 'CPC',
+    label: '点击成本',
+  },
+  {
+    value: 'CPA',
+    label: '订单成本',
+  },
+  {
+    value: 'Impression',
+    label: '曝光量',
+  },
+  {
+    value: 'Click',
+    label: '点击量',
+  },
+  {
+    value: 'qwe',
+    label: '点击率',
+  },
+  {
+    value: '转化率',
+    label: '转化率',
+  },
+  {
+    value: 'TotalSalesSameSKU',
+    label: '推广商品销售额',
+  },
+  {
+    value: 'TotalSalesOtherSKU',
+    label: '其他商品销售额',
+  },
+  {
+    value: 'TotalPurchasesSameSKU',
+    label: '推广商品订单数',
+  },
+  {
+    value: 'TotalPurchasesOtherSKU',
+    label: '其他商品订单数',
+  },
+  {
+    value: 'TotalUnitOrderedSameSKU',
+    label: '推广商品销量',
+  },
+  {
+    value: 'TotalUnitOrderedOtherSKU',
+    label: '其他商品销量',
+  },
+  {
+    value: 'TopOfSearchImpressionShare',
+    label: '搜索结果顶部展示份额',
+  },
 ]
 let barModelValue1 = ref(barOptions1[0].value)
 
 const barOptions2 = [
-    {
-        value: 'ACOS',
-        label: 'ACOS',
-    },
-    {
-        value: 'ROAS',
-        label: 'ROAS',
-    },
-    {
-        value: 'Spend',
-        label: '花费',
-        units: '$',
-    },
-    {
-        value: 'TotalSales',
-        label: '销售额',
-    },
-    {
-        value: 'TotalPurchases',
-        label: '订单数',
-    },
-    {
-        value: 'TotalUnitOrdered',
-        label: '销量',
-    },
-    {
-        value: 'CPC',
-        label: '点击成本'
-    },
-    {
-        value: 'CPA',
-        label: '订单成本'
-    },
-    {
-        value: 'Impression',
-        label: '曝光量',
-    },
-    {
-        value: 'Click',
-        label: '点击量',
-    },
-    {
-        value: 'qwe',
-        label: '点击率'
-    },
-    {
-        value: '转化率',
-        label: '转化率'
-    },
-    {
-        value: 'TotalSalesSameSKU',
-        label: '推广商品销售额'
-    },
-    {
-        value: 'TotalSalesOtherSKU',
-        label: '其他商品销售额'
-    },
-    {
-        value: 'TotalPurchasesSameSKU',
-        label: '推广商品订单数'
-    },
-    {
-        value: 'TotalPurchasesOtherSKU',
-        label: '其他商品订单数'
-    },
-    {
-        value: 'TotalUnitOrderedSameSKU',
-        label: '推广商品销量'
-    },
-    {
-        value: 'TotalUnitOrderedOtherSKU',
-        label: '其他商品销量'
-    },
-    {
-        value: 'TopOfSearchImpressionShare',
-        label: '搜索结果顶部展示份额'
-    },
+  {
+    value: 'ACOS',
+    label: 'ACOS',
+  },
+  {
+    value: 'ROAS',
+    label: 'ROAS',
+  },
+  {
+    value: 'Spend',
+    label: '花费',
+    units: '$',
+  },
+  {
+    value: 'TotalSales',
+    label: '销售额',
+  },
+  {
+    value: 'TotalPurchases',
+    label: '订单数',
+  },
+  {
+    value: 'TotalUnitOrdered',
+    label: '销量',
+  },
+  {
+    value: 'CPC',
+    label: '点击成本',
+  },
+  {
+    value: 'CPA',
+    label: '订单成本',
+  },
+  {
+    value: 'Impression',
+    label: '曝光量',
+  },
+  {
+    value: 'Click',
+    label: '点击量',
+  },
+  {
+    value: 'qwe',
+    label: '点击率',
+  },
+  {
+    value: '转化率',
+    label: '转化率',
+  },
+  {
+    value: 'TotalSalesSameSKU',
+    label: '推广商品销售额',
+  },
+  {
+    value: 'TotalSalesOtherSKU',
+    label: '其他商品销售额',
+  },
+  {
+    value: 'TotalPurchasesSameSKU',
+    label: '推广商品订单数',
+  },
+  {
+    value: 'TotalPurchasesOtherSKU',
+    label: '其他商品订单数',
+  },
+  {
+    value: 'TotalUnitOrderedSameSKU',
+    label: '推广商品销量',
+  },
+  {
+    value: 'TotalUnitOrderedOtherSKU',
+    label: '其他商品销量',
+  },
+  {
+    value: 'TopOfSearchImpressionShare',
+    label: '搜索结果顶部展示份额',
+  },
 ]
 let barModelValue2 = ref(barOptions2[2].value)
 
 onMounted(async () => {
-    barChart = echarts.init(bar.value)
+  barChart = echarts.init(bar.value)
 
-    window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-    setTimeout(() => {
-        resizeChart()
-    }, 0)
+  window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
+  setTimeout(() => {
+    resizeChart()
+  }, 0)
 
-    await initBarData()
-    initChart()
+  await initBarData()
+  initChart()
 })
 
 // 获取总数据
 let allData = null
 
 async function setAdStructureData() {
-    allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
-    return allData.data
+  allData = await getAdStructureData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: shopInfo.profile.profile_id })
+  return allData.data
 }
 
 // 柱状图总数据
@@ -225,26 +233,26 @@ let xAxisList
 let xAxisMapList
 
 async function initBarData() {
-    responseData = await setAdStructureData()
-    barData = responseData
-    // 柱状图初始化数据
-    ACOSList = barData.map(item => item.ACOS)
-    SpendList = barData.map(item => item.Spend)
-    // 将x轴映射为中文
-    xAxisList = barData.map(item => item.Classification)
-    const classificationMap = {
-        'BROAD': '关键词-广泛',
-        'category': '品类',
-        'EXACT': '关键词-精准',
-        'asin': '商品',
-        'PHRASE': '关键词-词组',
-        'close-match': '紧密匹配',
-        'loose-match': '广泛匹配',
-        'substitutes': '同类商品',
-        'complements': '关联商品'
-    }
-    xAxisMapList = xAxisList.map(item => classificationMap[item])
-    loading.value = false
+  responseData = await setAdStructureData()
+  barData = responseData
+  // 柱状图初始化数据
+  ACOSList = barData.map((item) => item.ACOS)
+  SpendList = barData.map((item) => item.Spend)
+  // 将x轴映射为中文
+  xAxisList = barData.map((item) => item.Classification)
+  const classificationMap = {
+    BROAD: '关键词-广泛',
+    category: '品类',
+    EXACT: '关键词-精准',
+    asin: '商品',
+    PHRASE: '关键词-词组',
+    'close-match': '紧密匹配',
+    'loose-match': '广泛匹配',
+    substitutes: '同类商品',
+    complements: '关联商品',
+  }
+  xAxisMapList = xAxisList.map((item) => classificationMap[item])
+  loading.value = false
 }
 
 // 重置图像
@@ -254,42 +262,45 @@ let option2
 
 // 点击下拉框后重新渲染柱状图
 function changeBarOne(newValue) {
-    barModelValue1.value = newValue
-    updateBarChart()
+  barModelValue1.value = newValue
+  updateBarChart()
 }
 
 function changeBarTwo(newValue) {
-    barModelValue2.value = newValue
-    updateBarChart()
+  barModelValue2.value = newValue
+  updateBarChart()
 }
 
 function updateBarChart() {
-    const barValues1 = barData.map(item => item[barModelValue1.value])
-    const barValues2 = barData.map(item => item[barModelValue2.value])
+  const barValues1 = barData.map((item) => item[barModelValue1.value])
+  const barValues2 = barData.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  // 同时更新系列的name属性,以确保鼠标悬停时显示的文本正确
+  option.series[0].name = barOptionsMap[barModelValue1.value] || barModelValue1.value
+  option.series[1].name = barOptionsMap[barModelValue2.value] || barModelValue2.value
+  barChart.setOption(option)
 }
 
 // 监听时间变化重新渲染表格
 watch(dateRange, async () => {
-    if (dateRange.value) {
-        loading.value = true
-        const resp = await setAdStructureData()
-        updateBarChartData(resp)
-        loading.value = false
-    }
+  if (dateRange.value) {
+    loading.value = true
+    const resp = await setAdStructureData()
+    updateBarChartData(resp)
+    loading.value = false
+  }
 })
 
 // 根据新数据和当前下拉框选择更新 柱状图数据
 function updateBarChartData(resp) {
-    const barValues1 = resp.map(item => item[barModelValue1.value])
-    const barValues2 = resp.map(item => item[barModelValue2.value])
+  const barValues1 = resp.map((item) => item[barModelValue1.value])
+  const barValues2 = resp.map((item) => item[barModelValue2.value])
 
-    option.series[0].data = barValues1
-    option.series[1].data = barValues2
-    barChart.setOption(option)
+  option.series[0].data = barValues1
+  option.series[1].data = barValues2
+  barChart.setOption(option)
 }
 
 const computedBarOptions1 = computed(() => createDisabledOptions(barOptions1, barModelValue2.value, barModelValue1.value))
@@ -297,97 +308,95 @@ const computedBarOptions2 = computed(() => createDisabledOptions(barOptions2, ba
 
 // 初始化图表
 function initChart() {
-    // 柱状图配置
-    option = {
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'shadow',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+  // 柱状图配置
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow',
+        label: {
+          backgroundColor: '#6a7985',
         },
-        // legend: {data: ['数据1', '数据2'],},
-        toolbox: {
-            feature: {
-                saveAsImage: { yAxisIndex: 'none' }
-            }
+      },
+    },
+    // legend: {data: ['数据1', '数据2'],},
+    toolbox: {
+      feature: {
+        saveAsImage: { yAxisIndex: 'none' },
+      },
+    },
+    grid: { top: 50, right: 60, bottom: 50, left: 60 },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: true,
+        data: xAxisMapList,
+      },
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#3a83f7', // 第一个 Y 轴的颜色
+          },
         },
-        grid: { top: 50, right: 60, bottom: 50, left: 60 },
-        xAxis: [
-            {
-                type: 'category',
-                boundaryGap: true,
-                data: xAxisMapList,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#3a83f7' // 第一个 Y 轴的颜色
-                    }
-                }
-            },
-            {
-                type: 'value',
-                splitLine: {
-                    show: false
-                },
-                axisLine: {
-                    show: true,
-                    lineStyle: {
-                        color: '#f19a37' // 第一个 Y 轴的颜色
-                    }
-                }
-            }
-        ],
-        series: [
-            {
-                name: barOptionsMap[barModelValue1.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: ACOSList,
-                yAxisIndex: 0,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                        { offset: 0, color: '#3a83f7' },
-                        { offset: 1, color: 'rgb(111, 209, 206)' },
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-            {
-                name: barOptionsMap[barModelValue2.value],
-                type: 'bar',
-                barWidth: '3%',
-                data: SpendList,
-                yAxisIndex: 1,
-                itemStyle: {
-                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                        { offset: 0, color: '#f19a37' },
-                        { offset: 1, color: 'rgb(234,207,135)' },
-                    ]),
-                    // 柱状图圆角
-                    borderRadius: [6, 6, 6, 6],
-                },
-            },
-        ],
-    }
-    barChart.setOption(option)
-    resizeChart()
+      },
+      {
+        type: 'value',
+        splitLine: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#f19a37', // 第一个 Y 轴的颜色
+          },
+        },
+      },
+    ],
+    series: [
+      {
+        name: barOptionsMap[barModelValue1.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: ACOSList,
+        yAxisIndex: 0,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#3a83f7' },
+            { offset: 1, color: 'rgb(111, 209, 206)' },
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+      {
+        name: barOptionsMap[barModelValue2.value],
+        type: 'bar',
+        barWidth: '3%',
+        data: SpendList,
+        yAxisIndex: 1,
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#f19a37' },
+            { offset: 1, color: 'rgb(234,207,135)' },
+          ]),
+          // 柱状图圆角
+          borderRadius: [6, 6, 6, 6],
+        },
+      },
+    ],
+  }
+  barChart.setOption(option)
+  resizeChart()
 }
 
 function resizeChart() {
-    barChart.resize()
+  barChart.resize()
 }
 defineExpose({ resizeChart })
 </script>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 0 - 1
src/views/system/login/index.vue

@@ -82,7 +82,6 @@ const state = reactive({
 
 // 获取布局配置信息
 const getThemeConfig = computed(() => {
-	console.log('11', getThemeConfig)
 	return themeConfig.value;
 });
 // 页面加载时