更新对账

This commit is contained in:
磷叶 2025-01-25 18:04:37 +08:00
parent 77b0f8877a
commit 5cd9a40550
4 changed files with 343 additions and 23 deletions

View File

@ -113,7 +113,7 @@ export default {
show: true,
},
series: [{
name: '订单服务费收入(元)',
name: '订单服务费收入',
type: 'line',
data: this.getChartData(this.billData, 'serviceAmount'),
itemStyle: {
@ -122,7 +122,7 @@ export default {
}
},
},{
name: '提现服务费收入(元)',
name: '提现服务费收入',
type: 'line',
data: this.getChartData(this.billData, 'withdrawServiceAmount'),
itemStyle: {
@ -131,7 +131,7 @@ export default {
}
},
}, {
name: '月费收入(元)',
name: '月费收入',
type: 'line',
data: this.getChartData(this.billData, 'monthAmount'),
itemStyle: {
@ -140,7 +140,7 @@ export default {
}
},
}, {
name: '订单手机号收入(元)',
name: '手机号收入',
type: 'line',
data: this.getChartData(this.billData, 'billMobileAmount'),
itemStyle: {
@ -149,7 +149,7 @@ export default {
}
},
}, {
name: '渠道成本(元)',
name: '渠道成本',
type: 'line',
data: this.getChartData(this.billData, 'channelCost'),
itemStyle: {
@ -157,6 +157,15 @@ export default {
color: '#ffb731',
}
},
}, {
name: '平台收益',
type: 'line',
data: this.billData.map(item => item.serviceAmount + item.monthAmount + item.billMobileAmount + item.withdrawServiceAmount - item.channelCost),
itemStyle: {
normal: {
color: '#ed4b4b',
}
},
},
]
})

View File

@ -53,6 +53,18 @@
<el-option label="否" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="日期" prop="createDateRange">
<el-date-picker
v-model="queryParams.createDateRange"
type="daterange"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
clearable
@change="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@ -296,6 +308,7 @@ export default {
isAsc: defaultSort.order,
arrivalTypes: [],
hasRefund: null,
createDateRange: [],
id: null,
billId: null,
billNo: null,

View File

