From 1c829f9177eab675b22be4d20ef2761ed1bbb423 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 15 九月 2026 16:15:48 +0800
Subject: [PATCH] refactor(layout): 调整布局样式并优化轮播卡片组件

---
 src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue |  215 +++++++++++++++++++++++++++++++++--------------------
 1 files changed, 135 insertions(+), 80 deletions(-)

diff --git a/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue b/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue
index a4824a2..9a36bcb 100644
--- a/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue
+++ b/src/views/reportAnalysis/dataDashboard/components/basic/center-bottom.vue
@@ -3,7 +3,10 @@
     <PanelHeader title="浜哄憳鍒嗗竷" />
     <div class="main-panel panel-item-customers">
       <div class="pie-chart-wrapper">
-        <div class="pie-background" :style="{ backgroundImage: `url(${roseBorderImg})` }"></div>
+        <div class="pie-center">
+          <span class="pie-center-value">{{ totalStaff }}</span>
+          <span class="pie-center-label">鍚堣(浜�)</span>
+        </div>
         <Echarts
           ref="echartsRef"
           :chartStyle="chartStyle"
@@ -12,8 +15,10 @@
           :tooltip="pieTooltip"
           :color="pieColors"
           :options="pieOptions"
-          style="height: 320px"
-        />
+          style="height: 100%"
+        >
+          <div v-if="loaded && !pieDatas.length" class="chart-empty">鏆傛棤鏁版嵁</div>
+        </Echarts>
       </div>
     </div>
   </div>
@@ -24,128 +29,150 @@
 import { deptStaffDistribution } from '@/api/viewIndex.js'
 import PanelHeader from '../PanelHeader.vue'
 import Echarts from '@/components/Echarts/echarts.vue'
-import roseBorderImg from '@/assets/BI/鐜懓鍥捐竟妗�.png'
+import { BI, baseChartOptions, withTooltip } from '../../theme.js'
 
-/**
- * @introduction 鎶婃暟缁勪腑key鍊肩浉鍚岀殑閭d竴椤规彁鍙栧嚭鏉ワ紝缁勬垚涓�涓璞�
- * @param {鍙傛暟绫诲瀷} array 浼犲叆鐨勬暟缁� [{a:"1",b:"2"},{a:"2",b:"3"}]
- * @param {鍙傛暟绫诲瀷} key  灞炴�у悕 a
- * @return {杩斿洖绫诲瀷璇存槑}
- */
-function array2obj(array, key) {
-  const resObj = {}
-  for (let i = 0; i < array.length; i++) {
-    resObj[array[i][key]] = array[i]
-  }
-  return resObj
-}
+const echartsRef = ref(null)
+const pieDatas = ref([])
+const loaded = ref(false)
+
+const pieColors = BI.series
+
+// 浜哄憳鎬绘暟
+const totalStaff = computed(() =>
+  pieDatas.value.reduce((sum, d) => sum + (Number(d.value) || 0), 0)
+)
 
 const chartStyle = {
   width: '100%',
   height: '100%',
 }
 
-const echartsRef = ref(null)
-const pieDatas = ref([])
-const pieColors = ['#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF', '#43e8fc', '#27EBE7']
+const pieObjData = computed(() => {
+  const obj = {}
+  pieDatas.value.forEach((d) => {
+    obj[d.name] = d
+  })
+  return obj
+})
 
