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
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>
|