| | |
| | | /> |
| | | </div> |
| | | <!-- <CarouselCards :items="cardItems" :visible-count="3" /> --> |
| | | <div class="pie-chart-wrapper"> |
| | | <div class="pie-background"></div> |
| | | <div class="pie-chart-wrapper" ref="pieWrapperRef"> |
| | | <div class="pie-background" ref="pieBackgroundRef"></div> |
| | | <Echarts |
| | | ref="chart" |
| | | :chartStyle="chartStyle" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, computed } from 'vue' |
| | | import { ref, onMounted, onBeforeUnmount, computed } from 'vue' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | import PanelHeader from './PanelHeader.vue' |
| | | import ProductTypeSwitch from './ProductTypeSwitch.vue' |
| | | import { rawMaterialPurchaseAmountRatio } from '@/api/viewIndex.js' |
| | | import { expenseCompositionAnalysis } from '@/api/viewIndex.js' |
| | | import { useChartBackground } from '@/hooks/useChartBackground.js' |
| | | |
| | | const pieWrapperRef = ref(null) |
| | | const pieBackgroundRef = ref(null) |
| | | |
| | | /** |
| | | * @introduction 把数组中key值相同的那一项提取出来,组成一个对象 |
| | |
| | | const amountType = ref(1) |
| | | |
| | | const amountTypeOptions = [ |
| | | { label: 1, text: '支出' }, |
| | | { label: 2, text: '收入' }, |
| | | { label: 1, text: '产品' }, |
| | | { label: 2, text: '客户' }, |
| | | ] |
| | | |
| | | // 数据列表(来自接口) |
| | |
| | | formatter: function (name) { |
| | | const item = landObjData.value[name] |
| | | if (!item) return name |
| | | return `{title|${name}}{value|${item.value}}{unit|元}{percent|${item.rate}}{unit|%}` |
| | | const num = Number(item.value) |
| | | const isWan = num > 10000 |
| | | const displayValue = isWan ? (num / 10000).toFixed(2) : num |
| | | const displayUnit = isWan ? '万元' : '元' |
| | | return `{title|${name}}{value|${displayValue}}{unit|${displayUnit}}{percent|${item.rate}}{unit|%}` |
| | | }, |
| | | textStyle: { |
| | | rich: { |
| | |
| | | textStyle: { color: '#B8C8E0' }, |
| | | } |
| | | |
| | | // 使用封装的背景位置调整方法 |
| | | // 图表中心是 ['25%', '50%'],背景需要对齐到这个位置 |
| | | const { init: initBackground, cleanup: cleanupBackground } = useChartBackground({ |
| | | wrapperRef: pieWrapperRef, |
| | | backgroundRef: pieBackgroundRef, |
| | | left: '25%', // 图表中心 X 是 25% |
| | | top: '50%', // 图表中心 Y 是 50% |
| | | offsetX: '-51.5%', // X 轴偏移 |
| | | offsetY: '-50%', // Y 轴偏移 |
| | | watchData: dataList // 监听数据变化,自动调整位置 |
| | | }) |
| | | |
| | | const fetchData = () => { |
| | | // 目前接口只有支出构成占比,先忽略类型参数 |
| | | // 预留扩展:后续可根据 amountType 切不同接口 |
| | | rawMaterialPurchaseAmountRatio() |
| | | expenseCompositionAnalysis({ type: amountType.value }) |
| | | .then((res) => { |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | const items = res.data |
| | |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error('获取原材料采购金额占比失败:', err) |
| | | console.error('获取费用构成分析失败:', err) |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | onMounted(() => { |
| | | fetchData() |
| | | initBackground() |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | cleanupBackground() |
| | | }) |
| | | </script> |
| | | |
| | |
| | | |
| | | .pie-background { |
| | | position: absolute; |
| | | left: 25%; |
| | | top: 50%; |
| | | transform: translate(-51.5%, -50%); |
| | | width: 310px; |
| | | height: 310px; |
| | | background-image: url('@/assets/BI/玫瑰图边框.png'); |
| | |
| | | background-repeat: no-repeat; |
| | | z-index: 1; |
| | | pointer-events: none; |
| | | /* 位置由 JS 动态设置,默认居中 */ |
| | | left: 25%; |
| | | top: 50%; |
| | | transform: translate(-51.5%, -50%); |
| | | } |
| | | </style> |