ylj20011123 d832cfa05d update
2025-10-30 11:38:09 +08:00

272 lines
8.1 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="consumption-period">
<!-- 消费时段分析标题 -->
<view class="section-header">
<text class="section-title">消费时段分析</text>
</view>
<!-- 消费时段分析图表 -->
<view class="chart-container">
<!-- 图表加载效果 -->
<ChartLoading v-if="isLoading" text="数据加载中..." />
<!-- 实际图表 -->
<QiunDataCharts v-else type="line" :opts="chartOpts" :chartData="chartData" :canvas2d="true"
:inScrollView="true" canvasId="consumptionPeriodChart" :animation="false" :ontap="true" :ontouch="true"
tooltipFormat="ConsumptionPeriod" />
</view>
</view>
</template>
<script>
import QiunDataCharts from './qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
import ChartLoading from './ChartLoading.vue'
import request from "@/util/index.js";
import moment from 'moment'
export default {
components: {
QiunDataCharts,
ChartLoading
},
data() {
return {
isLoading: false,
// 图表原始数据
rawData: {
category: [],
seriesData: []
}
}
},
props: {
selectTime: {
type: String,
default: ""
},
},
computed: {
// 检查是否有图表数据
hasChartData() {
return this.rawData.category.length > 0 &&
this.rawData.seriesData.length > 0
},
// 图表数据
chartData() {
return {
categories: this.rawData.category,
series: [
{
name: '客单占比',
data: this.rawData.seriesData
}
]
}
},
// 图表配置
chartOpts() {
return {
padding: [15, 15, 0, 15],
dataLabel: false,
enableScroll: false, // 关闭滚动
dataPointShape: true,
xAxis: {
disableGrid: true,
itemCount: this.rawData.category.length || 6, // 动态显示时间点数量
},
yAxis: {
showTitle: true,
data: [{
min: 0,
title: '客单占比(%)',
titleFontSize: 12,
titleOffsetY: -5,
titleOffsetX: 0
}]
},
legend: {
show: true,
position: 'bottom',
float: 'center',
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
fontSize: 12,
fontColor: '#333333',
margin: 0,
padding: 0,
itemGap: 10,
textAlign: 'left'
},
extra: {
line: {
type: 'curve',
width: 2,
activeType: 'hollow'
},
tooltip: {
showBox: true,
bgColor: '#000000',
bgOpacity: 0.7,
borderColor: '#333333',
borderWidth: 1
}
}
}
}
},
watch: {
selectTime: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.handleGetConsumptionPeriodData()
}
},
immediate: false
}
},
onReady() {
this.handleGetConsumptionPeriodData()
},
methods: {
// 获取消费时段分析数据
async handleGetConsumptionPeriodData() {
const req = {
Province_Code: '530000',
Statistics_Date: this.selectTime ? moment(this.selectTime).subtract(1, 'd').subtract(1, 'M').format('YYYY-MM-DD') : moment().subtract(1, 'd').subtract(1, 'M').format('YYYY-MM-DD'),
Serverpart_ID: '',
TimeSpan: 1
}
this.isLoading = true
const data = await this.getTransactionTimeAnalysis(req);
this.isLoading = false
// 处理数据
this.processChartData(data.Result_Data.CommonScatterList)
},
// 发起API请求获取消费时段分析数据
async getTransactionTimeAnalysis(params) {
const data = await request.$webGet(
"CommercialApi/Revenue/GetTransactionTimeAnalysis",
params
);
return data || []
},
// 处理图表数据
processChartData(data) {
let category = []
let seriesData = []
let dataMap = {}
let availableHours = new Set()
// 处理数据:获取消费时段分析数据
if (data && data.length > 0) {
// 拿到笔数的合计
let orderSum = 0
data.forEach((item) => {
orderSum += Number(item.data)
})
// 创建数据映射和记录可用时间点
data.forEach((item, index) => {
const hour = index
const percentage = Number(((item.data / orderSum) * 100).toFixed(2))
dataMap[hour] = percentage
availableHours.add(hour)
})
// 将Set转换为数组并排序
let sortedHours = Array.from(availableHours).sort((a, b) => a - b)
// 选择要显示的时间点
let selectedHours = []
// 1. 优先选择能被4整除的时间点4时、8时、12时、16时、20时
sortedHours.forEach(hour => {
if (hour % 4 === 0) {
if (hour === 24) {
return
}
selectedHours.push(hour)
}
})
// 2. 检查并补充0时和23时如果存在的话
if (availableHours.has(0) && !selectedHours.includes(0)) {
selectedHours.unshift(0) // 0时放在最前面
}
if (availableHours.has(23) && !selectedHours.includes(23)) {
selectedHours.push(23) // 23时放在最后面
}
// 3. 如果没有找到任何时间点,则使用默认的关键时间点
if (selectedHours.length === 0) {
selectedHours = [0, 4, 8, 12, 16, 20, 23]
}
// 按选定的时间点生成数据
selectedHours.forEach(hour => {
category.push(`${hour}`)
seriesData.push(dataMap[hour] || 0)
})
}
// 更新图表数据
this.rawData = {
category: category,
seriesData: seriesData
}
},
}
}
</script>
<style scoped lang="less">
@primary-color: #46B8F3;
@secondary-color: #3CD495;
@danger-color: #FF5E5E;
@success-color: #52C41A;
@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);
.consumption-period {
margin-top: 24rpx;
.section-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
padding: 0 8rpx;
.section-title {
font-size: 30rpx;
font-weight: 600;
color: @text-primary;
}
}
.chart-container {
background: @bg-white;
border-radius: @border-radius;
padding: 24rpx;
box-shadow: @shadow;
margin-bottom: 24rpx;
width: 100%;
box-sizing: border-box;
height: 400rpx;
}
}
</style>