From ea142cd8de3e3cafdaf92d99b5798bd9a5e7d762 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期五, 22 五月 2026 16:00:19 +0800
Subject: [PATCH] 财务报表页面开发及接口对接

---
 src/api/financialManagement/financialStatements.js          |   32 -
 src/views/financialManagement/financialStatements/index.vue | 1374 ++++++++++++++++++++------------------------------------
 2 files changed, 497 insertions(+), 909 deletions(-)

diff --git a/src/api/financialManagement/financialStatements.js b/src/api/financialManagement/financialStatements.js
index 537d36f..6c3b306 100644
--- a/src/api/financialManagement/financialStatements.js
+++ b/src/api/financialManagement/financialStatements.js
@@ -1,31 +1,13 @@
 import request from "@/utils/request";
 
-// 鏍规嵁鏃ユ湡鏌ヨ
-export const reportForms = (params) => {
-  console.log(params);
+/**
+ * 鑾峰彇璐㈠姟鎶ヨ〃鏈堝害鏄庣粏
+ * @param {Object} params { entryDateStart, entryDateEnd }
+ */
+export function accountStatementDetailsByMonth(params) {
   return request({
-    url: "/account/accountExpense/report/forms",
+    url: "/accounting/accountStatementDetailsByMonth",
     method: "get",
     params,
   });
-};
-
-// 鏌ヨ姣忔湀鏁版嵁-鏀跺叆
-export const reportIncome = (params) => {
-  console.log(params);
-  return request({
-    url: "/account/accountExpense/report/income",
-    method: "get",
-    params,
-  });
-};
-
-// 鏌ヨ姣忔湀鏁版嵁-鏀嚭
-export const reportExpense = (params) => {
-  console.log(params);
-  return request({
-    url: "/account/accountExpense/report/expense",
-    method: "get",
-    params,
-  });
-};
+}
diff --git a/src/views/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue
index 32520dc..5dbce9b 100644
--- a/src/views/financialManagement/financialStatements/index.vue
+++ b/src/views/financialManagement/financialStatements/index.vue
@@ -1,4 +1,4 @@
- <template>
+<template>
   <div style="padding: 20px;">
     <!-- 椤甸潰鏍囬鍜屾湀浠界瓫閫� -->
     <div class="w-full md:w-auto flex items-center gap-3"
@@ -24,125 +24,161 @@
     <main class="container mx-auto px-4 pb-10">
       <!-- 璐㈠姟鎸囨爣鍗$墖 -->
       <div class="stats-cards">
-        <!-- 鎬昏惀鏀� -->
         <div class="stat-card stat-card-blue">
-          <div class="stat-icon">
-            <img src="@/assets/icons/png/walletBlue@2x.png"
-                 alt="鎬昏惀鏀�" />
-          </div>
+          <div class="stat-icon"><img src="@/assets/icons/png/walletBlue@2x.png"
+                 alt="鎬昏惀鏀�" /></div>
           <div class="stat-content">
             <div class="stat-label">鎬昏惀鏀�</div>
-            <div class="stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }} 鍏�</div>
+            <div class="stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }}{{ Math.abs(pageInfo.totalIncome) < 10000 ? ' 鍏�' : '' }}</div>
           </div>
         </div>
-        <!-- 鎬绘敮鍑� -->
         <div class="stat-card stat-card-orange">
-          <div class="stat-icon">
-            <img src="@/assets/icons/png/walletOrange@2x.png"
-                 alt="鎬绘敮鍑�" />
-          </div>
+          <div class="stat-icon"><img src="@/assets/icons/png/walletOrange@2x.png"
+                 alt="鎬绘敮鍑�" /></div>
           <div class="stat-content">
             <div class="stat-label">鎬绘敮鍑�</div>
-            <div class="stat-value">{{ formatMoney(pageInfo.totalExpense || 0) }} 鍏�</div>
+            <div class="stat-value">{{ formatMoney(pageInfo.totalExpense || 0) }}{{ Math.abs(pageInfo.totalExpense) < 10000 ? ' 鍏�' : '' }}</div>
           </div>
         </div>
-        <!-- 鎬绘敹鍏ョ瑪鏁� -->
         <div class="stat-card stat-card-green">
-          <div class="stat-icon">
-            <img src="@/assets/icons/png/walletGreen@2x.png"
-                 alt="鎬绘敹鍏ョ瑪鏁�" />
-          </div>
+          <div class="stat-icon"><img src="@/assets/icons/png/walletGreen@2x.png"
+                 alt="搴旀敹璐︽" /></div>
           <div class="stat-content">
-            <div class="stat-label">鎬绘敹鍏ョ瑪鏁�</div>
-            <div class="stat-value">{{ pageInfo.incomeNumber || 0 }} 绗�</div>
+            <div class="stat-label">搴旀敹璐︽</div>
+            <div class="stat-value">{{ formatMoney(pageInfo.totalReceivable || 0) }}{{ Math.abs(pageInfo.totalReceivable) < 10000 ? ' 鍏�' : '' }}</div>
           </div>
         </div>
-        <!-- 鎬绘敮鍑虹瑪鏁� -->
         <div class="stat-card stat-card-red">
-          <div class="stat-icon">
-            <img src="@/assets/icons/png/walletRed@2x.png"
-                 alt="鎬绘敮鍑虹瑪鏁�" />
-          </div>
+          <div class="stat-icon"><img src="@/assets/icons/png/walletRed@2x.png"
+                 alt="搴斾粯璐︽" /></div>
           <div class="stat-content">
-            <div class="stat-label">鎬绘敮鍑虹瑪鏁�</div>
-            <div class="stat-value">{{ pageInfo.expenseNumber || 0 }} 绗�</div>
+            <div class="stat-label">搴斾粯璐︽</div>
+            <div class="stat-value">{{ formatMoney(pageInfo.totalPayable || 0) }}{{ Math.abs(pageInfo.totalPayable) < 10000 ? ' 鍏�' : '' }}</div>
           </div>
         </div>
-        <!-- 鍑�鏀跺叆 -->
         <div class="stat-card stat-card-yellow">
-          <div class="stat-icon">
-            <img src="@/assets/icons/png/walletYellow@2x.png"
-                 alt="鍑�鏀跺叆" />
-          </div>
+          <div class="stat-icon"><img src="@/assets/icons/png/walletYellow@2x.png"
+                 alt="鍑�鍒╂鼎" /></div>
           <div class="stat-content">
