Parcourir la source

feat: 新增统计分析模块的图表和组件

添加销售数据、搜索分析和营销分析模块的图表组件和页面
包含基础图表组件、漏斗图、趋势图、分布图等可视化组件
实现销售数据概览、搜索词分析和营销活动分析功能
ylong il y a 4 jours
Parent
commit
198c45976f

+ 56 - 0
src/components/Chart/BaseChart.vue

@@ -0,0 +1,56 @@
+<template>
+  <v-chart ref="chartRef" :option="option" :autoresize="true" class="base-chart" />
+</template>
+
+<script setup>
+import { ref, toRefs } from 'vue';
+import VChart from 'vue-echarts';
+import { useEcharts } from '@/utils/use-echarts';
+import { use } from 'echarts/core';
+import { CanvasRenderer } from 'echarts/renderers';
+import { BarChart, PieChart, LineChart } from 'echarts/charts';
+import {
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  DataZoomComponent,
+  GraphicComponent
+} from 'echarts/components';
+
+use([
+  CanvasRenderer,
+  BarChart,
+  PieChart,
+  LineChart,
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  DataZoomComponent,
+  GraphicComponent
+]);
+
+const props = defineProps({
+  option: {
+    type: Object,
+    required: true,
+    default: () => ({})
+  }
+});
+
+const { option } = toRefs(props);
+const chartRef = ref(null);
+
+useEcharts([chartRef]);
+
+defineExpose({
+  chartRef
+});
+</script>
+
+<style scoped>
+.base-chart {
+  width: 100%;
+  height: 100%;
+  min-height: 300px;
+}
+</style>

