2025-04-06 18:20:25 +08:00
|
|
|
|
<template>
|
2025-04-10 14:07:21 +08:00
|
|
|
|
<div v-loading="loading">
|
2025-04-08 08:48:03 +08:00
|
|
|
|
<el-date-picker
|
|
|
|
|
v-model="queryParams.dateRange"
|
|
|
|
|
type="daterange"
|
|
|
|
|
range-separator="至"
|
|
|
|
|
start-placeholder="开始日期"
|
|
|
|
|
end-placeholder="结束日期"
|
|
|
|
|
value-format="yyyy-MM-dd"
|
|
|
|
|
@change="getDailyAmount"
|
|
|
|
|
size="mini"
|
|
|
|
|
:clearable="false"
|
|
|
|
|
:picker-options="DatePickerOptions.DEFAULT"
|
|
|
|
|
/>
|
|
|
|
|
<div ref="chart" :style="{width: width, height: height}"></div>
|
2025-04-10 14:07:21 +08:00
|
|
|
|
</div>
|
2025-04-06 18:20:25 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-04-08 08:48:03 +08:00
|
|
|
|
import { getDailyAmount } from '@/api/dashboard/dashboard'
|
|
|
|
|
import { getLastDateStr } from '@/utils';
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
import $resize from '@/views/dashboard/mixins/resize';
|
|
|
|
|
import {DatePickerOptions} from '@/utils/constants';
|
2025-04-06 18:20:25 +08:00
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "OrderDailyStat",
|
2025-04-08 08:48:03 +08:00
|
|
|
|
mixins: [$resize],
|
|
|
|
|
props: {
|
|
|
|
|
width: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: '100%'
|
|
|
|
|
},
|
|
|
|
|
height: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: '300px'
|
2025-04-10 14:07:21 +08:00
|
|
|
|
},
|
|
|
|
|
query: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => ({})
|
2025-04-08 08:48:03 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
2025-04-06 18:20:25 +08:00
|
|
|
|
data() {
|
|
|
|
|
return {
|
2025-04-08 08:48:03 +08:00
|
|
|
|
DatePickerOptions,
|
2025-04-06 18:20:25 +08:00
|
|
|
|
loading: false,
|
2025-04-08 08:48:03 +08:00
|
|
|
|
dailyAmount: [],
|
|
|
|
|
queryParams: {
|
|
|
|
|
dateRange: [
|
|
|
|
|
getLastDateStr(7),
|
|
|
|
|
getLastDateStr(0)
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
chart: null
|
2025-04-06 18:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
2025-04-08 08:48:03 +08:00
|
|
|
|
this.getDailyAmount();
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.initChart();
|
|
|
|
|
},
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
if (this.chart) {
|
|
|
|
|
this.chart.dispose();
|
|
|
|
|
this.chart = null;
|
|
|
|
|
}
|
2025-04-06 18:20:25 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2025-04-08 08:48:03 +08:00
|
|
|
|
getDailyAmount() {
|
2025-04-06 18:20:25 +08:00
|
|
|
|
this.loading = true;
|
2025-04-10 14:07:21 +08:00
|
|
|
|
Object.assign(this.queryParams, this.query);
|
2025-04-08 08:48:03 +08:00
|
|
|
|
getDailyAmount(this.queryParams).then(res => {
|
|
|
|
|
this.dailyAmount = res.data;
|
|
|
|
|
this.updateChart();
|
|
|
|
|
}).finally(() => {
|
|
|
|
|
this.loading = false;
|
2025-04-06 18:20:25 +08:00
|
|
|
|
})
|
2025-04-08 08:48:03 +08:00
|
|
|
|
},
|
|
|
|
|
initChart() {
|
|
|
|
|
this.chart = echarts.init(this.$refs.chart);
|
|
|
|
|
this.updateChart();
|
|
|
|
|
},
|
|
|
|
|
resizeChart() {
|
|
|
|
|
if (this.chart) {
|
|
|
|
|
this.chart.resize();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
updateChart() {
|
|
|
|
|
if (!this.chart || !this.dailyAmount.length) return;
|
|
|
|
|
|
|
|
|
|
const dates = this.dailyAmount.map(item => item.date);
|
2025-04-10 14:07:21 +08:00
|
|
|
|
const orderCounts = this.dailyAmount.map(item => item.order?.count || 0)
|
2025-04-08 08:48:03 +08:00
|
|
|
|
const orderAmounts = this.dailyAmount.map(item => item.order?.payAmount || 0);
|
|
|
|
|
const bonusAmounts = this.dailyAmount.map(item => item.bonus?.amount || 0);
|
|
|
|
|
const orderRefunds = this.dailyAmount.map(item => item.orderRefund?.amount || 0);
|
|
|
|
|
const bonusRefunds = this.dailyAmount.map(item => item.bonusRefund?.amount || 0);
|
|
|
|
|
const orderNetAmounts = this.dailyAmount.map((item, index) =>
|
|
|
|
|
(item.order?.payAmount || 0) - (item.orderRefund?.amount || 0)
|
|
|
|
|
);
|
|
|
|
|
const bonusNetAmounts = this.dailyAmount.map((item, index) =>
|
|
|
|
|
(item.bonus?.amount || 0) - (item.bonusRefund?.amount || 0)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
color: [
|
2025-04-10 14:07:21 +08:00
|
|
|
|
'#5B8FF9', // 柔和蓝 - 订单数量
|
|
|
|
|
'#61DDAA', // 柔和绿 - 订单金额
|
|
|
|
|
'#F6BD16', // 柔和黄 - 订单退款
|
|
|
|
|
'#6DC8EC', // 淡青 - 订单实收
|
|
|
|
|
'#9270CA', // 淡紫 - 分成金额
|
|
|
|
|
'#E8684A', // 柔和橙 - 分成退款
|
|
|
|
|
'#FF9D4D' // 柔和橙红 - 分成实收
|
2025-04-08 08:48:03 +08:00
|
|
|
|
],
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'shadow'
|
2025-04-10 14:07:21 +08:00
|
|
|
|
},
|
|
|
|
|
formatter: function(params) {
|
|
|
|
|
let result = params[0].axisValueLabel + '<br/>';
|
|
|
|
|
params.forEach(param => {
|
|
|
|
|
const value = param.value;
|
|
|
|
|
const marker = param.marker;
|
|
|
|
|
const seriesName = param.seriesName;
|
|
|
|
|
if (seriesName === '订单数量') {
|
|
|
|
|
result += marker + seriesName + ':<span style="float: right; margin-left: 20px;">' + value + ' 单</span><br/>';
|
|
|
|
|
} else {
|
|
|
|
|
result += marker + seriesName + ':<span style="float: right; margin-left: 20px;">' + value.toFixed(2) + ' 元</span><br/>';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return result;
|
2025-04-08 08:48:03 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
legend: {
|
|
|
|
|
data: ['订单数量', '订单金额', '订单退款', '订单实收', '分成金额', '分成退款', '分成实收'],
|
2025-04-10 14:07:21 +08:00
|
|
|
|
top: 8,
|
|
|
|
|
selected: {
|
|
|
|
|
'订单数量': true,
|
|
|
|
|
'订单金额': false,
|
|
|
|
|
'订单退款': false,
|
|
|
|
|
'订单实收': true,
|
|
|
|
|
'分成金额': false,
|
|
|
|
|
'分成退款': false,
|
|
|
|
|
'分成实收': true
|
|
|
|
|
}
|
2025-04-08 08:48:03 +08:00
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
left: '3%',
|
2025-04-10 14:07:21 +08:00
|
|
|
|
right: '3%',
|
|
|
|
|
bottom: '2%',
|
2025-04-08 08:48:03 +08:00
|
|
|
|
top: '15%',
|
|
|
|
|
containLabel: true
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: dates,
|
|
|
|
|
axisLabel: {
|
|
|
|
|
interval: 'auto',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
},
|
|
|
|
|
boundaryGap: true
|
|
|
|
|
},
|
|
|
|
|
yAxis: [
|
|
|
|
|
{
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: '金额',
|
|
|
|
|
position: 'left',
|
|
|
|
|
axisLabel: {
|
2025-04-10 14:07:21 +08:00
|
|
|
|
formatter: value => {
|
|
|
|
|
return value.toFixed(2) + ' 元'
|
|
|
|
|
}
|
2025-04-08 08:48:03 +08:00
|
|
|
|
}
|
2025-04-10 14:07:21 +08:00
|
|
|
|
},
|
2025-04-08 08:48:03 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: '订单数量',
|
|
|
|
|
position: 'right',
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value}'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '订单数量',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
yAxisIndex: 1,
|
|
|
|
|
data: orderCounts,
|
|
|
|
|
itemStyle: {
|
|
|
|
|
opacity: 0.6
|
|
|
|
|
},
|
|
|
|
|
barWidth: '20%'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '订单金额',
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
data: orderAmounts,
|
|
|
|
|
smooth: true,
|
|
|
|
|
symbol: 'circle',
|
|
|
|
|
symbolSize: 5,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: 2
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '订单退款',
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
data: orderRefunds,
|
|
|
|
|
smooth: true,
|
|
|
|
|
symbol: 'circle',
|
|
|
|
|
symbolSize: 5,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: 2
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '订单实收',
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
data: orderNetAmounts,
|
|
|
|
|
smooth: true,
|
|
|
|
|
symbol: 'circle',
|
|
|
|
|
symbolSize: 6,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: 2
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '分成金额',
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
data: bonusAmounts,
|
|
|
|
|
smooth: true,
|
|
|
|
|
symbol: 'circle',
|
|
|
|
|
symbolSize: 5,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: 2
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '分成退款',
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
data: bonusRefunds,
|
|
|
|
|
smooth: true,
|
|
|
|
|
symbol: 'circle',
|
|
|
|
|
symbolSize: 5,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: 2
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '分成实收',
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
data: bonusNetAmounts,
|
|
|
|
|
smooth: true,
|
|
|
|
|
symbol: 'circle',
|
|
|
|
|
symbolSize: 6,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: 2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.chart.setOption(option);
|
2025-04-06 18:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2025-04-08 08:48:03 +08:00
|
|
|
|
.el-date-picker {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|