From a5378ba9d7f0aac37092c43eecdf54782d714bc5 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 29 一月 2026 17:58:25 +0800
Subject: [PATCH] fix: 财务大屏接口联调90%

---
 src/views/reportAnalysis/financialAnalysis/components/center-top.vue |  140 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 119 insertions(+), 21 deletions(-)

diff --git a/src/views/reportAnalysis/financialAnalysis/components/center-top.vue b/src/views/reportAnalysis/financialAnalysis/components/center-top.vue
index d46a0ac..85f4928 100644
--- a/src/views/reportAnalysis/financialAnalysis/components/center-top.vue
+++ b/src/views/reportAnalysis/financialAnalysis/components/center-top.vue
@@ -10,7 +10,10 @@
         <div class="card-body">
           <div class="card-left">
             <div class="card-title">鏈堝害鏀跺叆</div>
-            <div class="card-amount">{{ income.amount }}</div>
+            <div class="card-amount">
+              <span>{{ formatAmountWanNumber(income.amount) }}</span>
+              <span v-if="isWanAmount(income.amount)" class="card-amount-unit">涓�</span>
+            </div>
           </div>
           <div class="card-right">
             <div class="metric-row">
@@ -22,7 +25,15 @@
             </div>
             <div class="metric-row">
               <span class="metric-label">閫炬湡鏁�</span>
-              <span class="metric-value metric-up">{{ income.overdueCount }}</span>
+              <span class="metric-value metric-up">
+                {{ formatAmountWanNumber(income.overdueCount) }}
+                <span
+                  v-if="isWanAmount(income.overdueCount)"
+                  class="metric-unit"
+                >
+                  涓�
+                </span>
+              </span>
             </div>
             <div class="metric-row">
               <span class="metric-label">閫炬湡鐜�</span>
@@ -43,16 +54,30 @@
         <div class="card-body">
           <div class="card-left">
             <div class="card-title">鏈堝害鏀嚭</div>
-            <div class="card-amount">{{ expense.amount }}</div>
+            <div class="card-amount">
+              <span>{{ formatAmountWanNumber(expense.amount) }}</span>
+              <span v-if="isWanAmount(expense.amount)" class="card-amount-unit">涓�</span>
+            </div>
           </div>
           <div class="card-right">
             <div class="metric-row">
               <span class="metric-label">浠樻鐜�</span>
-              <span class="metric-value metric-down">{{ expense.netProfit }}</span>
+              <span class="metric-value" :class="metricClass(expense.netProfit)">
+                {{ formatPercent(expense.netProfit.value) }}
+                <span class="arrow">{{ metricArrow(expense.netProfit) }}</span>
+              </span>
             </div>
             <div class="metric-row">
               <span class="metric-label">姣涘埄娑�</span>
-              <span class="metric-value metric-down">{{ expense.grossProfit }}</span>
+              <span class="metric-value metric-down">
+                {{ formatAmountWanNumber(expense.grossProfit) }}
+                <span
+                  v-if="isWanAmount(expense.grossProfit)"
+                  class="metric-unit"
+                >
+                  涓�
+                </span>
+              </span>
             </div>
             <div class="metric-row">
               <span class="metric-label">鍒╂鼎鐜�</span>
@@ -70,33 +95,93 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { onMounted, ref } from 'vue'
+import { getMonthlyIncome, getMonthlyExpenditure } from '@/api/viewIndex'
 
-// 鏆傛椂浣跨敤鏈湴绀轰緥鏁版嵁锛屽悗缁彲鎺ョ湡瀹炴帴鍙h鐩�
 const income = ref({
-  amount: 102,
-  repayRate: { value: 52, trend: 1 }, // 姝e悜 鈫�
-  overdueCount: 10092,
-  overdueRate: { value: 12, trend: 1 },
+  amount: 0,
+  repayRate: { value: 0, trend: 0 },
+  overdueCount: 0,
+  overdueRate: { value: 0, trend: 0 },
 })
 
 const expense = ref({
-  amount: 102,
-  netProfit: 291013,
-  grossProfit: 10092,
-  profitRate: { value: 12, trend: -1 }, // 璐熷悜 鈫�
+  amount: 0,
+  netProfit: { value: 0, trend: 0 },
+  grossProfit: 0,
+  profitRate: { value: 0, trend: 0 },
 })