+ 79 - 0
src/components/Chart/FunnelChart.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="funnel-chart-container">
+    <svg viewBox="0 0 800 320" preserveAspectRatio="xMidYMid meet" class="funnel-svg">
+      <defs>
+        <filter id="shadow" x="-10%" y="-10%" width="120%" height="120%">
+          <feDropShadow dx="0" dy="1" stdDeviation="2" flood-color="#000000" flood-opacity="0.1" />
+        </filter>
+      </defs>
+
+      <!-- Conversion Line (Moved to background) -->
+      <polyline points="630,105 700,105 650,210 500,210" fill="none" stroke="#999" stroke-width="2" />
+      <text x="710" y="150" fill="#666" font-size="20">转化率</text>
+      <text x="710" y="180" fill="#333" font-size="24" font-weight="bold">{{ conversionRate }}</text>
+
+      <!-- Group 1: Visitors (Top) -->
+      <g transform="translate(0, 0)">
+        <!-- Left: Light Blue -->
+        <!-- Shape: Rect left, slanted right edge -->
+        <path d="M50,10 L350,10 L380,150 L50,150 Z" fill="#9ac1d9" stroke="none" />
+        
+        <!-- Right: Dark Blue -->
+        <!-- Shape: Slanted left edge (parallel gap), slanted right edge -->
+        <path d="M385,10 L700,10 L650,150 L415,150 Z" fill="#4a8aff" stroke="none" />
+        
+        <!-- Text: Left -->
+        <text x="150" y="60" fill="#fff" font-size="20">领取人数</text>
+        <text x="150" y="100" fill="#fff" font-size="24" font-weight="bold">{{ visitorCount }}</text>
+
+        <!-- Text: Right -->
+        <text x="540" y="90" text-anchor="middle" fill="#fff" font-size="32" font-weight="bold">{{ visitorLabel }}</text>
+      </g>
+
+      <!-- Group 2: Payment (Bottom) -->
+      <g transform="translate(0, 155)">
+        <!-- Left: Light Teal -->
+        <path d="M50,0 L380,0 L530,150 L50,150 Z" fill="#a5d1d3" stroke="none" />
+        
+        <!-- Right: Dark Teal (Triangle) -->
+        <path d="M415,0 L650,0 L532.5,150 Z" fill="#63c2cc" stroke="none" />
+
+        <!-- Text: Left -->
+        <!-- 营销支付人数 -->
+        <text x="100" y="60" fill="#fff" font-size="18">营销支付人数</text>
+        <text x="150" y="100" fill="#fff" font-size="22" font-weight="bold">{{ paymentCount }}</text>
+
+        <!-- 客单价 -->
+        <text x="280" y="60" fill="#fff" font-size="18">客单价</text>
+        <text x="310" y="100" fill="#fff" font-size="22" font-weight="bold">{{ unitPrice }}</text>
+
+        <!-- Text: Right -->
+        <text x="532" y="60" text-anchor="middle" fill="#fff" font-size="32" font-weight="bold">{{ paymentLabel }}</text>
+      </g>
+
+    </svg>
+  </div>
+</template>
+
+<script setup>
+defineProps({
+  visitorLabel: { type: String, default: '访客' },
+  paymentLabel: { type: String, default: '支付' },
+  visitorCount: { type: [Number, String], default: 0 },
+  paymentCount: { type: [Number, String], default: 0 },
+  unitPrice: { type: [Number, String], default: 0 },
+  conversionRate: { type: String, default: '0%' }
+});
+</script>
+
+<style scoped>
+.funnel-chart-container {
+  width: 100%;
+  height: 100%;
+  min-height: 250px;
+}
+.funnel-svg {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 172 - 0
src/views/statsAnalysis/marketing/components/ActivityAnalysis.vue

@@ -0,0 +1,172 @@
+<template>
+	<div class="activity-analysis">
+		<div class="section-title">{{ title }}</div>
+
+		<!-- Stats Grid -->
+		<div class="stats-grid">
+			<div v-for="(stat, index) in stats" :key="index" class="stat-card">
+				<div class="stat-label">{{ stat.label }}</div>
+				<div class="stat-value">{{ stat.value }}</div>
+			</div>
+		</div>
+
+		<!-- Charts Row -->
+		<div class="charts-row">
+			<!-- Left: New/Old Repurchase -->
+			<div class="chart-box left-chart">
+				<div class="chart-title">拉新复购</div>
+				<div class="chart-content">
+					<base-chart :option="donutOption" />
+				</div>
+			</div>
+
+			<!-- Right: Traffic Conversion -->
+			<div class="chart-box right-chart">
+				<div class="chart-title">流量转化</div>
+				<div class="chart-content">
+					<funnel-chart :visitor-count="funnelData.visitorCount" :payment-count="funnelData.paymentCount"
+						:unit-price="funnelData.unitPrice" :conversion-rate="funnelData.conversionRate" />
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import { computed } from 'vue';
+import BaseChart from '@/components/Chart/BaseChart.vue';
+import FunnelChart from '@/components/Chart/FunnelChart.vue';
+
+const props = defineProps({
+	title: {
+		type: String,
+		required: true
+	},
+	stats: {
+		type: Array,
+		default: () => []
+	},
+	newCustomerRatio: {
+		type: Number,
+		default: 0.6 // 60% new
+	},
+	funnelData: {
+		type: Object,
+		default: () => ({
+			visitorCount: 32,
+			paymentCount: 32,
+			unitPrice: 32,
+			conversionRate: '65%'
+		})
+	}
+});
+
+const donutOption = computed(() => ({
+	tooltip: {
+		trigger: 'item'
+	},
+	legend: {
+		top: '5%',
+		left: 'center',
+		data: ['老客户成交占比', '新客户成交占比']
+	},
+	series: [
+		{
+			name: '成交占比',
+			type: 'pie',
+			radius: ['40%', '70%'],
+			avoidLabelOverlap: false,
+			itemStyle: {
+				borderRadius: 0,
+				borderColor: '#fff',
+				borderWidth: 2
+			},
+			label: {
+				show: true,
+				formatter: '{b}\n{d}%'
+			},
+			emphasis: {
+				label: {
+					show: true,
+					fontSize: 16,
+					fontWeight: 'bold'
+				}
+			},
+			labelLine: {
+				show: true
+			},
+			data: [
+				{ value: 1 - props.newCustomerRatio, name: '老客户成交占比', itemStyle: { color: '#5b8ff9' } },
+				{ value: props.newCustomerRatio, name: '新客户成交占比', itemStyle: { color: '#5ebcb9' } }
+			]
+		}
+	]
+}));
+</script>
+
+<style scoped lang="scss">
+.activity-analysis {
+	margin-top: 30px;
+	border-top: 1px solid #eee;
+	padding-top: 20px;
+}
+
+.section-title {
+	font-size: 16px;
+	font-weight: bold;
+	margin-bottom: 20px;
+	color: #333;
+}
+
+.stats-grid {
+	display: grid;
+	grid-template-columns: repeat(4, 1fr);
+	gap: 15px;
+	margin-bottom: 20px;
+}
+
+.stat-card {
+	background-color: #f0f2f5;
+	padding: 20px;
+	border-radius: 4px;
+	text-align: center;
+
+	.stat-label {
+		color: #666;
+		font-size: 14px;
+	}
+
+	.stat-value {
+		color: #333;
+		font-size: 26px;
+		font-weight: 500;
+	}
+}
+
+.charts-row {
+	display: flex;
+	gap: 20px;
+}
+
+.chart-box {
+	flex: 1;
+	background-color: #f0f2f5;
+	padding: 20px;
+	border-radius: 4px;
+	height: 350px;
+	display: flex;
+	flex-direction: column;
+
+	.chart-title {
+		font-size: 14px;
+		font-weight: bold;
+		color: #666;
+		margin-bottom: 10px;
+	}
+
+	.chart-content {
+		flex: 1;
+		position: relative;
+	}
+}
+</style>

+ 218 - 0
src/views/statsAnalysis/marketing/components/MarketingOverview.vue

@@ -0,0 +1,218 @@
+<template>
+	<div class="marketing-overview">
+		<div class="overview-section">
+			<div class="section-title">营销概要</div>
+
+			<!-- Top Section: Analysis -->
+			<ele-card class="analysis-card" :body-style="{ padding: '20px' }">
+				<div class="card-header">营销分析</div>
+
+				<div class="stats-row">
+					<div class="stat-item">
+						<div class="stat-label">有效活动数</div>
+						<div class="stat-value">3</div>
+					</div>
+					<div class="stat-item">
+						<div class="stat-label">营销支付金额</div>
+						<div class="stat-value">366994.6</div>
+					</div>
+					<div class="stat-item">
+						<div class="stat-label">营销支付金额占比</div>
+						<div class="stat-value">15.6%</div>
+					</div>
+				</div>
+
+				<div class="chart-wrapper horizontal-bar">
+					<base-chart :option="marketingDistributionOption" />
+				</div>
+			</ele-card>
+
+			<!-- Bottom Section: Payment Amount -->
+			<ele-card class="payment-card" :body-style="{ padding: '20px' }">
+				<div class="card-header">支付金额</div>
+				<div class="chart-wrapper payment-bar">
+					<base-chart :option="paymentAmountOption" />
+				</div>
+			</ele-card>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import { reactive } from 'vue';
+import BaseChart from '@/components/Chart/BaseChart.vue';
+
+// Marketing Distribution Option (Horizontal Stacked Bar)
+const marketingDistributionOption = reactive({
+	tooltip: {
+		trigger: 'axis',
+		axisPointer: { type: 'shadow' }
+	},
+	legend: {
+		bottom: 0,
+		data: ['惊喜红包', '分享降价', '满减优惠']
+	},
+	grid: {
+		left: '3%',
+		right: '4%',
+		bottom: '15%',
+		containLabel: true,
+		height: '60px', // Thin bar
+		top: 'center'
+	},
+	xAxis: {
+		type: 'value',
+		show: false,
+		splitLine: { show: false }
+	},
+	yAxis: {
+		type: 'category',
+		data: [''],
+		show: false,
+		splitLine: { show: false }
+	},
+	series: [
+		{
+			name: '惊喜红包',
+			type: 'bar',
+			stack: 'total',
+			label: { show: true, position: 'inside' },
+			emphasis: { focus: 'series' },
+			data: [100],
+			itemStyle: { color: '#d4ad5b' },
+			barWidth: 40
+		},
+		{
+			name: '分享降价',
+			type: 'bar',
+			stack: 'total',
+			label: { show: true, position: 'inside' },
+			emphasis: { focus: 'series' },
+			data: [300],
+			itemStyle: { color: '#5ebcb9' }
+		},
+		{
+			name: '满减优惠',
+			type: 'bar',
+			stack: 'total',
+			label: { show: true, position: 'inside' },
+			emphasis: { focus: 'series' },
+			data: [100],
+			itemStyle: { color: '#4caf50' }
+		}
+	]
+});
+
+// Payment Amount Option (Bar Chart)
+const paymentAmountOption = reactive({
+	tooltip: {
+		trigger: 'axis',
+		axisPointer: { type: 'shadow' }
+	},
+	legend: {
+		top: 0,
+		right: 20,
+		data: ['营销金额', '非营销金额']
+	},
+	grid: {
+		left: '3%',
+		right: '4%',
+		bottom: '3%',
+		containLabel: true
+	},
+	xAxis: {
+		type: 'category',
+		data: ['8.1', '8.2', '8.3', '8.4', '8.5', '8.6', '8.7', '8.8', '8.9', '8.10', '8.11', '8.12']
+	},
+	yAxis: {
+		type: 'value'
+	},
+	series: [
+		{
+			name: '营销金额',
+			type: 'bar',
+			data: [100, 140, 230, 100, 130, 210, 200, 180, 115, 150, 220, 120],
+			itemStyle: { color: '#5b8ff9' }
+		},
+		{
+			name: '非营销金额',
+			type: 'bar',
+			data: [150, 100, 200, 140, 100, 230, 210, 150, 145, 210, 190, 130],
+			itemStyle: { color: '#5ebcb9' }
+		}
+	]
+});
+</script>
+
+<style scoped lang="scss">
+.marketing-overview {
+	margin-bottom: 20px;
+}
+
+.section-title {
+	font-size: 16px;
+	font-weight: bold;
+	margin-bottom: 15px;
+	color: #333;
+}
+
+.analysis-card {
+	margin-bottom: 20px;
+	background-color: #f5f5f5; // Light gray bg from design
+	border: none;
+
+	:deep(.el-card__body) {
+		background-color: #f0f2f5;
+	}
+}
+
+.payment-card {
+	background-color: #f5f5f5;
+	border: none;
+
+	:deep(.el-card__body) {
+		background-color: #f0f2f5;
+	}
+}
+
+.card-header {
+	font-size: 16px;
+	color: #333;
+	margin-bottom: 20px;
+}
+
+.stats-row {
+	display: flex;
+	justify-content: space-around;
+	margin-bottom: 30px;
+	text-align: center;
+
+	.stat-label {
+		color: #666;
+		font-size: 14px;
+		margin-bottom: 10px;
+	}
+
+	.stat-value {
+		color: #333;
+		font-size: 24px;
+		font-weight: 500;
+	}
+}
+
+.chart-wrapper {
+	width: 100%;
+
+	&.horizontal-bar {
+		height: 100px;
+
+		:deep(.base-chart) {
+			min-height: 100px;
+		}
+	}
+
+	&.payment-bar {
+		height: 350px;
+	}
+}
+</style>

+ 132 - 0
src/views/statsAnalysis/marketing/index.vue

@@ -0,0 +1,132 @@
+<template>
+    <ele-page>
+        <ele-card :body-style="{ padding: '20px' }">
+            <!-- Header / Filters -->
+            <div class="filter-container">
+                <div class="date-ranges">
+                    <el-button v-for="range in dateRanges" :key="range.value"
+                        :type="activeRange === range.value ? 'primary' : ''" @click="activeRange = range.value">
+                        {{ range.label }}
+                    </el-button>
+                </div>
+                <div class="date-picker-wrapper">
+                    <el-date-picker v-model="dateRange" type="daterange" range-separator="到" start-placeholder="开始时间"
+                        end-placeholder="结束时间" />
+                </div>
+                <el-button type="primary" @click="handleSearch">搜索</el-button>
+            </div>
+
+            <!-- Marketing Overview -->
+            <marketing-overview />
+
+            <!-- Surprise Red Packet Activity -->
+            <activity-analysis title="惊喜红包活动" :stats="redPacketStats" :new-customer-ratio="0.6"
+                :funnel-data="funnelData1" />
+
+            <!-- Share Price Reduction Activity -->
+            <activity-analysis title="分享降价活动" :stats="shareStats" :new-customer-ratio="0.35"
+                :funnel-data="funnelData2" />
+
+            <!-- Full Reduction Discount -->
+            <activity-analysis title="满减优惠" :stats="fullReductionStats" :new-customer-ratio="0.65"
+                :funnel-data="funnelData3" />
+
+        </ele-card>
+    </ele-page>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import MarketingOverview from './components/MarketingOverview.vue';
+import ActivityAnalysis from './components/ActivityAnalysis.vue';
+
+// Filters
+const activeRange = ref('yesterday');
+const dateRange = ref([]);
+const dateRanges = [
+    { label: '昨日', value: 'yesterday' },
+    { label: '7日', value: '7days' },
+    { label: '15日', value: '15days' },
+    { label: '30日', value: '30days' }
+];
+
+const handleSearch = () => {
+    console.log('Search clicked', activeRange.value, dateRange.value);
+};
+
+// Mock Data
+const redPacketStats = [
+    { label: '红包拉动成交金额 (元)', value: '1999.9' },
+    { label: '参与人数 (人)', value: '200' },
+    { label: '客单价(元)', value: '200' },
+    { label: '订单覆盖率', value: '20%' },
+    { label: '红包过期率', value: '20%' },
+    { label: '红包使用数(张)', value: '200' },
+    { label: '红包领取金额(元)', value: '200' },
+    { label: '红包消耗金额 (元)', value: '200.00' },
+    { label: '红包使用率', value: '0.10%' },
+    { label: '红包待使用金额(元)', value: '200' },
+    { label: '红包待使用量(张)', value: '200' },
+    { label: '红包领取数(张)', value: '200' }
+];
+
+const shareStats = [
+    { label: '营销支付金额', value: '1999.99 (元)' },
+    { label: '营销优惠金额', value: '200.00 (元)' },
+    { label: '参与人数', value: '200.00 (人)' },
+    { label: '支付订单数', value: '200.00 (单)' },
+    { label: '客单价', value: '200.00 (元)' },
+    { label: '助力人数', value: '200.00 (人)' }
+];
+
+const fullReductionStats = [
+    { label: '营销支付金额', value: '1999.99 (元)' },
+    { label: '营销优惠金额', value: '200.00 (元)' },
+    { label: '参与人数', value: '200.00 (人)' },
+    { label: '支付订单数', value: '200.00 (单)' },
+    { label: '客单价', value: '200.00 (元)' }
+];
+
+const funnelData1 = {
+    visitorCount: 32,
+    paymentCount: 32,
+    unitPrice: 32,
+    conversionRate: '65%'
+};
+
+const funnelData2 = {
+    visitorCount: 32,
+    paymentCount: 32,
+    unitPrice: 32,
+    conversionRate: '65%'
+};
+
+const funnelData3 = {
+    visitorCount: 32,
+    paymentCount: 32,
+    unitPrice: 32,
+    conversionRate: '65%'
+};
+
+</script>
+
+<style scoped lang="scss">
+.filter-container {
+    display: flex;
+    align-items: center;
+    margin-bottom: 20px;
+
+    .date-ranges {
+        margin-right: 15px;
+
+        .el-button {
+            margin-right: 5px;
+            margin-left: 0;
+        }
+    }
+
+    .date-picker-wrapper {
+        margin-right: 15px;
+    }
+}
+</style>

+ 140 - 0
src/views/statsAnalysis/search/components/SearchEffectModal.vue

@@ -0,0 +1,140 @@
+<template>
+  <el-dialog
+    v-model="visible"
+    :title="title"
+    width="800px"
+    @close="handleClose"
+  >
+    <div class="modal-content">
+      <!-- Product Effect Section -->
+      <div class="section">
+        <div class="table-wrapper">
+           <el-table :data="productData" border size="small">
+             <el-table-column label="引导商品效果" min-width="200">
+                <template #default="{ row }">
+                  <div class="product-info">
+                    <img :src="row.image" class="product-img" />
+                    <div class="product-details">
+                      <div class="name">{{ row.name }}</div>
+                      <div class="meta">ISBN: {{ row.isbn }}</div>
+                      <div class="meta">价格: {{ row.price }} 库存: {{ row.stock }}</div>
+                    </div>
+                  </div>
+                </template>
+             </el-table-column>
+             <el-table-column prop="visitors" label="带来的访客数" sortable width="120" />
+             <el-table-column prop="views" label="带来的浏览量" sortable width="120" />
+             <el-table-column prop="buyers" label="引导下单买家数" sortable width="140" />
+             <el-table-column prop="conversion" label="引导下单转化率" sortable width="140" />
+           </el-table>
+           
+           <div class="pagination">
+             <el-pagination 
+               layout="total, prev, pager, next, jumper" 
+               :total="100" 
+               small
+             />
+           </div>
+        </div>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, computed, watch } from 'vue';
+import { Goods } from '@element-plus/icons-vue';
+
+const props = defineProps({
+  modelValue: Boolean,
+  rowData: Object
+});
+
+const emit = defineEmits(['update:modelValue']);
+
+const visible = ref(false);
+
+watch(() => props.modelValue, (val) => {
+  visible.value = val;
+});
+
+const handleClose = () => {
+  emit('update:modelValue', false);
+};
+
+const title = computed(() => {
+  return props.rowData ? `搜索词详情: ${props.rowData.term} - 商品效果` : '商品效果详情';
+});
+
+// Mock Product Data
+const productData = ref([
+  { 
+    image: 'https://via.placeholder.com/60', 
+    name: '马克思主义基本原理', 
+    isbn: '9787123654587', 
+    price: '22.12', 
+    stock: 5,
+    visitors: 23,
+    views: 33,
+    buyers: 2,
+    conversion: '8.7%'
+  },
+  { 
+    image: 'https://via.placeholder.com/60', 
+    name: '马克思主义基本原理', 
+    isbn: '9787123654587', 
+    price: '22.12', 
+    stock: 5,
+    visitors: 23,
+    views: 33,
+    buyers: 2,
+    conversion: '8.7%'
+  },
+  { 
+    image: 'https://via.placeholder.com/60', 
+    name: '马克思主义基本原理', 
+    isbn: '9787123654587', 
+    price: '22.12', 
+    stock: 5,
+    visitors: 23,
+    views: 33,
+    buyers: 2,
+    conversion: '8.7%'
+  }
+]);
+</script>
+
+<style scoped lang="scss">
+.product-info {
+  display: flex;
+  align-items: center;
+  
+  .product-img {
+    width: 60px;
+    height: 60px;
+    object-fit: cover;
+    margin-right: 10px;
+    border-radius: 4px;
+  }
+  
+  .product-details {
+    .name {
+      font-weight: bold;
+      color: #333; // Usually green in example but let's stick to standard
+      &.green { color: #4caf50; } // If needed
+      font-size: 14px;
+      margin-bottom: 5px;
+    }
+    .meta {
+      font-size: 12px;
+      color: #999;
+    }
+  }
+}
+
+.pagination {
+  margin-top: 15px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 142 - 0
src/views/statsAnalysis/search/components/SearchOverview.vue

@@ -0,0 +1,142 @@
+<template>
+  <div class="search-overview">
+    <div class="header">
+      <div class="title">搜索的使用次数</div>
+      <div class="subtitle">2024-06-01至2024-06-25</div>
+    </div>
+    
+    <div class="content">
+      <!-- Stats -->
+      <div class="stats-section">
+        <div class="stat-item">
+          <div class="label">今日</div>
+          <div class="value">369次</div>
+          <div class="compare down">对比昨日 59% ↓</div>
+        </div>
+        <div class="stat-item">
+          <div class="label">合计</div>
+          <div class="value">36009次</div>
+        </div>
+        <div class="stat-item">
+          <div class="label">人均搜索次数</div>
+          <div class="value">3600次</div>
+        </div>
+      </div>
+
+      <!-- Chart -->
+      <div class="chart-section">
+        <base-chart :option="chartOption" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { computed } from 'vue';
+import BaseChart from '@/components/Chart/BaseChart.vue';
+
+const chartOption = computed(() => ({
+  tooltip: {
+    trigger: 'axis'
+  },
+  grid: {
+    top: '10%',
+    bottom: '10%',
+    left: '3%',
+    right: '4%',
+    containLabel: true
+  },
+  xAxis: {
+    type: 'category',
+    data: ['1日', '2日', '3日', '4日', '5日'],
+    axisTick: { alignWithLabel: true }
+  },
+  yAxis: {
+    type: 'value',
+    splitLine: { lineStyle: { type: 'dashed' } }
+  },
+  series: [
+    {
+      name: '搜索总次数',
+      type: 'line',
+      smooth: true,
+      data: [100, 140, 230, 100, 130],
+      itemStyle: { color: '#5b8ff9' },
+      areaStyle: {
+        color: {
+          type: 'linear',
+          x: 0, y: 0, x2: 0, y2: 1,
+          colorStops: [
+            { offset: 0, color: 'rgba(91, 143, 249, 0.2)' },
+            { offset: 1, color: 'rgba(91, 143, 249, 0)' }
+          ]
+        }
+      }
+    }
+  ]
+}));
+</script>
+
+<style scoped lang="scss">
+.search-overview {
+  background-color: #f5f5f5;
+  padding: 20px;
+  border-radius: 8px;
+  margin-bottom: 20px;
+}
+
+.header {
+  margin-bottom: 20px;
+  .title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #333;
+  }
+  .subtitle {
+    font-size: 12px;
+    color: #999;
+    margin-top: 5px;
+  }
+}
+
+.content {
+  display: flex;
+  align-items: center;
+
+  .stats-section {
+    flex: 0 0 40%;
+    display: flex;
+    justify-content: space-around;
+
+    .stat-item {
+      text-align: center;
+      
+      .label {
+        font-size: 14px;
+        color: #666;
+        margin-bottom: 10px;
+      }
+      
+      .value {
+        font-size: 24px;
+        font-weight: bold;
+        color: #333;
+        margin-bottom: 5px;
+      }
+      
+      .compare {
+        font-size: 12px;
+        &.down {
+          color: #52c41a; // Green for down usually means good? Or red? In finance Green is down (CN) or Up (US). 
+                          // Design shows green arrow down. Let's use green.
+        }
+      }
+    }
+  }
+
+  .chart-section {
+    flex: 1;
+    height: 200px;
+  }
+}
+</style>

+ 35 - 0
src/views/statsAnalysis/search/components/SearchTable.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="search-table">
+    <el-table :data="tableData" style="width: 100%" border>
+      <el-table-column prop="term" label="搜索词" />
+      <el-table-column prop="searchCount" label="搜索次数" sortable />
+      <el-table-column prop="cartCount" label="加购人数" sortable />
+      <el-table-column prop="favCount" label="商品收藏人数" sortable />
+      <el-table-column prop="payCount" label="支付买家数" sortable />
+      <el-table-column prop="conversionRate" label="支付转化率" sortable />
+      <el-table-column label="操作" width="200">
+        <template #default="scope">
+          <el-button link type="primary" @click="$emit('view-trend', scope.row)">[趋势]</el-button>
+          <el-button link type="warning" @click="$emit('view-effect', scope.row)">[商品效果]</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup>
+defineProps({
+  tableData: {
+    type: Array,
+    default: () => []
+  }
+});
+
+defineEmits(['view-trend', 'view-effect']);
+</script>
+
+<style scoped>
+.search-table {
+  margin-top: 20px;
+}
+</style>

+ 70 - 0
src/views/statsAnalysis/search/components/SearchTrendModal.vue

@@ -0,0 +1,70 @@
+<template>
+    <el-dialog v-model="visible" :title="title" width="800px" @close="handleClose">
+        <div class="modal-content">
+            <!-- Trend Section -->
+            <div class="section">
+                <div class="chart-wrapper">
+                    <base-chart :option="trendOption" />
+                </div>
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+<script setup>
+import { ref, computed, watch } from 'vue';
+import { DataLine } from '@element-plus/icons-vue';
+import BaseChart from '@/components/Chart/BaseChart.vue';
+
+const props = defineProps({
+    modelValue: Boolean,
+    rowData: Object
+});
+
+const emit = defineEmits(['update:modelValue']);
+
+const visible = ref(false);
+
+watch(() => props.modelValue, (val) => {
+    visible.value = val;
+});
+
+const handleClose = () => {
+    emit('update:modelValue', false);
+};
+
+const title = computed(() => {
+    return props.rowData ? `搜索词详情: ${props.rowData.term} - 趋势` : '趋势详情';
+});
+
+// Mock Trend Data
+const trendOption = computed(() => ({
+    tooltip: { trigger: 'axis' },
+    legend: { top: 0 },
+    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
+    xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: ['09-07', '09-08', '09-10', '09-11', '09-12', '09-13', '09-14']
+    },
+    yAxis: { type: 'value' },
+    series: [
+        { name: '搜索次数', type: 'line', smooth: true, data: [100, 120, 300, 100, 130, 210, 150], itemStyle: { color: '#5b8ff9' } },
+        { name: '加购人数', type: 'line', smooth: true, data: [150, 100, 200, 140, 100, 160, 110], itemStyle: { color: '#5ebcb9' } },
+        { name: '商品收藏人数', type: 'line', smooth: true, data: [150, 180, 110, 150, 200, 160, 220], itemStyle: { color: '#4caf50' } },
+        { name: '支付买家数', type: 'line', smooth: true, data: [100, 110, 220, 140, 150, 160, 130], itemStyle: { color: '#ffc107' } },
+        { name: '支付转化率', type: 'line', smooth: true, data: [100, 100, 120, 140, 140, 190, 180], itemStyle: { color: '#ff5722' } }
+    ]
+}));
+</script>
+
+<style scoped lang="scss">
+.section {
+    .chart-wrapper {
+        height: 300px;
+        background: #fafafa;
+        padding: 10px;
+        border-radius: 4px;
+    }
+}
+</style>

