From e1535c267711c7c8d560e8916437167bbcd3156b Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 02 二月 2026 17:54:31 +0800
Subject: [PATCH] feat: 进销质量类分析接口对接
---
src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue | 227 ++++++++++++++++++++------------------------------------
1 files changed, 83 insertions(+), 144 deletions(-)
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue b/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
index cd22d56..49621f3 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
@@ -1,43 +1,34 @@
<template>
<div>
- <PanelHeader title="浜у搧澶х被" />
+ <PanelHeader title="涓嶅悎鏍兼鍝佸鐞嗗垎鏋�" />
<div class="panel-item-customers">
<div class="pie-chart-wrapper" ref="pieWrapperRef">
<div class="pie-background" ref="pieBackgroundRef"></div>
- <Echarts
- ref="chart"
- :chartStyle="chartStyle"
- :legend="landLegend"
- :series="landSeries"
- :tooltip="landTooltip"
- :color="landColors"
- :options="pieOptions"
- style="height: 100%"
- class="land-chart"
- />
+ <Echarts ref="chart" :chartStyle="chartStyle" :legend="landLegend" :series="computedSeries"
+ :tooltip="landTooltip" :color="landColors" :options="pieOptions" style="height: 100%" class="land-chart" />
</div>
</div>
</div>
</template>
<script setup>
-import { ref, onMounted, onBeforeUnmount } from 'vue'
+import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import PanelHeader from './PanelHeader.vue'
-import { productCategoryDistribution } from '@/api/viewIndex.js'
+import { unqualifiedProductProcessingAnalysis } from '@/api/viewIndex.js'
import { useChartBackground } from '@/hooks/useChartBackground.js'
const pieWrapperRef = ref(null)
const pieBackgroundRef = ref(null)
const chart = ref(null)
-// 鏁版嵁鍒楄〃锛堟潵鑷帴鍙o級
+// 鏁版嵁鍒楄〃
const dataList = ref([])
-// 棰滆壊鍒楄〃
+// 棰滆壊鍒楄〃
const landColors = ['#26FFCB', '#24CBFF', '#35FBF4', '#2651FF', '#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF']
-// label 瀵屾枃鏈細涓烘瘡涓鑹茬敓鎴愪竴涓皬鍦嗙偣鏍峰紡锛堢‘淇濆湪 label 涓彲瑙侊級
+// label 瀵屾枃鏈牱寮�
const dotRich = landColors.reduce((acc, color, idx) => {
acc[`dot${idx}`] = {
width: 8,
@@ -49,163 +40,113 @@
return acc
}, {})
-// 鍥句緥閰嶇疆锛堝彸渚х珫鎺掞級
-const landLegend = {
+// 鍥句緥閰嶇疆
+const landLegend = ref({
show: false,
icon: 'circle',
data: [],
right: '8%',
top: '40%',
orient: 'vertical',
- itemGap: 14,
- itemWidth: 6,
- itemHeight: 6,
textStyle: {
- fontSize: 12,
+ color: '#fff',
rich: {
- unit: {
- color: '#fff',
- fontSize: 12,
- padding: [0, 10, 0, 0],
- },
- text: {
- width: 60,
- color: '#fff',
- fontSize: 12,
- },
- },
- },
- formatter: function (name) {
- const list = dataList.value || []
- const item = list.find((d) => d.name === name)
- if (!item) return name
- const val = Number(item.value || 0)
- const totalValue = list.reduce((sum, it) => sum + Number(it.value || 0), 0)
- const percent = totalValue ? ((val / totalValue) * 100).toFixed(2) : '0.00'
- return `{text|${name}}${val}{unit| 鍏》}${percent}{unit|%}`
- },
-}
+ unit: { color: '#fff', fontSize: 12, padding: [0, 10, 0, 0] },
+ text: { width: 60, color: '#fff', fontSize: 12 },
+ }
+ }
+})
-// 鎻愮ず妗�
+// 鎻愮ず妗嗛厤缃�
const landTooltip = {
- // triggerOn: 'hover',
- alwaysShowContent: true,
+ trigger: 'item',
+ alwaysShowContent: false,
position: function (pt) {
return [pt[0], 130]
},
formatter: function (params) {
- return `${params.name} (${params.value}绫�)`
+ // 纭繚 params.data 瀛樺湪
+ if (!params.data) return ''
+ const { name, value, rate } = params.data
+ return `${name}<br/>鏁伴噺锛�${value}涓�<br/>鍗犳瘮锛�${rate}%`
},
}
-// 鍙屽眰鐜舰楗煎浘
-const landSeries = ref([
- {
- name: '浜у搧澶х被',
- type: 'pie',
- radius: ['35%', '55%'],
- center: ['50%', '50%'],
- label: {
- show: true,
- position: 'outside',
- color: '#fff',
- fontSize: 12,
- lineHeight: 18,
- rich: {
- ...dotRich,
- parent: { fontSize: 14, fontWeight: 600, color: '#fff', lineHeight: 20, overflow: 'break' },
- child: { fontSize: 12, color: '#fff', lineHeight: 18 },
+// 浣跨敤璁$畻灞炴�у鐞� Series
+const computedSeries = computed(() => {
+ return [
+ {
+ name: '涓嶅悎鏍兼鍝佸鐞嗗垎鏋�',
+ type: 'pie',
+ radius: ['35%', '55%'],
+ center: ['50%', '50%'],
+ label: {
+ show: true,
+ position: 'outside',
+ color: '#fff',
+ rich: {
+ ...dotRich,
+ parent: { fontSize: 14, fontWeight: 600, color: '#fff', lineHeight: 20 },
+ child: { fontSize: 12, color: '#fff', lineHeight: 18 },
+ },
+ formatter: function (params) {
+ if (!params.data) return ''
+ const dotKey = `dot${params.dataIndex % landColors.length}`
+ return `{${dotKey}|} {parent|${params.data.name} (${params.data.value}涓�)}`
+ },
},
- formatter: function (params) {
- const children = params?.data?.children || []
- const parentName = params?.data?.name || ''
- const rawVal = params?.data?.value
- const parentValue = typeof rawVal === 'number' && !Number.isNaN(rawVal) ? rawVal : (Number(rawVal) || 0)
- const dotKey = `dot${(params?.dataIndex || 0) % landColors.length}`
- const dot = `{${dotKey}|} `
- const parentLine = `${dot}{parent|${parentName} (${parentValue}绫�)}`
- if (!children.length) return parentLine
- // 鐖剁骇鍏ㄩ儴鏄剧ず锛涘瓙绾ф渶澶� 5 涓紝瓒呭嚭鏄剧ず鐪佺暐鍙�
- const displayed = children.slice(0, 5).map((c) => `{child|${c.name}}`)
- if (children.length > 5) displayed.push('{child|鈥')
- return [parentLine, ...displayed].join('\n')
+ labelLine: {
+ show: true,
+ length: 20,
+ lineStyle: { color: '#B8C8E0' },
},
+ data: dataList.value,
},
- labelLine: {
- show: true,
- length: 20,
- length2: 20,
- lineStyle: {
- color: '#B8C8E0',
- },
+ {
+ // 鍐呭湀瑁呴グ
+ type: 'pie',
+ radius: ['35%', '40%'],
+ center: ['50%', '50%'],
+ silent: true,
+ label: { show: false },
+ itemStyle: { color: 'rgba(0, 127, 255, 0.25)' },
+ data: [1],
},
- itemStyle: {
- color: function (params) {
- return landColors[params.dataIndex % landColors.length]
- },
- },
- data: dataList.value,
- },
- {
- // 鍐呭湀
- type: 'pie',
- radius: ['35%', '40%'],
- center: ['50%', '50%'],
- silent: true,
- label: {
- show: false,
- },
- labelLine: {
- show: false,
- },
- itemStyle: {
- color: 'rgba(0, 127, 255, 0.25)',
- },
- data: [1],
- },
-])
+ ]
+})
-const chartStyle = {
- width: '100%',
- height: '126%',
-}
+const chartStyle = { width: '100%', height: '126%' }
+const pieOptions = { backgroundColor: 'transparent' }
-const pieOptions = {
- backgroundColor: 'transparent',
- textStyle: { color: '#B8C8E0' },
-}
-
-// 浣跨敤灏佽鐨勮儗鏅綅缃皟鏁存柟娉曪紝鍙嚜瀹氫箟鍋忕Щ鍊�
+// 鑳屾櫙澶勭悊閽╁瓙
const { adjustBackgroundPosition, init: initBackground, cleanup: cleanupBackground } = useChartBackground({
wrapperRef: pieWrapperRef,
backgroundRef: pieBackgroundRef,
- offsetX: '-51.5%', // X 杞村亸绉伙紝鍙姩鎬佽皟鏁�
- offsetY: '-39%', // Y 杞村亸绉伙紝鍙姩鎬佽皟鏁�
- watchData: dataList // 鐩戝惉鏁版嵁鍙樺寲锛岃嚜鍔ㄨ皟鏁翠綅缃�
+ offsetX: '-51.5%',
+ offsetY: '-39%',
+ watchData: dataList
})
const loadData = async () => {
try {
- const res = await productCategoryDistribution()
- const items = res?.data?.items || []
- dataList.value = items.map((it) => ({
- name: it.name,
- value: Number(it.value || 0),
- rate: it.rate,
- children: Array.isArray(it.children) ? it.children : [],
- }))
- landLegend.data = dataList.value.map((d) => d.name)
- landSeries.value[0].data = dataList.value
- // 鏁版嵁鍔犺浇瀹屾垚鍚庤皟鏁磋儗鏅綅缃�
- adjustBackgroundPosition()
+ const res = await unqualifiedProductProcessingAnalysis()
+ if (res && res.code === 200) {
+ dataList.value = (res.data || []).map((it) => ({
+ name: it.name,
+ value: Number(it.value || 0),
+ rate: it.rate,
+ }))
+ landLegend.value.data = dataList.value.map((d) => d.name)
+
+ // 鏁版嵁鏇存柊鍚庡井璋冭儗鏅�
+ setTimeout(() => {
+ adjustBackgroundPosition()
+ }, 100)
+ }
} catch (e) {
- console.error('鑾峰彇浜у搧澶х被鍒嗗竷澶辫触:', e)
- dataList.value = []
- landLegend.data = []
- landSeries.value[0].data = []
+ console.error('鑾峰彇鏁版嵁澶辫触:', e)
}
}
-
onMounted(() => {
loadData()
@@ -229,7 +170,6 @@
position: relative;
width: 100%;
height: 320px;
- background: transparent;
}
.pie-background {
@@ -242,9 +182,8 @@
background-repeat: no-repeat;
z-index: 1;
pointer-events: none;
- /* 榛樿灞呬腑锛屼細鍦� JS 涓姩鎬佽皟鏁� */
left: 50%;
top: 50%;
transform: translate(-51.5%, -39%);
}
-</style>
+</style>
\ No newline at end of file
--
Gitblit v1.9.3