WanGxC 1 anno fa
parent
commit
1b7e86f907

+ 6 - 2
package-lock.json

@@ -38,6 +38,7 @@
 				"pinia-plugin-persist": "^1.0.0",
 				"postcss": "^8.4.21",
 				"print-js": "^1.6.0",
+				"process": "^0.11.10",
 				"qrcodejs2-fixes": "^0.0.2",
 				"qs": "^6.11.0",
 				"screenfull": "^6.0.2",
@@ -7401,7 +7402,8 @@
 		},
 		"node_modules/process": {
 			"version": "0.11.10",
-			"license": "MIT",
+			"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
+			"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
 			"engines": {
 				"node": ">= 0.6.0"
 			}
@@ -13906,7 +13908,9 @@
 			"version": "1.6.0"
 		},
 		"process": {
-			"version": "0.11.10"
+			"version": "0.11.10",
+			"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
+			"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
 		},
 		"process-nextick-args": {
 			"version": "2.0.1"

+ 1 - 0
package.json

@@ -38,6 +38,7 @@
 		"pinia-plugin-persist": "^1.0.0",
 		"postcss": "^8.4.21",
 		"print-js": "^1.6.0",
+		"process": "^0.11.10",
 		"qrcodejs2-fixes": "^0.0.2",
 		"qs": "^6.11.0",
 		"screenfull": "^6.0.2",

+ 164 - 0
src/components/echartsComponents/BarChart.vue

@@ -0,0 +1,164 @@
+<template>
+    <div style="margin-left: 45%">
+        <span style="background: rgb(176,234,232); width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px;"></span>
+        <TextSelector :modelValue="modelValue" :options="options" style="margin-top: 5px; margin-left: 8px;"/>
+        <span style="background: rgb(234,207,135); width: 18px; height: 10px; margin-top: 8px; margin-left: 20px; display: inline-block; border-radius: 3px;"></span>
+        <TextSelector :modelValue="modelValue" :options="options" style="margin-top: 5px; margin-left: 8px;"/>
+    </div>
+    <div ref="barRef" style="height: 400px;"></div>
+</template>
+
+<script lang="ts" setup>
+import {ref, onMounted, onBeforeUnmount} from 'vue'
+import * as echarts from 'echarts'
+import TextSelector from '/@/components/TextSelector/index.vue'
+
+// defineOptions({
+//     name: 'DataTendencyChart'
+// })
+
+let chartObj: any
+const barRef = ref()
+
+function resizeChart() {
+    chartObj.resize()
+}
+
+function addResize() {
+    window.addEventListener('resize', resizeChart)
+}
+
+function removeResize() {
+    window.removeEventListener('resize', resizeChart)
+}
+
+onMounted(() => {
+    initLine()
+    addResize()
+})
+onBeforeUnmount(() => {
+    if (chartObj) {
+        chartObj.dispose()
+        chartObj = null
+    }
+    removeResize()
+})
+
+function initLine() {
+    chartObj = echarts.init(barRef.value)
+    const option = {
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+                label: {
+                    backgroundColor: '#6a7985'
+                }
+            }
+        },
+        toolbox: {
+            feature: {
+                saveAsImage: {yAxisIndex: 'none'}
+            }
+        },
+        grid: {
+            top: 70, right: 60, bottom: 30, left: 55,
+
+        },
+        xAxis: [
+            {
+                type: 'category',
+                boundaryGap: true,
+                data: ['商品', '品类', '关键词-精准', '关键词-广泛', '关键词-词组'],
+            }
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                name: '数据1',
+                axisLabel: {
+                    formatter: '{value} 单位1'
+                },
+                axisLine: {
+                    show: true
+                }
+            },
+            {
+                type: 'value',
+                name: '数据2',
+                splitLine: {
+                    show: false
+                },
+                axisLabel: {
+                    formatter: '{value} 单位2'
+                },
+                axisLine: {
+                    show: true
+                }
+            }
+        ],
+        series: [
+            {
+                name: '数据1',
+                type: 'bar',
+                // tooltip: {
+                //   valueFormatter: function (value) {
+                //     return value + ' ml';
+                //   }
+                // },
+                barWidth: '30%',
+                data: [15, 24, 21, 26, 34],
+                yAxisIndex: 0,
+                itemStyle: {
+                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                        {offset: 0, color: 'rgba(111, 209, 206, 0.8)'},
+                        {offset: 1, color: 'rgba(111, 209, 206, 0.1)'},
+                    ]),
+                    //柱状图圆角
+                    borderRadius: [15, 15, 0, 0],
+                },
+            },
+            {
+                name: '数据2',
+                type: 'bar',
+                barWidth: '30%',
+                data: [10, 16, 28, 21, 30],
+                yAxisIndex: 1,
+                itemStyle: {
+                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                        {offset: 0, color: '#ebb14d'},
+                        {offset: 1, color: 'rgba(111, 209, 206, 0.1)'},
+                    ]),
+                    //柱状图圆角
+                    borderRadius: [15, 15, 0, 0],
+                },
+            },
+        ],
+    }
+    chartObj.setOption(option)
+}
+
+defineExpose({resizeChart})
+
+// 下拉框相关
+const options = [
+    {
+        value: '花费',
+        label: '花费',
+    },
+    {
+        value: 'Option2',
+        label: 'Option2',
+    },
+    {
+        value: 'Option3',
+        label: 'Option3',
+    }
+]
+const modelValue = ref(options[0].value)
+
+</script>
+
+<style scoped>
+
+</style>

+ 182 - 179
src/components/echartsComponents/BarLineChart.vue

@@ -1,199 +1,202 @@
 <template>
-    <div id="barLine" ref="barLine" style="height: 400px;"></div>
-
+    <div ref="barLine" style="height: 400px;"></div>
 </template>
 
-<script>
-import { onMounted, onBeforeUnmount, ref } from 'vue'
+<script setup>
+import {onMounted, onBeforeUnmount, ref} from 'vue'
 import * as echarts from 'echarts'
 