+ 92 - 0
src/views/statsAnalysis/search/index.vue

@@ -0,0 +1,92 @@
+<template>
+    <ele-page>
+        <ele-card :body-style="{ padding: '20px' }">
+            <!-- Search Filter Bar -->
+            <div class="filter-container">
+                <el-select v-model="searchType" placeholder="搜索词分类" style="width: 120px; margin-right: 15px;">
+                    <el-option label="搜索词分类" value="category" />
+                </el-select>
+
+                <div class="date-ranges">
+                    <el-button-group>
+                        <el-button type="primary">实时</el-button>
+                        <el-button>昨日</el-button>
+                        <el-button>7日</el-button>
+                        <el-button>15日</el-button>
+                        <el-button>30日</el-button>
+                    </el-button-group>
+                </div>
+
+                <div class="date-picker-wrapper">
+                    <el-date-picker v-model="dateRange" type="daterange" range-separator="-" start-placeholder="选择时间"
+                        end-placeholder="选择时间" size="default" />
+                </div>
+
+                <el-button type="primary">搜索</el-button>
+                <el-button>重置</el-button>
+            </div>
+
+            <!-- Overview Stats -->
+            <search-overview />
+
+            <!-- Data Table -->
+            <search-table :table-data="tableData" @view-trend="handleViewTrend" @view-effect="handleViewEffect" />
+
+            <!-- Trend Modal -->
+            <search-trend-modal v-model="trendModalVisible" :row-data="currentRow" />
+            
+            <!-- Effect Modal -->
+            <search-effect-modal v-model="effectModalVisible" :row-data="currentRow" />
+
+        </ele-card>
+    </ele-page>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import SearchOverview from './components/SearchOverview.vue';
+import SearchTable from './components/SearchTable.vue';
+import SearchTrendModal from './components/SearchTrendModal.vue';
+import SearchEffectModal from './components/SearchEffectModal.vue';
+
+const searchType = ref('category');
+const dateRange = ref([]);
+
+const trendModalVisible = ref(false);
+const effectModalVisible = ref(false);
+const currentRow = ref(null);
+
+const tableData = ref([
+    { term: '中医基础理论', searchCount: 23, cartCount: 5, favCount: 0, payCount: 2, conversionRate: '8.70%' },
+    { term: '大学语文', searchCount: 6, cartCount: 3, favCount: 1, payCount: 0, conversionRate: '0.00%' },
+    { term: '马克思主义发展史', searchCount: 6, cartCount: 3, favCount: 0, payCount: 3, conversionRate: '50.00%' },
+    { term: '高等数学', searchCount: 15, cartCount: 8, favCount: 2, payCount: 5, conversionRate: '33.33%' },
+    { term: 'Python编程', searchCount: 12, cartCount: 4, favCount: 3, payCount: 1, conversionRate: '8.33%' }
+]);
+
+const handleViewTrend = (row) => {
+    currentRow.value = row;
+    trendModalVisible.value = true;
+};
+
+const handleViewEffect = (row) => {
+    currentRow.value = row;
+    effectModalVisible.value = true;
+};
+</script>
+
+<style scoped lang="scss">
+.filter-container {
+    display: flex;
+    align-items: center;
+    margin-bottom: 20px;
+
+    .date-ranges {
+        margin-right: 15px;
+    }
+
+    .date-picker-wrapper {
+        margin-right: 15px;
+    }
+}
+</style>