@ -0,0 +1,260 @@
<template>
<div class="chart-container">
<div ref="chartRef" style="width: 100%; height: 600px;"></div>
</div>
</template>
<script>
import * as echarts from 'echarts'
export default {
name: 'ReconcilicationDateChart',
props: {
data: {
type: Array,
default: () => []
}
},
data() {
return {
chart: null,
//
defaultFields: [
'orderTotalAmount',
'orderReceiveAmount',
'refundAmount',
'totalBonus',
'totalBonusRefund',
'actualBonus',
'difference'
],
// 使Y
rightYAxisFields: [
'withdrawServiceFee',
'receiveAmount',
'platformIncome',
'channelCost',
'platformBonus',
'platformBonusRefund',
],
//
fieldColors: {
//
orderTotalAmount: '#2F54EB', // -
orderReceiveAmount: '#389E0D', // 绿 - /
refundAmount: '#CF1322', // - 退/
totalBonus: '#531DAB', // -
totalBonusRefund: '#D4380D', // - 退
actualBonus: '#006D75', // -
difference: '#D46B08', // -
//
orderAmount: '#595959', //
vipOrderAmount: '#8C8C8C', //
userBonus: '#9254DE', //
platformBonus: '#73D13D', // 绿
userBonusRefund: '#FF7875', //
platformBonusRefund: '#FF9C6E', //
withdrawAmount: '#D4B106', //
withdrawServiceFee: '#40A9FF', //
receiveAmount: '#36CFC9', //
platformIncome: '#FFA940', //
channelCost: '#D48806' //
},
chartOptions: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
formatter: function(params) {
let result = params[0].axisValueLabel + '<br/>';
//
const mainAxis = [];
const secondAxis = [];
params.forEach(param => {
const item = param.marker + param.seriesName + ': ' + param.value;
if (param.seriesName.includes('服务费') ||
param.seriesName.includes('应收金额') ||
param.seriesName.includes('平台收益') ||
param.seriesName.includes('平台分成') ||
param.seriesName.includes('平台退款') ||
param.seriesName.includes('渠道成本')) {
secondAxis.push(item);
} else {
mainAxis.push(item);
}
});
//
result += mainAxis.join('<br/>');
// 线
if (secondAxis.length > 0) {
result += '<br/>------------------------<br/>';
result += secondAxis.join('<br/>');
}
return result;
}
},
legend: {
type: 'plain',
data: [],
bottom: 10,
itemWidth: 25,
itemHeight: 14,
textStyle: {
fontSize: 12
},
selected: {},
formatter: function(name) {
return name.length > 6 ? name.slice(0, 6) + '...' : name;
}
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
yAxis: [
{
type: 'value',
name: '大额数据',
position: 'left',
axisLabel: {
formatter: '{value} 元'
}
},
{
type: 'value',
name: '小额数据',
position: 'right',
axisLabel: {
formatter: '{value} 元'
}
}
],
series: []
}
}
},
watch: {
data: {
handler(newVal) {
this.updateChart()
},
deep: true
}
},
mounted() {
this.initChart()
this.updateChart()
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose()
this.chart = null
}
window.removeEventListener('resize', this.handleResize)
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.chartRef)
window.addEventListener('resize', this.handleResize)
},
handleResize() {
if (this.chart) {
this.chart.resize()
}
},
updateChart() {
if (!this.data.length || !this.chart) return
//
const sortedData = [...this.data].sort((a, b) => new Date(a.date) - new Date(b.date))
//
const dates = sortedData.map(item => item.date)
const seriesData = {}
const fieldGroups = {
'订单相关': ['orderAmount', 'vipOrderAmount', 'orderTotalAmount', 'refundAmount', 'orderReceiveAmount'],
'分成相关': ['userBonus', 'platformBonus', 'totalBonus', 'userBonusRefund', 'platformBonusRefund', 'totalBonusRefund', 'actualBonus'],
'其他数据': ['difference', 'withdrawAmount', 'withdrawServiceFee', 'receiveAmount', 'platformIncome', 'channelCost']
}
//
const fieldNameMap = {
orderAmount: '充值订单',
vipOrderAmount: '会员订单',
orderTotalAmount: '订单总额',
refundAmount: '订单退款',
orderReceiveAmount: '订单实收',
userBonus: '用户分成',
platformBonus: '平台分成',
totalBonus: '分成总计',
userBonusRefund: '用户退款',
platformBonusRefund: '平台退款',
totalBonusRefund: '分成退款',
actualBonus: '实际分成',
difference: '收支差额',
withdrawAmount: '提现金额',
withdrawServiceFee: '提现服务费',
receiveAmount: '应收金额',
platformIncome: '平台收益',
channelCost: '渠道成本'
}
//
const legendSelected = {}
Object.keys(fieldNameMap).forEach(field => {
legendSelected[fieldNameMap[field]] = this.defaultFields.includes(field)
})
//
Object.keys(fieldGroups).forEach(group => {
fieldGroups[group].forEach(field => {
seriesData[field] = {
name: fieldNameMap[field],
type: 'line',
smooth: true,
showSymbol: false,
yAxisIndex: this.rightYAxisFields.includes(field) ? 1 : 0, // 使Y
lineStyle: {
width: 2
},
itemStyle: {
color: this.fieldColors[field]
},
data: sortedData.map(item => Number(item[field]).toFixed(2))
}
})
})
//
this.chartOptions.xAxis.data = dates
this.chartOptions.legend.data = Object.values(fieldNameMap)
this.chartOptions.legend.selected = legendSelected
this.chartOptions.series = Object.values(seriesData)
//
this.chart.setOption(this.chartOptions)
}
}
}
</script>
<style lang="scss" scoped>
.chart-container {
background: #fff;
padding: 20px;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}
</style>