-export default {
-    props: ['barLineData'],
-
-    setup(props) {
-        let lineChart = ref()
+const props = defineProps({
+    barLineData: {type: Object}
+})
+let lineChart = ref()
+const barLine = ref()
 
-        onMounted(() => {
-            lineChart = echarts.init(document.getElementById('barLine'))
-            updateChart()
-            window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
-            setTimeout(() => {
-                resizeChart()
-            },0)
-        })
-        onBeforeUnmount(() => {
-            window.removeEventListener('resize', resizeChart)   // 在组件销毁前移除事件监听,避免内存泄漏
-        })
-        // 获取图像数据 lieChartData
-        let chartData = props.barLineData
+onMounted(() => {
+    lineChart = echarts.init(barLine.value)
+    updateChart()
+    addResize()  // 监听窗口大小变化,调整图表大小
+    setTimeout(() => {
+        resizeChart()
+    }, 0)
+})
+onBeforeUnmount(() => {
+    if (lineChart) {
+        lineChart.dispose()
+        lineChart = null
+    }
+    removeResize()   // 在组件销毁前移除事件监听,避免内存泄漏
+})
+// 获取图像数据 lieChartData
+let chartData = props.barLineData
 
-        function updateChart() {
-            const option = {
-                // title: {
-                //   text: chartData.title,
-                // },
-                tooltip: {
-                    trigger: 'axis',
-                    axisPointer: {
-                        type: 'cross',
-                        label: {
-                            backgroundColor: '#6a7985'
-                        }
-                    }
+function updateChart() {
+    const option = {
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+                label: {
+                    backgroundColor: '#6a7985'
+                }
+            }
+        },
+        // legend: {data: ['数据1', '数据2'], right: '50%',left: '50%'},
+        // toolbox: {
+        //     feature: {
+        //         saveAsImage: { yAxisIndex: 'none' }
+        //     }
+        // },
+        grid: {
+            top: 50, right: 150, bottom: 30, left: 55,
+        },
+        xAxis: [
+            {
+                type: 'category',
+                boundaryGap: true,
+                data: chartData.xData,
+            }
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                name: 'ACOS',
+                splitLine: {
+                    show: true // 设置显示分割线
+                },
+                axisLabel: {
+                    formatter: '{value} 单位1'
+                },
+                axisLine: {
+                    show: true
+                }
+            },
+            {
+                type: 'value',
+                name: '点击率',
+                position: 'right',
+                splitLine: {
+                    show: false
+                },
+                axisLabel: {
+                    formatter: '{value} 单位2'
+                },
+                axisLine: {
+                    show: true
+                }
+            },
+            {
+                type: 'value',
+                position: 'right',
+                offset: 80,
+                name: '订单数',
+                splitLine: {
+                    show: false
                 },
-                // legend: {data: ['数据1', '数据2'], right: '50%',left: '50%'},
-                // toolbox: {
-                //     feature: {
-                //         saveAsImage: { yAxisIndex: 'none' }
-                //     }
+                axisLabel: {
+                    formatter: '{value} 单位3'
+                },
+                axisLine: {
+                    show: true
+                }
+            }
+        ],
+        series: [
+            {
+                name: '柱状图',
+                type: 'bar',
+                // tooltip: {
+                //   valueFormatter: function (value) {
+                //     return value + ' ml';
+                //   }
                 // },
-                grid: {
-                    top: 50, right: 150, bottom: 30, left: 55,
-
+                barWidth: '30%',
+                data: chartData.barData,
+                yAxisIndex: 0,
+                itemStyle: {
+                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                        {offset: 0, color: 'rgba(111, 209, 206, 0.8)'},
+                        {offset: 1, color: 'rgba(111, 209, 206, 0.1)'},
+                    ]),
+                    //柱状图圆角
+                    borderRadius: [15, 15, 0, 0],
                 },
-                xAxis: [
-                    {
-                        type: 'category',
-                        boundaryGap: true,
-                        data: chartData.xData,
-                    }
-                ],
-                yAxis: [
-                    {
-                        type: 'value',
-                        name: 'ACOS',
-                        splitLine: {
-                            show: true // 设置显示分割线
-                        },
-                        axisLabel: {
-                            formatter: '{value} 单位1'
-                        },
-                        axisLine: {
-                            show: true
-                        }
-                    },
-                    {
-                        type: 'value',
-                        name: '点击率',
-                        position: 'right',
-                        splitLine: {
-                            show: false
-                        },
-                        axisLabel: {
-                            formatter: '{value} 单位2'
-                        },
-                        axisLine: {
-                            show: true
-                        }
-                    },
-                    {
-                        type: 'value',
-                        position: 'right',
-                        offset: 80,
-                        name: '订单数',
-                        splitLine: {
-                            show: false
-                        },
-                        axisLabel: {
-                            formatter: '{value} 单位3'
-                        },
-                        axisLine: {
-                            show: true
-                        }
-                    }
-                ],
-                series: [
-                    {
-                        name: '柱状图',
-                        type: 'bar',
-                        // tooltip: {
-                        //   valueFormatter: function (value) {
-                        //     return value + ' ml';
-                        //   }
-                        // },
-                        barWidth: '30%',
-                        data: chartData.barData,
-                        yAxisIndex: 0,
-                        itemStyle: {
-                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                                { offset: 0, color: 'rgba(111, 209, 206, 0.8)' },
-                                { offset: 1, color: 'rgba(111, 209, 206, 0.1)' },
-                            ]),
-                            //柱状图圆角
-                            borderRadius: [15, 15, 0, 0],
-                        },
-                    },
-                    {
-                        name: '数据1',
-                        type: 'line',
-                        symbolSize: 6,
-                        symbol: 'circle',
-                        smooth: true,
-                        data: chartData.yData1,
-                        yAxisIndex: 1,
-                        lineStyle: { color: '#fe9a8b' },
-                        itemStyle: { color: '#fe9a8b', borderColor: '#fe9a8b' },
-                        areaStyle: {
-                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                                { offset: 0, color: '#fe9a8bb3' },
-                                { offset: 1, color: '#fe9a8b03' },
-                            ]),
-                        },
-                    },
-                    {
-                        name: '数据2',
-                        type: 'line',
-                        symbolSize: 6,
-                        symbol: 'circle',
-                        smooth: true,
-                        data: chartData.yData2,
-                        yAxisIndex: 2,
-                        lineStyle: { color: '#9E87FF' },
-                        itemStyle: { color: '#9E87FF', borderColor: '#9E87FF' },
-                        areaStyle: {
-                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                                { offset: 0, color: '#9E87FFb3' },
-                                { offset: 1, color: '#9E87FF03' },
-                            ]),
-                        },
-                        emphasis: {
-                            itemStyle: {
-                                color: {
-                                    type: 'radial',
-                                    x: 0.5,
-                                    y: 0.5,
-                                    r: 0.5,
-                                    colorStops: [
-                                        { offset: 0, color: '#9E87FF' },
-                                        { offset: 0.4, color: '#9E87FF' },
-                                        { offset: 0.5, color: '#fff' },
-                                        { offset: 0.7, color: '#fff' },
-                                        { offset: 0.8, color: '#fff' },
-                                        { offset: 1, color: '#fff' },
-                                    ],
-                                },
-                                borderColor: '#9E87FF',
-                                borderWidth: 2,
-                            },
+            },
+            {
+                name: '数据1',
+                type: 'line',
+                symbolSize: 6,
+                symbol: 'circle',
+                smooth: true,
+                data: chartData.yData1,
+                yAxisIndex: 1,
+                lineStyle: {color: '#fe9a8b'},
+                itemStyle: {color: '#fe9a8b', borderColor: '#fe9a8b'},
+                areaStyle: {
+                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                        {offset: 0, color: '#fe9a8bb3'},
+                        {offset: 1, color: '#fe9a8b03'},
+                    ]),
+                },
+            },
+            {
+                name: '数据2',
+                type: 'line',
+                symbolSize: 6,
+                symbol: 'circle',
+                smooth: true,
+                data: chartData.yData2,
+                yAxisIndex: 2,
+                lineStyle: {color: '#9E87FF'},
+                itemStyle: {color: '#9E87FF', borderColor: '#9E87FF'},
+                areaStyle: {
+                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                        {offset: 0, color: '#9E87FFb3'},
+                        {offset: 1, color: '#9E87FF03'},
+                    ]),
+                },
+                emphasis: {
+                    itemStyle: {
+                        color: {
+                            type: 'radial',
+                            x: 0.5,
+                            y: 0.5,
+                            r: 0.5,
+                            colorStops: [
+                                {offset: 0, color: '#9E87FF'},
+                                {offset: 0.4, color: '#9E87FF'},
+                                {offset: 0.5, color: '#fff'},
+                                {offset: 0.7, color: '#fff'},
+                                {offset: 0.8, color: '#fff'},
+                                {offset: 1, color: '#fff'},
+                            ],
                         },
+                        borderColor: '#9E87FF',
+                        borderWidth: 2,
                     },
-                ],
-            }
-            lineChart.setOption(option)
-        }
+                },
+            },
+        ],
+    }
+    lineChart.setOption(option)
+}
 