+ 106 - 0
src/views/statsAnalysis/sellData/components/DistributionCharts.vue

@@ -0,0 +1,106 @@
+<template>
+  <div class="distribution-charts">
+    <div class="chart-box">
+      <div class="chart-title">支付方式占比</div>
+      <div class="chart-content">
+        <base-chart :option="paymentOption" />
+      </div>
+    </div>
+    <div class="chart-box">
+      <div class="chart-title">订单状态占比</div>
+      <div class="chart-content">
+        <base-chart :option="statusOption" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { computed } from 'vue';
+import BaseChart from '@/components/Chart/BaseChart.vue';
+
+const props = defineProps({
+  paymentData: {
+    type: Array,
+    default: () => []
+  },
+  statusData: {
+    type: Array,
+    default: () => []
+  }
+});
+
+const paymentOption = computed(() => ({
+  tooltip: {
+    trigger: 'item'
+  },
+  legend: {
+    top: '5%',
+    left: 'center'
+  },
+  series: [
+    {
+      name: '支付方式',
+      type: 'pie',
+      radius: '50%',
+      data: props.paymentData,
+      emphasis: {
+        itemStyle: {
+          shadowBlur: 10,
+          shadowOffsetX: 0,
+          shadowColor: 'rgba(0, 0, 0, 0.5)'
+        }
+      }
+    }
+  ]
+}));
+
+const statusOption = computed(() => ({
+  tooltip: {
+    trigger: 'item'
+  },
+  legend: {
+    top: '5%',
+    left: 'center'
+  },
+  series: [
+    {
+      name: '订单状态',
+      type: 'pie',
+      radius: '50%',
+      data: props.statusData,
+      emphasis: {
+        itemStyle: {
+          shadowBlur: 10,
+          shadowOffsetX: 0,
+          shadowColor: 'rgba(0, 0, 0, 0.5)'
+        }
+      }
+    }
+  ]
+}));
+</script>
+
+<style scoped lang="scss">
+.distribution-charts {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+
+  .chart-box {
+    flex: 1;
+    background: #fff; // Or transparent if card handles bg
+    
+    .chart-title {
+      font-size: 16px;
+      font-weight: bold;
+      margin-bottom: 15px;
+      color: #333;
+    }
+
+    .chart-content {
+      height: 300px;
+    }
+  }
+}
+</style>

