ylj20011123 2900c384eb update
2025-10-29 10:02:45 +08:00

389 lines
12 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="business-case">
<!-- 营收特征标题 -->
<view class="section-header">
<text class="section-title">营收特征</text>
</view>
<!-- 营收特征分析图表 -->
<view class="chart-container">
<view style="width:100%;height: 80rpx;">
<!-- 选择器 -->
<picker mode="selector" :range="tabList" range-key="label" :value="getCurrentPickerIndex()"
@change="handlePickerChange" class="picker-container">
<view class="picker-display">
<text class="picker-text">{{ getCurrentTabLabel() }}</text>
<text class="picker-arrow"></text>
</view>
</picker>
</view>
<view style="width:100%;height: 400rpx;">
<!-- 图表 -->
<QiunDataCharts type="column" :opts="chartOpts" :chartData="chartData" :canvas2d="true"
:inScrollView="true" canvasId="businessCaseChart" :animation="false" :ontap="true" :ontouch="true"
tooltipFormat="businessCaseChart" />
</view>
</view>
</view>
</template>
<script>
import QiunDataCharts from './qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
import request from "@/util/index.js";
import moment from 'moment'
export default {
components: {
QiunDataCharts
},
data() {
return {
// Tab列表
tabList: [
{ label: "营收金额", value: 1 },
{ label: "客单量", value: 2 },
{ label: "客单均价", value: 3 }
],
selectTab: 1, // 当前选中的Tab
// 当前请求来的实际数据
realData: {},
// 图表原始数据
rawData: {
category: [],
seriesData: []
}
}
},
computed: {
// 图表数据
chartData() {
return {
categories: this.rawData.category,
series: this.rawData.seriesData
}
},
// 图表配置
chartOpts() {
return {
padding: [15, 15, 15, 15], // 增加顶部padding为picker留出空间
dataLabel: false,
enableScroll: true,
xAxis: {
disableGrid: true,
itemCount: 4,
},
yAxis: {
data: [{
min: 0,
title: this.getYAxisTitle()
}]
},
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: {
column: {
type: 'group',
width: 12,
activeBgColor: '#000000',
activeBgOpacity: 0.08,
seriesGap: 0,
barBorderRadius: [3, 3, 0, 0]
}
}
}
}
},
onReady() {
this.handleGetBusinessCaseData()
},
methods: {
// 获取营收特征数据
async handleGetBusinessCaseData() {
const req = {
ProvinceCode: "530000",
StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
ServerpartId: "", // 暂时为空如果需要传入服务区ID可以在这里添加
}
const data = await this.getRevenueCompare(req);
// 处理数据
this.processChartData(data.Result_Data)
},
// 发起API请求获取营收特征数据
async getRevenueCompare(params) {
const data = await request.$webGet(
"CommercialApi/Revenue/GetRevenueCompare",
params
);
return data || {}
},
// 处理图表数据
processChartData(data) {
let monthList = []
// 获取月份列表
let list = data.RevenueAmountList
if (list && list.length > 0) {
list.forEach((item, index) => {
if (index === 0 && item.data && item.data.length > 0) {
item.data.forEach((subItem) => {
monthList.push(subItem[0])
})
}
})
}
// 营收金额数据
let revenueData = this.processRevenueAmount(data, monthList)
// 客单量数据
let ticketData = this.processTicketCount(data, monthList)
// 客单均价数据
let avgData = this.processAvgTicketAmount(data, monthList)
// 保存所有数据
this.realData = {
1: revenueData,
2: ticketData,
3: avgData
}
// 显示当前选中的数据
this.handleShowData(this.selectTab)
},
// 处理营收金额数据
processRevenueAmount(data, monthList) {
let category = []
let seriesData = []
let list = data.RevenueAmountList
if (list && list.length > 0) {
list.forEach((item) => {
let dataValues = []
if (monthList && monthList.length > 0) {
monthList.forEach((month) => {
let newData = item.data
dataValues.push(Number(((newData[month - 1][1]) / 10000).toFixed(2)))
})
}
seriesData.push({
name: item.name,
data: dataValues
})
})
}
if (monthList && monthList.length > 0) {
monthList.forEach((month) => {
category.push(`${month}`)
})
}
return { category, seriesData }
},
// 处理客单量数据
processTicketCount(data, monthList) {
let category = []
let seriesData = []
let list = data.TicketCountList
if (list && list.length > 0) {
list.forEach((item) => {
let dataValues = []
if (monthList && monthList.length > 0) {
monthList.forEach((month) => {
let newData = item.data
dataValues.push(Number(((newData[month - 1][1]) / 10000).toFixed(2)))
})
}
seriesData.push({
name: item.name,
data: dataValues
})
})
}
if (monthList && monthList.length > 0) {
monthList.forEach((month) => {
category.push(`${month}`)
})
}
return { category, seriesData }
},
// 处理客单均价数据
processAvgTicketAmount(data, monthList) {
let category = []
let seriesData = []
let list = data.AvgTicketAmountList
if (list && list.length > 0) {
list.forEach((item) => {
let dataValues = []
if (monthList && monthList.length > 0) {
monthList.forEach((month) => {
let newData = item.data
dataValues.push(Number(newData[month - 1][1]))
})
}
seriesData.push({
name: item.name,
data: dataValues
})
})
}
if (monthList && monthList.length > 0) {
monthList.forEach((month) => {
category.push(`${month}`)
})
}
return { category, seriesData }
},
// 切换显示的数据
handleShowData(tabValue) {
const data = this.realData[tabValue]
if (data) {
this.rawData = {
category: data.category,
seriesData: data.seriesData
}
}
},
// 切换Tab
handleChangeTab(value) {
this.selectTab = value
this.handleShowData(value)
},
// picker选择改变
handlePickerChange(e) {
const selectedIndex = e.detail.value
const selectedTab = this.tabList[selectedIndex]
this.handleChangeTab(selectedTab.value)
},
// 获取当前picker的索引
getCurrentPickerIndex() {
return this.tabList.findIndex(item => item.value === this.selectTab)
},
// 获取当前选中的Tab标签
getCurrentTabLabel() {
const currentTab = this.tabList.find(item => item.value === this.selectTab)
return currentTab ? currentTab.label : '营收金额'
},
// 获取Y轴标题
getYAxisTitle() {
if (this.selectTab === 1) {
return '营收金额(万元)'
} else if (this.selectTab === 2) {
return '客单量(万笔)'
} else if (this.selectTab === 3) {
return '客单均价(元)'
}
return ''
},
}
}
</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);
.business-case {
margin-top: 24rpx;
.section-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
padding: 0 8rpx;
box-sizing: border-box;
height: 40rpx;
.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;
position: relative;
.picker-container {
position: absolute;
top: 16rpx;
right: 16rpx;
z-index: 10;
background: rgba(255, 255, 255, 0.9);
border-radius: 8rpx;
padding: 8rpx 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
.picker-display {
display: flex;
align-items: center;
font-size: 28rpx;
color: @text-primary;
.picker-arrow {
font-size: 24rpx;
color: @text-secondary;
margin-left: 8rpx;
}
}
}
}
}
</style>