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