+ 110 - 0
src/views/statsAnalysis/sellData/components/OrderTrendChart.vue

@@ -0,0 +1,110 @@
+<template>
+  <div class="order-trend-chart">
+    <div class="chart-header">
+      <div class="title">订单数量</div>
+      <div class="legend">
+        <!-- Custom Legend if needed, or rely on ECharts legend -->
+      </div>
+    </div>
+    <div class="chart-container">
+      <base-chart :option="chartOption" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { computed } from 'vue';
+import BaseChart from '@/components/Chart/BaseChart.vue';
+
+const props = defineProps({
+  chartData: {
+    type: Object,
+    default: () => ({
+      dates: [],
+      orderCount: [],
+      paymentAmount: [],
+      conversionRate: [],
+      refundAmount: []
+    })
+  }
+});
+
+const chartOption = computed(() => ({
+  tooltip: {
+    trigger: 'axis'
+  },
+  legend: {
+    data: ['订单数', '支付金额', '转化率', '退款金额'],
+    top: 0
+  },
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '3%',
+    containLabel: true
+  },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    data: props.chartData.dates
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      name: '订单数',
+      type: 'line',
+      smooth: true,
+      data: props.chartData.orderCount,
+      itemStyle: { color: '#5b8ff9' }
+    },
+    {
+      name: '支付金额',
+      type: 'line',
+      smooth: true,
+      data: props.chartData.paymentAmount,
+      itemStyle: { color: '#5ebcb9' }
+    },
+    {
+      name: '转化率',
+      type: 'line',
+      smooth: true,
+      data: props.chartData.conversionRate,
+      itemStyle: { color: '#4caf50' }
+    },
+    {
+      name: '退款金额',
+      type: 'line',
+      smooth: true,
+      data: props.chartData.refundAmount,
+      itemStyle: { color: '#ff9800' }
+    }
+  ]
+}));
+</script>
+
+<style scoped lang="scss">
+.order-trend-chart {
+  background: #fff;
+  padding: 20px 0;
+  margin-bottom: 20px;
+
+  .chart-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+
+    .title {
+      font-size: 16px;
+      font-weight: bold;
+      color: #333;
+    }
+  }
+
+  .chart-container {
+    height: 350px;
+  }
+}
+</style>

