ylj20011123 c78652a8d1 update
2025-10-23 18:35:54 +08:00

820 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="revenue-share-analysis">
<!-- 报表标题 -->
<view class="report-header">
<text class="report-title">平台和服务商及店铺分账数据交叉分析</text>
<view class="report-period">
<text class="period-label">分析周期</text>
<text class="period-value">{{ analysisPeriod }}</text>
</view>
</view>
<!-- 关键指标卡片 -->
<view class="metrics-row">
<view class="metric-card">
<view class="metric-icon total-revenue"></view>
<text class="metric-title">交易总额</text>
<view class="metric-value-container">
<text class="metric-value">¥{{ formatMoney(totalRevenue) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon platform-income"></view>
<text class="metric-title">平台收入</text>
<view class="metric-value-container">
<text class="metric-value">¥{{ formatMoney(platformIncome) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon provider-income"></view>
<text class="metric-title">服务商收入</text>
<view class="metric-value-container">
<text class="metric-value">¥{{ formatMoney(providerIncome) }}</text>
<text class="metric-unit"></text>
</view>
</view>
</view>
<view class="metrics-row">
<view class="metric-card">
<view class="metric-icon shop-income"></view>
<text class="metric-title">店铺收入</text>
<view class="metric-value-container">
<text class="metric-value">¥{{ formatMoney(shopIncome) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon provider-ratio"></view>
<text class="metric-title">服务商收入占比</text>
<view class="metric-value-container">
<text class="metric-value">{{ providerIncomeRatio }}%</text>
<text class="metric-unit">占比</text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon shop-ratio"></view>
<text class="metric-title">店铺收入占比</text>
<view class="metric-value-container">
<text class="metric-value">{{ shopIncomeRatio }}%</text>
<text class="metric-unit">占比</text>
</view>
</view>
</view>
<!-- 收入趋势分析 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">收入趋势分析</text>
<text class="chart-subtitle">平台服务商店铺收入变化趋势</text>
</view>
<view class="chart-content">
<view class="line-chart-container">
<QiunDataCharts
type="line"
:opts="revenueTrendOpts"
:chartData="revenueTrendChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="revenueTrendChart"
/>
<view class="chart-legend">
<view class="legend-item">
<view class="legend-dot platform"></view>
<text class="legend-text">平台收入</text>
</view>
<view class="legend-item">
<view class="legend-dot provider"></view>
<text class="legend-text">服务商收入</text>
</view>
<view class="legend-item">
<view class="legend-dot shop"></view>
<text class="legend-text">店铺收入</text>
</view>
</view>
</view>
</view>
</view>
<!-- 收入结构分析 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">收入结构分析</text>
<text class="chart-subtitle">各收入方占比情况</text>
</view>
<view class="chart-content">
<view class="pie-chart-container">
<QiunDataCharts
type="pie"
:opts="revenueStructureOpts"
:chartData="revenueStructureChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="revenueStructureChart"
/>
<view class="pie-legend">
<view class="legend-item" v-for="(item, index) in revenueStructureList" :key="index">
<view class="legend-color" :style="{ backgroundColor: item.color }"></view>
<text class="legend-name">{{ item.name }}</text>
<text class="legend-value">{{ item.percentage }}%</text>
</view>
</view>
</view>
</view>
</view>
<!-- 月度收入对比 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">月度收入对比</text>
<text class="chart-subtitle">各收入方月度收入对比情况</text>
</view>
<view class="chart-content">
<view class="column-chart-container">
<QiunDataCharts
type="column"
:opts="monthlyCompareOpts"
:chartData="monthlyCompareChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="monthlyCompareChart"
/>
</view>
</view>
</view>
<!-- 收入增长率分析 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">收入增长率分析</text>
<text class="chart-subtitle">各收入方同比增长率</text>
</view>
<view class="chart-content">
<view class="bar-chart-container">
<QiunDataCharts
type="column"
:opts="growthRateOpts"
:chartData="growthRateChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="growthRateChart"
/>
</view>
</view>
</view>
<!-- 分账明细数据 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">分账明细数据</text>
<view class="table-actions">
<text class="action-btn" @click="toggleFilter">筛选</text>
<text class="action-btn" @click="exportData">导出</text>
</view>
</view>
<view class="revenue-cards">
<view class="revenue-card" v-for="(item, index) in revenueList" :key="index">
<view class="revenue-header">
<view class="revenue-type-tag" :style="{
backgroundColor: item.type === '平台收入' ? '#576EFF' :
item.type === '服务商收入' ? '#52C41A' :
item.type === '店铺收入' ? '#FAAD14' : '#666666'
}">
{{ item.type }}
</view>
<text class="revenue-date">{{ item.date }}</text>
</view>
<view class="revenue-body">
<text class="revenue-merchant">{{ item.merchant }}</text>
<view class="revenue-metrics">
<view class="metric-item">
<text class="metric-label">收入金额</text>
<text class="metric-value">¥{{ formatMoney(item.amount) }}</text>
</view>
<view class="metric-divider"></view>
<view class="metric-item">
<text class="metric-label">收入占比</text>
<text class="metric-value">{{ item.ratio }}%</text>
</view>
<view class="metric-divider"></view>
<view class="metric-item">
<text class="metric-label">同比增长</text>
<text class="metric-value" :class="{ 'growth-positive': item.growth > 0, 'growth-negative': item.growth < 0 }">
{{ item.growth > 0 ? '+' : '' }}{{ item.growth }}%
</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import QiunDataCharts from './qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
export default {
components: {
QiunDataCharts
},
data() {
return {
analysisPeriod: '2024年10月',
totalRevenue: 56789012,
platformIncome: 5678901,
providerIncome: 12345678,
shopIncome: 38764433,
providerIncomeRatio: 21.7,
shopIncomeRatio: 68.3,
// 收入趋势数据
revenueTrendData: {
categories: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月'],
platformData: [345678, 412345, 478901, 523456, 567890, 534567, 567890, 545678, 578901, 567890],
providerData: [876543, 923456, 978901, 1023456, 1067890, 1034567, 1067890, 1045678, 1078901, 12345678],
shopData: [2345678, 2567890, 2789012, 3012345, 3234567, 3123456, 3234567, 3123456, 3345678, 38764433]
},
// 收入结构数据
revenueStructureList: [
{ name: '店铺收入', amount: 38764433, percentage: 68.3, color: '#FAAD14' },
{ name: '服务商收入', amount: 12345678, percentage: 21.7, color: '#52C41A' },
{ name: '平台收入', amount: 5678901, percentage: 10.0, color: '#576EFF' }
],
// 月度收入对比数据
monthlyCompareData: {
categories: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月'],
currentYear: [3567899, 3902691, 4236284, 4569257, 4866347, 4692590, 4866347, 4714812, 4992480, 56789012],
lastYear: [2854319, 3122153, 3389027, 3655406, 3893078, 3754072, 3893078, 3771850, 3993984, 45431210]
},
// 收入增长率数据
growthRateData: [
{ name: '平台收入', rate: 25.5 },
{ name: '服务商收入', rate: 41.2 },
{ name: '店铺收入', rate: 25.0 }
],
// 分账明细数据
revenueList: [
{ type: '平台收入', date: '2024-10-28', merchant: '平台总部', amount: 567891, ratio: 10.0, growth: 25.5 },
{ type: '店铺收入', date: '2024-10-28', merchant: '云南特产店', amount: 2345678, ratio: 4.1, growth: 18.6 },
{ type: '服务商收入', date: '2024-10-28', merchant: '顺丰物流', amount: 1234567, ratio: 2.2, growth: 35.2 },
{ type: '店铺收入', date: '2024-10-27', merchant: '茶叶专营店', amount: 1987654, ratio: 3.5, growth: 22.1 },
{ type: '服务商收入', date: '2024-10-27', merchant: '支付宝', amount: 987654, ratio: 1.7, growth: 28.9 },
{ type: '店铺收入', date: '2024-10-26', merchant: '手工艺品店', amount: 1567890, ratio: 2.8, growth: 15.3 }
]
}
},
computed: {
// 收入趋势图表数据
revenueTrendChartData() {
return {
categories: this.revenueTrendData.categories,
series: [
{
name: '平台收入',
data: this.revenueTrendData.platformData
},
{
name: '服务商收入',
data: this.revenueTrendData.providerData
},
{
name: '店铺收入',
data: this.revenueTrendData.shopData
}
]
}
},
// 收入趋势图表配置
revenueTrendOpts() {
return {
color: ['#576EFF', '#52C41A', '#FAAD14'],
padding: [15, 15, 15, 15],
dataLabel: false,
legend: {
show: false
},
xAxis: {
disableGrid: true
},
yAxis: {
gridType: 'dash',
dashLength: 2,
data: [{
min: 0
}]
},
extra: {
line: {
type: 'curve',
width: 2,
activeType: 'hollow'
}
}
}
},
// 收入结构图表数据
revenueStructureChartData() {
return {
series: [{
data: this.revenueStructureList.map(item => ({
name: item.name,
value: item.amount
}))
}]
}
},
// 收入结构图表配置
revenueStructureOpts() {
return {
color: this.revenueStructureList.map(item => item.color),
padding: [5, 5, 5, 5],
dataLabel: true,
legend: {
show: false
},
extra: {
pie: {
activeOpacity: 0.5,
activeRadius: 10,
offsetAngle: 0,
labelWidth: 15,
border: false,
borderWidth: 3,
borderColor: '#FFFFFF'
}
}
}
},
// 月度收入对比图表数据
monthlyCompareChartData() {
return {
categories: this.monthlyCompareData.categories,
series: [
{
name: '今年',
data: this.monthlyCompareData.currentYear
},
{
name: '去年',
data: this.monthlyCompareData.lastYear
}
]
}
},
// 月度收入对比图表配置
monthlyCompareOpts() {
return {
color: ['#576EFF', '#13C2C2'],
padding: [15, 15, 15, 15],
dataLabel: false,
legend: {
show: false
},
xAxis: {
disableGrid: true
},
yAxis: {
gridType: 'dash',
dashLength: 2,
data: [{
min: 0
}]
},
extra: {
column: {
type: 'group',
width: 20,
activeBgColor: '#000000',
activeBgOpacity: 0.08,
linearType: 'custom',
barBorderCircle: true
}
}
}
},
// 收入增长率图表数据
growthRateChartData() {
return {
categories: this.growthRateData.map(item => item.name),
series: [{
name: '增长率',
data: this.growthRateData.map(item => item.rate)
}]
}
},
// 收入增长率图表配置
growthRateOpts() {
return {
color: ['#52C41A'],
padding: [15, 15, 15, 15],
dataLabel: true,
enableScroll: true,
xAxis: {
itemCount: 3,
scrollShow: false,
scrollColor: '#52C41A',
scrollBackgroundColor: 'rgba(82, 196, 26, 0.1)',
scrollWidth: 4,
scrollHeight: 8
},
yAxis: {
gridType: 'dash',
dashLength: 2,
data: [{
min: 0
}]
},
extra: {
column: {
type: 'group',
width: 60,
activeBgColor: '#000000',
activeBgOpacity: 0.08,
linearType: 'custom',
barBorderCircle: true
}
}
}
}
},
methods: {
formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
},
formatMoney(amount) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
},
toggleFilter() {
console.log('打开筛选器')
},
exportData() {
console.log('导出数据')
}
}
}
</script>
<style scoped lang="less">
@primary-color: #667eea;
@secondary-color: #764ba2;
@success-color: #52c41a;
@warning-color: #faad14;
@error-color: #ff4d4f;
@text-primary: #333;
@text-secondary: #666;
@text-light: #999;
@bg-white: #ffffff;
@border-radius: 16rpx;
@shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
.revenue-share-analysis {
.report-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 32rpx;
padding: 0 8rpx;
.report-title {
font-size: 36rpx;
font-weight: 600;
color: @text-primary;
}
.report-period {
display: flex;
align-items: center;
.period-label {
font-size: 24rpx;
color: @text-secondary;
margin-right: 8rpx;
}
.period-value {
font-size: 24rpx;
color: @primary-color;
font-weight: 500;
}
}
}
.metrics-row {
display: flex;
gap: 24rpx;
margin-bottom: 24rpx;
.metric-card {
flex: 1;
background: @bg-white;
border-radius: @border-radius;
padding: 32rpx 24rpx;
box-shadow: @shadow;
text-align: center;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4rpx;
background: linear-gradient(90deg, @primary-color, @secondary-color);
}
.metric-icon {
width: 48rpx;
height: 48rpx;
margin: 0 auto 16rpx;
border-radius: 50%;
position: relative;
&.total-revenue {
background: linear-gradient(135deg, #1890ff, #40a9ff);
&::after { content: '💰'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.platform-income {
background: linear-gradient(135deg, #576EFF, #7B8CFF);
&::after { content: '🏢'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.provider-income {
background: linear-gradient(135deg, #52c41a, #73d13d);
&::after { content: '🤝'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.shop-income {
background: linear-gradient(135deg, #faad14, #ffc53d);
&::after { content: '🏪'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.provider-ratio {
background: linear-gradient(135deg, #722ed1, #9254de);
&::after { content: '📊'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.shop-ratio {
background: linear-gradient(135deg, #13c2c2, #36cfc9);
&::after { content: '📈'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
}
.metric-title {
font-size: 24rpx;
color: @text-secondary;
margin-bottom: 12rpx;
}
.metric-value-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
}
.metric-value {
font-size: 32rpx;
font-weight: 600;
color: @text-primary;
font-family: 'DINAlternate-Bold', sans-serif;
line-height: 1;
}
.metric-unit {
font-size: 20rpx;
color: @text-light;
line-height: 1;
}
}
}
.chart-card {
background: @bg-white;
border-radius: @border-radius;
padding: 24rpx;
box-shadow: @shadow;
margin-bottom: 24rpx;
.chart-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.chart-title {
font-size: 28rpx;
font-weight: 600;
color: @text-primary;
}
.chart-subtitle {
font-size: 22rpx;
color: @text-light;
margin-top: 4rpx;
}
.table-actions {
display: flex;
gap: 16rpx;
.action-btn {
font-size: 24rpx;
color: @primary-color;
padding: 8rpx 16rpx;
border: 1rpx solid @primary-color;
border-radius: 8rpx;
}
}
}
.chart-content {
.line-chart-container,
.column-chart-container,
.bar-chart-container {
width: 100%;
}
.line-chart-container {
.chart-legend {
display: flex;
justify-content: center;
gap: 32rpx;
margin-top: 16rpx;
.legend-item {
display: flex;
align-items: center;
gap: 8rpx;
.legend-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
&.platform {
background: #576EFF;
}
&.provider {
background: #52C41A;
}
&.shop {
background: #FAAD14;
}
}
.legend-text {
font-size: 22rpx;
color: @text-secondary;
}
}
}
}
.pie-chart-container {
display: flex;
flex-direction: column;
align-items: center;
.pie-legend {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 16rpx;
margin-top: 16rpx;
.legend-item {
display: flex;
align-items: center;
gap: 8rpx;
.legend-color {
width: 12rpx;
height: 12rpx;
border-radius: 2rpx;
}
.legend-name {
font-size: 22rpx;
color: @text-secondary;
}
.legend-value {
font-size: 22rpx;
color: @text-primary;
font-weight: 600;
}
}
}
}
}
.revenue-cards {
display: flex;
flex-direction: column;
gap: 16rpx;
.revenue-card {
background: #fafafa;
border-radius: 12rpx;
padding: 20rpx;
border: 1rpx solid #f0f0f0;
.revenue-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
.revenue-type-tag {
padding: 4rpx 12rpx;
border-radius: 12rpx;
font-size: 20rpx;
color: white;
font-weight: 500;
}
.revenue-date {
font-size: 20rpx;
color: @text-light;
font-family: monospace;
}
}
.revenue-body {
.revenue-merchant {
font-size: 28rpx;
color: @text-primary;
font-weight: 600;
margin-bottom: 12rpx;
display: block;
}
.revenue-metrics {
display: flex;
align-items: center;
.metric-item {
flex: 1;
text-align: center;
.metric-label {
font-size: 20rpx;
color: @text-secondary;
display: block;
margin-bottom: 4rpx;
}
.metric-value {
font-size: 24rpx;
color: @text-primary;
font-weight: 600;
display: block;
&.growth-positive {
color: @success-color;
}
&.growth-negative {
color: @error-color;
}
}
}
.metric-divider {
width: 1rpx;
height: 40rpx;
background: #e0e0e0;
margin: 0 16rpx;
}
}
}
}
}
}
}
</style>