-            <div class="stat-label">鍑�鏀跺叆</div>
-            <div class="stat-value">{{ formatMoney(pageInfo.netRevenue || 0) }} 鍏�</div>
+            <div class="stat-label">鍑�鍒╂鼎</div>
+            <div class="stat-value">{{ formatMoney(pageInfo.netRevenue || 0) }}{{ Math.abs(pageInfo.netRevenue) < 10000 ? ' 鍏�' : '' }}</div>
           </div>
         </div>
       </div>
-      <!-- 涓棿鍥捐〃鍖哄煙 -->
+      <!-- 鍥捐〃鍖哄煙 -->
       <div class="charts-row">
-        <!-- 宸︿晶锛氭敹鍏ユ敮鍑哄垎鏋� -->
+        <!-- 1. 鏀舵敮鏋勬垚鍒嗘瀽 (鍙岀幆褰㈠浘 + 鍑�鍒╀腑蹇�) -->
         <el-card class="chart-card">
-          <h2 class="section-title">鏀跺叆鏀嚭鍒嗘瀽</h2>
-          <div class="pie-chart-container">
-            <Echarts :legend="pieLegendIncomeExpense"
-                     :chartStyle="chartStylePie"
-                     :series="pieSeriesIncomeExpense"
-                     :tooltip="pieTooltipIncomeExpense"
-                     style="height: 320px; width: 100%;">
-            </Echarts>
-            <div class="pie-stats">
-              <div class="bar-stat-item">
-                <span class="bar-stat-label">鏀跺叆鏁伴噺</span>
-                <span class="bar-stat-value">{{ pageInfo.incomeNumber || 0 }}</span>
+          <template #header>
+            <div class="card-header">
+              <span class="header-title">鏀舵敮鏋勬垚鍙婂噣鍒╁垎鏋�</span>
+              <el-tooltip content="宸︿晶涓烘敹鍏ユ瀯鎴愶紝鍙充晶涓烘敮鍑烘瀯鎴愶紝涓棿灞曠ず鐩堜簭鍑�棰�"
+                          placement="top">
+                <el-icon>
+                  <QuestionFilled />
+                </el-icon>
+              </el-tooltip>
+            </div>
+          </template>
+          <div class="financial-overview-container">
+            <!-- 鏀跺叆灞曠ず (宸︿晶) -->
+            <div style="width:60%">
+              <div class="overview-item income"
+                   style="margin-bottom: 20px;">
+                <div class="overview-box">
+                  <div class="icon-circle">
+                    <el-icon>
+                      <TrendCharts />
+                    </el-icon>
+                  </div>
+                  <div class="data-content">
+                    <div class="label">鏈湡鎬绘敹鍏�</div>
+                    <div class="value">{{ formatMoney(pageInfo.totalIncome) }}</div>
+                    <div class="unit">RMB{{ Math.abs(pageInfo.totalIncome) < 10000 ? ' / 鍏�' : '' }}</div>
+                  </div>
+                  <div class="bg-decoration">INCOME</div>
+                </div>
               </div>
-              <div class="bar-stat-item">
-                <span class="bar-stat-label">鏀嚭鏁伴噺</span>
-                <span class="bar-stat-value">{{ pageInfo.expenseNumber || 0 }}</span>
+              <div class="overview-item expense">
+                <div class="overview-box">
+                  <div class="icon-circle">
+                    <el-icon>
+                      <Sell />
+                    </el-icon>
+                  </div>
+                  <div class="data-content">
+                    <div class="label">鏈湡鎬绘敮鍑�</div>
+                    <div class="value">{{ formatMoney(pageInfo.totalExpense) }}</div>
+                    <div class="unit">RMB{{ Math.abs(pageInfo.totalExpense) < 10000 ? ' / 鍏�' : '' }}</div>
+                  </div>
+                  <div class="bg-decoration">EXPENSE</div>
+                </div>
               </div>
             </div>
+            <!-- 鍑�鍒╂鼎鏍稿績鎸囩ず (涓棿) -->
+            <div class="profit-indicator">
+              <div class="profit-gauge-wrapper">
+                <Echarts :chartStyle="chartStylePie"
+                         :series="profitGaugeSeries"
+                         :tooltip="gaugeTooltip"
+                         style="height: 200px; width: 100%; max-width: 200px;">
+                </Echarts>
+                <div class="profit-center-text">
+                  <div class="label">鍑�鍒╂鼎</div>
+                  <div class="value"
+                       :class="pageInfo.netRevenue >= 0 ? 'plus' : 'minus'">
+                    {{ pageInfo.netRevenue >= 0 ? '+' : '' }}{{ formatMoney(pageInfo.netRevenue) }}
+                  </div>
+                  <div class="rate">鍒╂鼎鐜�: {{ pageInfo.totalIncome > 0 ? ((pageInfo.netRevenue / pageInfo.totalIncome) * 100).toFixed(1) : 0 }}%</div>
+                </div>
+              </div>
+            </div>
+            <!-- 鏀嚭灞曠ず (鍙充晶) -->
           </div>
         </el-card>
-        <!-- 鍙充晶锛氳椤圭泩鍒╁垎鏋� -->
+        <!-- 2. 搴旀敹/搴斾粯瀵瑰啿鍒嗘瀽 (鏌辩姸鍥�) -->
         <el-card class="chart-card">
-          <h2 class="section-title">琛岄」鐩堝埄鍒嗘瀽</h2>
-          <div class="bar-chart-header">
-            <div class="bar-stat-item">
-              <span class="bar-stat-label">褰撳墠鎬讳釜鏁�</span>
-              <span class="bar-stat-value">{{ allBarTypes.value?.length || 0 }}</span>
+          <template #header>
+            <div class="card-header">
+              <span class="header-title">搴旀敹/搴斾粯姒傝</span>
+              <el-tooltip content="瀵规瘮褰撳墠鍚勬湀浠界殑搴旀敹璐︽涓庡簲浠樿处娆�"
+                          placement="top">
+                <el-icon>
+                  <QuestionFilled />
+                </el-icon>
+              </el-tooltip>
             </div>
-            <div class="bar-stat-item">
-              <span class="bar-stat-label">鏀嚭閲戦</span>
-              <span class="bar-stat-value">{{ formatMoney(pageInfo.totalExpense || 0) }}</span>
-            </div>
-            <div class="bar-stat-item">
-              <span class="bar-stat-label">鏀跺叆閲戦</span>
-              <span class="bar-stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }}</span>
-            </div>
-          </div>
-          <Echarts ref="barChart"
-                   :chartStyle="chartStyle"
+          </template>
+          <Echarts :chartStyle="chartStyle"
                    :grid="barGrid"
                    :legend="barLegend"
                    :series="barSeries"
                    :tooltip="barTooltip"
                    :xAxis="barXAxis"
                    :yAxis="barYAxis"