+ 157 - 0
src/views/statsAnalysis/sellData/components/RefundStats.vue

@@ -0,0 +1,157 @@
+<template>
+  <div class="refund-stats">
+    <div class="header">
+      <div class="title">已完结退款</div>
+      <div class="filters">
+        <span class="range-text">统计时间: {{ dateRangeText }}</span>
+        <div class="actions">
+           <!-- Filters can be passed via slots or handled in parent, 
+                but UI shows them here. Let's make them visual only for now or simple props -->
+           <el-button-group size="small">
+             <el-button>昨日</el-button>
+             <el-button type="primary">7日</el-button>
+             <el-button>30日</el-button>
+           </el-button-group>
+           <el-date-picker size="small" type="daterange" style="width: 200px; margin: 0 10px;" />
+           <el-button type="primary" size="small">搜索</el-button>
+           <el-button size="small">重置</el-button>
+        </div>
+      </div>
+    </div>
+
+    <div class="cards-container">
+      <div v-for="(card, index) in refundData" :key="index" class="refund-card">
+        <div class="card-header">
+          <div class="indicator"></div>
+          <span class="card-title">{{ card.title }}</span>
+        </div>
+        
+        <div class="card-content">
+          <div class="row">
+            <span class="label">退款人数</span>
+            <span class="value">{{ card.refundUsers }}</span>
+          </div>
+          <div class="row">
+            <span class="label">退款子订单数</span>
+            <span class="value">{{ card.subOrders }}</span>
+          </div>
+          <div class="row">
+            <span class="label">订单退款率</span>
+            <span class="value">{{ card.refundRate }}</span>
+          </div>
+          
+          <div class="divider"></div>
+
+          <div class="row">
+            <span class="label">退款金额</span>
+            <span class="value">{{ card.refundAmount }}</span>
+          </div>
+          <div class="row">
+            <span class="label">金额退款率</span>
+            <span class="value">{{ card.amountRate }}</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineProps({
+  dateRangeText: {
+    type: String,
+    default: '2025-09-15 ~ 2025-10-14'
+  },
+  refundData: {
+    type: Array,
+    default: () => []
+  }
+});
+</script>
+
+<style scoped lang="scss">
+.refund-stats {
+  margin-top: 30px;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+
+  .title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #333;
+  }
+
+  .filters {
+    display: flex;
+    align-items: center;
+
+    .range-text {
+      font-size: 12px;
+      color: #999;
+      margin-right: 20px;
+    }
+  }
+}
+
+.cards-container {
+  display: flex;
+  gap: 15px;
+  overflow-x: auto;
+}
+
+.refund-card {
+  flex: 0 0 240px;
+  background: #fff;
+  border: 1px solid #e6ebf5;
+  border-radius: 8px;
+  padding: 15px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+
+  .card-header {
+    display: flex;
+    align-items: center;
+    margin-bottom: 15px;
+    
+    .indicator {
+      width: 4px;
+      height: 14px;
+      background-color: #409eff;
+      margin-right: 8px;
+      border-radius: 2px;
+    }
+    
+    .card-title {
+      font-weight: bold;
+      color: #333;
+    }
+  }
+
+  .card-content {
+    .row {
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 10px;
+      font-size: 13px;
+      
+      .label {
+        color: #666;
+      }
+      .value {
+        color: #333;
+        font-weight: 500;
+      }
+    }
+
+    .divider {
+      height: 1px;
+      background-color: #eee;
+      margin: 15px 0;
+    }
+  }
+}
+</style>