View File

@ -30,6 +30,16 @@
v-hasPermi="['ss:reconciliationDate:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-view"
size="mini"
@click="handleViewChart"
v-hasPermi="['ss:reconciliationDate:export']"
>查看图表</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
@ -39,19 +49,26 @@
show-icon>
<div style="display: flex; flex-direction: row; flex-wrap: wrap; ">
<div style="margin-right: 32px;">订单实收 = 订单总额 - 订单退款总额</div>
<div style="margin-right: 32px;">分成 = 用户分成 + 平台分成</div>
<div style="margin-right: 32px;">分成总计 = 用户分成 + 平台分成</div>
<div style="margin-right: 32px;">用户退款 = 用户分成退款金额</div>
<div style="margin-right: 32px;">平台退款 = 平台分成退款金额</div>
<div style="margin-right: 32px;">分成退款 = 用户退款 + 平台退款</div>
<div style="margin-right: 32px;">实际分成 = 总分成 - 分成退款</div>
<div style="margin-right: 32px;">差额 = 订单实收 - 实际分成</div>
<div style="margin-right: 32px;">应收 = 月费 + 订单手机号服务费 + 其他费用</div>
<div style="margin-right: 32px;">平台收益 = 平台分成 + 应收- 平台退款</div>
<div style="margin-right: 32px;">收支差额 = 订单实收 - 实际分成</div>
<div style="margin-right: 32px;">应收金额 = 月费 + 订单手机号服务费 + 其他费用</div>
<div style="margin-right: 32px;">平台收益 = 平台分成 + 应收金额 + 提现服务费 - 平台分成退款 - 渠道成本</div>
</div>
</el-alert>
<el-table v-loading="loading" :data="reconciliationDateList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="onSortChange">
<el-table-column type="selection" width="55" align="center" />
<el-table
v-loading="loading"
:data="reconciliationDateList"
@selection-change="handleSelectionChange"
:default-sort="defaultSort"
@sort-change="onSortChange"
header-row-class-name="header-row"
size="mini"
>
<el-table-column label="ID" align="center" prop="id" sortable v-if="isShow('id')"/>
<el-table-column label="日期" align="center" prop="date" sortable v-if="isShow('date')"/>
<el-table-column label="订单" align="center">
@ -60,10 +77,10 @@
<el-table-column :key="column.key" :label="column.label" :prop="column.key" :align="column.align" :min-width="column.minWidth" :sort-orders="orderSorts" :sortable="column.sortable" :show-overflow-tooltip="column.overflow" :width="column.width">
<template slot-scope="d">
<template v-if="['orderReceiveAmount'].includes(column.key)">
<span :style="{color: d.row[column.key] > 0 ? 'red' : 'green'}">{{d.row[column.key] | fix2}} </span>
<span :style="{color: d.row[column.key] > 0 ? 'red' : 'green'}">{{d.row[column.key] | fix2}}</span>
</template>
<template v-else>
{{d.row[column.key] | fix2}}
{{d.row[column.key] | fix2}}
</template>
</template>
</el-table-column>
@ -75,10 +92,10 @@
<el-table-column :key="column.key" :label="column.label" :prop="column.key" :align="column.align" :min-width="column.minWidth" :sort-orders="orderSorts" :sortable="column.sortable" :show-overflow-tooltip="column.overflow" :width="column.width">
<template slot-scope="d">
<template v-if="['actualBonus'].includes(column.key)">
<span :style="{color: d.row[column.key] > 0 ? 'red' : 'green'}">{{d.row[column.key] | fix2}} </span>
<span :style="{color: d.row[column.key] > 0 ? 'red' : 'green'}">{{d.row[column.key] | fix2}}</span>
</template>
<template v-else>
{{d.row[column.key] | fix2}}
{{d.row[column.key] | fix2}}
</template>
</template>
</el-table-column>
@ -86,14 +103,14 @@
</el-table-column>
<el-table-column label="其他" align="center">
<template v-for="column of showColumns.filter(item =>
['difference', 'withdrawAmount', 'receiveAmount', 'platformIncome'].includes(item.key))">
['difference', 'withdrawAmount', 'withdrawServiceFee', 'receiveAmount', 'platformIncome', 'channelCost'].includes(item.key))">
<el-table-column :key="column.key" :label="column.label" :prop="column.key" :align="column.align" :min-width="column.minWidth" :sort-orders="orderSorts" :sortable="column.sortable" :show-overflow-tooltip="column.overflow" :width="column.width">
<template slot-scope="d">
<template v-if="['platformIncome', 'difference'].includes(column.key)">
<span :style="{color: d.row[column.key] > 0 ? 'red' : 'green'}">{{d.row[column.key] | fix2}} </span>
<span :style="{color: d.row[column.key] > 0 ? 'red' : 'green'}">{{d.row[column.key] | fix2}}</span>
</template>
<template v-else>
{{d.row[column.key] | fix2}}
{{d.row[column.key] | fix2}}
</template>
</template>
</el-table-column>
@ -109,10 +126,15 @@
@pagination="getList"
/>
<el-dialog title="图表" :visible.sync="chartVisible" width="80%">
<reconcilication-date-chart v-if="chartVisible" :data="reconciliationDateList" />
</el-dialog>
</div>
</template>
<script>
import ReconcilicationDateChart from '@/views/ss/reconciliationDate/components/ReconcilicationDateChart.vue';
import { listReconciliationDate, getReconciliationDate, delReconciliationDate, addReconciliationDate, updateReconciliationDate } from "@/api/ss/reconciliationDate";
import { $showColumns } from '@/utils/mixins';
@ -125,27 +147,33 @@ const defaultSort = {
export default {
name: "ReconciliationDate",
mixins: [$showColumns],
components: {
ReconcilicationDateChart
},
data() {
return {
chartVisible: false,
//
columns: [
{key: 'id', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
{key: 'date', visible: true, label: '日期', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'orderAmount', visible: true, label: '充值订单', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'vipOrderAmount', visible: true, label: 'VIP订单', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'vipOrderAmount', visible: true, label: '会员订单', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'orderTotalAmount', visible: true, label: '订单总额', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'refundAmount', visible: true, label: '订单退款', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'orderReceiveAmount', visible: true, label: '订单实收', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'userBonus', visible: true, label: '用户分成', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'platformBonus', visible: true, label: '平台分成', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'totalBonus', visible: true, label: '分成', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'totalBonus', visible: true, label: '分成总计', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'userBonusRefund', visible: true, label: '用户退款', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'platformBonusRefund', visible: true, label: '平台退款', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'totalBonusRefund', visible: true, label: '分成退款', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'actualBonus', visible: true, label: '实际分成', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'difference', visible: true, label: '差额', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'withdrawAmount', visible: true, label: '提现', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'receiveAmount', visible: true, label: '应收账', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'difference', visible: true, label: '收支差额', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'withdrawAmount', visible: true, label: '提现金额', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'withdrawServiceFee', visible: true, label: '提现服务费', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'channelCost', visible: true, label: '渠道成本', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'receiveAmount', visible: true, label: '应收金额', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
{key: 'platformIncome', visible: true, label: '平台收益', minWidth: null, sortable: true, overflow: false, align: 'right', width: null},
],
//
@ -191,6 +219,9 @@ export default {
this.getList();
},
methods: {
handleViewChart() {
this.chartVisible = true;
},
/** 当排序按钮被点击时触发 **/
onSortChange(column) {
if (column.order == null) {
@ -302,3 +333,10 @@ export default {
}
};
</script>
<style scoped>
.header-row {
background-color: #f0f2f5;
font-size: 12px !important;
}
</style>