ylj20011123 8d08edf247 update
2025-06-12 17:33:07 +08:00

280 lines
8.2 KiB
Vue

<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue';
import './BrandDetail.less'
import * as echarts from 'echarts/core';
import { PieChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { handleGetBrandStructureAnalysis, handleGetBusinessTradeTree, handleGetCombineBrandList, handleGetFieldEnumTree } from '../../service';
import defaultImg from '../../../../assets/image/defaultImg.png'
import brandTotalIcon from '../../../../assets/image/brandTotalIcon.png'
// 注册组件
echarts.use([
PieChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
CanvasRenderer
]);
let myChart: echarts.ECharts;
// 自定义颜色列表
const colorList = ['#FF9500', '#0094FF', '#7D4CD2', '#00FFB7'];
// tab的数组
let tabList = ref<any>([])
// 选择的tab
let selectTab = ref<number>(1)
// 全部的品牌数据
let allBrandList = ref<any>([])
// 品牌列表数据
let brandListData = ref<any>([])
// 传入的数据
const props = defineProps<{
currentService?: any;
}>();
// 监听传入的选中服务区
watch(
() => props.currentService,
(newVal, oldVal) => {
handleGoMounted()
},
{ deep: true }
);
onMounted(async () => {
await handleGoMounted()
})
const handleGoMounted = async () => {
const res: any = await handleGetData()
const chartDom = document.getElementById('brandChartBox');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
legend: {
orient: 'vertical', // 图例纵向排列
left: '50%', // 距离右侧5%
top: 'center', // 垂直居中
itemWidth: 12, // 图例标记宽度
itemHeight: 12, // 图例标记高度
textStyle: {
color: '#fff', // 文字颜色
rich: {
// 可以在这里添加富文本样式
value: {
fontWeight: 'bold',
padding: [0, 0, 0, 5] // 文字间距
}
}
},
// 自定义图例内容
formatter: function (name: string) {
// 找到对应的数据项
const dataItem = res.pieData.find((item: any) => item.name === name);
// 返回自定义格式
return `${name} ${dataItem?.value}%`;
}
},
tooltip: { // 新增 tooltip 配置
trigger: 'item', // 触发类型:坐标轴触发
axisPointer: { // 坐标轴指示器配置
type: 'shadow' // 阴影指示器(适合柱状图)
},
formatter: function (params: any) { // 自定义提示框内容
return `
<div style="font-weight:bold">${params.name} ${params?.percent}% </div>
`;
}
},
series: [
{
name: 'Access From',
type: 'pie',
radius: ['0%', '100%'],
center: ['25%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
color: function (params: any) {
return colorList[params.dataIndex];
}
},
label: {
show: false
},
emphasis: false,
labelLine: {
show: false
},
data: res.pieData
}
]
};
myChart.setOption(option);
myChart.resize();
window.addEventListener('resize', resizeChart);
}
// 拿到数据
const handleGetData = async () => {
// 拿到枚举数据
const enumData: any = await handleGetFieldEnumTree({
FieldExplainField: "BRAND_TYPE",
sessionName: "BRAND_TYPE"
})
console.log('enumDataenumDataenumDataenumData', enumData);
let req: any = {
ProvinceCode: "530000"
}
const data = await handleGetBrandStructureAnalysis(req)
console.log('datadatadatadatadata', data);
let category: any = []
let pieData: any = []
if (data && data.length > 0) {
data.forEach((item: any) => {
category.push(item.name)
pieData.push({ name: item.name, value: Number(item.value) })
})
}
// let category: any = ["全国品牌", "地方连锁", "本地个体"]
// let pieData: any = [
// { name: "全国品牌", value: 33.3 },
// { name: "地方连锁", value: 33.3 },
// { name: "本地个体", value: 33.3 }
// ]
// let realData: any = []
// const req: any = {
// ProvinceCode: "530000"
// }
// const data = await handleGetBusinessTradeTree(req)
const listData = await handleGetBusinessTradeTree({
PROVINCE_CODE: "530000",
PageIndex: 1
// BRAND_STATE: 1,
// SERVERPART_IDS: props.currentService?.SERVERPART_ID || ""
})
console.log('listDatalistDatalistData', listData);
let tableList: any = []
if (listData && listData.length > 0) {
listData.forEach((item: any) => {
tableList.push({ label: item.AUTOSTATISTICS_NAME, value: item.AUTOSTATISTICS_ID })
})
}
tabList.value = tableList
await handleGetTableData(tableList[0].value)
let res: any = {
category: category,// x轴的内容
pieData: pieData,// y轴的数据
// realData: realData// 真实数据
}
return res
}
// 获得表单数据
const handleGetTableData = async (BRAND_INDUSTRY: number) => {
const req: any = {
PROVINCE_CODE: "530000",
BRAND_STATE: 1,
BRAND_INDUSTRY: BRAND_INDUSTRY
// SERVERPART_IDS:""
}
const data = await handleGetCombineBrandList(req)
console.log('tableDatasadasd', data);
brandListData.value = data.slice(0, 6)
}
// 切换tab
const handleChangeTab = async (value: number) => {
brandListData.value = []
selectTab.value = value
await handleGetTableData(tabList.value[value - 1].value)
}
const resizeChart = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
</script>
<template>
<div class="BrandDetailBox">
<div class="brandTypeBox">
<SmallTitle title="商户类别比例图" />
<div class="brandChartBox" id="brandChartBox">
</div>
</div>
<div class="brandList">
<div class="tabBox">
<div :class="selectTab === index + 1 ? 'tabItem selectTab' : 'tabItem'" v-for="(item, index) in tabList"
:key="index" @click="handleChangeTab(index + 1)">
{{ item.label }}
</div>
</div>
<div class="brandListBox">
<div class="brandItem" v-for="(item, index) in brandListData" :key="index"
:style="{ marginBottom: index + 1 === brandListData.length ? '0' : '' }">
<div class="brandLeft">
<img class="brandIcon" :src="item.BRAND_INTRO || defaultImg" />
</div>
<div class="brandRight">
<div class="brandRightTop">
<div class="brandRightTopLeft">{{ item.BRAND_NAME }}</div>
<div class="brandRightTopRight">
<img class="brandRightTopRightIcon" :src="brandTotalIcon" />
<div class="brandRightTopRightValue">{{ item.ServerpartList.length || 0 }}</div>
<div class="brandRightTopRightUnit"></div>
</div>
</div>
<div class="brandRightBottom">
<div class="brandRightBottomItem">{{ item.BRAND_TYPENAME }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>