+ 111 - 0
src/views/statsAnalysis/sellData/components/SalesStatCards.vue

@@ -0,0 +1,111 @@
+<template>
+  <div class="sales-stat-cards">
+    <!-- Top Status Cards -->
+    <div class="status-cards">
+      <div v-for="(item, index) in statusData" :key="index" class="status-card">
+        <div class="status-value">{{ item.value }}</div>
+        <div class="status-label">{{ item.label }}</div>
+      </div>
+    </div>
+
+    <!-- Main Sales Stats Grid -->
+    <div class="stats-grid">
+      <div v-for="(item, index) in salesData" :key="index" class="stat-card">
+        <div class="stat-header">{{ item.label }}</div>
+        <div class="stat-value">{{ item.value }}</div>
+        <div class="stat-compare">
+          昨日 {{ item.yesterdayValue }}
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineProps({
+  statusData: {
+    type: Array,
+    default: () => []
+  },
+  salesData: {
+    type: Array,
+    default: () => []
+  }
+});
+</script>
+
+<style scoped lang="scss">
+.sales-stat-cards {
+  margin-bottom: 20px;
+}
+
+.status-cards {
+  display: flex;
+  justify-content: space-between;
+  background-color: #f5f5f5;
+  padding: 20px;
+  border-radius: 8px;
+  margin-bottom: 20px;
+
+  .status-card {
+    text-align: center;
+    flex: 1;
+    position: relative;
+
+    &:not(:last-child)::after {
+      content: '';
+      position: absolute;
+      right: 0;
+      top: 10%;
+      height: 80%;
+      width: 1px;
+      background-color: #e0e0e0;
+    }
+
+    .status-value {
+      font-size: 24px;
+      font-weight: bold;
+      color: #333;
+      margin-bottom: 5px;
+    }
+
+    .status-label {
+      font-size: 14px;
+      color: #666;
+    }
+  }
+}
+
+.stats-grid {
+  display: grid;
+  grid-template-columns: repeat(5, 1fr);
+  gap: 15px;
+
+  .stat-card {
+    background-color: #f5f5f5;
+    padding: 20px;
+    border-radius: 8px;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+
+    .stat-header {
+      font-size: 14px;
+      color: #666;
+      margin-bottom: 10px;
+    }
+
+    .stat-value {
+      font-size: 24px;
+      font-weight: bold;
+      color: #333;
+      margin-bottom: 5px;
+    }
+
+    .stat-compare {
+      font-size: 12px;
+      color: #999;
+    }
+  }
+}
+</style>