-                   style="height: 300px; width: 100%;">
+                   style="height: 270px; width: 100%;">
           </Echarts>
         </el-card>
       </div>
-      <!-- 搴曢儴锛氳惀鏀惰秼鍔垮垎鏋� -->
+      <!-- 3. 璐㈠姟缁煎悎瓒嬪娍鍒嗘瀽 (鎶樼嚎鍥�) -->
       <el-card class="trend-chart-card">
-        <h2 class="section-title">钀ユ敹瓒嬪娍鍒嗘瀽</h2>
-        <Echarts ref="trendChart"
-                 :chartStyle="chartStyle"
-                 :grid="grid"
+        <template #header>
+          <div class="card-header">
+            <span class="header-title">璐㈠姟缁╂晥缁煎悎瓒嬪娍</span>
+            <el-tooltip content="灞曠ず鏀跺叆銆佹敮鍑哄強鍑�鍒╂鼎鐨勬湀搴﹀彉鍖栬秼鍔�"
+                        placement="top">
+              <el-icon>
+                <QuestionFilled />
+              </el-icon>
+            </el-tooltip>
+          </div>
+        </template>
+        <Echarts :chartStyle="chartStyle"
+                 :grid="trendGrid"
                  :legend="trendLegend"
                  :series="trendSeries"
-                 :tooltip="tooltip"
-                 :xAxis="xAxis0"
+                 :tooltip="trendTooltip"
+                 :xAxis="trendXAxis"
                  :yAxis="trendYAxis"
                  style="height: 350px; width: 100%;">
         </Echarts>
@@ -160,883 +196,453 @@
     nextTick,
     getCurrentInstance,
   } from "vue";
-  import "element-plus/dist/index.css";
+  import { QuestionFilled, TrendCharts, Sell } from "@element-plus/icons-vue";
   import Echarts from "@/components/Echarts/echarts.vue";
-  import {
-    reportForms,
-    reportIncome,
-    reportExpense,
-  } from "@/api/financialManagement/financialStatements";
+  import { accountStatementDetailsByMonth } from "@/api/financialManagement/financialStatements";
   import dayjs from "dayjs";
 
-  // 鏃ユ湡鑼冨洿
-  const dateRange = ref(null);
   const { proxy } = getCurrentInstance();