-const pieObjData = computed(() => array2obj(pieDatas.value, 'name'))
-
+// 鍥句緥閰嶇疆锛堝彸渚х珫鎺掞級
 const pieLegend = computed(() => {
   const data = pieDatas.value.map((d, idx) => ({
     name: d.name,
     icon: 'circle',
     textStyle: {
-      fontSize: 18,
+      fontSize: 14,
       color: pieColors[idx % pieColors.length],
     },
   }))
 
   return {
+    show: data.length > 0,
     orient: 'vertical',
     top: 'center',
     left: '50%',
-    itemGap: 30,
-    data: data,
-    formatter: function (name) {
+    itemGap: 18,
+    itemWidth: 8,
+    itemHeight: 8,
+    data,
+    formatter(name) {
       const item = pieObjData.value[name]
       if (!item) return name
-      return `{title|${name}}{value|${item.value}}{unit|浜簘{percent|${item.rate}}{unit|%}`
+      const short = name.length > 6 ? `${name.slice(0, 6)}鈥 : name
+      return `{title|${short}}{value|${item.value}}{unit|浜簘`
     },
     textStyle: {
       rich: {
-        value: {
-          color: '#43e8fc',
-          fontSize: 18,
-          fontWeight: 600,
-          padding: [0, 10, 0, 30],
+        title: {
+          fontSize: 13,
+          color: BI.text,
+          width: 96,
+          overflow: 'truncate',
         },
-        unit: {
-          color: '#82baff',
+        value: {
+          color: BI.textStrong,
           fontSize: 14,
           fontWeight: 600,
-          padding: [0, 50, 0, 0],
+          padding: [0, 0, 0, 10],
         },
-        percent: {
-          color: '#43e8fc',
-          fontSize: 18,
-          fontWeight: 600,
-          padding: [0, 10, 0, 0],
-        },
-        title: {
-          fontSize: 18,
-          padding: [0, 0, 0, 0],
+        unit: {
+          color: BI.text,
+          fontSize: 12,
         },
       },
     },
   }
 })
 
-const pieTooltip = {
+// 鎻愮ず妗嗭細浜烘暟 + 鍗犳瘮
+const pieTooltip = withTooltip({
   trigger: 'item',
-  formatter: '{a} <br/>{b} : {c} ({d}%)',
-}
+  confine: true,
+  formatter(params) {
+    const d = params.data || {}
+    const val = Number(d.value || 0)
+    return `${params.marker}<b>${d.name || ''}</b>&nbsp;&nbsp;${val} 浜� 路 ${params.percent}%`
+  },
+})
 
+// 鍙屽眰鐜舰楗煎浘
 const pieSeries = computed(() => [
   {
     name: '浜哄憳鍒嗗竷',
     type: 'pie',
-    radius: '70%',
+    radius: ['48%', '68%'],
     center: ['20%', '50%'],
     itemStyle: {
-      borderColor: '#0a1c3a',
-      borderWidth:5,
+      borderColor: BI.sliceBorder,
+      borderWidth: 2,
+      borderRadius: 4,
     },
     label: {
-      show: false
+      show: false,
     },
-    minAngle: 15,
+    minAngle: 8,
     data: pieDatas.value,
     animationType: 'scale',
     animationEasing: 'elasticOut',
-    animationDelay: function () {
-      return Math.random() * 200
+  },
+  {
+    // 鍐呭湀杞ㄩ亾鐜�
+    type: 'pie',
+    radius: ['40%', '43%'],
+    center: ['20%', '50%'],
+    silent: true,
+    label: {
+      show: false,
     },
+    labelLine: {
+      show: false,
+    },
+    itemStyle: {
+      color: 'rgba(74, 108, 240, 0.22)',
+    },
+    data: [1],
   },
 ])
 
-const pieOptions = {
-  backgroundColor: 'transparent',
-  textStyle: { color: '#B8C8E0' },
-}
+const pieOptions = baseChartOptions
 
 const getDeptStaffDistribution = () => {
-  deptStaffDistribution().then(res => {
-    if (res.code === 200) {
-      pieDatas.value = res.data.items.map(item => ({
+  deptStaffDistribution()
+    .then((res) => {
+      const items = res.data?.items || []
+      pieDatas.value = items.map((item) => ({
         name: item.name,
-        value: parseInt(item.value),
-        rate: item.rate
+        value: Number(item.value) || 0,
+        rate: item.rate,
       }))
-    }
-  }).catch(err => {
-    console.error('鑾峰彇閮ㄩ棬浜哄憳鍒嗗竷鏁版嵁澶辫触:', err)
-  })
+    })
+    .catch((err) => {
+      console.error('鑾峰彇閮ㄩ棬浜哄憳鍒嗗竷鏁版嵁澶辫触:', err)
+      pieDatas.value = []
+    })
+    .finally(() => {
+      loaded.value = true
+    })
 }
 
 onMounted(() => {
@@ -160,32 +187,60 @@
   gap: 20px;
 }
 
+/* 330 = 涓爮鍓╀綑楂樺害锛屼繚璇佸乏涓彸涓夋爮搴曡竟瀵归綈 */
 .panel-item-customers {
-  border: 1px solid #1a58b0;
+  border: 1px solid var(--bi-panel-border);
+  background: var(--bi-panel-bg);
+  border-radius: 8px;
   padding: 18px;
   width: 100%;
-  height: 370px;
+  height: 330px;
 }
 
 .pie-chart-wrapper {
   position: relative;
   width: 100%;
-  height: 320px;
+  height: 276px;
   background: transparent;
 }
 
-
-.pie-background {
+.pie-center {
   position: absolute;
-  left: 50%;
+  left: 20%;
   top: 50%;
-  transform: translate(-113%, -50%);
-  width: 360px;
-  height: 360px;
-  background-size: contain;
-  background-position: center;
-  background-repeat: no-repeat;
-  z-index: 1;
+  transform: translate(-50%, -50%);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 4px;
+  pointer-events: none;
+  z-index: 2;
+}
+
+.pie-center-value {
+  font-weight: 600;
+  font-size: 22px;
+  color: var(--bi-text-strong);
+  font-variant-numeric: tabular-nums;
+}
+
+.pie-center-label {
+  font-size: 12px;
+  color: var(--bi-text);
+}
+
+.chart-empty {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 276px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: var(--bi-text);
+  font-size: 14px;
+  letter-spacing: 1px;
   pointer-events: none;
 }
 </style>

--
Gitblit v1.9.3