1
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
<el-form-item label="商品名称" prop="skuName">
|
||||
<el-input v-model="queryParams.skuName" placeholder="请输入商品名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品SKU" prop="skuId">
|
||||
<el-input v-model="queryParams.skuId" placeholder="SKU ID" clearable style="width: 200px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单状态" prop="statusGroup">
|
||||
<el-select v-model="queryParams.statusGroup" placeholder="订单状态" clearable style="width: 240px">
|
||||
<el-option v-for="status in mergedStatusList" :key="status.value" :label="status.label" :value="status.value" />
|
||||
@@ -50,7 +53,7 @@
|
||||
</mobile-search-form>
|
||||
|
||||
<!-- 统计悬浮模块 -->
|
||||
<el-card class="statistics-card" shadow="hover" v-if="orderrowsList.length > 0">
|
||||
<el-card class="statistics-card" shadow="hover">
|
||||
<div slot="header" class="clearfix">
|
||||
<span><i class="el-icon-data-analysis"></i> 佣金统计</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text" @click="toggleStatistics">
|
||||
@@ -367,6 +370,7 @@ export default {
|
||||
unionId: null,
|
||||
orderId: null,
|
||||
skuName: null,
|
||||
skuId: null,
|
||||
validCode: null,
|
||||
statusGroup: null, // 新增
|
||||
orderBy: null, // 排序字段
|
||||
@@ -725,21 +729,11 @@ export default {
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
console.log(this.queryParams.validCode);
|
||||
|
||||
// 合并项转为原始code数组
|
||||
if (this.queryParams.statusGroup) {
|
||||
this.queryParams.validCodes = this.statusValueMap[this.queryParams.statusGroup].map(code => Number(code));
|
||||
} else if (this.queryParams.validCodes && Array.isArray(this.queryParams.validCodes)) {
|
||||
this.queryParams.validCodes = this.queryParams.validCodes.map(code => Number(code));
|
||||
const codes = this.statusValueMap[this.queryParams.statusGroup]
|
||||
this.queryParams.validCodes = codes && codes.length ? codes.map(code => Number(code)) : null
|
||||
} else {
|
||||
this.queryParams.validCodes = null;
|
||||
}
|
||||
// 打印类型检查
|
||||
if (this.queryParams.validCode) {
|
||||
this.queryParams.validCode = this.queryParams.validCode.map(item => Number(item));
|
||||
console.log('validCode值:', this.queryParams.validCodes);
|
||||
console.log('validCode类型:', this.queryParams.validCodes.map(item => typeof item));
|
||||
this.queryParams.validCodes = null
|
||||
}
|
||||
this.getList();
|
||||
},
|
||||
@@ -747,7 +741,7 @@ export default {
|
||||
resetQuery() {
|
||||
this.dateRange = [];
|
||||
this.resetForm("queryForm");
|
||||
this.queryParams.validCodes = [];
|
||||
this.queryParams.validCodes = null;
|
||||
// 重置时恢复默认分页条数
|
||||
this.queryParams.pageSize = 10;
|
||||
this.queryParams.pageNum = 1;
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="app-container" v-loading="loading">
|
||||
<!-- 查询条件 -->
|
||||
<el-card style="margin-bottom: 20px;">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
|
||||
<el-form-item label="时间范围" prop="dateRange">
|
||||
<el-card class="filter-card">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" size="small" v-show="showSearch" label-width="88px">
|
||||
<el-form-item label="京粉账号" prop="unionId">
|
||||
<el-select v-model="queryParams.unionId" placeholder="全部京东联盟账号" clearable filterable style="width: 220px">
|
||||
<el-option
|
||||
v-for="admin in adminList"
|
||||
:key="admin.value || admin.id"
|
||||
:label="admin.label || (admin.name + ' (' + admin.wxid + ')')"
|
||||
:value="admin.value || admin.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
@@ -11,131 +21,95 @@
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
@change="handleDateRangeChange">
|
||||
</el-date-picker>
|
||||
style="width: 260px"
|
||||
@change="handleDateRangeChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单状态" prop="validCode">
|
||||
<el-select v-model="queryParams.validCode" placeholder="请选择订单状态" clearable>
|
||||
<el-select v-model="queryParams.validCode" placeholder="全部状态" clearable style="width: 160px">
|
||||
<el-option
|
||||
v-for="dict in validCodeOptions"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value">
|
||||
</el-option>
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品ID" prop="skuId">
|
||||
<el-form-item label="商品SKU" prop="skuId">
|
||||
<el-input
|
||||
v-model="queryParams.skuId"
|
||||
placeholder="请输入商品ID"
|
||||
placeholder="SKU ID"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
</el-input>
|
||||
style="width: 160px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<span>总订单数</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h2>{{ statistics.totalOrders || 0 }}</h2>
|
||||
<p>累计订单数量</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<span>总佣金</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h2>¥{{ formatMoney(statistics.totalCommission) }}</h2>
|
||||
<p>累计佣金收入</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<span>总商品数</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h2>{{ statistics.totalSkuNum || 0 }}</h2>
|
||||
<p>累计商品数量</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<span>实际费用</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h2>¥{{ formatMoney(statistics.totalActualFee) }}</h2>
|
||||
<p>累计实际费用</p>
|
||||
<!-- 统计卡片:与列表页口径对齐,总佣金=后端 totalCommission(预估佣金口径) -->
|
||||
<el-row :gutter="16" class="summary-row">
|
||||
<el-col v-for="item in summaryItems" :key="item.key" :xs="24" :sm="12" :md="8" :lg="4">
|
||||
<el-card class="summary-card" shadow="hover">
|
||||
<div class="summary-card-inner">
|
||||
<div class="summary-title">{{ item.title }}</div>
|
||||
<div class="summary-value">
|
||||
<template v-if="item.money">¥{{ item.display }}</template>
|
||||
<template v-else>{{ item.display }}</template>
|
||||
</div>
|
||||
<div class="summary-hint">{{ item.hint }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 图表区域 -->
|
||||
<el-row :gutter="20" style="margin-top: 20px;">
|
||||
<el-col :span="12">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<el-row :gutter="16" class="charts-row">
|
||||
<el-col :xs="24" :lg="12">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header" class="card-header-plain">
|
||||
<span>订单状态分布</span>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<div ref="statusChart" style="height: 300px;"></div>
|
||||
<div ref="statusChart" class="chart-el" />
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<span>佣金分布</span>
|
||||
<el-col :xs="24" :lg="12">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header" class="card-header-plain">
|
||||
<span>佣金分布(预估口径)</span>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<div ref="commissionChart" style="height: 300px;"></div>
|
||||
<div ref="commissionChart" class="chart-el" />
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 状态详情表格 -->
|
||||
<el-row :gutter="20" style="margin-top: 20px;">
|
||||
<!-- 状态详情表格(分组顺序与列表页一致) -->
|
||||
<el-row :gutter="16" class="table-row">
|
||||
<el-col :span="24">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header" class="card-header-plain">
|
||||
<span>订单状态详情</span>
|
||||
</div>
|
||||
<el-table :data="statusDetails" style="width: 100%">
|
||||
<el-table-column prop="label" label="状态" width="120" />
|
||||
<el-table-column prop="count" label="订单数量" width="120" align="center" />
|
||||
<el-table-column prop="skuNum" label="商品数量" width="120" align="center" />
|
||||
<el-table-column prop="commission" label="佣金" width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
¥{{ formatMoney(scope.row.commission) }}
|
||||
</template>
|
||||
<el-table :data="statusDetails" stripe style="width: 100%">
|
||||
<el-table-column prop="label" label="状态" min-width="100" />
|
||||
<el-table-column prop="count" label="订单数" width="100" align="center" />
|
||||
<el-table-column prop="skuNum" label="商品件数" width="100" align="center" />
|
||||
<el-table-column prop="commission" label="预估佣金" min-width="110" align="right">
|
||||
<template slot-scope="scope">¥{{ formatMoney(scope.row.commission) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="actualFee" label="实际费用" width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
¥{{ formatMoney(scope.row.actualFee) }}
|
||||
</template>
|
||||
<el-table-column prop="actualFee" label="实际费用" min-width="110" align="right">
|
||||
<template slot-scope="scope">¥{{ formatMoney(scope.row.actualFee) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="percentage" label="占比" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.percentage }}%
|
||||
</template>
|
||||
<el-table-column prop="percentage" label="占比" width="88" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.percentage }}%</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
@@ -146,86 +120,173 @@
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import { debounce } from '@/utils'
|
||||
import { getOrderStatistics, getValidCodeSelectData } from '@/api/system/orderrows'
|
||||
import { getAdminSelectData } from '@/api/system/superadmin'
|
||||
|
||||
/** 与列表页、后端 groupStats 逻辑顺序一致 */
|
||||
const GROUP_STAT_ORDER = ['pending', 'paid', 'deposit', 'finished', 'cancel', 'invalid', 'illegal']
|
||||
|
||||
const PIE_COLORS = ['#e6a23c', '#409eff', '#909399', '#67c23a', '#f56c6c', '#c0c4cc', '#f78989']
|
||||
|
||||
export default {
|
||||
name: "OrderStatistics",
|
||||
name: 'OrderStatistics',
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
loading: false,
|
||||
showSearch: true,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
beginTime: null,
|
||||
endTime: null,
|
||||
validCode: null,
|
||||
skuId: null
|
||||
skuId: null,
|
||||
unionId: null
|
||||
},
|
||||
// 日期范围
|
||||
dateRange: [],
|
||||
// 订单状态选项
|
||||
validCodeOptions: [],
|
||||
// 统计数据
|
||||
adminList: [],
|
||||
statistics: {
|
||||
totalOrders: 0,
|
||||
totalCosPrice: 0,
|
||||
totalCommission: 0,
|
||||
totalSkuNum: 0,
|
||||
totalActualFee: 0,
|
||||
groupStats: {}
|
||||
},
|
||||
// 状态详情数据
|
||||
statusDetails: []
|
||||
statusDetails: [],
|
||||
_statusChart: null,
|
||||
_commissionChart: null,
|
||||
_chartResize: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
summaryItems() {
|
||||
const s = this.statistics
|
||||
return [
|
||||
{
|
||||
key: 'orders',
|
||||
title: '总订单数',
|
||||
money: false,
|
||||
display: s.totalOrders || 0,
|
||||
hint: '符合当前筛选'
|
||||
},
|
||||
{
|
||||
key: 'cos',
|
||||
title: '总计佣金额',
|
||||
money: true,
|
||||
display: this.formatMoney(s.totalCosPrice),
|
||||
hint: 'estimateCosPrice 汇总'
|
||||
},
|
||||
{
|
||||
key: 'commission',
|
||||
title: '预估佣金',
|
||||
money: true,
|
||||
display: this.formatMoney(s.totalCommission),
|
||||
hint: '与列表页「预估佣金」同口径'
|
||||
},
|
||||
{
|
||||
key: 'sku',
|
||||
title: '总商品件数',
|
||||
money: false,
|
||||
display: s.totalSkuNum || 0,
|
||||
hint: 'skuNum 汇总'
|
||||
},
|
||||
{
|
||||
key: 'actual',
|
||||
title: '实际费用',
|
||||
money: true,
|
||||
display: this.formatMoney(s.totalActualFee),
|
||||
hint: 'actualFee 汇总'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getValidCodeOptions()
|
||||
this.getStatistics()
|
||||
this.bootstrap()
|
||||
},
|
||||
mounted() {
|
||||
this.initCharts()
|
||||
this._chartResize = debounce(() => {
|
||||
this._statusChart && this._statusChart.resize()
|
||||
this._commissionChart && this._commissionChart.resize()
|
||||
}, 120)
|
||||
window.addEventListener('resize', this._chartResize)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this._chartResize)
|
||||
this._disposeCharts()
|
||||
},
|
||||
methods: {
|
||||
/** 获取订单状态选项 */
|
||||
getValidCodeOptions() {
|
||||
getValidCodeSelectData().then(response => {
|
||||
this.validCodeOptions = response.data
|
||||
})
|
||||
bootstrap() {
|
||||
Promise.all([
|
||||
getValidCodeSelectData().then(res => {
|
||||
this.validCodeOptions = res.data || []
|
||||
}),
|
||||
getAdminSelectData().then(res => {
|
||||
this.adminList = res.data || res || []
|
||||
})
|
||||
])
|
||||
.catch(() => {
|
||||
this.$message.error('加载筛选项失败')
|
||||
})
|
||||
.finally(() => {
|
||||
this.getStatistics()
|
||||
})
|
||||
},
|
||||
_disposeCharts() {
|
||||
if (this._statusChart) {
|
||||
this._statusChart.dispose()
|
||||
this._statusChart = null
|
||||
}
|
||||
if (this._commissionChart) {
|
||||
this._commissionChart.dispose()
|
||||
this._commissionChart = null
|
||||
}
|
||||
},
|
||||
/** 获取统计数据 */
|
||||
getStatistics() {
|
||||
this.loading = true
|
||||
getOrderStatistics(this.queryParams).then(response => {
|
||||
this.statistics = response.data
|
||||
this.processStatusDetails()
|
||||
this.$nextTick(() => {
|
||||
this.initCharts()
|
||||
const params = { ...this.queryParams }
|
||||
if (params.skuId === '' || params.skuId === undefined) {
|
||||
params.skuId = null
|
||||
}
|
||||
getOrderStatistics(params)
|
||||
.then(response => {
|
||||
this.statistics = Object.assign(
|
||||
{
|
||||
totalOrders: 0,
|
||||
totalCosPrice: 0,
|
||||
totalCommission: 0,
|
||||
totalSkuNum: 0,
|
||||
totalActualFee: 0,
|
||||
groupStats: {}
|
||||
},
|
||||
response.data || {}
|
||||
)
|
||||
this.processStatusDetails()
|
||||
this.$nextTick(() => this.updateCharts())
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message.error('加载统计数据失败')
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
/** 处理状态详情数据 */
|
||||
processStatusDetails() {
|
||||
const groupStats = this.statistics.groupStats || {}
|
||||
this.statusDetails = Object.values(groupStats).map(item => {
|
||||
const percentage = this.statistics.totalOrders > 0
|
||||
? ((item.count / this.statistics.totalOrders) * 100).toFixed(2)
|
||||
: '0.00'
|
||||
return {
|
||||
const total = this.statistics.totalOrders || 0
|
||||
this.statusDetails = GROUP_STAT_ORDER.map(key => groupStats[key])
|
||||
.filter(Boolean)
|
||||
.map(item => ({
|
||||
...item,
|
||||
percentage
|
||||
}
|
||||
})
|
||||
skuNum: item.skuNum != null ? item.skuNum : 0,
|
||||
percentage: total > 0 ? ((item.count / total) * 100).toFixed(2) : '0.00'
|
||||
}))
|
||||
},
|
||||
/** 格式化金额 */
|
||||
formatMoney(amount) {
|
||||
if (!amount && amount !== 0) return '0.00'
|
||||
return parseFloat(amount).toFixed(2)
|
||||
if (amount == null || amount === '') return '0.00'
|
||||
const n = parseFloat(amount)
|
||||
return Number.isFinite(n) ? n.toFixed(2) : '0.00'
|
||||
},
|
||||
/** 日期范围变化处理 */
|
||||
handleDateRangeChange(dates) {
|
||||
if (dates && dates.length === 2) {
|
||||
this.queryParams.beginTime = dates[0]
|
||||
@@ -235,150 +296,175 @@ export default {
|
||||
this.queryParams.endTime = null
|
||||
}
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.getStatistics()
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.dateRange = []
|
||||
this.resetForm("queryForm")
|
||||
this.resetForm('queryForm')
|
||||
this.queryParams = {
|
||||
beginTime: null,
|
||||
endTime: null,
|
||||
validCode: null,
|
||||
skuId: null
|
||||
skuId: null,
|
||||
unionId: null
|
||||
}
|
||||
this.getStatistics()
|
||||
},
|
||||
/** 初始化图表 */
|
||||
initCharts() {
|
||||
this.initStatusChart()
|
||||
this.initCommissionChart()
|
||||
},
|
||||
/** 初始化状态分布图表 */
|
||||
initStatusChart() {
|
||||
const chartDom = this.$refs.statusChart
|
||||
if (!chartDom) return
|
||||
|
||||
const myChart = echarts.init(chartDom)
|
||||
|
||||
const groupStats = this.statistics.groupStats || {}
|
||||
const data = Object.values(groupStats).map(item => ({
|
||||
value: item.count,
|
||||
name: item.label
|
||||
}))
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left',
|
||||
type: 'scroll'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '订单状态',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
myChart.setOption(option)
|
||||
},
|
||||
/** 初始化佣金分布图表 */
|
||||
initCommissionChart() {
|
||||
const chartDom = this.$refs.commissionChart
|
||||
if (!chartDom) return
|
||||
|
||||
const myChart = echarts.init(chartDom)
|
||||
|
||||
const groupStats = this.statistics.groupStats || {}
|
||||
const data = Object.values(groupStats)
|
||||
.filter(item => item.commission > 0)
|
||||
.map(item => ({
|
||||
value: item.commission,
|
||||
updateCharts() {
|
||||
this._renderPie(this.$refs.statusChart, '_statusChart', (groupStats) => {
|
||||
const data = GROUP_STAT_ORDER.map(k => groupStats[k]).filter(Boolean).map(item => ({
|
||||
value: item.count,
|
||||
name: item.label
|
||||
}))
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: ¥{c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left',
|
||||
type: 'scroll'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '佣金分布',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
return {
|
||||
name: '订单状态',
|
||||
data,
|
||||
isAmount: false
|
||||
}
|
||||
})
|
||||
this._renderPie(this.$refs.commissionChart, '_commissionChart', (groupStats) => {
|
||||
const data = GROUP_STAT_ORDER.map(k => groupStats[k])
|
||||
.filter(Boolean)
|
||||
.filter(item => Number(item.commission) > 0)
|
||||
.map(item => ({
|
||||
value: item.commission,
|
||||
name: item.label
|
||||
}))
|
||||
return {
|
||||
name: '佣金分布',
|
||||
data,
|
||||
isAmount: true
|
||||
}
|
||||
})
|
||||
this._chartResize && this._chartResize()
|
||||
},
|
||||
_renderPie(domRef, instKey, build) {
|
||||
if (!domRef) return
|
||||
const groupStats = this.statistics.groupStats || {}
|
||||
const built = build(groupStats)
|
||||
let chart = this[instKey]
|
||||
if (!chart) {
|
||||
chart = echarts.init(domRef)
|
||||
this[instKey] = chart
|
||||
}
|
||||
|
||||
myChart.setOption(option)
|
||||
if (!built.data.length) {
|
||||
chart.setOption(
|
||||
{
|
||||
tooltip: { show: false },
|
||||
color: PIE_COLORS,
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'middle',
|
||||
style: { text: '暂无数据', fill: '#909399', fontSize: 14 }
|
||||
}
|
||||
],
|
||||
series: []
|
||||
},
|
||||
true
|
||||
)
|
||||
return
|
||||
}
|
||||
chart.setOption(
|
||||
{
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: built.isAmount
|
||||
? (p) => `${p.seriesName}<br/>${p.name}: ¥${this.formatMoney(p.value)} (${p.percent}%)`
|
||||
: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
color: PIE_COLORS,
|
||||
graphic: [],
|
||||
legend: { orient: 'vertical', left: 'left', type: 'scroll' },
|
||||
series: [
|
||||
{
|
||||
name: built.name,
|
||||
type: 'pie',
|
||||
radius: ['42%', '72%'],
|
||||
center: ['56%', '52%'],
|
||||
avoidLabelOverlap: true,
|
||||
itemStyle: { borderRadius: 4, borderColor: '#fff', borderWidth: 1 },
|
||||
label: { show: true, formatter: '{b}\n{d}%' },
|
||||
emphasis: {
|
||||
label: { show: true, fontSize: 16, fontWeight: 'bold' }
|
||||
},
|
||||
data: built.data
|
||||
}
|
||||
]
|
||||
},
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card-body {
|
||||
.filter-card {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.summary-row {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
margin-bottom: 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.summary-card-inner {
|
||||
text-align: center;
|
||||
padding: 6px 4px 4px;
|
||||
}
|
||||
|
||||
.card-body h2 {
|
||||
color: #409EFF;
|
||||
margin: 10px 0;
|
||||
font-size: 28px;
|
||||
.summary-title {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.card-body p {
|
||||
color: #666;
|
||||
margin: 5px 0;
|
||||
.summary-value {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #409eff;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.summary-hint {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.charts-row {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.card-header-plain {
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
padding: 10px;
|
||||
padding: 8px 8px 4px;
|
||||
}
|
||||
|
||||
.chart-el {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.filter-card ::v-deep .el-form--inline .el-form-item {
|
||||
display: block;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user