-  const chartStyle = {
-    width: "100%",
-    height: "100%", // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-    position: "relative",
-  };
-  const grid = {
-    left: "3%",
-    right: "4%",
-    bottom: "3%",
-    containLabel: true,
-  };
-  const lineLegend = {
-    show: false,
-  };
-  // 鎶樼嚎鍥炬彁绀烘
-  const tooltip = reactive({
-    trigger: "axis",
-    axisPointer: {
-      type: "line",
-      lineStyle: { color: "#aaa" },
-    },
-    // 鑷畾涔夊唴瀹�
-    formatter: function (params) {
-      if (!params || !params.length) return "";
-      const axisLabel = params[0].axisValueLabel || params[0].axisValue || "";
-      const rows = params
-        .map(p => {
-          const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
-          return `${colorDot}${p.seriesName}: ${p.value}`;
-        })
-        .join("<br/>");
-      return `<div>${axisLabel}</div><div>${rows}</div>`;
-    },
-  });
-  const lineSeries0 = ref([]);
-  const lineSeries1 = ref([]);
-
-  // 鏍规嵁鏈堜唤鑼冨洿鐢熸垚 x 杞存暟鎹�
-  const generateMonthLabels = (startMonth, endMonth) => {
-    const labels = [];
-    let current = dayjs(startMonth);
-    const end = dayjs(endMonth);
-
-    while (current.isBefore(end) || current.isSame(end, "month")) {
-      labels.push(`${current.month() + 1}鏈坄);
-      current = current.add(1, "month");
-    }
-
-    return labels;
-  };
-
-  const xAxis0 = ref([
-    {
-      type: "category",
-      axisTick: { show: true, alignWithLabel: true },
-      data: [],
-    },
-  ]);
-  const xAxis1 = ref([
-    {
-      type: "category",
-      axisTick: { show: true, alignWithLabel: true },
-      data: [],
-    },
-  ]);
-  const yAxis0 = [
-    {
-      type: "value",
-      name: "鏀跺叆缁熻", // 宸︿晶y杞�
-      position: "left",
-      min: 0,
-      // 鍧愭爣杞村悕绉版牱寮�
-      nameTextStyle: {
-        color: "#000",
-        fontSize: 14,
-      },
-    },
-  ];
-
-  const yAxis1 = [
-    {
-      type: "value",
-      name: "鏀嚭缁熻", // 宸︿晶y杞�
-      position: "left",
-      min: 0,
-      // 鍧愭爣杞村悕绉版牱寮�
-      nameTextStyle: {
-        color: "#000",
-        fontSize: 14,
-      },
-    },
-  ];
-
-  const chartStylePie = {
-    width: "100%",
-    height: "100%", // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-  };
-  const pieColors = [
-    "#F04864",
-    "#FACC14",
-    "#8543E0",
-    "#1890FF",
-    "#13C2C2",
-    "#2FC25B",
-  ]; // 鍙牴鎹疄闄呰皟鏁�
-  const pieData0 = ref([]);
-  const pieData1 = ref([]);
-
-  const pieLegend0 = computed(() => ({
-    show: true,
-    top: "center",
-    left: "60%",
-    orient: "vertical",
-    icon: "circle",
-    data: (pieData0.value || [])
-      .filter(item => item && item.name)
-      .map(item => item.name),
-    formatter: function (name) {
-      if (!name) return "";
-      const item = pieData0.value.find(i => i && i.name === name);
-      if (!item) return name;
-      return `${name} | ${item.percent} ${item.amount}`;
-    },
-    textStyle: {
-      color: "#333",
-      fontSize: 14,
-      lineHeight: 26,
-    },
-  }));
-  const pieLegend1 = computed(() => ({
-    show: true,
-    top: "center",
-    left: "60%",
-    orient: "vertical",
-    icon: "circle",
-    data: (pieData1.value || [])
-      .filter(item => item && item.name)
-      .map(item => item.name),
-    formatter: function (name) {
-      if (!name) return "";
-      const item = pieData1.value.find(i => i && i.name === name);
-      if (!item) return name;
-      return `${name} | ${item.percent} ${item.amount}`;
-    },
-    textStyle: {
-      color: "#333",
-      fontSize: 14,
-      lineHeight: 26,
-    },
-  }));
-
-  const materialPieSeries0 = computed(() => [
-    {
-      type: "pie",
-      radius: ["50%", "65%"],
-      center: ["25%", "50%"],
-      avoidLabelOverlap: false,
-      itemStyle: {
-        borderColor: "#fff",
-        borderWidth: 2,
-      },
-      label: {
-        show: false,
-      },
-      data: (pieData0.value || []).filter(item => item && item.name),
-      color: pieColors,
-    },
-  ]);
-  const materialPieSeries1 = computed(() => [
-    {
-      type: "pie",
-      radius: ["50%", "65%"],
-      center: ["25%", "50%"],
-      avoidLabelOverlap: false,
-      itemStyle: {
-        borderColor: "#fff",
-        borderWidth: 2,
-      },
-      label: {
-        show: false,
-      },
-      data: (pieData1.value || []).filter(item => item && item.name),
-      color: pieColors,
-    },
-  ]);
-  const pieTooltip = reactive({
-    trigger: "item",
-    formatter: function (params) {
-      // 妫�鏌ユ暟鎹槸鍚﹀瓨鍦�
-      if (!params.data) return params.name;
-      // 鎷兼帴瀹屾暣鍐呭
-      return `
-            <div>
-              <div style="color:${params.color};font-size:16px;">鈼�</div>
-              <div>${params.name}</div>
-              <div>鍗犳瘮锛�${params.data.percent}</div>
-              <div>閲戦锛�${params.data.amount}</div>
-            </div>
-          `;
-    },
+  const dateRange = ref(null);
+  const pageInfo = reactive({
+    totalIncome: 0,
+    totalExpense: 0,
+    totalReceivable: 0,
+    totalPayable: 0,
+    netRevenue: 0,
   });
 
-  const pageInfo = ref({});
+  const chartStyle = { width: "100%", height: "100%", position: "relative" };
+  const chartStylePie = { width: "100%", height: "100%" };
 
-  // 鏍煎紡鍖栭噾棰�
-  const formatMoney = value => {
-    if (!value && value !== 0) return "0";
-    return Number(value).toLocaleString("zh-CN", {
-      minimumFractionDigits: 2,
-      maximumFractionDigits: 2,
-    });
-  };
+  const monthlyTrendList = ref([]);
+  const receivablePayableList = ref([]);
 
-  // 鏀跺叆鏀嚭鍒嗘瀽楗煎浘
-  const pieDataIncomeExpense = computed(() => {
-    const totalIncome = Number(pageInfo.value.totalIncome) || 0;
-    const totalExpense = Number(pageInfo.value.totalExpense) || 0;
-    const total = totalIncome + totalExpense;
-    if (total === 0) {
-      return [
-        { name: "鏀跺叆", value: 0, percent: "0%" },
-        { name: "鏀嚭", value: 0, percent: "0%" },
-      ];
-    }
-    const incomePercent = ((totalIncome / total) * 100).toFixed(0);
-    const expensePercent = ((totalExpense / total) * 100).toFixed(0);
+  // --- 1. 鏀舵敮鏋勬垚鍒嗘瀽 (绠�鍖栫増閫昏緫) ---
+  const gaugeTooltip = { show: false };
+
+  const profitGaugeSeries = computed(() => {
+    const rate =
+      pageInfo.totalIncome > 0
+        ? (pageInfo.netRevenue / pageInfo.totalIncome) * 100
+        : 0;
     return [
-      { name: "鏀跺叆", value: totalIncome, percent: `${incomePercent}%` },
-      { name: "鏀嚭", value: totalExpense, percent: `${expensePercent}%` },
-    ];
-  });
-
-  const pieLegendIncomeExpense = computed(() => ({
-    show: false,
-  }));
-
-  const pieTooltipIncomeExpense = reactive({
-    trigger: "item",
-    formatter: function (params) {
-      if (!params.data) return params.name;
-      return `${params.name}鍗犳瘮 ${params.percent}%`;
-    },
-  });
-
-  const pieSeriesIncomeExpense = computed(() => [
-    {
-      type: "pie",
-      radius: ["0%", "70%"],
-      center: ["50%", "50%"],
-      avoidLabelOverlap: true,
-      itemStyle: {
-        borderColor: "#fff",
-        borderWidth: 2,
-      },
-      label: {
-        show: true,
-        position: "outside",
-        formatter: function (params) {
-          return `${params.name}鍗犳瘮 ${params.percent}%`;
-        },
-        fontSize: 14,
-        color: "#333",
-      },
-      labelLine: {
-        show: true,
-        length: 15,
-        length2: 10,
-        lineStyle: {
-          color: "#333",
-        },
-      },
-      emphasis: {
-        label: {
+      {
+        type: "gauge",
+        startAngle: 210,
+        endAngle: -30,
+        min: 0,
+        max: 100,
+        splitNumber: 10,
+        radius: "100%",
+        progress: {
           show: true,
-          fontSize: 16,
-          fontWeight: "bold",
+          width: 14,
+          itemStyle: { color: pageInfo.netRevenue >= 0 ? "#10b981" : "#f43f5e" },
         },
+        pointer: { show: false },
+        axisLine: { lineStyle: { width: 14, color: [[1, "#f1f5f9"]] } },
+        axisTick: { show: false },
+        splitLine: { show: false },
+        axisLabel: { show: false },
+        anchor: { show: false },
+        title: { show: false },
+        detail: { show: false },
+        data: [{ value: Math.max(0, Math.min(100, rate)) }],
       },
-      data: pieDataIncomeExpense.value,
-      color: ["#1890FF", "#FACC14"],
+    ];
+  });
+
+  // --- 2. 搴旀敹/搴斾粯姒傝 (鏌辩姸鍥�) ---
+  const barGrid = { left: "3%", right: "4%", bottom: "3%", containLabel: true };
+  const barLegend = { top: "0", right: "center" };
+  const barXAxis = computed(() => [
+    {
+      type: "category",
+      data: receivablePayableList.value.map(item => item.month || ""),
+      axisTick: { alignWithLabel: true },
+    },
+  ]);
+  const barYAxis = [{ type: "value", name: "閲戦 (鍏�)" }];
+  const barTooltip = { trigger: "axis", axisPointer: { type: "shadow" } };
+  const barSeries = computed(() => [
+    {
+      name: "搴旀敹璐︽",
+      type: "bar",
+      barWidth: "30%",
+      data: receivablePayableList.value.map(item => item.receivable || 0),
+      itemStyle: { color: "#10b981" },
+    },
+    {
+      name: "搴斾粯璐︽",
+      type: "bar",
+      barWidth: "30%",
+      data: receivablePayableList.value.map(item => item.payable || 0),
+      itemStyle: { color: "#ef4444" },
     },
   ]);
 
-  // 琛岄」鐩堝埄鍒嗘瀽鏌辩姸鍥�
-  const barXAxis = computed(() => {
-    return [
-      {
-        type: "category",
-        data:
-          allBarTypes.value && allBarTypes.value.length > 0
-            ? allBarTypes.value
-            : ["椤圭洰1", "椤圭洰2", "椤圭洰3", "椤圭洰4", "椤圭洰5", "椤圭洰6", "椤圭洰7"],
-        axisTick: { show: true, alignWithLabel: true },
-      },
-    ];
-  });
-
-  const barYAxis = [
+  // --- 3. 璐㈠姟缁煎悎瓒嬪娍鍒嗘瀽 (鎶樼嚎鍥�) ---
+  const trendGrid = { left: "3%", right: "4%", bottom: "3%", containLabel: true };
+  const trendLegend = { top: "0", right: "center" };
+  const trendXAxis = computed(() => [
     {
-      type: "value",
-      name: "鍗曚綅: 鍏�",
-      position: "left",
-      min: 0,
-      nameTextStyle: {
-        color: "#000",
-        fontSize: 14,
-      },
+      type: "category",
+      boundaryGap: false,
+      data: monthlyTrendList.value.map(item => item.month || ""),
     },
-  ];
-
-  const barGrid = {
-    left: "3%",
-    right: "4%",
-    bottom: "3%",
-    containLabel: true,
-  };
-
-  const barLegend = {
-    show: true,
-    top: 10,
-    right: 10,
-  };
-
-  // 鑾峰彇鎵�鏈夌被鍨嬪悕绉�
-  const allBarTypes = computed(() => {
-    const incomeTypes = (lineSeries0.value || [])
-      .map(item => item.name || item.typeName)
-      .filter(Boolean);
-    const expenseTypes = (lineSeries1.value || [])
-      .map(item => item.name || item.typeName)
-      .filter(Boolean);
-    return [...new Set([...incomeTypes, ...expenseTypes])];
-  });
-
-  const barSeries = computed(() => {
-    if (allBarTypes.value.length === 0) {
-      return [
-        {
-          name: "鏀嚭",
-          type: "bar",
-          data: [],
-          itemStyle: { color: "#1890FF" },
-        },
-        {
-          name: "鏀跺叆",
-          type: "bar",
-          data: [],
-          itemStyle: { color: "#13C2C2" },
-        },
-      ];
-    }
-
-    // 璁$畻姣忎釜椤圭洰鐨勬�绘敹鍏ワ紙姹囨�绘墍鏈夋湀浠斤級
-    const incomeData = allBarTypes.value.map(typeName => {
-      const incomeItem = (lineSeries0.value || []).find(
-        item => (item.name || item.typeName) === typeName
-      );
-      if (incomeItem && incomeItem.data && Array.isArray(incomeItem.data)) {
-        return incomeItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
-      }
-      return 0;
-    });
-
-    // 璁$畻姣忎釜椤圭洰鐨勬�绘敮鍑猴紙姹囨�绘墍鏈夋湀浠斤級
-    const expenseData = allBarTypes.value.map(typeName => {
-      const expenseItem = (lineSeries1.value || []).find(
-        item => (item.name || item.typeName) === typeName
-      );
-      if (expenseItem && expenseItem.data && Array.isArray(expenseItem.data)) {
-        return expenseItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
-      }
-      return 0;
-    });
-
-    return [
-      {
-        name: "鏀嚭",
-        type: "bar",
-        data: expenseData,
-        itemStyle: { color: "#1890FF" },
-      },
-      {
-        name: "鏀跺叆",
-        type: "bar",
-        data: incomeData,
-        itemStyle: { color: "#13C2C2" },
-      },
-    ];
-  });
-
-  const barTooltip = reactive({
-    trigger: "axis",
-    axisPointer: {
-      type: "shadow",
-    },
-    formatter: function (params) {
-      if (!params || !params.length) return "";
-      const axisLabel = params[0].axisValueLabel || params[0].axisValue || "";
-      const rows = params
-        .map(p => {
-          const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
-          const value =
-            typeof p.value === "number" ? p.value.toFixed(2) : p.value;
-          return `${colorDot}${p.seriesName} ${value}`;
-        })
-        .join("<br/>");
-      return `<div>${axisLabel}</div><div>${rows}</div>`;
-    },
-  });
-
-  // 钀ユ敹瓒嬪娍鍒嗘瀽
-  const trendLegend = {
-    show: true,
-    top: 10,
-    right: 10,
-  };
-
-  const trendYAxis = [
+  ]);
+  const trendYAxis = [{ type: "value", name: "閲戦 (鍏�)" }];
+  const trendTooltip = { trigger: "axis" };
+  const trendSeries = computed(() => [
     {
-      type: "value",
-      name: "鍗曚綅: 鍏�",
-      position: "left",
-      min: 0,
-      nameTextStyle: {
-        color: "#000",
-        fontSize: 14,
-      },
+      name: "鎬昏惀鏀�",
+      type: "line",
+      smooth: true,
+      data: monthlyTrendList.value.map(item => item.income || 0),
+      itemStyle: { color: "#4f46e5" },
+      areaStyle: { opacity: 0.1 },
     },
-  ];
+    {
+      name: "鎬绘敮鍑�",
+      type: "line",
+      smooth: true,
+      data: monthlyTrendList.value.map(item => item.expense || 0),
+      itemStyle: { color: "#f97316" },
+    },
+    {
+      name: "鍑�鍒╂鼎",
+      type: "line",
+      smooth: true,
+      data: monthlyTrendList.value.map(item => item.profit || 0),
+      lineStyle: { width: 4, type: "dashed" },
+      itemStyle: { color: "#10b981" },
+    },
+  ]);
 
-  const trendSeries = computed(() => {
-    // 姹囨�绘墍鏈夋敮鍑虹被鍨嬬殑鏁版嵁
-    let expenseTrend = [];
-    if (lineSeries1.value.length > 0) {
-      const monthCount = Math.max(
-        ...lineSeries1.value.map(item => item.data?.length || 0)
-      );
-      expenseTrend = Array(monthCount).fill(0);
-      lineSeries1.value.forEach(item => {
-        if (item.data && Array.isArray(item.data)) {
-          item.data.forEach((val, index) => {
-            if (index < monthCount) {
-              expenseTrend[index] += Number(val) || 0;
-            }
-          });
-        }
-      });
-    }
-
-    // 姹囨�绘墍鏈夋敹鍏ョ被鍨嬬殑鏁版嵁
-    let incomeTrend = [];
-    if (lineSeries0.value.length > 0) {
-      const monthCount = Math.max(
-        ...lineSeries0.value.map(item => item.data?.length || 0)
-      );
-      incomeTrend = Array(monthCount).fill(0);
-      lineSeries0.value.forEach(item => {
-        if (item.data && Array.isArray(item.data)) {
-          item.data.forEach((val, index) => {
-            if (index < monthCount) {
-              incomeTrend[index] += Number(val) || 0;
-            }
-          });
-        }
-      });
-    }
-
-    return [
-      {
-        name: "鏀嚭",
-        type: "line",
-        data: expenseTrend,
-        itemStyle: { color: "#1890FF" },
-        smooth: true,
-      },
-      {
-        name: "鏀跺叆",
-        type: "line",
-        data: incomeTrend,
-        itemStyle: { color: "#13C2C2" },
-        smooth: true,
-      },
-    ];
-  });
-
-  // 鑾峰彇鏈�杩戝叚涓湀鐨勮寖鍥�
-  const getLastSixMonths = () => {
-    const endMonth = dayjs().format("YYYY-MM");
-    const startMonth = dayjs().subtract(5, "month").format("YYYY-MM");
-    return [startMonth, endMonth];
+  // --- 鍏敤閫昏緫 ---
+  const formatMoney = val => {
+    return val;
   };
+
+  const handleDateChange = val => {
+    if (val) getData();
+  };
+
+  const resetDateRange = () => {
+    dateRange.value = [
+      dayjs().subtract(5, "month").format("YYYY-MM"),
+      dayjs().format("YYYY-MM"),
+    ];
+    getData();
+  };
+
+  const disabledDate = time => dayjs(time).isAfter(dayjs(), "month");
 
   const getData = async () => {
-    if (
-      !dateRange.value ||
-      !Array.isArray(dateRange.value) ||
-      dateRange.value.length !== 2
-    ) {
-      return;
-    }
-    const startDateStr = dateRange.value[0];
-    const endDateStr = dateRange.value[1];
-    if (!startDateStr || !endDateStr) {
-      return;
-    }
+    if (!dateRange.value || dateRange.value.length !== 2) return;
 
-    // 楠岃瘉鏃ユ湡鏍煎紡骞惰浆鎹负瀹屾暣鏃ユ湡
-    const startDate = dayjs(startDateStr);
-    const endDate = dayjs(endDateStr);
-    if (!startDate.isValid() || !endDate.isValid()) {
-      console.error("鏃犳晥鐨勬棩鏈熸牸寮�");
-      return;
-    }
-
-    // 鏇存柊 x 杞存暟鎹�
-    const monthLabels = generateMonthLabels(startDateStr, endDateStr);
-    xAxis0.value[0].data = monthLabels;
-    xAxis1.value[0].data = monthLabels;
-
-    // 寮�濮嬫湀浠芥嫾鎺ョ涓�澶╋紝缁撴潫鏈堜唤鎷兼帴鏈�鍚庝竴澶�
-    const entryDateStart = startDate.startOf("month").format("YYYY-MM-DD");
-    const entryDateEnd = endDate.endOf("month").format("YYYY-MM-DD");
+    const params = {
+      entryDateStart: dayjs(dateRange.value[0])
+        .startOf("month")
+        .format("YYYY-MM-DD"),
+      entryDateEnd: dayjs(dateRange.value[1]).endOf("month").format("YYYY-MM-DD"),
+    };
 
     try {
-      // const {code,data} = await reportForms({entryDateStart, entryDateEnd});
-      // if(code === 200 && data) {
-      //   pageInfo.value = data || {};
-      //   // 瀹夊叏澶勭悊鏁版嵁锛岃繃婊ゆ帀 null 鎴� undefined
-      //   pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
-      //     name:item.typeName || '',
-      //     value:item.account || 0,
-      //     percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
-      //     amount:`楼${(item.account || 0).toFixed(2)}`
-      //   }))
-      //   pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
-      //     name:item.typeName || '',
-      //     value:item.account || 0,
-      //     percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
-      //     amount:`楼${(item.account || 0).toFixed(2)}`
-      //   }))
-      // }
+      const res = await accountStatementDetailsByMonth(params);
+      if (res.code === 200 && res.data) {
+        const data = res.data;
+        // 鏇存柊椤堕儴姹囨�诲崱鐗囨暟鎹�
+        pageInfo.totalIncome = data.totalIncome || 0;
+        pageInfo.totalExpense = data.totalExpense || 0;
+        pageInfo.totalReceivable = data.accountsReceivable || 0;
+        pageInfo.totalPayable = data.accountsPayable || 0;
+        pageInfo.netRevenue = data.netRevenue || 0;
+
+        // 鏇存柊鍥捐〃鏁版嵁
+        monthlyTrendList.value = data.monthlyTrendList || [];
+        receivablePayableList.value = data.receivablePayableList || [];
+      }
     } catch (error) {
-      console.error("鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�", error);
-    }
-    try {
-      // const { code, data } = await reportIncome({ entryDateStart, entryDateEnd });
-      // if (code == 200 && data && Array.isArray(data)) {
-      //   lineSeries0.value = data
-      //     .filter(item => item && item.typeName)
-      //     .map(item => ({
-      //       name: item.typeName || "",
-      //       type: "line",
-      //       data: (item.account || []).map(val => Number(val) || 0),
-      //     }));
-      // }
-    } catch (error) {
-      console.error("鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�", error);
-    }
-    try {
-      // const { code, data } = await reportExpense({
-      //   entryDateStart,
-      //   entryDateEnd,
-      // });
-      // if (code == 200 && data && Array.isArray(data)) {
-      //   lineSeries1.value = data
-      //     .filter(item => item && item.typeName)
-      //     .map(item => ({
-      //       name: item.typeName || "",
-      //       type: "line",
-      //       data: (item.account || []).map(val => Number(val) || 0),
-      //     }));
-      // }
-    } catch (error) {
-      console.error("鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�", error);
+      console.error("鑾峰彇璐㈠姟鎶ヨ〃鏁版嵁澶辫触锛�", error);
     }
   };
 
-  // 鍒濆鍖�
   onMounted(() => {
-    // 璁剧疆榛樿鍊间负鏈�杩戝叚涓湀
-    const defaultRange = getLastSixMonths();
-    dateRange.value = defaultRange;
-    // 浣跨敤 nextTick 纭繚缁勪欢瀹屽叏娓叉煋鍚庡啀璋冪敤
-    nextTick(() => {
-      getData();
-    });
+    resetDateRange();
   });
-
-  // 闄愬埗鏈堜唤閫夋嫨鑼冨洿锛堟渶澶�12涓湀锛�
-  const disabledDate = time => {
-    // 濡傛灉娌℃湁閫夋嫨寮�濮嬫湀浠斤紝涓嶇鐢ㄤ换浣曟棩鏈�
-    if (
-      !dateRange.value ||
-      !Array.isArray(dateRange.value) ||
-      !dateRange.value[0]
-    ) {
-      return false;
-    }
-
-    const startMonth = dayjs(dateRange.value[0]);
-    const currentMonth = dayjs(time);
-
-    // 濡傛灉褰撳墠鏈堜唤鍦ㄥ紑濮嬫湀浠戒箣鍓嶏紝绂佺敤
-    if (currentMonth.isBefore(startMonth, "month")) {
-      return true;
-    }
-
-    // 璁$畻鏈�澶у厑璁哥殑鏈堜唤锛堝紑濮嬫湀浠� + 11涓湀 = 12涓湀锛�
-    const maxMonth = startMonth.add(11, "month");
-
-    // 绂佺敤瓒呰繃12涓湀鐨勬湀浠�
-    return currentMonth.isAfter(maxMonth, "month");
-  };
-
-  // 澶勭悊鏈堜唤鑼冨洿鍙樺寲
-  const handleDateChange = newRange => {
-    if (!newRange || !Array.isArray(newRange) || newRange.length !== 2) {
-      return;
-    }
-
-    // 楠岃瘉鏈堜唤鑼冨洿涓嶈秴杩�12涓湀
-    const startDate = dayjs(newRange[0]);
-    const endDate = dayjs(newRange[1]);
-    const monthDiff = endDate.diff(startDate, "month");
-
-    if (monthDiff > 11) {
-      proxy.$modal.msgWarning("鏈�澶氬彧鑳介�夋嫨12涓湀浠�");
-      // 鑷姩璋冩暣涓�12涓湀
-      const adjustedEnd = startDate.add(11, "month").format("YYYY-MM");
-      dateRange.value = [newRange[0], adjustedEnd];
-      getData();
-      return;
-    }
-
-    dateRange.value = newRange;
-    getData();
-  };
-
-  // 閲嶇疆鏈堜唤鑼冨洿
-  const resetDateRange = () => {
-    // 閲嶇疆涓烘渶杩戝叚涓湀
-    dateRange.value = getLastSixMonths();
-    getData();
-  };
 </script>
 
 <style scoped lang="scss">
-  /* 鍩虹鏍峰紡琛ュ厖 */
-  :root {
-    --el-color-primary: #4f46e5;
-  }
-
-  /* 缁熻鍗$墖鏍峰紡 */
   .stats-cards {
     display: grid;
-    grid-template-columns: repeat(5, 1fr);
+    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
     gap: 20px;
-    margin-bottom: 20px;
+    margin-bottom: 24px;
   }
 
   .stat-card {
     background: #fff;
-    border: 1px solid #e4e7ed;
-    border-radius: 8px;
-    padding: 20px;
+    border: 1px solid #edf2f7;
+    border-radius: 12px;
+    padding: 24px;
     display: flex;
     align-items: center;
-    gap: 15px;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-    transition: all 0.3s;
+    gap: 16px;
+    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
+    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
 
     &:hover {
-      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-      transform: translateY(-2px);
+      box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
+      transform: translateY(-4px);
     }
 
     .stat-icon {
-      width: 48px;
-      height: 48px;
-      flex-shrink: 0;
-
+      width: 56px;
+      height: 56px;
+      background: #f7fafc;
+      border-radius: 12px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
       img {
-        width: 100%;
-        height: 100%;
-        object-fit: contain;
+        width: 32px;
+        height: 32px;
       }
     }
 
     .stat-content {
-      flex: 1;
-      display: flex;
-      flex-direction: column;
-      gap: 8px;
-    }
-
-    .stat-label {
-      font-size: 14px;
-      color: #666;
-      line-height: 1.2;
-    }
-
-    .stat-value {
-      font-size: 24px;
-      font-weight: 600;
-      color: #333;
-      line-height: 1.2;
-    }
-
-    .stat-trend {
-      font-size: 12px;
-      line-height: 1.2;
-
-      &.trend-up {
-        color: #f56c6c;
+      .stat-label {
+        font-size: 14px;
+        color: #718096;
+        margin-bottom: 4px;
       }
-
-      &.trend-down {
-        color: #67c23a;
+      .stat-value {
+        font-size: 20px;
+        font-weight: 700;
+        color: #2d3748;
       }
     }
   }
 
-  /* 鍥捐〃琛屽竷灞� */
   .charts-row {
     display: grid;
-    grid-template-columns: 1fr 1fr;
-    gap: 20px;
-    margin-bottom: 20px;
+    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
+    gap: 24px;
+    margin-bottom: 24px;
   }
 
-  .chart-card {
-    border: 1px solid #e4e7ed;
-    border-radius: 8px;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-
-    :deep(.el-card__body) {
-      padding: 20px !important;
-    }
-  }
-
-  .trend-chart-card {
-    border: 1px solid #e4e7ed;
-    border-radius: 8px;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-
-    :deep(.el-card__body) {
-      padding: 20px !important;
-    }
-  }
-
-  /* 楗煎浘瀹瑰櫒 */
-  .pie-chart-container {
-    position: relative;
-
-    .pie-stats {
-      display: flex;
-      justify-content: space-between;
-      gap: 20px;
-      margin-top: 20px;
-
-      .bar-stat-item {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        gap: 8px;
-        padding: 15px;
-        background: #f5f7fa;
-        border-radius: 6px;
-        flex: 1;
-
-        .bar-stat-label {
-          font-size: 14px;
-          color: #666;
-        }
-
-        .bar-stat-value {
-          font-size: 18px;
-          font-weight: 600;
-          color: #333;
-        }
-      }
-    }
-  }
-
-  /* 鏌辩姸鍥惧ご閮ㄧ粺璁� */
-  .bar-chart-header {
-    display: flex;
-    justify-content: space-between;
-    gap: 20px;
-    margin-bottom: 20px;
-
-    .bar-stat-item {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      gap: 8px;
-      padding: 15px;
-      background: #f5f7fa;
-      border-radius: 6px;
-      flex: 1;
-
-      .bar-stat-label {
-        font-size: 14px;
-        color: #666;
-      }
-
-      .bar-stat-value {
-        font-size: 18px;
-        font-weight: 600;
-        color: #333;
-      }
-    }
-  }
-
-  /* 鏍囬鏍峰紡 */
-  .section-title {
-    position: relative;
-    font-size: 18px;
-    color: #333;
-    padding-left: 12px;
-    margin-bottom: 20px;
-    font-weight: 700;
-
-    &::before {
-      position: absolute;
-      left: 0;
-      top: 2px;
-      content: "";
-      width: 4px;
-      height: 18px;
-      background-color: #002fa7;
-      border-radius: 2px;
-    }
-  }
-
-  /* 鍝嶅簲寮忚璁� */
-  @media (max-width: 1400px) {
-    .stats-cards {
-      grid-template-columns: repeat(3, 1fr);
-    }
-  }
-
-  @media (max-width: 1024px) {
-    .stats-cards {
+  @media (min-width: 1200px) {
+    .charts-row {
       grid-template-columns: repeat(2, 1fr);
     }
+  }
 
-    .charts-row {
-      grid-template-columns: 1fr;
+  .chart-card,
+  .trend-chart-card {
+    border-radius: 16px;
+    border: none;
+    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
+
+    .card-header {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      .header-title {
+        font-size: 16px;
+        font-weight: 600;
+        color: #1a202c;
+      }
+      .el-icon {
+        color: #a0aec0;
+        cursor: help;
+      }
     }
   }
 
-  @media (max-width: 640px) {
-    .stats-cards {
-      grid-template-columns: 1fr;
+  .financial-overview-container {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    flex-wrap: nowrap;
+    gap: 10px;
+    padding: 20px 0;
+    width: 100%;
+    overflow: hidden;
+
+    .overview-item {
+      flex: 1;
+      min-width: 0; // 鍏佽鍦� flex 瀹瑰櫒涓缉鍐欙紝闃叉鍐呭鎾戝紑
+      display: flex;
+      justify-content: center;
+
+      .overview-box {
+        position: relative;
+        width: 100%;
+        max-width: 320px;
+        height: 110px;
+        background: #f8fafc;
+        border-radius: 12px;
+        padding: 12px 16px;
+        display: flex;
+        align-items: center;
+        gap: 12px;
+        overflow: hidden;
+        transition: all 0.3s ease;
+
+        &:hover {
+          transform: translateY(-5px);
+          box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
+        }
+
+        .icon-circle {
+          flex-shrink: 0;
+          width: 42px;
+          height: 42px;
+          border-radius: 10px;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          font-size: 20px;
+          z-index: 2;
+        }
+
+        .data-content {
+          z-index: 2;
+          min-width: 0;
+          .label {
+            font-size: 13px;
+            color: #718096;
+            margin-bottom: 2px;
+            font-weight: 500;
+            white-space: nowrap;
+          }
+          .value {
+            font-size: 18px;
+            font-weight: 800;
+            color: #1a202c;
+            line-height: 1.2;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+          .unit {
+            font-size: 11px;
+            color: #a0aec0;
+          }
+        }
+
+        .bg-decoration {
+          position: absolute;
+          right: -5px;
+          bottom: -5px;
+          font-size: 32px;
+          font-weight: 950;
+          color: rgba(0, 0, 0, 0.03);
+          font-style: italic;
+          user-select: none;
+          z-index: 1;
+        }
+      }
+
+      &.income {
+        .icon-circle {
+          background: #eef2ff;
+          color: #4f46e5;
+        }
+        .overview-box {
+          border-left: 5px solid #4f46e5;
+        }
+      }
+
+      &.expense {
+        .icon-circle {
+          background: #fff7ed;
+          color: #f97316;
+        }
+        .overview-box {
+          border-left: 5px solid #f97316;
+        }
+      }
+    }
+
+    .profit-indicator {
+      flex: 0 40%; // 鍥哄畾瀹藉害锛屼笉鍙備笌寮规�х缉鏀句互淇濊瘉浠〃鐩樺畬鏁�
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      .profit-gauge-wrapper {
+        position: relative;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        width: 100%;
+        // max-width: 180px;
+
+        .profit-center-text {
+          position: absolute;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+          text-align: center;
+          width: 100%;
+
+          .label {
+            font-size: 12px;
+            color: #718096;
+            font-weight: 500;
+          }
+
+          .value {
+            font-size: 20px;
+            font-weight: 800;
+            margin: 2px 0;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+
+            &.plus {
+              color: #10b981;
+            }
+
+            &.minus {
+              color: #f43f5e;
+            }
+          }
+
+          .rate {
+            font-size: 11px;
+            color: #a0aec0;
+            font-weight: 500;
+          }
+        }
+      }
+    }
+
+    // 閽堝闈炲父绐勭殑灞忓箷杩涜鏁翠綋缂╂斁
+    @media (max-width: 1400px) {
+      transform-origin: center;
+      // 濡傛灉瀹瑰櫒澶獎锛岄�氳繃缂╁皬鍐呴儴鍏冪礌鏉ラ�傚簲
+      // 杩欓噷涓嶄娇鐢� transform: scale 鍥犱负浼氬奖鍝嶅竷灞�娴侊紝鏀圭敤鍐呴儴灏哄寰皟
+      .overview-item .overview-box {
+        padding: 10px;
+        gap: 8px;
+        .value {
+          font-size: 16px;
+        }
+        .icon-circle {
+          width: 36px;
+          height: 36px;
+          font-size: 18px;
+        }
+      }
+      .profit-indicator {
+        flex: 0 40%;
+        .profit-gauge-wrapper .value {
+          font-size: 18px;
+        }
+      }
     }
   }
 </style>
-
-
-
-
-
-
-
-
-
-

--
Gitblit v1.9.3