You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
3.9 KiB
207 lines
3.9 KiB
<template>
|
|
<BaseCard title="销售渠道统计">
|
|
<div class="stats-container">
|
|
<div class="stats-row">
|
|
<div class="stat-item">
|
|
<div class="stat-value">1,234</div>
|
|
<div class="stat-label">线上销售</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value">856</div>
|
|
<div class="stat-label">线下销售</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value">2,090</div>
|
|
<div class="stat-label">总销售额</div>
|
|
</div>
|
|
</div>
|
|
<div class="chart-container">
|
|
<div ref="chartRef" class="chart"></div>
|
|
</div>
|
|
</div>
|
|
</BaseCard>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|
import * as echarts from 'echarts'
|
|
import BaseCard from './BaseCard.vue'
|
|
|
|
const chartRef = ref(null)
|
|
let chartInstance = null
|
|
|
|
// 图例数据
|
|
const legendData = [
|
|
{ name: '直销', color: '#409EFF', percent: 50 },
|
|
{ name: '代销', color: '#67C23A', percent: 30 },
|
|
{ name: '其他', color: '#E6A23C', percent: 20 }
|
|
]
|
|
|
|
// 模拟数据
|
|
const data = [
|
|
{ name: '直销', value: 50 },
|
|
{ name: '代销', value: 30 },
|
|
{ name: '其他', value: 20 }
|
|
]
|
|
|
|
const initChart = () => {
|
|
if (!chartRef.value) return
|
|
|
|
chartInstance = echarts.init(chartRef.value)
|
|
|
|
const option = {
|
|
tooltip: {
|
|
trigger: 'item',
|
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
borderColor: '#409EFF',
|
|
textStyle: {
|
|
color: '#fff',
|
|
fontSize: 12
|
|
},
|
|
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
|
},
|
|
series: [{
|
|
name: '销售渠道',
|
|
type: 'pie',
|
|
radius: ['40%', '65%'],
|
|
center: ['50%', '50%'],
|
|
data: data.map((item, index) => ({
|
|
...item,
|
|
itemStyle: {
|
|
color: legendData[index].color,
|
|
borderRadius: 8,
|
|
borderColor: '#1a1f2e',
|
|
borderWidth: 2
|
|
}
|
|
})),
|
|
emphasis: {
|
|
itemStyle: {
|
|
shadowBlur: 10,
|
|
shadowOffsetX: 0,
|
|
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
}
|
|
},
|
|
labelLine: {
|
|
show: false
|
|
},
|
|
label: {
|
|
show: false
|
|
}
|
|
}]
|
|
}
|
|
|
|
chartInstance.setOption(option)
|
|
|
|
// 自动高亮效果
|
|
let currentIndex = 0
|
|
const timer = setInterval(() => {
|
|
chartInstance.dispatchAction({
|
|
type: 'downplay',
|
|
seriesIndex: 0,
|
|
dataIndex: currentIndex
|
|
})
|
|
currentIndex = (currentIndex + 1) % data.length
|
|
chartInstance.dispatchAction({
|
|
type: 'highlight',
|
|
seriesIndex: 0,
|
|
dataIndex: currentIndex
|
|
})
|
|
}, 2000)
|
|
|
|
chartInstance._autoTimer = timer
|
|
}
|
|
|
|
onMounted(() => {
|
|
initChart()
|
|
window.addEventListener('resize', () => {
|
|
chartInstance?.resize()
|
|
})
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
if (chartInstance) {
|
|
if (chartInstance._autoTimer) {
|
|
clearInterval(chartInstance._autoTimer)
|
|
}
|
|
chartInstance.dispose()
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.channel-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
}
|
|
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 8px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.stat-item {
|
|
text-align: center;
|
|
background: rgba(255, 255, 255, 0.02);
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
border-radius: 4px;
|
|
padding: 8px;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 11px;
|
|
color: #a0a8b8;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 13px;
|
|
font-weight: bold;
|
|
color: #409EFF;
|
|
}
|
|
|
|
.chart-section {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
}
|
|
|
|
.chart {
|
|
flex: 1;
|
|
height: 150px;
|
|
}
|
|
|
|
.chart-legend {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
min-width: 80px;
|
|
}
|
|
|
|
.legend-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.legend-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.legend-text {
|
|
color: #a0a8b8;
|
|
flex: 1;
|
|
}
|
|
|
|
.legend-percent {
|
|
color: #409EFF;
|
|
font-weight: bold;
|
|
}
|
|
</style> |