-        // 自适应调整窗口
-        function resizeChart() {
-            if (lineChart) {
-                lineChart.resize()
-            }
-        }
+// 自适应调整窗口
+function resizeChart() {
+    if (lineChart) {
+        lineChart.resize()
+    }
+}
 
-        return {resizeChart}
-    },
+function addResize() {
+    window.addEventListener('resize', resizeChart)
+}
 
+function removeResize() {
+    window.removeEventListener('resize', resizeChart)
 }
 
+defineExpose({resizeChart, updateChart})
 
 </script>
 

+ 37 - 24
src/components/echartsComponents/PieBarChart.vue

@@ -2,15 +2,21 @@
     <div>
         <el-row :gutter="5">
             <el-col :span="8">
-                <div style="display: flex;">
+                <div>
                     <!--<span>{{ modelValue }}</span>-->
                     <TextSelector :modelValue="modelValue" :options="options" style="margin-top: 5px"/>
                 </div>
 
-                <div id="pie" style="height: 400px;"></div>
+                <div ref="pie" style="height: 400px;"></div>
             </el-col>
             <el-col :span="16">
-                <div id="bar" style="height: 400px;"></div>
+                <div style="margin-left: 40%">
+                    <span style="background: rgb(176,234,232); width: 18px; height: 10px; margin-top: 8px; display: inline-block; border-radius: 3px;"></span>
+                    <TextSelector :modelValue="modelValue" :options="options" style="margin-top: 5px; margin-left: 8px;"/>
+                    <span style="background: rgb(234,207,135); width: 18px; height: 10px; margin-top: 8px; margin-left: 20px; display: inline-block; border-radius: 3px;"></span>
+                    <TextSelector :modelValue="modelValue" :options="options" style="margin-top: 5px; margin-left: 8px;"/>
+                </div>
+                <div ref="bar" style="height: 400px;"></div>
             </el-col>
         </el-row>
     </div>
@@ -23,16 +29,17 @@ import TextSelector from '/@/components/TextSelector/index.vue'
 
 let pieChart = ref()
 let barChart = ref()
+const pie = ref()
+const bar = ref()
 
 onMounted(() => {
-    pieChart = echarts.init(document.getElementById('pie'))
-    barChart = echarts.init(document.getElementById('bar'))
+    barChart = echarts.init(bar.value)
+    pieChart = echarts.init(pie.value)
     setChartData()
     window.addEventListener('resize', resizeChart)  // 监听窗口大小变化,调整图表大小
     setTimeout(() => {
         resizeChart()
     }, 0)
-
 })
 
 function setChartData() {
@@ -47,7 +54,7 @@ function setChartData() {
                 }
             }
         },