+ 120 - 0
src/views/statsAnalysis/sellData/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <ele-page>
+    <ele-card :body-style="{ padding: '20px' }">
+      <!-- Filters -->
+      <div class="filter-container">
+        <div class="date-ranges">
+          <el-button-group>
+            <el-button type="primary">实时</el-button>
+            <el-button>昨日</el-button>
+            <el-button>7日</el-button>
+            <el-button>15日</el-button>
+            <el-button>30日</el-button>
+          </el-button-group>
+        </div>
+        <div class="date-picker-wrapper">
+          <el-date-picker v-model="dateRange" type="daterange" range-separator="到" start-placeholder="开始时间"
+            end-placeholder="结束时间" size="default" />
+        </div>
+        <el-button type="primary" class="search-btn">搜索</el-button>
+        <el-button>重置</el-button>
+      </div>
+
+      <!-- Stats Cards -->
+      <sales-stat-cards :status-data="statusData" :sales-data="salesData" />
+
+      <!-- Order Trend Chart -->
+      <order-trend-chart :chart-data="trendChartData" />
+
+      <!-- Distribution Charts -->
+      <distribution-charts :payment-data="paymentMethodData" :status-data="orderStatusData" />
+
+      <!-- Refund Stats -->
+      <refund-stats :refund-data="refundData" />
+
+    </ele-card>
+  </ele-page>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import SalesStatCards from './components/SalesStatCards.vue';
+import OrderTrendChart from './components/OrderTrendChart.vue';
+import DistributionCharts from './components/DistributionCharts.vue';
+import RefundStats from './components/RefundStats.vue';
+
+const dateRange = ref([]);
+
+// Mock Data
+const statusData = [
+  { label: '待付款', value: 11 },
+  { label: '待发货', value: 11 },
+  { label: '待售后', value: 11 },
+  { label: '待处理投诉', value: 11 }
+];
+
+const salesData = [
+  { label: '支付金额', value: '55366', yesterdayValue: '53669' },
+  { label: '访客数', value: '55366', yesterdayValue: '53669' },
+  { label: '支付订单数', value: '55366', yesterdayValue: '53669' },
+  { label: '支付转化率', value: '55366', yesterdayValue: '53669' },
+  { label: '商品浏览量', value: '55366', yesterdayValue: '53669' },
+  { label: '客单价', value: '55366', yesterdayValue: '53669' },
+  { label: '支付买家数', value: '55366', yesterdayValue: '53669' },
+  { label: '加购商品数', value: '55366', yesterdayValue: '53669' },
+  { label: '收藏商品数', value: '55366', yesterdayValue: '53669' },
+  { label: '在途订单数', value: '55366', yesterdayValue: '53669' },
+  { label: '在途金额', value: '55366', yesterdayValue: '53669' },
+  { label: '老客复购率', value: '55366', yesterdayValue: '53669' },
+  { label: '老客复购金额', value: '55366', yesterdayValue: '53669' },
+  { label: '老客复购人数', value: '55366', yesterdayValue: '53669' },
+  { label: '净支付金额', value: '55366', yesterdayValue: '53669' }
+];
+
+const trendChartData = reactive({
+  dates: ['15日', '16日', '17日', '18日', '19日', '20日', '21日', '22日', '23日', '24日', '25日', '26日', '27日'],
+  orderCount: [100, 120, 200, 100, 130, 150, 180, 220, 150, 170, 110, 160, 210],
+  paymentAmount: [150, 100, 230, 110, 100, 170, 210, 110, 108, 150, 190, 180, 170],
+  conversionRate: [150, 130, 180, 150, 210, 210, 210, 220, 180, 130, 160, 180, 170],
+  refundAmount: [160, 220, 230, 160, 210, 150, 160, 150, 170, 200, 170, 220, 100]
+});
+
+const paymentMethodData = [
+  { value: 100, name: '微信支付', itemStyle: { color: '#5b8ff9' } },
+  { value: 150, name: '支付宝支付', itemStyle: { color: '#5ebcb9' } },
+  { value: 224, name: '余额支付', itemStyle: { color: '#4caf50' } }
+];
+
+const orderStatusData = [
+  { value: 122, name: '待发货', itemStyle: { color: '#ff9800' } },
+  { value: 150, name: '已退款', itemStyle: { color: '#5ebcb9' } },
+  { value: 170, name: '待收货', itemStyle: { color: '#4caf50' } },
+  { value: 174, name: '已取消', itemStyle: { color: '#f44336' } },
+  { value: 175, name: '已完成', itemStyle: { color: '#e91e63' } },
+  { value: 100, name: '已发货', itemStyle: { color: '#5b8ff9' } }
+];
+
+const refundData = [
+  { title: '全部', refundUsers: 2720, subOrders: 3089, refundRate: '10.63%', refundAmount: 36738.53, amountRate: '11.03%' },
+  { title: '退货退款', refundUsers: 339, subOrders: 354, refundRate: '1.22%', refundAmount: 36738.53, amountRate: '11.03%' },
+  { title: '已收货退款', refundUsers: 28, subOrders: 3089, refundRate: '10.63%', refundAmount: 36738.53, amountRate: '11.03%' },
+  { title: '未收货退款', refundUsers: 2720, subOrders: 3089, refundRate: '10.63%', refundAmount: 36738.53, amountRate: '11.03%' },
+  { title: '未发货退款', refundUsers: 2720, subOrders: 3089, refundRate: '10.63%', refundAmount: 36738.53, amountRate: '11.03%' }
+];
+</script>
+
+<style scoped lang="scss">
+.filter-container {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20px;
+
+  .date-ranges {
+    margin-right: 15px;
+  }
+
+  .date-picker-wrapper {
+    margin-right: 15px;
+  }
+}
+</style>