+
+const fetchMonthlyIncome = async () => {
+  const res = await getMonthlyIncome()
+  const data = res?.data || {}
+
+  income.value.amount = data.monthlyIncome ?? 0
+  const collectionRate = Number(data.collectionRate ?? 0)
+  const overdueRate = Number(data.overdueRate ?? 0)
+  income.value.repayRate = {
+    value: collectionRate,
+    trend: collectionRate >= 0 ? 1 : -1,
+  }
+  income.value.overdueCount = data.overdueNum ?? 0
+  income.value.overdueRate = {
+    value: overdueRate,
+    trend: overdueRate >= 0 ? 1 : -1,
+  }
+}
+
+const fetchMonthlyExpenditure = async () => {
+  const res = await getMonthlyExpenditure()
+  const data = res?.data || {}
+
+  expense.value.amount = data.monthlyExpenditure ?? 0
+  const paymentRate = Number(data.paymentRate ?? 0)
+  expense.value.netProfit = {
+    value: paymentRate,
+    trend: paymentRate >= 0 ? 1 : -1,
+  }
+  expense.value.grossProfit = data.grossProfit ?? 0
+
+  const profitMarginRate = Number(data.profitMarginRate ?? 0)
+  expense.value.profitRate = {
+    value: profitMarginRate,
+    trend: profitMarginRate >= 0 ? 1 : -1,
+  }
+}
+
+const isWanAmount = (val) => {
+  const num = Number(val) || 0
+  return Math.abs(num) >= 10000
+}
+
+const formatAmountWanNumber = (val) => {
+  const num = Number(val) || 0
+  if (Math.abs(num) >= 10000) {
+    return (num / 10000).toFixed(2)
+  }
+  return num.toFixed(2)
+}
 
 const formatPercent = (val) => {
   const num = Number(val) || 0
-  return `${num.toFixed(2)}%`
+  // 鐧惧垎姣斿睍绀哄缁堢敤缁濆鍊硷紝灏忔暟淇濈暀涓や綅
+  return `${Math.abs(num).toFixed(2)}%`
 }
 
-const metricClass = (metric) =>
-  Number(metric.trend) >= 0 ? 'metric-up' : 'metric-down'
+const metricClass = (metric) => {
+  if (metric?.trend === undefined || metric?.trend === null) return 'metric-up'
+  return Number(metric.trend) >= 0 ? 'metric-up' : 'metric-down'
+}
 
-const metricArrow = (metric) =>
-  Number(metric.trend) >= 0 ? '鈫�' : '鈫�'
+const metricArrow = (metric) => {
+  if (metric?.trend === undefined || metric?.trend === null) return ''
+  return Number(metric.trend) >= 0 ? '鈫�' : '鈫�'
+}
+
+onMounted(() => {
+  fetchMonthlyIncome()
+  fetchMonthlyExpenditure()
+})
 </script>
 
 <style scoped>
@@ -110,7 +195,7 @@
   flex: 1;
   display: flex;
   align-items: center;
-  padding: 18px 24px;
+  padding: 18px 10px;
   background-image: url('@/assets/BI/border@2x.png');
   background-size: 100% 100%;
   background-position: center;
@@ -156,10 +241,18 @@
   font-size: 36px;
   line-height: 1.1;
   margin-top: 8px;
+  display: inline-flex;
+  align-items: baseline;
+  white-space: nowrap;
   background: linear-gradient(360deg, #008bfd 0%, #ffffff 100%);
   -webkit-background-clip: text;
   -webkit-text-fill-color: transparent;
   background-clip: text;
+}
+
+.card-amount-unit {
+  font-size: 20px;
+  margin-left: 4px;
 }
 
 .card-right {
@@ -193,6 +286,11 @@
   align-items: center;
 }
 
+.metric-unit {
+  font-size: 12px;
+  margin-left: 2px;
+}
+
 .metric-value .arrow {
   font-size: 13px;
   margin-left: 4px;

--
Gitblit v1.9.3