-        legend: {data: ['数据1', '数据2'],},
+        // legend: {data: ['数据1', '数据2'],},
         toolbox: {
             feature: {
                 saveAsImage: { yAxisIndex: 'none' }
@@ -99,7 +106,7 @@ function setChartData() {
                 //   }
                 // },
                 barWidth: '30%',
-                data: [2, 24, 21, 40, 51],
+                data: [15, 24, 21, 26, 34],
                 yAxisIndex: 0,
                 itemStyle: {
                     color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
@@ -114,7 +121,7 @@ function setChartData() {
                 name: '数据2',
                 type: 'bar',
                 barWidth: '30%',
-                data: [10, 20, 30, 40, 50],
+                data: [10, 16, 28, 21, 30],
                 yAxisIndex: 1,
                 itemStyle: {
                     color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
@@ -131,32 +138,39 @@ function setChartData() {
     // 饼图配置
     const option2 = {
         tooltip: {
-            trigger: 'item'
+            trigger: 'item',
         },
         series: [
             {
                 name: 'Access From',
                 type: 'pie',
-                radius: ['40%', '70%'],
+                radius: ['25%', '50%'],
                 avoidLabelOverlap: false,
-                label: {
-                    show: false,
-                    position: 'center'
+                itemStyle: {
+                    borderWidth: 1, // 设置边框的宽度
+                    borderColor: '#fff', // 将边框颜色设置为白色或图表背景颜色
                 },
                 emphasis: {
                     label: {
                         show: true,
-                        fontSize: 40,
+                        // fontSize: 40,
                         fontWeight: 'bold'
                     }
                 },
+                label: {
+                    normal: {
+                        show: true,
+                        position: 'outside',
+                        // formatter: '{b}: {c} ({d}%)' // b为数据名,c为数据值,d为百分比
+                    }
+                },
                 labelLine: {
-                    show: false
+                    normal: {
+                        show: true
+                    }
                 },
                 data: [
                     { value: 1048, name: 'Search Engine' },
-                    { value: 735, name: 'Direct' },
-                    { value: 580, name: 'Email' },
                     { value: 484, name: 'Union Ads' },
                     { value: 300, name: 'Video Ads' }
                 ]
@@ -168,10 +182,8 @@ function setChartData() {
 }
 
 function resizeChart() {
-    if (barChart) {
-        barChart.resize()
-        pieChart.resize()
-    }
+    barChart.resize()
+    pieChart.resize()
 }
 
 defineExpose({ resizeChart })
@@ -179,8 +191,8 @@ defineExpose({ resizeChart })
 // 下拉框相关
 const options = [
     {
-        value: 'Option1',
-        label: 'Option1',
+        value: '花费',
+        label: '花费',
     },
     {
         value: 'Option2',
@@ -192,6 +204,7 @@ const options = [
     }
 ]
 const modelValue = ref(options[0].value)
+
 </script>
 
 <style scoped>

+ 0 - 1
src/views/adManage/sb/campaigns/crud.tsx

@@ -7,7 +7,6 @@ import {useRouter} from 'vue-router'
 export const createCrudOptions = function ({crudExpose, context}: CreateCrudOptionsProps): CreateCrudOptionsRet {
     const pageRequest = async (query: UserPageQuery) => {
         return await api.GetList(query)
-
     }
     const editRequest = async ({form, row}: EditReq) => {
         form.id = row.id

+ 39 - 42
src/views/adManage/sb/campaigns/index.vue

@@ -2,14 +2,14 @@
     <fs-page class="fs-page-custom">
         <fs-crud ref="crudRef" v-bind="crudBinding">
             <template #header-middle>
-                <el-tabs type="border-card" @click="clickFn" class="chart-tabs">
+                <el-tabs type="border-card" @click="changeTab" class="chart-tabs">
                     <el-tab-pane label="数据趋势">
                         <MetricsCards v-model="metrics" :metric-items="options" @change="changeMetric"></MetricsCards>
                         <div style="display: flex; justify-content: flex-end">
                             <el-button-group class="ml-4" style="margin-top: 10px; margin-right: 30px">
-                                <el-button type="primary">日</el-button>
-                                <el-button type="primary">周</el-button>
-                                <el-button type="primary">月</el-button>
+                                <el-button type="primary" @click="changeChartData">日</el-button>
+                                <el-button type="primary" @click="changeChartData">周</el-button>
+                                <el-button type="primary" @click="changeChartData">月</el-button>
                             </el-button-group>
                         </div>
                         <BarLineChart ref="barLine" :barLineData="barLineData"/>
@@ -17,7 +17,9 @@
                     <el-tab-pane label="广告结构">
                         <PieBarChart ref="pieBar"/>
                     </el-tab-pane>
-                    <el-tab-pane label="散点透视"><ScatterChart ref="scatter"/></el-tab-pane>
+                    <el-tab-pane label="散点透视">
+                        <ScatterChart ref="scatter"/>
+                    </el-tab-pane>
                 </el-tabs>
             </template>
         </fs-crud>
@@ -25,60 +27,36 @@
 </template>
 
 <script setup>
-import { ref, onMounted, reactive } from 'vue'
+import { ref, onMounted, reactive, inject } from 'vue'
 import { useFs, FsPage } from '@fast-crud/fast-crud'
 import { createCrudOptions } from './crud'
 import BarLineChart from '/@/components/echartsComponents/BarLineChart.vue'
 import PieBarChart from '/@/components/echartsComponents/PieBarChart.vue'
 import ScatterChart from '/@/components/echartsComponents/ScatterChart.vue'
 import MetricsCards from "/@/components/MetricsCards/index.vue"
+import { nextTick } from "process"
 
 const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} })
 
-let barLineData = reactive({
-    xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
-    barData: [12, 13.4, 12.5, 16, 14.5, 15.6, 12.3],
-    yData1: [5, 6, 7, 8, 9, 10, 11],
-    yData2: [14, 15, 12, 16, 15, 13, 14.5]
-})
-
-let scatterData = [
-    [10.0, 8.04],
-    [8.07, 6.95],
-    [13.0, 7.58],
-    [9.05, 8.81],
-    [11.0, 8.33],
-    [14.0, 7.66],
-    [13.4, 6.81],
-    [10.0, 6.33],
-    [14.0, 8.96],
-    [12.5, 6.82],
-    [9.15, 7.2],
-    [11.5, 7.2],
-    [3.03, 4.23],
-    [12.2, 7.83],
-    [2.02, 4.47],
-    [1.05, 3.33],
-    [4.05, 4.96],
-    [6.03, 7.24],
-    [12.0, 6.26],
-    [12.0, 8.84],
-    [7.08, 5.82],
-    [5.02, 5.68]
-]
+const barLineData = inject('barLineData')
 
 onMounted(() => {
     crudExpose.doRefresh()
 })
 
-const pieBar = ref(null)
-const barLine = ref(null)
-const scatter = ref(null)
+const pieBar = ref()
+const barLine = ref()
+const scatter = ref()
 
-function clickFn() {
+function resizeTabChart() {
     pieBar.value.resizeChart()
     barLine.value.resizeChart()
-    scatter.value.resizeChart()
+}
+
+const changeTab = () => {
+    nextTick(() => {
+        resizeTabChart()
+    })
 }
 
 const metrics = ref([{ metric: 'ACOS', color: 'blue' }])
@@ -98,6 +76,25 @@ function changeMetric() {
     console.log(metrics.value)
 }
 
+// todo 发送请求获取数据切换图表
+function changeChartData() {
+    updateData({
+        xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
+        barData: [10, 13.4, 12, 14, 20, 14, 11.1],
+        yData1: [7, 2, 4, 8, 4, 15, 10],
+        yData2: [15, 10, 12, 14, 12, 10, 12.5]
+    });
+}
+
+function updateData(newData) {
+    // 更新响应式数据
+    Object.assign(barLineData, newData)
+    // 然后更新图表
+    barLine.value.updateChart()
+}
+
+defineExpose({ resizeTabChart })
+
 </script>
 
 <style scoped>

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

@@ -5,14 +5,22 @@
             <el-select v-model="portfolios" placeholder="广告组合"></el-select>
         </div>
         <div>
-            <el-tabs class="asj-tabs">
+            <el-tabs class="asj-tabs" @tab-change="changeTab">
                 <el-tab-pane label="广告活动">
-                    <campaigns></campaigns>
+                    <campaigns ref="campaignsRef"/>
+                </el-tab-pane>
+                <el-tab-pane label="关键词" :lazy="true">
+                    <keywords ref="keywordsRef"/>
+                </el-tab-pane>
+                <el-tab-pane label="商品投放" :lazy="true">
+
+                </el-tab-pane>
+                <el-tab-pane label="搜索词" :lazy="true">
+                    <SearchTerm ref="searchTermRef"/>
+                </el-tab-pane>
+                <el-tab-pane label="广告位" :lazy="true">
+
                 </el-tab-pane>
-                <el-tab-pane label="关键词" ></el-tab-pane>
-                <el-tab-pane label="商品投放"></el-tab-pane>
-                <el-tab-pane label="搜索词"></el-tab-pane>
-                <el-tab-pane label="广告位"></el-tab-pane>
             </el-tabs>
         </div>
     </div>
@@ -21,7 +29,10 @@
 <script lang="ts" setup>
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 import campaigns from './campaigns/index.vue'
-import {ref} from 'vue'
+import keywords from './keywords/index.vue'
+import SearchTerm from './searchTerms/index.vue'
+import {provide, reactive, ref} from 'vue'
+import {nextTick} from 'process'
 
 const portfolios = ref([])
 const dateRange = ref([])
@@ -30,18 +41,36 @@ function changeDateRange(val: string[]) {
     console.log(val)
 }
 
+const campaignsRef = ref()
+const keywordsRef = ref()
+
+function changeTab() {
+    nextTick(() => {
+        campaignsRef.value.resizeTabChart()
+        keywordsRef.value.resizeTabChart()
+    })
+}
+// 提供柱线图数据
+let barLineData = reactive({
+    xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
+    barData: [12, 13.4, 12.5, 16, 14.5, 15.6, 12.3],
+    yData1: [18, 13, 10, 8, 9, 10, 14.2],
+    yData2: [14, 15, 12, 16, 15, 13, 14.5]
+})
+provide('barLineData', barLineData)
+
 </script>
 
 <style>
-.public-search {
-    display: flex;
-    gap: 3px;
-    padding-bottom: 3px;
-    position: sticky;
-    top: 0;
-    z-index: 10;
-    width: 100%;
-    background-color: #f8f8f8;
-    box-shadow: 0 0 0 rgba(51, 89, 181, 0.16);
-}
+    .public-search {
+        display: flex;
+        gap: 3px;
+        padding-bottom: 3px;
+        position: sticky;
+        top: 0;
+        z-index: 10;
+        width: 100%;
+        background-color: #f8f8f8;
+        box-shadow: 0 0 0 rgba(51, 89, 181, 0.16);
+    }
 </style>

+ 42 - 0
src/views/adManage/sb/keywords/api.ts

@@ -0,0 +1,42 @@
+import { request } from '/@/utils/service';
+import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
+import XEUtils from 'xe-utils';
+
+export const apiPrefix = '/api/ad_manage/spkeywords/';
+export function GetList(query: UserPageQuery) {
+    return request({
+        url: apiPrefix,
+        method: 'get',
+        params: query,
+    })
+}
+export function GetObj(id: InfoReq) {
+    return request({
+        url: apiPrefix + id + "/",
+        method: 'get',
+    });
+}
+
+export function AddObj(obj: AddReq) {
+    return request({
+        url: apiPrefix,
+        method: 'post',
+        data: obj,
+    });
+}
+
+export function UpdateObj(obj: EditReq) {
+    return request({
+        url: apiPrefix + obj.id + '/',
+        method: 'put',
+        data: obj,
+    });
+}
+
+export function DelObj(id: DelReq) {
+    return request({
+        url: apiPrefix + id + '/',
+        method: 'delete',
+        data: { id },
+    });
+}

+ 114 - 0
src/views/adManage/sb/keywords/crud.tsx

@@ -0,0 +1,114 @@
+import * as api from './api'
+import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
+import { inject, nextTick, ref } from 'vue'
+import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+
+
+export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
+	const pageRequest = async (query: UserPageQuery) => {
+		return await api.GetList(query);
+	};
+	const editRequest = async ({ form, row }: EditReq) => {
+		form.id = row.id;
+		return await api.UpdateObj(form);
+	};
+	const delRequest = async ({ row }: DelReq) => {
+		return await api.DelObj(row.id);
+	};
+	const addRequest = async ({ form }: AddReq) => {
+		return await api.AddObj(form);
+	};
+
+	//权限判定
+	const hasPermissions = inject('$hasPermissions');
+
+	return {
+		crudOptions: {
+			table: {
+				height: 600
+			},
+			container: {
+        fixedHeight: false
+      },
+			actionbar: {
+				show: true,
+				buttons: {
+					add: {
+						show: false
+					}
+				}
+			},
+			search: {
+				show: false
+			},
+			toolbar: {
+        buttons: {
+					search: {
+						show: true
+					},
+					compact: {
+						show: false
+					}
+				}
+			},
+			request: {
+				pageRequest,
+				addRequest,
+				editRequest,
+				delRequest,
+			},
+			rowHandle: {
+				fixed: 'right',
+				width: 80,
+				buttons: {
+					view: {
+						show: false,
+					},
+					edit: {
+						iconRight: 'Edit',
+						type: 'text',
+            text: null
+						// show: hasPermissions('dictionary:Update'),
+					},
+					remove: {
+						iconRight: 'Delete',
+						type: 'text',
+            text: null
+						// show: hasPermissions('dictionary:Delete'),
+					},
+				},
+			},
+			columns: {
+        keywordText: {
+          title: '关键词'
+        },
+				matchType: {
+					title: '匹配类型',
+					type: 'dict-select',
+					search: {
+						show: true
+					},
+					dict: dict({
+						data: [
+							{ value: 'BROAD', label: '广泛匹配' },
+							{ value: 'PHRASE', label: '词组匹配' },
+							{ value: 'EXACT', label: '精准匹配' },
+						]
+					})
+				},
+				state: {
+					title: '状态'
+				},
+				bid: {
+					title: '出价'
+				},
+				"campaign": {
+					title: '广告活动'
+				},
+				"adGroup": {
+					title: '广告组'
+				}
+			}
+		}
+	}
+}

+ 116 - 0
src/views/adManage/sb/keywords/index.vue

@@ -0,0 +1,116 @@
+<template>
+    <fs-page class="fs-page-custom">
+        <fs-crud ref="crudRef" v-bind="crudBinding">
+            <template #header-middle>
+                <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card" @tab-change="changeTab">
+                    <el-tab-pane label="数据趋势" name="barLine">
+                        <MetricsCards v-model="metrics" :metric-items="options" @change="changeMetric"></MetricsCards>
+                        <div style="display: flex; justify-content: flex-end">
+                            <el-button-group class="ml-4" style="margin-top: 10px; margin-right: 30px">
+                                <el-button type="primary" @click="changeChartData">日</el-button>
+                                <el-button type="primary" @click="changeChartData">周</el-button>
+                                <el-button type="primary" @click="changeChartData">月</el-button>
+                            </el-button-group>
+                        </div>
+                        <BarLineChart ref="barLineRef" :barLineData="barLineData"/>
+                    </el-tab-pane>
+                    <el-tab-pane label="广告结构" name="bar" :lazy="true">
+                        <BarChart ref="BarChartRef"/>
+                    </el-tab-pane>
+                    <el-tab-pane label="散点视图" name="scatterView" :lazy="true"></el-tab-pane>
+                </el-tabs>
+            </template>
+        </fs-crud>
+    </fs-page>
+</template>
+
+<script setup>
+import {ref, onMounted, onBeforeUnmount, watch, nextTick, onActivated, reactive} from 'vue'
+import {useFs, FsPage} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import {useRoute, useRouter} from 'vue-router'
+import MetricsCards from '/@/components/MetricsCards/index.vue'
+import AdStructChart from '/@/views/adManage/sp/campaigns/chartComponents/adStruct.vue'
+import DataTendencyChart from '/@/views/adManage/sp/campaigns/chartComponents/dataTendency.vue'
+import BarLineChart from '/@/components/echartsComponents/BarLineChart.vue'
+import PieBarChart from '/@/components/echartsComponents/PieBarChart.vue'
+import BarChart from "/@/components/echartsComponents/BarChart.vue"
+
+const tabActiveName = ref('barLine')
+const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: {}})
+
+const metrics = ref([{metric: 'ACOS', color: 'blue'}])
+const options = ref([
+    {label: 'ACOS', value: 'ACOS', metricVal: '18.00%', preVal: '20.15%', gapVal: '-2.00%', disabled: true},
+    {label: '点击量', value: 'clicks', metricVal: '19.00%', preVal: '20.15%', gapVal: '-1.00%', disabled: true},
+    {label: '曝光量', value: 'impression', metricVal: '20.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率1', value: 'rate1', metricVal: '1.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率2', value: 'rate2', metricVal: '2.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率3', value: 'rate3', metricVal: '3.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率4', value: 'rate4', metricVal: '4.00%', preVal: '15.00%', gapVal: '5.00%'},
+    {label: '转化率5', value: 'rate5', metricVal: '5.00%', preVal: '15.00%', gapVal: '5.00%'},
+    {label: '转化率6', value: 'rate6', metricVal: '6.00%', preVal: '15.00%', gapVal: '5.00%'},
+])
+const route = useRoute()
+const router = useRouter()
+const BarChartRef = ref()
+const barLineRef = ref()
+
+const barLineData = reactive({
+    xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
+    barData: [12, 13.4, 12.5, 16, 14.5, 15.6, 12.3],
+    yData1: [18, 13, 10, 8, 9, 10, 14.2],
+    yData2: [14, 15, 12, 16, 15, 13, 14.5]
+})
+
+onMounted(() => {
+    crudExpose.doRefresh()
+})
+
+const resizeTabChart = () => {
+    if (tabActiveName.value === 'barLine') {
+        barLineRef.value.resizeChart()
+    } else if (tabActiveName.value === 'bar') {
+        BarChartRef.value.resizeChart()
+    }
+}
+const changeTab = () => {
+    nextTick(() => {
+        resizeTabChart()
+    })
+}
+const changeMetric = () => {
+    console.log(metrics.value)
+}
+
+// todo 发送请求获取数据切换图表
+function changeChartData() {
+    updateData({
+        xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
+        barData: [10, 13.4, 12, 14, 20, 14, 11.1],
+        yData1: [7, 2, 4, 8, 4, 15, 10],
+        yData2: [15, 10, 12, 14, 12, 10, 12.5]
+    });
+}
+
+function updateData(newData) {
+    // 更新响应式数据
+    Object.assign(barLineData, newData)
+    // 然后更新图表
+    barLineRef.value.updateChart()
+}
+
+defineExpose({resizeTabChart})
+
+</script>
+
+<style lang="scss">
+.chart-tabs {
+    margin: 5px 0;
+
+    .el-tabs__nav {
+        padding-left: 0 !important;
+    }
+}
+
+</style>

+ 42 - 0
src/views/adManage/sb/searchTerms/api.ts

@@ -0,0 +1,42 @@
+import { request } from '/@/utils/service';
+import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
+import XEUtils from 'xe-utils';
+
+export const apiPrefix = '/api/ad_manage/spkeywords/';
+export function GetList(query: UserPageQuery) {
+    return request({
+        url: apiPrefix,
+        method: 'get',
+        params: query,
+    })
+}
+export function GetObj(id: InfoReq) {
+    return request({
+        url: apiPrefix + id + "/",
+        method: 'get',
+    });
+}
+
+export function AddObj(obj: AddReq) {
+    return request({
+        url: apiPrefix,
+        method: 'post',
+        data: obj,
+    });
+}
+
+export function UpdateObj(obj: EditReq) {
+    return request({
+        url: apiPrefix + obj.id + '/',
+        method: 'put',
+        data: obj,
+    });
+}
+
+export function DelObj(id: DelReq) {
+    return request({
+        url: apiPrefix + id + '/',
+        method: 'delete',
+        data: { id },
+    });
+}

+ 114 - 0
src/views/adManage/sb/searchTerms/crud.tsx

@@ -0,0 +1,114 @@
+import * as api from './api'
+import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
+import { inject, nextTick, ref } from 'vue'
+import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
+
+
+export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
+	const pageRequest = async (query: UserPageQuery) => {
+		return await api.GetList(query);
+	};
+	const editRequest = async ({ form, row }: EditReq) => {
+		form.id = row.id;
+		return await api.UpdateObj(form);
+	};
+	const delRequest = async ({ row }: DelReq) => {
+		return await api.DelObj(row.id);
+	};
+	const addRequest = async ({ form }: AddReq) => {
+		return await api.AddObj(form);
+	};
+
+	//权限判定
+	const hasPermissions = inject('$hasPermissions');
+
+	return {
+		crudOptions: {
+			table: {
+				height: 600
+			},
+			container: {
+        fixedHeight: false
+      },
+			actionbar: {
+				show: true,
+				buttons: {
+					add: {
+						show: false
+					}
+				}
+			},
+			search: {
+				show: false
+			},
+			toolbar: {
+        buttons: {
+					search: {
+						show: true
+					},
+					compact: {
+						show: false
+					}
+				}
+			},
+			request: {
+				pageRequest,
+				addRequest,
+				editRequest,
+				delRequest,
+			},
+			rowHandle: {
+				fixed: 'right',
+				width: 80,
+				buttons: {
+					view: {
+						show: false,
+					},
+					edit: {
+						iconRight: 'Edit',
+						type: 'text',
+            text: null
+						// show: hasPermissions('dictionary:Update'),
+					},
+					remove: {
+						iconRight: 'Delete',
+						type: 'text',
+            text: null
+						// show: hasPermissions('dictionary:Delete'),
+					},
+				},
+			},
+			columns: {
+        keywordText: {
+          title: '关键词'
+        },
+				matchType: {
+					title: '匹配类型',
+					type: 'dict-select',
+					search: {
+						show: true
+					},
+					dict: dict({
+						data: [
+							{ value: 'BROAD', label: '广泛匹配' },
+							{ value: 'PHRASE', label: '词组匹配' },
+							{ value: 'EXACT', label: '精准匹配' },
+						]
+					})
+				},
+				state: {
+					title: '状态'
+				},
+				bid: {
+					title: '出价'
+				},
+				"campaign": {
+					title: '广告活动'
+				},
+				"adGroup": {
+					title: '广告组'
+				}
+			}
+		}
+	}
+}

+ 112 - 0
src/views/adManage/sb/searchTerms/index.vue

@@ -0,0 +1,112 @@
+<template>
+    <fs-page class="fs-page-custom">
+        <fs-crud ref="crudRef" v-bind="crudBinding">
+            <template #header-middle>
+                <el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card" @tab-change="changeTab">
+                    <el-tab-pane label="数据趋势" name="barLine">
+                        <MetricsCards v-model="metrics" :metric-items="options" @change="changeMetric"></MetricsCards>
+                        <div style="display: flex; justify-content: flex-end">
+                            <el-button-group class="ml-4" style="margin-top: 10px; margin-right: 30px">
+                                <el-button type="primary" @click="changeChartData">日</el-button>
+                                <el-button type="primary" @click="changeChartData">周</el-button>
+                                <el-button type="primary" @click="changeChartData">月</el-button>
+                            </el-button-group>
+                        </div>
+                        <BarLineChart ref="barLineRef" :barLineData="barLineData"/>
+                    </el-tab-pane>
+                    <el-tab-pane label="散点视图" name="scatterView" :lazy="true"></el-tab-pane>
+                </el-tabs>
+            </template>
+        </fs-crud>
+    </fs-page>
+</template>
+
+<script setup>
+import {ref, onMounted, onBeforeUnmount, watch, nextTick, onActivated, reactive} from 'vue'
+import {useFs, FsPage} from '@fast-crud/fast-crud'
+import {createCrudOptions} from './crud'
+import {useRoute, useRouter} from 'vue-router'
+import MetricsCards from '/@/components/MetricsCards/index.vue'
+import AdStructChart from '/@/views/adManage/sp/campaigns/chartComponents/adStruct.vue'
+import DataTendencyChart from '/@/views/adManage/sp/campaigns/chartComponents/dataTendency.vue'
+import BarLineChart from '/@/components/echartsComponents/BarLineChart.vue'
+import PieBarChart from '/@/components/echartsComponents/PieBarChart.vue'
+import BarChart from "/@/components/echartsComponents/BarChart.vue"
+
+const tabActiveName = ref('barLine')
+const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: {}})
+
+const metrics = ref([{metric: 'ACOS', color: 'blue'}])
+const options = ref([
+    {label: 'ACOS', value: 'ACOS', metricVal: '18.00%', preVal: '20.15%', gapVal: '-2.00%', disabled: true},
+    {label: '点击量', value: 'clicks', metricVal: '19.00%', preVal: '20.15%', gapVal: '-1.00%', disabled: true},
+    {label: '曝光量', value: 'impression', metricVal: '20.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率1', value: 'rate1', metricVal: '1.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率2', value: 'rate2', metricVal: '2.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率3', value: 'rate3', metricVal: '3.00%', preVal: '15.00%', gapVal: '5.00%', disabled: true},
+    {label: '转化率4', value: 'rate4', metricVal: '4.00%', preVal: '15.00%', gapVal: '5.00%'},
+    {label: '转化率5', value: 'rate5', metricVal: '5.00%', preVal: '15.00%', gapVal: '5.00%'},
+    {label: '转化率6', value: 'rate6', metricVal: '6.00%', preVal: '15.00%', gapVal: '5.00%'},
+])
+const route = useRoute()
+const router = useRouter()
+const barLineRef = ref()
+
+const barLineData = reactive({
+    xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
+    barData: [12, 13.4, 12.5, 16, 14.5, 15.6, 12.3],
+    yData1: [18, 13, 10, 8, 9, 10, 14.2],
+    yData2: [14, 15, 12, 16, 15, 13, 14.5]
+})
+
+onMounted(() => {
+    crudExpose.doRefresh()
+})
+
+const resizeTabChart = () => {
+    if (tabActiveName.value === 'barLine') {
+        barLineRef.value.resizeChart()
+    } else if (tabActiveName.value === 'bar') {
+        // BarChartRef.value.resizeChart()
+    }
+}
+const changeTab = () => {
+    nextTick(() => {
+        resizeTabChart()
+    })
+}
+const changeMetric = () => {
+    console.log(metrics.value)
+}
+
+// todo 发送请求获取数据切换图表
+function changeChartData() {
+    updateData({
+        xData: ['2023-10-18', '2023-10-19', '2023-10-20', '2023-10-21', '2023-10-22', '2023-10-23', '2023-10-24'],
+        barData: [10, 13.4, 12, 14, 20, 14, 11.1],
+        yData1: [7, 2, 4, 8, 4, 15, 10],
+        yData2: [15, 10, 12, 14, 12, 10, 12.5]
+    });
+}
+
+function updateData(newData) {
+    // 更新响应式数据
+    Object.assign(barLineData, newData)
+    // 然后更新图表
+    barLineRef.value.updateChart()
+}
+
+defineExpose({resizeTabChart})
+
+</script>
+
+<style lang="scss">
+.chart-tabs {
+    margin: 5px 0;
+
+    .el-tabs__nav {
+        padding-left: 0 !important;
+    }
+}
+
+</style>

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

@@ -1,47 +1,53 @@
 <template>
-  <div style="height: 500px;" ref="lineRef"></div>
+    <div style="height: 500px;" ref="lineRef"></div>
 </template>
 
 <script lang="ts" setup>
-import { ref,onMounted, onBeforeUnmount } from 'vue'
+import {ref, onMounted, onBeforeUnmount} from 'vue'
 import * as echarts from 'echarts'
 
 defineOptions({
-  name: "AdStructChart"
+    name: 'AdStructChart'
 })
 
-let chartObj:any
+let chartObj: any
 const lineRef = ref()
-const resizeChart = () => { chartObj.resize() }
-const addResize = () => { window.addEventListener('resize', resizeChart) }
-const removeResize = () => { window.removeEventListener('resize', resizeChart) }
+const resizeChart = () => {
+    chartObj.resize()
+}
+const addResize = () => {
+    window.addEventListener('resize', resizeChart)
+}
+const removeResize = () => {
+    window.removeEventListener('resize', resizeChart)
+}
 
 onMounted(() => {
-	initLine()
-	addResize()
-});
+    initLine()
+    addResize()
+})
 onBeforeUnmount(() => {
-	if(chartObj) {
-		chartObj.dispose()
-    chartObj = null
-	}
-	removeResize()
+    if (chartObj) {
+        chartObj.dispose()
+        chartObj = null
+    }
+    removeResize()
 })
 const initLine = () => {
-	chartObj = echarts.init(lineRef.value)
-	const option = {
-		xAxis: {
-			data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-		},
-		yAxis: {},
-		series: [
-			{
-				type: 'bar',
-				data: [23, 24, 18, 25, 27, 28, 25]
-			}
-		]
-	}
-	chartObj.setOption(option)
+    chartObj = echarts.init(lineRef.value)
+    const option = {
+        xAxis: {
+            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+        },
+        yAxis: {},
+        series: [
+            {
+                type: 'bar',
+                data: [23, 24, 18, 25, 27, 28, 25]
+            }
+        ]
+    }
+    chartObj.setOption(option)
 }
 defineExpose({resizeChart})
 
@@ -49,4 +55,4 @@ defineExpose({resizeChart})
 
 <style scoped>
 
-</style>
+</style>

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

@@ -1,56 +1,56 @@
 <template>
-  <div class="asj-container">
-    <div class="public-search">
-      <DateRangePicker v-model="dateRange" timezone="America/Los_Angeles"></DateRangePicker>
-      <el-select v-model="selectedPortfolios" placeholder="广告组合" clearable multiple>
-        <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
-      </el-select>
+    <div class="asj-container">
+        <div class="public-search">
+            <DateRangePicker v-model="dateRange" timezone="America/Los_Angeles"></DateRangePicker>
+            <el-select v-model="selectedPortfolios" placeholder="广告组合" clearable multiple>
+                <el-option v-for="info of portfolios" :label="info.name" :value="info.portfolioId"></el-option>
+            </el-select>
+        </div>
+        <el-tabs v-model="tabActiveName" class="asj-tabs" @tab-change="changeTab">
+            <el-tab-pane label="广告活动" name="campaigns">
+                <Campaigns ref="campaignsRef"/>
+            </el-tab-pane>
+            <el-tab-pane label="关键词投放" name="keywords" :lazy="true">
+                <Keywords ref="keywordsRef"/>
+            </el-tab-pane>
+            <el-tab-pane label="商品投放" :lazy="true"></el-tab-pane>
+            <el-tab-pane label="搜索词" :lazy="true"></el-tab-pane>
+            <el-tab-pane label="广告位" :lazy="true"></el-tab-pane>
+        </el-tabs>
     </div>
-    <el-tabs v-model="tabActiveName" class="asj-tabs" @tab-change="changeTab">
-      <el-tab-pane label="广告活动" name="campaigns">
-        <Campaigns ref="campaignsRef"/>
-      </el-tab-pane>
-      <el-tab-pane label="关键词投放" name="keywords" :lazy="true">
-        <Keywords ref="keywordsRef"/>
-      </el-tab-pane>
-      <el-tab-pane label="商品投放" :lazy="true"></el-tab-pane>
-      <el-tab-pane label="搜索词" :lazy="true"></el-tab-pane>
-      <el-tab-pane label="广告位" :lazy="true"></el-tab-pane>
-    </el-tabs>
-  </div>
 </template>
 
 <script lang="ts" setup>
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 import Campaigns from './campaigns/index.vue'
 import Keywords from './keywords/index.vue'
-import { recentDaysRange } from '/@/views/adManage/utils/tools'
-import { ref, onBeforeMount, Ref } from 'vue'
-import { useShopInfo } from '/@/stores/shopInfo'
-import { GetList } from '/@/views/adManage/portfolios/api'
-import { nextTick } from 'process'
+import {recentDaysRange} from '/@/views/adManage/utils/tools'
+import {ref, onBeforeMount, Ref} from 'vue'
+import {useShopInfo} from '/@/stores/shopInfo'
+import {GetList} from '/@/views/adManage/portfolios/api'
+import {nextTick} from 'process'
 
 
 const shopInfo = useShopInfo()
 const selectedPortfolios: Ref<string[]> = ref([])
 const portfolios: Ref<Portfolio[]> = ref([])
 const dateRange: Ref<string[]> = ref([])
-const tabActiveName = ref("campaigns")
+const tabActiveName = ref('campaigns')
 const keywordsRef = ref()
 const campaignsRef = ref()
 
 onBeforeMount(async () => {
-  console.log(shopInfo.profile)
-  dateRange.value = recentDaysRange(shopInfo.profile.time_zone, 7)
+    console.log(shopInfo.profile)
+    dateRange.value = recentDaysRange(shopInfo.profile.time_zone, 7)
 
-  const resp:APIResponseData = await GetList({ limit: 999 })
-  portfolios.value = resp.data
+    const resp: APIResponseData = await GetList({limit: 999})
+    portfolios.value = resp.data
 })
 const changeTab = () => {
-  nextTick(() => {
-    campaignsRef.value.resizeTabChart()
-    keywordsRef.value.resizeTabChart()
-  })
+    nextTick(() => {
+        campaignsRef.value.resizeTabChart()
+        keywordsRef.value.resizeTabChart()
+    })
 }
 
 </script>