electripper-v2-ui/src/views/bst/index/components/DailySettleAmountStat.vue

375 lines
9.4 KiB
Vue
Raw Normal View History

2025-05-14 09:32:06 +08:00
<template>
<div v-loading="loading">
<el-date-picker
v-model="queryParams.dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="getList"
size="mini"
:clearable="false"
:picker-options="DatePickerOptions.DEFAULT"
/>
<div ref="chart" :style="{width: width, height: height}"></div>
</div>
</template>
<script>
import { getDailySettleAmount } from '@/api/dashboard/dashboard';
import { getLastDateStr } from '@/utils';
import { DatePickerOptions } from '@/utils/constants';
import * as echarts from 'echarts';
export default {
name: 'DailySettleAmountStat',
props: {
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
query: {
type: Object,
default: () => ({})
}
},
data() {
return {
DatePickerOptions,
loading: false,
chartData: [],
queryParams: {
dateRange: [
getLastDateStr(7),
getLastDateStr(0)
]
},
chart: null
}
},
created() {
this.getList();
},
mounted() {
this.initChart();
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose();
this.chart = null;
}
},
methods: {
getList() {
this.loading = true;
Object.assign(this.queryParams, this.query);
getDailySettleAmount(this.queryParams).then(res => {
this.chartData = res.data;
this.updateChart();
}).finally(() => {
this.loading = false;
})
},
initChart() {
this.chart = echarts.init(this.$refs.chart);
this.updateChart();
},
resizeChart() {
if (this.chart) {
this.chart.resize();
}
},
updateChart() {
if (!this.chart || !this.chartData.length) {
return;
}
const dates = this.chartData.map(item => item.date);
const orderSettleAmounts = this.chartData.map(item => item.orderSettleAmount || 0);
const refundAmounts = this.chartData.map(item => item.refundAmount || 0);
const bonusSettleAmounts = this.chartData.map(item => item.bonusSettleAmount || 0);
const bonusRefundAmounts = this.chartData.map(item => item.bonusRefundAmount || 0);
const orderNetAmounts = this.chartData.map((item) =>
(item.orderSettleAmount || 0) - (item.refundAmount || 0)
);
const bonusNetAmounts = this.chartData.map((item) =>
(item.bonusSettleAmount || 0) - (item.bonusRefundAmount || 0)
);
const option = {
color: [
'#67C23A', // 支付金额
'#F56C6C', // 退款金额
'#E6A23C', // 订单实收
'#909399', // 分成结算金额
'#F56C6C', // 分成退款金额
'#67C23A' // 分成实收
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
backgroundColor: 'rgba(255, 255, 255, 0.9)',
borderColor: '#ccc',
borderWidth: 1,
textStyle: {
color: '#333'
},
formatter: function(params) {
let result = params[0].axisValueLabel + '<br/>';
params.forEach(param => {
const value = param.value;
const marker = param.marker;
const seriesName = param.seriesName;
result += marker + seriesName + '<span style="float: right; margin-left: 20px;">' + value.toFixed(2) + ' 元</span><br/>';
});
return result;
}
},
legend: {
data: ['支付金额', '退款金额', '订单实收', '分成结算金额', '分成退款金额', '分成实收'],
bottom: 0,
left: 'center',
textStyle: {
color: '#666'
},
selected: {
'支付金额': false,
'退款金额': false,
'订单实收': true,
'分成结算金额': false,
'分成退款金额': false,
'分成实收': true
}
},
grid: {
left: '3%',
right: '3%',
bottom: '40px',
top: '15%',
containLabel: true
},
xAxis: {
type: 'category',
data: dates,
axisLabel: {
interval: 'auto',
fontSize: 12,
color: '#666'
},
axisLine: {
lineStyle: {
color: '#ddd'
}
},
boundaryGap: true
},
yAxis: {
type: 'value',
name: '金额',
axisLabel: {
formatter: value => {
return value.toFixed(2) + ' 元'
},
color: '#666'
},
axisLine: {
lineStyle: {
color: '#ddd'
}
},
splitLine: {
lineStyle: {
color: '#eee'
}
}
},
series: [
{
name: '支付金额',
type: 'line',
data: orderSettleAmounts,
smooth: true,
symbol: 'circle',
symbolSize: 4,
areaStyle: {
opacity: 0.2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(103, 194, 58, 0.3)'
}, {
offset: 1,
color: 'rgba(103, 194, 58, 0.1)'
}]
}
},
lineStyle: {
width: 2
}
},
{
name: '退款金额',
type: 'line',
data: refundAmounts,
smooth: true,
symbol: 'circle',
symbolSize: 4,
areaStyle: {
opacity: 0.2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(245, 108, 108, 0.3)'
}, {
offset: 1,
color: 'rgba(245, 108, 108, 0.1)'
}]
}
},
lineStyle: {
width: 2
}
},
{
name: '订单实收',
type: 'line',
data: orderNetAmounts,
smooth: true,
symbol: 'circle',
symbolSize: 4,
areaStyle: {
opacity: 0.2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(230, 162, 60, 0.3)'
}, {
offset: 1,
color: 'rgba(230, 162, 60, 0.1)'
}]
}
},
lineStyle: {
width: 2
}
},
{
name: '分成结算金额',
type: 'line',
data: bonusSettleAmounts,
smooth: true,
symbol: 'circle',
symbolSize: 4,
areaStyle: {
opacity: 0.2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(144, 147, 153, 0.3)'
}, {
offset: 1,
color: 'rgba(144, 147, 153, 0.1)'
}]
}
},
lineStyle: {
width: 2
}
},
{
name: '分成退款金额',
type: 'line',
data: bonusRefundAmounts,
smooth: true,
symbol: 'circle',
symbolSize: 4,
areaStyle: {
opacity: 0.2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(245, 108, 108, 0.3)'
}, {
offset: 1,
color: 'rgba(245, 108, 108, 0.1)'
}]
}
},
lineStyle: {
width: 2
}
},
{
name: '分成实收',
type: 'line',
data: bonusNetAmounts,
smooth: true,
symbol: 'circle',
symbolSize: 4,
areaStyle: {
opacity: 0.2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(103, 194, 58, 0.3)'
}, {
offset: 1,
color: 'rgba(103, 194, 58, 0.1)'
}]
}
},
lineStyle: {
width: 2
}
}
]
};
this.chart.setOption(option);
}
}
}
</script>
<style lang="scss" scoped>
.el-date-picker {
margin-bottom: 20px;
}
</style>