ylj20011123 d829c7bc93 update
2025-06-23 19:16:56 +08:00

545 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.

<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import SmallTitle from '../smallTitle/smallTitle.vue'
import RevenueYOYIcon from '../../../../assets/image/RevenueYOYIcon.png'
import './BusinessCase.less'
import moment from 'moment';
import { handleCodeGetRevenueCompare, handleGetRevenueTrend } from '../../service';
import * as echarts from 'echarts/core';
import { BarChart, LineChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, // 必须添加!否则 dataset 功能无效
TransformComponent // 如果使用 dataset.source 需要此组件
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import addIcon from '../../../../assets/image/addIcon.png'
import reduce from '../../../../assets/image/reduce.png'
// 注册组件
echarts.use([
LineChart,
BarChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, // 必须注册
TransformComponent, // 必须注册
CanvasRenderer
]);
let myChart: echarts.ECharts;
let myChartBottom: echarts.ECharts;
const tabList: any = [
{ label: "营收金额", value: 1 },
{ label: "客单量", value: 2 },
{ label: "客单均价", value: 3 },
]
let selectTab = ref<number>(1)
// 当前请求来的实际数据
let realData = ref<any>()
// 请求到的整个数据
let getAllData = ref<any>()
// 传入的数据
const props = defineProps<{
currentService?: any;
selectTab?: any
}>();
// 监听传入的选中服务区
watch(
() => props.currentService,
(newVal, oldVal) => {
handleGetData()
handleGetBottomData()
},
{ deep: true }
);
// 监听传入的选中服务区
watch(
() => props.selectTab,
(newVal, oldVal) => {
handleShowData(newVal)
},
{ deep: true }
);
onMounted(async () => {
// 用tab可以修改的方法
await handleGetData()
// await handleGetBottomData()
})
// 切换tab的内容
const handleChangeTab = async (value: number) => {
selectTab.value = value
handleShowData(value)
}
// 拿到数据的方法
const handleGetData = async () => {
const req: any = {
ProvinceCode: "530000",
StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
ServerpartId: props.currentService?.SERVERPART_ID || "",
}
let BusinessCase = sessionStorage.getItem('BusinessCase')
let data: any = []
if (BusinessCase) {
data = JSON.parse(BusinessCase)
} else {
data = await handleCodeGetRevenueCompare(req)
sessionStorage.setItem("BusinessCase", JSON.stringify(data))
}
// const data = await handleCodeGetRevenueCompare(req)
getAllData.value = data
// 营收金额
let category: any = ['product']
let monthList: number[] = []
let list = data.RevenueAmountList
if (list && list.length > 0) {
list.forEach((item: any, index: number) => {
category.push(item.name)
if (index === 0 && item.data && item.data.length > 0) {
item.data.forEach((subItem: any) => {
monthList.push(subItem[0])
})
}
})
}
let aiObj1: any = {}
// 营收
let res: any = []
if (monthList && monthList.length > 0) {
monthList.forEach((item: number) => {
let list: any = [`${item}`]
data.RevenueAmountList.forEach((subItem: any) => {
let newData: any = subItem.data
list.push(Number(((newData[item - 1][1]) / 10000).toFixed(2)))
})
aiObj1[`${item}`] = `工作日平均${list[1]}元,周末平均${list[2]}元,节假日平均${list[3]}`
res.push(list)
})
}
// 客单量
let res2: any = []
let aiObj2: any = {}
if (monthList && monthList.length > 0) {
monthList.forEach((item: number) => {
let list: any = [`${item}`]
data.TicketCountList.forEach((subItem: any) => {
let newData: any = subItem.data
list.push(Number(((newData[item - 1][1]) / 10000).toFixed(2)))
})
aiObj2[`${item}`] = `工作日平均${list[1]}元,周末平均${list[2]}元,节假日平均${list[3]}`
res2.push(list)
})
}
// 均价
let res3: any = []
let aiObj3: any = {}
if (monthList && monthList.length > 0) {
monthList.forEach((item: number) => {
let list: any = [`${item}`]
data.AvgTicketAmountList.forEach((subItem: any) => {
let newData: any = subItem.data
list.push(newData[item - 1][1])
})
aiObj3[`${item}`] = `工作日平均${list[1]}元,周末平均${list[2]}元,节假日平均${list[3]}`
res3.push(list)
})
}
let obj: any = {
1: [category, ...res],
2: [category, ...res2],
3: [category, ...res3],
}
realData.value = obj
let BusinessCaseAI = sessionStorage.getItem('BusinessCaseAI')
if (BusinessCaseAI) { } else {
let aiObj: any = {
"营收金额": aiObj1,
"客单量": aiObj2,
"客单均价": aiObj3,
}
sessionStorage.setItem("BusinessCaseAI", JSON.stringify(aiObj))
}
handleShowData(selectTab.value)
}
// 拿到底部的方法
const handleGetBottomData = async () => {
const req: any = {
ProvinceCode: "530000",
StatisticsDate: moment().format('YYYY'),
StatisticsType: 1,
ServerpartId: props.currentService?.SERVERPART_ID || "",
}
const yesReq: any = {
ProvinceCode: "530000",
StatisticsDate: moment().subtract(1, 'y').format('YYYY'),
StatisticsType: 1,
ServerpartId: props.currentService?.SERVERPART_ID || "",
}
const data = await handleGetRevenueTrend(req)
const yesData = await handleGetRevenueTrend(yesReq)
let category: string[] = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
let currentYear: number[] = []
let lastYear: number[] = []
if (data && data.length > 0) {
data.forEach((item: any) => {
currentYear.push(Number((Number(item.value) / 10000).toFixed(2)))
})
}
if (yesData && yesData.length > 0) {
yesData.forEach((item: any) => {
lastYear.push(Number((Number(item.value) / 10000).toFixed(2)))
})
}
await handleShowBottomData({
category: category,
currentYear: currentYear,
lastYear: lastYear,
})
}
// 切换显示的数据源 营收特征分析的
const handleShowData = async (value: number) => {
let data = realData.value[value]
const chartDom = document.getElementById('featureAnalysis');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
legend: {
top: 15,
right: 10,
textStyle: {
color: '#ffffff' // 设置图例文字为白色
}
},
tooltip: { trigger: 'axis' },
dataset: { source: data },
xAxis: {
type: 'category',
axisLabel: {
width: '80',
interval: 0,
color: '#fff',
formatter: '{value}' // 刻度值保持纯数字
},
axisLine: {
lineStyle: {
color: '#fff' // 设置 y 轴线颜色为白色(可选)
}
},
axisTick: {
show: false // 隐藏刻度小线条
}
},
yAxis: {
name: `${selectTab.value === 1 ? '营收金额(万元)' : selectTab.value === 2 ? '客单量(万笔)' : selectTab.value === 3 ? '客单均价(元)' : ''}`,
splitLine: { show: false }, // 隐藏网格线
axisLine: {
show: true, // 显示Y轴线
lineStyle: {
color: '#fff' // 轴线颜色
}
},
axisTick: {
show: false // 隐藏刻度线(短横线)
},
axisLabel: {
width: '80',
color: '#fff'
},
nameTextStyle: {
color: '#fff', // 名称颜色
padding: [0, 0, 0, 30] // 名称位置调整
}
},
series: [{
type: 'bar',
itemStyle: {
color: '#0094FF' // 第一根柱子的颜色
}
},
{
type: 'bar',
itemStyle: {
color: '#69BCFF' // 第一根柱子的颜色
}
},
{
type: 'bar',
itemStyle: {
color: '#6B7C8B' // 第一根柱子的颜色
}
}],
grid: {
left: '0', // 左侧间距
right: '0', // 右侧间距
bottom: '0', // 底部间距
top: '50', // 顶部间距
containLabel: true // 确保坐标轴标签在grid内
},
};
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
}
// 切换显示数据源 营收同比分析的
const handleShowBottomData = async (res: any) => {
const chartDom = document.getElementById('featureAnalysisBottom');
if (!chartDom) return;
myChartBottom = echarts.init(chartDom);
const option = {
legend: {
top: 0, // 距离容器底部距离
right: 0,
itemWidth: 20, // 图例标记的图形宽度
itemHeight: 10, // 图例标记的图形高度
textStyle: {
color: '#fff' // 图例文字颜色
}
},
xAxis: {
type: 'category',
data: res.category,
boundaryGap: true,
axisLabel: {
interval: 0,
lineStyle: {
color: '#fff' // 设置 y 轴线颜色为白色(可选)
}
},
axisLine: {
lineStyle: {
color: '#fff' // 设置 y 轴线颜色为白色(可选)
}
},
axisTick: {
show: false // 隐藏刻度小线条
}
},
yAxis: {
name: `${selectTab.value === 1 ? '营收金额(万元)' : selectTab.value === 2 ? '客单量(万笔)' : selectTab.value === 3 ? '客单均价(元)' : ''}`,
type: 'value',
splitLine: { show: false },
axisLine: {
show: true,
lineStyle: {
color: '#fff' // 设置 y 轴线颜色为白色(可选)
}
},
axisLabel: {
color: '#fff',
},
nameTextStyle: {
color: '#fff', // 名称颜色
padding: [0, 0, 0, 20] // 名称位置调整
}
},
grid: {
left: '10', // 增加左侧空间
right: '10', // 增加右侧空间
bottom: '0',
top: '30',
containLabel: true
},
series: [
{
name: '今年',
data: res.currentYear,
type: 'line',
lineStyle: {
width: 2,
color: '#0094FF'
},
itemStyle: {
color: '#0094FF'
},
},
{
name: '去年',
data: res.lastYear,
type: 'line',
lineStyle: {
width: 2,
color: '#00FFB7' // 改为橙色
},
itemStyle: {
color: '#00FFB7' // 改为橙色
},
}
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line' // 改为线条指示器
},
formatter: function (params: any) {
return `${params.map((item: any) => {
return `<div>
${item.seriesName}${item.value}万元
</div>`
}).join("")}`
}
}
};
myChartBottom.setOption(option);
window.addEventListener('resize', resizeChartBottom);
}
const resizeChart = () => {
myChart?.resize();
};
const resizeChartBottom = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
window.removeEventListener('resize', resizeChartBottom);
myChartBottom?.dispose();
});
</script>
<template>
<div class="BusinessCaseBox">
<SmallTitle title="营收特征">
<!-- <template #extra>
<div class="BusinessCaseTabBox">
<div :class="selectTab === item.value ? 'BusinessCaseItem selectBusinessCaseItem' : 'BusinessCaseItem'"
v-for="(item, index) in tabList" :key="index" @click="handleChangeTab(item.value)">
{{ item.label }}
</div>
</div>
</template> -->
</SmallTitle>
<!-- 营收同比 -->
<div class="BusinessCaseRevenueYOY" v-if="false">
<div class="BusinessCaseLeftItem">
<img class="BusinessIcon" :src="RevenueYOYIcon" />
</div>
<div class="BusinessCaseRightItem">
<div class="BusinessCaseRightItemTop">
<div class="rightItemTitle">营收同比</div>
<div class="rightItemUpdate">{{ moment().subtract(1, 'd').format('YYYY-MM-DD') }}</div>
</div>
<div class="BusinessCaseRightItemBottom">
<div class="BusinessCaseItemBottomLeft">
<div class="changeBox">
<img v-if="getAllData?.RevenueAmountYOYRate || getAllData?.TicketCountYOYRate || getAllData?.AvgTicketAmountRate"
class="changeIcon" :src="selectTab === 1 ? getAllData?.RevenueAmountYOYRate > 0 ? addIcon : reduce :
selectTab === 2 ? getAllData?.TicketCountYOYRate > 0 ? addIcon : reduce :
selectTab === 3 ? getAllData?.AvgTicketAmountRate > 0 ? addIcon : reduce : ''
" />
<div class="changeText" :style="{
color: selectTab === 1 ? getAllData?.RevenueAmountYOYRate > 0 ? '#00FF00' : '#D24343' :
selectTab === 2 ? getAllData?.TicketCountYOYRate > 0 ? '#00FF00' : '#D24343' :
selectTab === 3 ? getAllData?.AvgTicketAmountRate > 0 ? '#00FF00' : '#D24343' : ''
}">{{
selectTab === 1 ? getAllData?.RevenueAmountYOYRate || '-' :
selectTab === 2 ? getAllData?.TicketCountYOYRate || '-' :
selectTab === 3 ? getAllData?.AvgTicketAmountRate || '-' : ''
}}%</div>
<div class="compareTitle">(相比去年同日)</div>
</div>
</div>
<div class="BusinessCaseItemBottomRight">
<div class="BusinessCaseRevenueValue">{{ selectTab === 1 ?
getAllData?.RevenueAmount.toLocaleString() :
selectTab
=== 2 ?
getAllData?.TicketCount.toLocaleString() : selectTab === 3 ?
getAllData?.AvgTicketAmount.toLocaleString() : ''
}}</div>
<div class="BusinessCaseRevenueUnit">{{ selectTab === 2 ? '笔' : '元' }}</div>
</div>
</div>
<!-- <div class="rightItemLeft">
<div class="rightItemTitleBox">
<div class="rightItemTitle">营收同比</div>
<div class="rightItemUpdate">{{ moment().subtract(1, 'd').format('YYYY-MM-DD') }}</div>
</div>
<div class="rightItemBottom">
<div class="compareTitle">相比去年同日</div>
<div class="changeBox">
<img class="changeIcon" />
<div class="changeText"></div>
</div>
</div>
</div> -->
<!-- <div class="rightItemRight">
<div class="BusinessCaseRevenueValue"></div>
<div class="BusinessCaseRevenueUnit"></div>
</div> -->
</div>
</div>
<!-- 营收特征分析 -->
<div class="featureAnalysis">
<!-- <SmallTitle title="营收特征分析" /> -->
<div class="featureAnalysisBox" id="featureAnalysis"></div>
<!-- <SmallTitle title="营收同比分析" style="margin-top: 31px;" />
<div class="featureAnalysisBottom" id="featureAnalysisBottom"></div> -->
</div>
</div>
</template>