From d54e45f8c324cb1dc3094a644697ae92210cd736 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期二, 27 一月 2026 17:31:09 +0800
Subject: [PATCH] feat: BI大屏接口对接

---
 src/views/reportAnalysis/dataDashboard/components/basic/left-bottom.vue   |   54 ++++--
 src/api/viewIndex.js                                                      |   53 ++++++
 src/views/reportAnalysis/dataDashboard/components/basic/right-top.vue     |   25 +-
 src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue |  138 +++++++++-------
 src/views/reportAnalysis/dataDashboard/components/basic/right-bottom.vue  |   26 ++
 src/views/reportAnalysis/dataDashboard/components/basic/center-top.vue    |   41 ++--
 src/views/reportAnalysis/dataDashboard/components/basic/left-top.vue      |  111 ++-----------
 7 files changed, 236 insertions(+), 212 deletions(-)

diff --git a/src/api/viewIndex.js b/src/api/viewIndex.js
index 9abd3cc..2acf915 100644
--- a/src/api/viewIndex.js
+++ b/src/api/viewIndex.js
@@ -57,9 +57,60 @@
 
 //鍦ㄥ埗鍝佸懆杞儏鍐�
 //home/workInProcessTurnover
-export const getWorkInProcessTurnover= ()=>{
+export const getWorkInProcessTurnover = () => {
     return request({
         url: '/home/workInProcessTurnover',
         method: 'get'
     })
+}
+
+// 瀹㈡埛钀ユ敹璐$尞鏁板�煎垎鏋�
+export const customerRevenueAnalysis = (params) => {
+    return request({
+        url: '/home/customerRevenueAnalysis',
+        method: 'get',
+        params
+    })
+}
+
+// 鍛樺伐-瀹㈡埛-渚涘簲鍟嗘�绘暟
+export const summaryStatistics = () => {
+    return request({
+        url: '/home/summaryStatistics',
+        method: 'get'
+    })
+}
+
+// 鍚勯儴闂ㄤ汉鍛樺垎甯�
+export const deptStaffDistribution = () => {
+    return request({
+        url: '/home/deptStaffDistribution',
+        method: 'get'
+    })
+}
+
+// 渚涘簲鍟嗛噰璐帓鍚�
+export const supplierPurchaseRanking = (query) => {
+    return request({
+        url: '/home/supplierPurchaseRanking',
+        method: 'get',
+        params: query
+    })
+}
+
+// 瀹㈡埛閲戦璐$尞鎺掑悕
+export const customerContributionRanking = (query) => {
+    return request({
+        url: '/home/customerContributionRanking',
+        method: 'get',
+        params: query
+    })
+}
+
+// 鍚勪骇鍝佸ぇ绫诲垎甯�
+export const productCategoryDistribution = () => {
+    return request({
+        url: '/home/productCategoryDistribution',
+        method: 'get'
+    })
 }
\ No newline at end of file
diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue b/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue
index 92e4fbc..72ba5ba 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue
@@ -3,6 +3,7 @@
     <PanelHeader title="浜哄憳鍒嗗竷" />
     <div class="main-panel panel-item-customers">
       <Echarts
+        ref="echartsRef"
         :chartStyle="chartStyle"
         :legend="pieLegend"
         :series="pieSeries"
@@ -16,18 +17,16 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
-import { getProgressStatistics } from '@/api/viewIndex.js'
+import { ref, onMounted, computed } from 'vue'
+import { deptStaffDistribution } from '@/api/viewIndex.js'
 import PanelHeader from '../PanelHeader.vue'
 import Echarts from '@/components/Echarts/echarts.vue'
 
 /**
  * @introduction 鎶婃暟缁勪腑key鍊肩浉鍚岀殑閭d竴椤规彁鍙栧嚭鏉ワ紝缁勬垚涓�涓璞�
- * @description 璇︾粏鎻忚堪
  * @param {鍙傛暟绫诲瀷} array 浼犲叆鐨勬暟缁� [{a:"1",b:"2"},{a:"2",b:"3"}]
  * @param {鍙傛暟绫诲瀷} key  灞炴�у悕 a
  * @return {杩斿洖绫诲瀷璇存槑}
- * @exception [杩濅緥绫诲瀷] [杩濅緥绫诲瀷璇存槑]
  */
 function array2obj(array, key) {
   const resObj = {}
@@ -42,83 +41,82 @@
   height: '100%',
 }
 
-// 楗煎浘鏁版嵁锛堢ず渚嬶級
-const pieDatas = [
-  { value: 335, name: '杩涘叆鍖哄煙', percent: '10' },
-  { value: 310, name: '鍖哄煙鍏ヤ镜', percent: '40' },
-  { value: 274, name: '浜哄憳鑱氶泦', percent: '30' },
-  { value: 235, name: '瓒婄晫渚︽祴', percent: '20' },
-]
+const echartsRef = ref(null)
+const pieDatas = ref([])
+const pieColors = ['#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF', '#43e8fc', '#27EBE7']
 
-const pieColors = ['#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF']
-const pieLegendData = pieDatas.map((d, idx) => ({
-  name: d.name,
-  icon: 'circle',
-  textStyle: {
-    fontSize: 18,
-    color: pieColors[idx],
-  },
-}))
-const pieObjData = array2obj(pieDatas, 'name')
+const pieObjData = computed(() => array2obj(pieDatas.value, 'name'))
 
-const pieLegend = {
-  orient: 'vertical',
-  top: 'center',
-  left: '50%',
-  itemGap: 30,
-  data: pieLegendData,
-  formatter: function (name) {
-    return `{title|${name}}{value|${pieObjData[name].value}}{unit|浜簘{percent|${pieObjData[name].percent}}{unit|%}`
-  },
-  textStyle: {
-    rich: {
-      value: {
-        color: '#43e8fc',
-        fontSize: 18,
-        fontWeight: 600,
-        padding: [0, 10, 0, 30],
-      },
-      unit: {
-        color: '#82baff',
-        fontSize: 14,
-        fontWeight: 600,
-        padding: [0, 50, 0, 0],
-      },
-      percent: {
-        color: '#43e8fc',
-        fontSize: 18,
-        fontWeight: 600,
-        padding: [0, 10, 0, 0],
-      },
-      title: {
-        fontSize: 18,
-        padding: [0, 0, 0, 0],
+const pieLegend = computed(() => {
+  const data = pieDatas.value.map((d, idx) => ({
+    name: d.name,
+    icon: 'circle',
+    textStyle: {
+      fontSize: 18,
+      color: pieColors[idx % pieColors.length],
+    },
+  }))
+
+  return {
+    orient: 'vertical',
+    top: 'center',
+    left: '50%',
+    itemGap: 30,
+    data: data,
+    formatter: function (name) {
+      const item = pieObjData.value[name]
+      if (!item) return name
+      return `{title|${name}}{value|${item.value}}{unit|浜簘{percent|${item.rate}}{unit|%}`
+    },
+    textStyle: {
+      rich: {
+        value: {
+          color: '#43e8fc',
+          fontSize: 18,
+          fontWeight: 600,
+          padding: [0, 10, 0, 30],
+        },
+        unit: {
+          color: '#82baff',
+          fontSize: 14,
+          fontWeight: 600,
+          padding: [0, 50, 0, 0],
+        },
+        percent: {
+          color: '#43e8fc',
+          fontSize: 18,
+          fontWeight: 600,
+          padding: [0, 10, 0, 0],
+        },
+        title: {
+          fontSize: 18,
+          padding: [0, 0, 0, 0],
+        },
       },
     },
-  },
-}
+  }
+})
 
 const pieTooltip = {
   trigger: 'item',
   formatter: '{a} <br/>{b} : {c} ({d}%)',
 }
 
-const pieSeries = ref([
+const pieSeries = computed(() => [
   {
-    name: '璁块棶鏉ユ簮',
+    name: '浜哄憳鍒嗗竷',
     type: 'pie',
     radius: '70%',
     center: ['20%', '50%'],
     itemStyle: {
-      // 缁欐瘡涓墖鍖哄姞鍒嗛殧缂濋殭锛岄鑹插彇娣辫壊鑳屾櫙
       borderColor: '#0a1c3a',
-      borderWidth: 4,
+      borderWidth: 2,
     },
     label: {
       show: false
     },
-    data: pieDatas,
-    roseType: 'radius',
+    minAngle: 15,
+    data: pieDatas.value,
     animationType: 'scale',
     animationEasing: 'elasticOut',
     animationDelay: function () {
@@ -131,6 +129,24 @@
   backgroundColor: 'transparent',
   textStyle: { color: '#B8C8E0' },
 }
+
+const getDeptStaffDistribution = () => {
+  deptStaffDistribution().then(res => {
+    if (res.code === 200) {
+      pieDatas.value = res.data.items.map(item => ({
+        name: item.name,
+        value: parseInt(item.value),
+        rate: item.rate
+      }))
+    }
+  }).catch(err => {
+    console.error('鑾峰彇閮ㄩ棬浜哄憳鍒嗗竷鏁版嵁澶辫触:', err)
+  })
+}
+
+onMounted(() => {
+  getDeptStaffDistribution()
+})
 </script>
 
 <style scoped>
diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/center-top.vue b/src/views/reportAnalysis/dataDashboard/components/basic/center-top.vue
index 40ac9da..1cbdaa1 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/center-top.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/center-top.vue
@@ -95,7 +95,7 @@
             <div class="todo-division">寰呭姙浜嬬敱锛歿{ item.approveReason }}</div>
               <div style="display: flex;justify-content: space-between;align-items: center;"
               >
-                <div class="todo-title">鐢宠绫诲瀷锛歿{ item.approveId }}</div>
+                <div class="todo-title">鐢宠绫诲瀷锛歿{ item.approveTypeName }}</div>
                 <div class="todo-division">鐢宠閮ㄩ棬锛歿{ item.approveDeptName }}</div>
                 <div class="todo-time">{{ item.approveTime }}</div>
               </div>
@@ -111,10 +111,7 @@
 
 <script setup>
 import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
-import { homeTodos } from '@/api/viewIndex.js'
-import { staffOnJobListPage } from '@/api/personnelManagement/employeeRecord.js'
-import { listCustomer } from '@/api/basicData/customerFile.js'
-import { listSupplier } from '@/api/basicData/supplierManageFile.js'
+import { homeTodos, summaryStatistics } from '@/api/viewIndex.js'
 import { getLedgerPage } from '@/api/equipmentManagement/ledger.js'
 import { getRepairPage } from '@/api/equipmentManagement/repair.js'
 import { getUpkeepPage } from '@/api/equipmentManagement/upkeep.js'
@@ -124,10 +121,10 @@
 const totalStaff = ref(0)
 const totalCustomers = ref(0)
 const totalSuppliers = ref(0)
-// 鍚屾瘮锛堝崰浣嶅�硷紝鍙帴鍏ョ湡瀹炴帴鍙o級
-const staffYoY = ref(-0.52) // 绀轰緥锛�-0.52%
-const customersYoY = ref(0.82) // 绀轰緥锛�0.82%
-const suppliersYoY = ref(0.1) // 绀轰緥锛�0.10%
+// 鍚屾瘮
+const staffYoY = ref(0)
+const customersYoY = ref(0)
+const suppliersYoY = ref(0)
 const equipmentNum = ref(0)
 const equipmentRepair = ref(0)
 const equipmentMaintain = ref(0)
@@ -146,18 +143,15 @@
 
 // 鑾峰彇鍛樺伐銆佸鎴枫�佷緵搴斿晢鏁伴噺
 const getNum = () => {
-  const params = {
-    pageNum: -1,
-    pageSize: -1,
-  }
-  staffOnJobListPage({ ...params, staffState: 1 }).then((res) => {
-    totalStaff.value = res.data.total
-  })
-  listCustomer(params).then((res) => {
-    totalCustomers.value = res.total
-  })
-  listSupplier(params).then((res) => {
-    totalSuppliers.value = res.data.total
+  summaryStatistics().then((res) => {
+    totalStaff.value = res.data.totalStaff
+    staffYoY.value = res.data.staffGrowthRate
+    totalCustomers.value = res.data.totalCustomer
+    customersYoY.value = res.data.customerGrowthRate
+    totalSuppliers.value = res.data.totalSupplier
+    suppliersYoY.value = res.data.supplierGrowthRate
+  }).catch(err => {
+    console.error('鑾峰彇鍩虹缁熻鏁版嵁澶辫触:', err)
   })
 }
 
@@ -348,6 +342,11 @@
   color: #d0e7ff;
 }
 
+.card-compare > span:first-child {
+  font-size: 13px;
+  opacity: 0.8;
+}
+
 .compare-value {
   font-weight: 600;
 }
diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/left-bottom.vue b/src/views/reportAnalysis/dataDashboard/components/basic/left-bottom.vue
index e4ebc30..520ffdf 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/left-bottom.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/left-bottom.vue
@@ -42,18 +42,16 @@
 import Echarts from '@/components/Echarts/echarts.vue'
 import PanelHeader from '../PanelHeader.vue'
 import DateTypeSwitch from '../DateTypeSwitch.vue'
-import { qualityStatistics } from '@/api/viewIndex.js'
+import { customerRevenueAnalysis } from '@/api/viewIndex.js'
 import { listCustomer } from '@/api/basicData/customerFile.js'
 
 const dateType = ref(1) // 1=鍛� 2=鏈� 3=瀛e害
 const customerValue = ref(null)
 const customerOptions = ref([])
 
-// 璐ㄦ缁熻瀵硅薄
-const qualityStatisticsObject = ref({
-  supplierNum: 0,
-  processNum: 0,
-  factoryNum: 0,
+// 钀ユ敹鍒嗘瀽鏁版嵁
+const revenueData = ref({
+  items: []
 })
 
 const chartStyle = {
@@ -130,25 +128,34 @@
   },
 ]
 
-// 璐ㄦ缁熻
-const qualityStatisticsInfo = () => {
-  qualityStatistics()
+// 鑾峰彇瀹㈡埛钀ユ敹鍒嗘瀽鏁版嵁
+const getCustomerRevenueAnalysis = () => {
+  if (customerOptions.value.length > 0 && !customerValue.value) {
+    // 榛樿閫変腑绗竴涓鎴�
+    customerValue.value = customerOptions.value[0].value
+  }
+
+  if (!customerValue.value) return
+
+  const params = {
+    customerId: customerValue.value,
+    type: dateType.value
+  }
+
+  customerRevenueAnalysis(params)
     .then((res) => {
-      // 鍒囨崲绛涢�夋潯浠舵椂锛屽厛娓呯┖鍐嶅~鍏咃紝閬垮厤閲嶅 push
       xAxis1.value[0].data = []
       barSeries1.value[0].data = []
 
-      res.data.item.forEach((item) => {
-        xAxis1.value[0].data.push(item.date)
-        // 杩欓噷鏆傜敤 supplierNum 浣滀负鏌辩姸鍥炬暟鍊硷紙鎺ュ彛杩斿洖閲屽綋鍓嶄篃鏈夎繖涓変釜瀛楁锛�
-        barSeries1.value[0].data.push(item.supplierNum)
+      const items = res.data?.items || []
+      items.forEach((item) => {
+        xAxis1.value[0].data.push(item.name)
+        barSeries1.value[0].data.push(item.value)
       })
-      qualityStatisticsObject.value.supplierNum = res.data.supplierNum
-      qualityStatisticsObject.value.processNum = res.data.processNum
-      qualityStatisticsObject.value.factoryNum = res.data.factoryNum
+      revenueData.value = res.data
     })
     .catch((error) => {
-      console.error('鑾峰彇璐ㄦ缁熻澶辫触:', error)
+      console.error('鑾峰彇瀹㈡埛钀ユ敹鍒嗘瀽澶辫触:', error)
     })
 }
 
@@ -161,6 +168,12 @@
       label: r.customerName || r.name || r.customer || '-',
       value: r.id ?? r.customerId ?? r.customerCode ?? r.customerName,
     }))
+    
+    // 鑾峰彇鍒伴�夐」鍚庯紝濡傛灉杩樻病閫変腑锛岄粯璁ら�変腑绗竴涓�
+    if (customerOptions.value.length > 0 && !customerValue.value) {
+      customerValue.value = customerOptions.value[0].value
+      getCustomerRevenueAnalysis()
+    }
   } catch (e) {
     // 鎺ュ彛寮傚父鏃剁粰涓�缁勬ā鎷熷鎴凤紝淇濊瘉UI鍙敤
     customerOptions.value = [
@@ -174,14 +187,11 @@
 }
 
 const handleFilterChange = () => {
-  // 鐩墠 qualityStatistics 鎺ュ彛鏈惡甯︾瓫閫夊弬鏁帮紝杩欓噷鍏堢粺涓�瑙﹀彂鍒锋柊锛岄伩鍏嶉噸澶嶆暟鎹�
-  // 鑻ュ悗绔悗缁敮鎸� customerId/type锛屽彲鍦� qualityStatistics() 澶勬敼涓轰紶鍙�
-  qualityStatisticsInfo()
+  getCustomerRevenueAnalysis()
 }
 
 onMounted(() => {
   fetchCustomerOptions()
-  qualityStatisticsInfo()
 })
 </script>
 
diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/left-top.vue b/src/views/reportAnalysis/dataDashboard/components/basic/left-top.vue
index 4f88f0b..7bd7307 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/left-top.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/left-top.vue
@@ -2,7 +2,7 @@
   <div>
     <PanelHeader title="浜у搧澶х被" />
     <div class="panel-item-customers">
-      <div style="height: 70%"> 
+      <div style="height: 100%"> 
         <Echarts
           ref="chart"
           :chartStyle="chartStyle"
@@ -25,21 +25,18 @@
 import { ref, onMounted } from 'vue'
 import Echarts from '@/components/Echarts/echarts.vue'
 import PanelHeader from '../PanelHeader.vue'
-import { getWorkInProcessTurnover } from '@/api/viewIndex.js'
-
-// 鍦ㄥ埗鍝佸懆杞粺璁″璞�
-const workInProcessStatistics = ref({
-  totalQuantity: 0,
-  avgTurnoverDays: 0,
-  turnoverEfficiency: 0,
-})
+import { productCategoryDistribution } from '@/api/viewIndex.js'
 
 // 鍦ㄥ埗鍝佸伐搴忔煴鐘跺浘閰嶇疆
 const workInProcessXAxis = ref([
   {
     type: 'category',
     axisTick: { show: false },
-    axisLabel: { color: '#B8C8E0' },
+    axisLabel: { 
+      color: '#B8C8E0',
+      interval: 0,
+      rotate: 25
+    },
     data: [],
   },
 ])
@@ -60,7 +57,7 @@
 
 const workInProcessBarSeries = ref([
   {
-    name: '鍦ㄥ埗鍝佹暟閲�',
+    name: '浜у搧鏁伴噺',
     type: 'bar',
     barWidth: 25,
     barGap: 0,
@@ -79,6 +76,7 @@
           { offset: 1, color: '#00A4ED' },
         ],
       },
+      borderRadius: [4, 4, 0, 0]
     },
     label: {
       show: true,
@@ -91,13 +89,13 @@
 
 const chartStyle = {
   width: '100%',
-  height: '115%',
+  height: '100%',
 }
 
 const grid = {
   left: '3%',
   right: '4%',
-  bottom: '3%',
+  bottom: '15%',
   containLabel: true,
 }
 
@@ -115,51 +113,22 @@
   },
 }
 
-// 鍦ㄥ埗鍝佸懆杞粺璁�
-const workInProcessTurnoverInfo = () => {
-  getWorkInProcessTurnover()
+// 鑾峰彇鍚勪骇鍝佸ぇ绫诲垎甯�
+const getProductCategoryDistribution = () => {
+  productCategoryDistribution()
     .then((res) => {
-      console.log('鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹�:', res)
-
-      if (!res || !res.data) {
-        console.warn('鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹负绌�')
-        return
-      }
-
-      // 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
-      workInProcessStatistics.value = {
-        totalQuantity: res.data.totalOrderCount || 0,
-        avgTurnoverDays: res.data.averageTurnoverDays || 0,
-        turnoverEfficiency: res.data.turnoverEfficiency || 0,
-      }
-
-      // 璁剧疆宸ュ簭鏌辩姸鍥炬暟鎹�
-      // X杞达細processDetails (宸ュ簭璇︽儏鏁扮粍)
-      // Y杞达細processQuantityDetails (宸ュ簭鏁伴噺璇︽儏鏁扮粍)
-      if (res.data.processDetails && Array.isArray(res.data.processDetails)) {
-        // 璁剧疆X杞存暟鎹紙宸ュ簭鍚嶇О锛�
-        workInProcessXAxis.value[0].data = res.data.processDetails
-      } else {
-        workInProcessXAxis.value[0].data = []
-      }
-
-      if (
-        res.data.processQuantityDetails &&
-        Array.isArray(res.data.processQuantityDetails)
-      ) {
-        // 璁剧疆Y杞存暟鎹紙鍦ㄥ埗鍝佹暟閲忥級
-        workInProcessBarSeries.value[0].data = res.data.processQuantityDetails
-      } else {
-        workInProcessBarSeries.value[0].data = []
+      if (res.code === 200 && res.data && res.data.items) {
+        workInProcessXAxis.value[0].data = res.data.items.map(item => item.name)
+        workInProcessBarSeries.value[0].data = res.data.items.map(item => parseInt(item.value))
       }
     })
     .catch((error) => {
-      console.error('鑾峰彇鍦ㄥ埗鍝佸懆杞粺璁″け璐�:', error)
+      console.error('鑾峰彇鍚勪骇鍝佸ぇ绫诲垎甯冨け璐�:', error)
     })
 }
 
 onMounted(() => {
-  workInProcessTurnoverInfo()
+  getProductCategoryDistribution()
 })
 </script>
 
@@ -169,47 +138,5 @@
   padding: 18px;
   width: 100%;
   height: 420px;
-}
-
-.quality-cards {
-  display: flex;
-  gap: 12px;
-  width: 100%;
-  height: 54px;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.quality-cardSec {
-  display: flex;
-}
-
-.quality-cardTitle {
-  font-weight: 400;
-  font-size: 14px;
-  color: #ffffff;
-  display: flex;
-  align-items: flex-start;
-  flex-direction: column;
-}
-
-.quality-card {
-  width: 80px;
-  height: 60px;
-  background-size: cover;
-  background-position: center;
-  background-repeat: no-repeat;
-}
-
-.quality-card.one {
-  background-image: url('@/assets/BI/yuancailiaoyijianicon@2x.png');
-}
-
-.quality-card.two {
-  background-image: url('@/assets/BI/guochengyijianicon@2x.png');
-}
-
-.quality-card.three {
-  background-image: url('@/assets/BI/chuchangyijianicon@2x.png');
 }
 </style>
diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/right-bottom.vue b/src/views/reportAnalysis/dataDashboard/components/basic/right-bottom.vue
index 3f18a50..bcd6ead 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/right-bottom.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/right-bottom.vue
@@ -26,6 +26,7 @@
 import Echarts from '@/components/Echarts/echarts.vue'
 import PanelHeader from '../PanelHeader.vue'
 import DateTypeSwitch from '../DateTypeSwitch.vue'
+import { customerContributionRanking } from '@/api/viewIndex.js'
 
 const chartStyle = {
   width: '100%',
@@ -49,7 +50,6 @@
 // 鍘熷鏁版嵁锛堢粺涓�鎴� { NAME, NUM }锛�
 const dataArr = ref([])
 
-// 浠呬繚鐣欓噾棰濇渶楂樼殑 5 鏉★紙骞舵寜浠庡皬鍒板ぇ灞曠ず锛岃瑙変笂鏈�楂樺湪鏈�涓嬫柟锛�
 const dataArray = computed(() => {
   const sortedAsc = [...dataArr.value].sort((a, b) => a.NUM - b.NUM)
   return sortedAsc.length > 5 ? sortedAsc.slice(-5) : sortedAsc
@@ -183,6 +183,7 @@
     z: 6,
     type: 'bar',
     barWidth: 25,
+    tooltip: { show: false },
     itemStyle: {
       color: 'rgba(255,255,255,.1)',
       barBorderRadius: [0, 20, 20, 0],
@@ -194,6 +195,7 @@
     type: 'bar',
     barWidth: 25,
     barGap: '-100%',
+    tooltip: { show: false },
     itemStyle: {
       color: {
         type: 'linear',
@@ -274,12 +276,30 @@
   dataArr.value = getMockListByType(type).map(normalizeItem)
 }
 
+const fetchCustomerRanking = () => {
+  customerContributionRanking({ type: dateType.value })
+    .then((res) => {
+      if (res.code === 200 && Array.isArray(res.data)) {
+        dataArr.value = res.data.map(item => ({
+          NAME: item.customerName,
+          NUM: item.totalAmount
+        }))
+      } else {
+        setMockData(dateType.value)
+      }
+    })
+    .catch((error) => {
+      console.error('鑾峰彇瀹㈡埛閲戦璐$尞鎺掑悕澶辫触:', error)
+      setMockData(dateType.value)
+    })
+}
+
 const handleDateTypeChange = () => {
-  setMockData(dateType.value)
+  fetchCustomerRanking()
 }
 
 onMounted(() => {
-  setMockData(dateType.value)
+  fetchCustomerRanking()
 })
 </script>
 
diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/right-top.vue b/src/views/reportAnalysis/dataDashboard/components/basic/right-top.vue
index 4c023ff..357a452 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/right-top.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/right-top.vue
@@ -25,7 +25,7 @@
 import Echarts from '@/components/Echarts/echarts.vue'
 import PanelHeader from '../PanelHeader.vue'
 import DateTypeSwitch from '../DateTypeSwitch.vue'
-import { statisticsReceivablePayable } from '@/api/viewIndex.js'
+import { supplierPurchaseRanking } from '@/api/viewIndex.js'
 
 const chartStyle = {
   width: '100%',
@@ -242,6 +242,7 @@
       z: 6,
       type: 'bar',
       barWidth: 25,
+      tooltip: { show: false },
       itemStyle: {
         color: 'rgba(255,255,255,.1)',
         barBorderRadius: [0, 20, 20, 0],
@@ -252,6 +253,7 @@
       type: 'bar',
       barWidth: 25,
       barGap: '-100%',
+      tooltip: { show: false },
       itemStyle: {
         color: {
           type: 'linear',
@@ -282,16 +284,15 @@
   ]
 })
 
-// 搴斾粯搴旀敹缁熻
-const statisticsReceivable = () => {
-  statisticsReceivablePayable({ type: radio1.value })
+// 渚涘簲鍟嗛噰璐帓鍚�
+const fetchSupplierRanking = () => {
+  supplierPurchaseRanking({ type: radio1.value })
     .then((res) => {
-      // 鍋囪 API 杩斿洖鐨勬暟鎹牸寮忎负鏁扮粍锛屽寘鍚� NAME 鍜� NUM 瀛楁
-      // 濡傛灉杩斿洖鏍煎紡涓嶅悓锛岄渶瑕佹牴鎹疄闄� API 璋冩暣
-      if (res.data && Array.isArray(res.data)) {
-        dataArr.value = res.data
-      } else if (res.data && res.data.list) {
-        dataArr.value = res.data.list
+      if (res.code === 200 && Array.isArray(res.data)) {
+        dataArr.value = res.data.map(item => ({
+          NAME: item.supplierName,
+          NUM: item.totalAmount
+        }))
       } else {
         // 濡傛灉娌℃湁鏁版嵁锛屼娇鐢ㄦā鎷熸暟鎹�
         dataArr.value = [
@@ -318,11 +319,11 @@
 
 // 澶勭悊鏃ユ湡绫诲瀷鍒囨崲
 const handleDateTypeChange = (value) => {
-  statisticsReceivable()
+  fetchSupplierRanking()
 }
 
 onMounted(() => {
-  statisticsReceivable()
+  fetchSupplierRanking()
 })
 </script>
 

--
Gitblit v1.9.3