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.

182 lines
3.6 KiB

<template>
<div class="revenue-chart">
<div class="chart-header">
<h3>收入趋势</h3>
<div class="chart-tabs">
<el-button
size="small"
:class="{ active: activeTab === 'month' }"
@click="switchTab('month')"
>
月度
</el-button>
<el-button
size="small"
:class="{ active: activeTab === 'quarter' }"
@click="switchTab('quarter')"
>
季度
</el-button>
<el-button
size="small"
:class="{ active: activeTab === 'year' }"
@click="switchTab('year')"
>
年度
</el-button>
</div>
</div>
<v-chart class="chart" :option="chartOption" autoresize />
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
} from 'echarts/components'
import VChart from 'vue-echarts'
import RPC from '@/utils/rpc'
use([CanvasRenderer, LineChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent])
const activeTab = ref('month')
const switchTab = (tab) => {
activeTab.value = tab
console.log(activeTab.value)
getData()
}
const data = ref([])
const getData = () => {
RPC.post('/dashboard/revenue_trend', { granularity: activeTab.value }).then((res) => {
console.log(activeTab.value, res)
data.value = res.items || []
})
}
getData()
const chartOption = computed(() => {
return {
tooltip: {
trigger: 'axis',
formatter: '{b}: ¥{c}',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: data.value.map((item) => item.label),
axisLine: {
lineStyle: {
color: '#e4e7ed',
},
},
axisLabel: {
color: '#606266',
},
},
yAxis: {
type: 'value',
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: '#606266',
formatter: '{value}',
},
splitLine: {
lineStyle: {
color: '#f5f7fa',
},
},
},
series: [
{
type: 'line',
data: data.value.map((item) => item.value_cents / 100),
smooth: true,
lineStyle: {
color: '#409eff',
width: 3,
},
itemStyle: {
color: '#409eff',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(64, 158, 255, 0.3)',
},
{
offset: 1,
color: 'rgba(64, 158, 255, 0.1)',
},
],
},
},
},
],
}
})
</script>
<style lang="scss" scoped>
.revenue-chart {
padding: 20px;
.chart-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h3 {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #303133;
}
.chart-tabs {
.el-button {
margin-left: 8px;
&.active {
background-color: #157ee8;
border-color: #177de3;
color: white;
}
}
}
}
.chart {
height: 300px;
width: 100%;
}
}
</style>