ccy_DIB/pages/DigitalIntelligenceDashboard/components/OrderTransactionAnalysis.vue
ylj20011123 c78652a8d1 update
2025-10-23 18:35:54 +08:00

630 lines
17 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="order-transaction-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-amount"></view>
<text class="metric-title">交易总量</text>
<view class="metric-value-container">
<text class="metric-value">{{ formatNumber(totalTransactions) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon total-money"></view>
<text class="metric-title">交易总金额</text>
<view class="metric-value-container">
<text class="metric-value">¥{{ formatMoney(totalAmount) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon conversion-rate"></view>
<text class="metric-title">成交转化率</text>
<view class="metric-value-container">
<text class="metric-value">{{ conversionRate }}%</text>
<text class="metric-unit"></text>
</view>
</view>
</view>
<view class="metrics-row">
<view class="metric-card">
<view class="metric-icon order-users"></view>
<text class="metric-title">下单用户数</text>
<view class="metric-value-container">
<text class="metric-value">{{ formatNumber(orderUsers) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon deal-users"></view>
<text class="metric-title">成交用户数</text>
<view class="metric-value-container">
<text class="metric-value">{{ formatNumber(dealUsers) }}</text>
<text class="metric-unit"></text>
</view>
</view>
<view class="metric-card">
<view class="metric-icon avg-order"></view>
<text class="metric-title">客单价</text>
<view class="metric-value-container">
<text class="metric-value">¥{{ formatMoney(avgOrderValue) }}</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">24小时交易量分布情况</text>
</view>
<view class="chart-content">
<view class="line-chart-container">
<QiunDataCharts
type="line"
:opts="timeDistributionOpts"
:chartData="timeDistributionChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="timeDistributionChart"
/>
</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="map-chart-container">
<QiunDataCharts
type="pie"
:opts="regionDistributionOpts"
:chartData="regionDistributionData"
:canvas2d="true"
:inScrollView="true"
canvasId="regionDistributionChart"
/>
<view class="region-legend">
<view class="legend-item" v-for="(item, index) in regionData" :key="index">
<view class="legend-color" :style="{ backgroundColor: item.color }"></view>
<text class="legend-name">{{ item.name }}</text>
<text class="legend-value">¥{{ formatMoney(item.amount) }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 商品销售量分析 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">商品销售量分析</text>
<text class="chart-subtitle">TOP 10 热销商品销量</text>
</view>
<view class="chart-content">
<view class="bar-chart-container">
<QiunDataCharts
type="column"
:opts="salesVolumeOpts"
:chartData="salesVolumeChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="salesVolumeChart"
/>
</view>
</view>
</view>
<!-- 商品销售额分析 -->
<view class="chart-card">
<view class="chart-header">
<text class="chart-title">商品销售额分析</text>
<text class="chart-subtitle">TOP 10 高销售额商品排行</text>
</view>
<view class="chart-content">
<view class="bar-chart-container">
<QiunDataCharts
type="column"
:opts="salesAmountOpts"
:chartData="salesAmountChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="salesAmountChart"
/>
</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月',
totalTransactions: 45678,
totalAmount: 23456789,
conversionRate: 68.5,
orderUsers: 12890,
dealUsers: 8834,
avgOrderValue: 5136,
// 时间分布数据
timeDistributionData: {
categories: ['00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'],
transactionData: [234, 156, 89, 123, 567, 1234, 2345, 1876, 1567, 2890, 2456, 1876],
amountData: [12345, 8234, 4567, 6789, 34567, 67890, 123456, 98765, 82345, 156789, 123456, 98765]
},
// 地域分布数据
regionData: [
{ name: '云南省', amount: 5678901, percentage: 28.5, color: '#576EFF' },
{ name: '广东省', amount: 3456789, percentage: 17.3, color: '#52C41A' },
{ name: '北京市', amount: 2345678, percentage: 11.8, color: '#FAAD14' },
{ name: '上海市', amount: 1987654, percentage: 10.0, color: '#FF7875' },
{ name: '四川省', amount: 1567890, percentage: 7.9, color: '#B37FEB' },
{ name: '浙江省', amount: 1234567, percentage: 6.2, color: '#13C2C2' },
{ name: '江苏省', amount: 987654, percentage: 5.0, color: '#722ED1' },
{ name: '其他', amount: 2567890, percentage: 13.3, color: '#999999' }
],
// 商品销售量数据
salesVolumeData: [
{ name: '云南白药套装', volume: 3456 },
{ name: '普洱茶礼盒', volume: 2890 },
{ name: '鲜花饼组合', volume: 2345 },
{ name: '三七粉精品', volume: 1876 },
{ name: '云南咖啡豆', volume: 1567 },
{ name: '玉石手镯', volume: 1234 },
{ name: '民族服饰', volume: 987 },
{ name: '鲜花精油', volume: 876 },
{ name: '手工皂套装', volume: 654 },
{ name: '银饰项链', volume: 543 }
],
// 商品销售额数据
salesAmountData: [
{ name: '玉石手镯', amount: 567890 },
{ name: '云南白药套装', amount: 456789 },
{ name: '普洱茶礼盒', amount: 345678 },
{ name: '民族服饰', amount: 234567 },
{ name: '三七粉精品', amount: 198765 },
{ name: '鲜花饼组合', amount: 156789 },
{ name: '鲜花精油', amount: 123456 },
{ name: '云南咖啡豆', amount: 98765 },
{ name: '银饰项链', amount: 87654 },
{ name: '手工皂套装', amount: 65432 }
]
}
},
computed: {
// 时间分布图表数据
timeDistributionChartData() {
return {
categories: this.timeDistributionData.categories,
series: [
{
name: '交易量',
data: this.timeDistributionData.transactionData
},
{
name: '交易额(÷100)',
data: this.timeDistributionData.amountData.map(v => v / 100)
}
]
}
},
// 时间分布图表配置
timeDistributionOpts() {
return {
color: ['#576EFF', '#52C41A'],
padding: [15, 15, 15, 15],
dataLabel: false,
legend: {
show: false
},
xAxis: {
disableGrid: true
},
yAxis: {
gridType: 'dash',
dashLength: 2,
data: [
{
min: 0
},
{
min: 0,
position: 'right'
}
]
},
extra: {
line: {
type: 'curve',
width: 2,
activeType: 'hollow'
}
}
}
},
// 地域分布图表数据
regionDistributionData() {
return {
series: [{
data: this.regionData.map(item => ({
name: item.name,
value: item.amount
}))
}]
}
},
// 地域分布图表配置
regionDistributionOpts() {
return {
color: this.regionData.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'
}
}
}
},
// 销售量图表数据
salesVolumeChartData() {
return {
categories: this.salesVolumeData.map(item =>
item.name.length > 6 ? item.name.substring(0, 6) + '...' : item.name
),
series: [{
name: '销售量',
data: this.salesVolumeData.map(item => item.volume)
}]
}
},
// 销售量图表配置
salesVolumeOpts() {
return {
color: ['#576EFF'],
padding: [15, 15, 15, 15],
dataLabel: false,
enableScroll: true,
xAxis: {
itemCount: 4,
scrollShow: true,
scrollAlign: 'right',
scrollColor: '#576EFF',
scrollBackgroundColor: 'rgba(87, 110, 255, 0.1)',
scrollWidth: 4,
scrollHeight: 8
},
yAxis: {
gridType: 'dash',
dashLength: 2,
data: [{
min: 0
}]
},
extra: {
column: {
type: 'group',
width: 30,
activeBgColor: '#000000',
activeBgOpacity: 0.08,
linearType: 'custom',
barBorderCircle: true
}
}
}
},
// 销售额图表数据
salesAmountChartData() {
return {
categories: this.salesAmountData.map(item =>
item.name.length > 6 ? item.name.substring(0, 6) + '...' : item.name
),
series: [{
name: '销售额',
data: this.salesAmountData.map(item => item.amount)
}]
}
},
// 销售额图表配置
salesAmountOpts() {
return {
color: ['#52C41A'],
padding: [15, 15, 15, 15],
dataLabel: false,
enableScroll: true,
xAxis: {
itemCount: 4,
scrollShow: true,
scrollAlign: 'right',
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: 30,
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, ",")
}
}
}
</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);
.order-transaction-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-amount {
background: linear-gradient(135deg, #1890ff, #40a9ff);
&::after { content: '📊'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.total-money {
background: linear-gradient(135deg, #52c41a, #73d13d);
&::after { content: '💰'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.conversion-rate {
background: linear-gradient(135deg, #faad14, #ffc53d);
&::after { content: '📈'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.order-users {
background: linear-gradient(135deg, #722ed1, #9254de);
&::after { content: '👥'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.deal-users {
background: linear-gradient(135deg, #eb2f96, #f759ab);
&::after { content: '✅'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
}
&.avg-order {
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 {
margin-bottom: 20rpx;
.chart-title {
font-size: 28rpx;
font-weight: 600;
color: @text-primary;
margin-bottom: 4rpx;
}
.chart-subtitle {
font-size: 22rpx;
color: @text-light;
}
}
.chart-content {
.line-chart-container {
width: 100%;
}
.map-chart-container {
display: flex;
flex-direction: column;
align-items: center;
.region-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;
}
}
}
}
.bar-chart-container {
width: 100%;
}
}
}
}
</style>