From 0152b0200faff12f0ece317cdb32dcbcf486757d Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期日, 04 一月 2026 14:32:03 +0800
Subject: [PATCH] 添加库存核算统计页面,调整固定资产页面图表

---
 src/views/financialManagement/accounting/index.vue |  710 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 513 insertions(+), 197 deletions(-)

diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
index 06bf4cf..f8e4a9f 100644
--- a/src/views/financialManagement/accounting/index.vue
+++ b/src/views/financialManagement/accounting/index.vue
@@ -1,231 +1,547 @@
 <template>
-  <div class="app-container">
-    <el-row :gutter="16" class="mb-16">
-      <el-col :span="12">
-        <el-card shadow="hover">
-          <div class="section-title">缁熶竴浼氳绉戠洰浣撶郴</div>
-          <el-tree
-            :data="accountTree"
-            node-key="code"
-            :props="{ label: 'label', children: 'children' }"
-            highlight-current
-            default-expand-all
-          />
-        </el-card>
-      </el-col>
-      <el-col :span="12">
-        <el-card shadow="hover">
-          <div class="section-title">鍑瘉妯℃澘</div>
-          <el-table :data="voucherTemplates" border size="small">
-            <el-table-column prop="name" label="妯℃澘鍚嶇О" min-width="140" />
-            <el-table-column prop="bizScene" label="涓氬姟鍦烘櫙" min-width="140" />
-            <el-table-column prop="debit" label="鍊熸柟绉戠洰" min-width="160" />
-            <el-table-column prop="credit" label="璐锋柟绉戠洰" min-width="160" />
-            <el-table-column prop="auxDims" label="杈呭姪鏍哥畻缁村害" min-width="180">
-              <template #default="scope">
-                <el-space wrap>
-                  <el-tag v-for="dim in scope.row.auxDims" :key="dim" size="small" type="info">{{ dim }}</el-tag>
-                </el-space>
-              </template>
-            </el-table-column>
-          </el-table>
-        </el-card>
-      </el-col>
-    </el-row>
+  <div style="padding: 20px;">
+    <!-- 椤甸潰鏍囬鍜岀瓫閫夋潯浠� -->
+    <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
+      <el-button
+        type="primary"
+        icon="Refresh"
+        @click="resetFilters"
+        size="default"
+      >
+        鏌ヨ
+      </el-button>
+    </div>
 
-    <el-row :gutter="16" class="mb-16">
-      <el-col :span="12">
-        <el-card shadow="hover">
-          <div class="section-title">涓氬姟娴佺▼ 鈫� 鍑瘉鑷姩鐢熸垚</div>
-          <div class="toolbar">
-            <el-text type="info">婕旂ず鏁版嵁浠呯敤浜庡睍绀虹粨鏋勪笌瀛楁</el-text>
-          </div>
-          <el-table :data="generatedVouchers" border size="small">
-            <el-table-column prop="date" label="鏃ユ湡" width="110" />
-            <el-table-column prop="bizScene" label="涓氬姟鍦烘櫙" min-width="120" />
-            <el-table-column prop="summary" label="鎽樿" min-width="160" />
-            <el-table-column prop="amount" label="閲戦(楼)" width="110" />
-            <el-table-column prop="status" label="鐘舵��" width="100">
-              <template #default="scope">
-                <el-tag :type="scope.row.status === '宸茬敓鎴�' ? 'success' : 'warning'">{{ scope.row.status }}</el-tag>
-              </template>
-            </el-table-column>
-          </el-table>
+    <main class="container mx-auto px-4 pb-10">
+      <!-- 鍥哄畾璧勪骇鎸囨爣鍗$墖 -->
+      <div class="grid-container">
+        <!-- 璁惧鎬绘暟 -->
+        <el-card class="bg2">
+          <p>璁惧鎬绘暟</p>
+          <h3>
+            {{ assetInfo.totalEquipment }}
+          </h3>
         </el-card>
-      </el-col>
-      <el-col :span="12">
-        <el-card shadow="hover">
-          <div class="section-title">澶氱淮杈呭姪鏍哥畻</div>
-          <div class="dims">
-            <el-tag type="success">瀹㈡埛</el-tag>
-            <el-tag type="warning">椤圭洰</el-tag>
-            <el-tag type="info">閮ㄩ棬</el-tag>
-            <el-tag type="primary">绠$悊鍛�</el-tag>
-          </div>
-          <el-table :data="auxSummary" size="small" border>
-            <el-table-column prop="dimension" label="缁村害" width="100" />
-            <el-table-column prop="category" label="绫诲埆" min-width="140" />
-            <el-table-column prop="debit" label="鍊熸柟(鏈湡)" width="110" />
-            <el-table-column prop="credit" label="璐锋柟(鏈湡)" width="110" />
-            <el-table-column prop="balance" label="浣欓" width="100" />
-          </el-table>
-        </el-card>
-      </el-col>
-    </el-row>
 
-    <el-row :gutter="16" class="mb-16">
-      <el-col :span="12">
-        <el-card shadow="hover">
-          <div class="section-title">缁撹处浠诲姟锛堟湀/瀛�/骞达級</div>
-          <div class="toolbar">
-            <el-space>
-              <el-button size="small" @click="runClose('鏈堢粨')">鎵ц鏈堢粨</el-button>
-              <el-button size="small" @click="runClose('瀛f姤')">鎵ц瀛f姤</el-button>
-              <el-button size="small" @click="runClose('骞村害缁撹处')">鎵ц骞村害缁撹处</el-button>
-            </el-space>
-          </div>
-          <el-timeline style="margin-top: 6px;">
-            <el-timeline-item
-              v-for="item in closingTasks"
-              :key="item.id"
-              :type="item.type"
-              :timestamp="item.time"
-              placement="top"
-            >
-              <div class="close-item">
-                <div class="title">{{ item.name }}</div>
-                <el-tag :type="item.status === '瀹屾垚' ? 'success' : 'info'" size="small">{{ item.status }}</el-tag>
+        <!-- 璧勪骇鍘熷�� -->
+        <el-card class="bg3">
+          <p>璧勪骇鍘熷��</p>
+          <h3>
+            楼{{ assetInfo.totalOriginalValue }}
+          </h3>
+        </el-card>
+
+        <!-- 绱鎶樻棫 -->
+        <el-card class="bg4">
+          <p>绱鎶樻棫</p>
+          <h3>
+            楼{{ assetInfo.totalDepreciation }}
+          </h3>
+        </el-card>
+
+        <!-- 鍑�鍊� -->
+        <el-card class="bg5">
+          <p>鍑�鍊�</p>
+          <h3>
+            楼{{ assetInfo.totalNetValue }}
+          </h3>
+        </el-card>
+      </div>
+
+      <!-- 鍥哄畾璧勪骇缁熻鍥捐〃 -->
+      <div class="grid-layout">
+        <!-- 鎸夎澶囩被鍨嬬粺璁� -->
+        <el-card style="margin-bottom: 20px;">
+          <h2 class="section-title">璁惧绫诲瀷鍒嗗竷</h2>
+          <div class="echarts">
+            <Echarts
+                :legend="typeDistributionLegend"
+                :chartStyle="chartStylePie"
+                :series="typeDistributionSeries"
+                :tooltip="pieTooltip"
+                style="height: 260px; width: 35%;">
+              <div class="chart-num">
+                <span style="font-size: 22px;">璁惧绫诲瀷</span>
+                <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ assetInfo.totalEquipment }}</span>
               </div>
-            </el-timeline-item>
-          </el-timeline>
+            </Echarts>
+            <Echarts
+                ref="chart"
+                :chartStyle="chartStyle"
+                :grid="grid"
+                :legend="lineLegend"
+                :series="typeDistributionLineSeries"
+                :tooltip="tooltip"
+                :xAxis="xAxis"
+                :yAxis="yAxis"
+                style="height: 260px; width: 64%;"></Echarts>
+          </div>
         </el-card>
-      </el-col>
-      <el-col :span="12">
-        <el-card shadow="hover">
-          <div class="section-title">瀹¤鐣欑棔涓庡鎵规潈闄�</div>
-          <el-table :data="auditTrail" border size="small">
-            <el-table-column prop="time" label="鏃堕棿" width="160" />
-            <el-table-column prop="action" label="鍔ㄤ綔" min-width="160" />
-            <el-table-column prop="bizScene" label="鍏宠仈涓氬姟" min-width="140" />
-            <el-table-column prop="role" label="鎵ц瑙掕壊" width="120" />
-            <el-table-column prop="result" label="缁撴灉" width="100">
-              <template #default="scope">
-                <el-tag :type="scope.row.result === '閫氳繃' ? 'success' : (scope.row.result === '椹冲洖' ? 'danger' : 'info')">
-                  {{ scope.row.result }}
-                </el-tag>
-              </template>
-            </el-table-column>
-          </el-table>
-        </el-card>
-      </el-col>
-    </el-row>
+      </div>
+      <!-- 璁惧鍙拌处琛ㄦ牸 -->
+      <el-card style="margin-bottom: 20px;">
+        <el-table
+          :data="equipmentList"
+          stripe
+          style="width: 100%"
+          :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
+        >
+          <el-table-column prop="id" label="璧勪骇缂栧彿" width="120" />
+          <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="250" />
+          <el-table-column prop="deviceModel" label="鍨嬪彿瑙勬牸" min-width="150" />
+          <el-table-column prop="supplierName" label="渚涘簲鍟�" min-width="120" />
+          <el-table-column prop="unit" label="鍗曚綅" width="120" />
+          <el-table-column prop="number" label="鏁伴噺" width="120" />
+          <el-table-column prop="originalValue" label="鍘熷��(鍏�)" width="120">
+            <template #default="{ row }">
+              楼{{ formatCurrency(row.taxIncludingPriceTotal) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="depreciation" label="绱鎶樻棫(鍏�)" width="140">
+            <template #default="{ row }">
+              楼{{ formatCurrency(row.taxIncludingPriceTotal-row.unTaxIncludingPriceTotal) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="netValue" label="鍑�鍊�(鍏�)" width="120">
+            <template #default="{ row }">
+              楼{{ formatCurrency(row.unTaxIncludingPriceTotal) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="status" label="鐘舵��" width="100">
+            <template #default="{ row }">
+              <el-tag
+                :type="getStatusTagType(row.status)"
+                size="small"
+              >
+                {{ row.status }}
+              </el-tag>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <!-- 鍒嗛〉 -->
+        <div class="pagination-container">
+          <el-pagination
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            :current-page="pagination.currentPage"
+            :page-sizes="[10, 20, 50, 100]"
+            :page-size="pagination.pageSize"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="pagination.total"
+          />
+        </div>
+      </el-card>
+    </main>
+
   </div>
-  
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, computed, onMounted, reactive } from 'vue';
+import 'element-plus/dist/index.css';
+import Echarts from "@/components/Echarts/echarts.vue";
+import { getLedgerPage, getAssetInfo } from "@/api/equipmentManagement/ledger";
+import dayjs from "dayjs";
 
-// 绉戠洰鏍戯紙绀轰緥锛�
-const accountTree = ref([
-  { code: '1001', label: '璧勪骇', children: [
-    { code: '100101', label: '搴撳瓨鐜伴噾' },
-    { code: '100102', label: '閾惰瀛樻' },
-    { code: '1122', label: '搴旀敹璐︽' },
-    { code: '1601', label: '鍥哄畾璧勪骇' },
-  ]},
-  { code: '2001', label: '璐熷��', children: [
-    { code: '2202', label: '搴斾粯璐︽' },
-    { code: '2241', label: '鍏朵粬搴斾粯娆�' },
-  ]},
-  { code: '3001', label: '鎵�鏈夎�呮潈鐩�', children: [
-    { code: '3103', label: '鏈勾鍒╂鼎' },
-  ]},
-  { code: '4001', label: '鎴愭湰璐圭敤', children: [
-    { code: '5601', label: '鍒堕�犺垂鐢�' },
-    { code: '6602', label: '绠$悊璐圭敤' },
-  ]},
-])
+// 绛涢�夋潯浠�
+const dateRange = ref(null);
+const equipmentType = ref('');
 
-// 鍑瘉妯℃澘锛堢ず渚嬶級
-const voucherTemplates = ref([
-  { name: '閿�鍞敹鍏ョ‘璁�', bizScene: '閿�鍞嚭搴�', debit: '1122 搴旀敹璐︽', credit: '6001 涓昏惀涓氬姟鏀跺叆', auxDims: ['瀹㈡埛','椤圭洰'] },
-  { name: '閲囪喘搴斾粯纭', bizScene: '閲囪喘鍏ュ簱', debit: '1403 鍦ㄩ�旂墿璧�', credit: '2202 搴斾粯璐︽', auxDims: ['椤圭洰','閮ㄩ棬'] },
-  { name: '璐圭敤鎶ラ攢', bizScene: '璐圭敤鍗�', debit: '6602 绠$悊璐圭敤', credit: '1002 閾惰瀛樻', auxDims: ['閮ㄩ棬'] },
-  { name: '鍥哄畾璧勪骇鎶樻棫', bizScene: '鏈堟湯鎶樻棫', debit: '6602 绠$悊璐圭敤', credit: '1602 绱鎶樻棫', auxDims: ['閮ㄩ棬'] },
-])
 
-// 鑷姩鐢熸垚鐨勫嚟璇侊紙绀轰緥锛�
-const generatedVouchers = ref([
-  { date: '2025-10-01', bizScene: '閿�鍞嚭搴�', summary: '纭搴旀敹涓庢敹鍏�', amount: 128000, status: '宸茬敓鎴�' },
-  { date: '2025-10-03', bizScene: '閲囪喘鍏ュ簱', summary: '纭鍒拌揣搴斾粯', amount: 56000, status: '宸茬敓鎴�' },
-  { date: '2025-10-05', bizScene: '璐圭敤鍗�', summary: '鍔炲叕璐圭敤鎶ラ攢', amount: 3200, status: '宸茬敓鎴�' },
-])
+// 鍥哄畾璧勪骇淇℃伅
+const assetInfo = ref({
+  totalEquipment: 0,
+  totalOriginalValue: 0,
+  totalDepreciation: 0,
+  totalNetValue: 0
+});
 
-// 鏃犳ā鎷熺敓鎴愭搷浣滐紝浠呭睍绀洪潤鎬佺ず渚嬫暟鎹�
+// 璁惧鍒楄〃
+const equipmentList = ref([]);
+const pagination = ref({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0
+});
 
-// 杈呭姪鏍哥畻绀轰緥姹囨�伙紙鏃犱釜浜哄鍚嶏紝浠呯淮搴︾被鍒級
-const auxSummary = ref([
-  { dimension: '瀹㈡埛', category: '閲嶇偣瀹㈡埛闆嗗悎', debit: 320000, credit: 210000, balance: 110000 },
-  { dimension: '椤圭洰', category: '椤圭洰A', debit: 150000, credit: 120000, balance: 30000 },
-  { dimension: '閮ㄩ棬', category: '杩愯惀涓績', debit: 42000, credit: 18000, balance: 24000 },
-  { dimension: '绠$悊鍛�', category: '绯荤粺瑙掕壊', debit: 0, credit: 0, balance: 0 },
-])
+// 鍥捐〃閰嶇疆
+const chartStyle = {
+  width: '100%',
+  height: '100%',
+  position: 'relative',
+};
 
-// 缁撹处浠诲姟
-const closingTasks = ref([
-  { id: 1, name: '2025骞�10鏈� 鏈堢粨', time: '2025-10-31 18:00', status: '瀹屾垚', type: 'success' },
-  { id: 2, name: '2025骞碤4 瀛f姤', time: '2025-12-31 18:00', status: '璁″垝', type: 'info' },
-  { id: 3, name: '2025骞村害 骞村害缁撹处', time: '2025-12-31 23:00', status: '璁″垝', type: 'info' },
-])
+const grid = {
+  left: '3%',
+  right: '4%',
+  bottom: '3%',
+  containLabel: true
+};
 
-function runClose(kind) {
-  closingTasks.value.unshift({
-    id: Date.now(),
-    name: `${new Date().getFullYear()}骞�${kind}`,
-    time: new Date().toISOString().replace('T',' ').slice(0,16),
-    status: '瀹屾垚',
-    type: 'success',
-  })
-}
+const lineLegend = {
+  show: false,
+};
 
-// 瀹¤鐣欑棔锛堜笉鍚釜浜哄鍚嶏紝浠呰鑹�/鏈哄埗锛�
-const auditTrail = ref([
-  { time: '2025-10-01 09:12', action: '閿�鍞嚭搴撹Е鍙戝嚟璇佺敓鎴�', bizScene: '閿�鍞嚭搴�', role: '绯荤粺鑷姩鍖�', result: '閫氳繃' },
-  { time: '2025-10-03 14:20', action: '閲囪喘鍏ュ簱瑙﹀彂搴斾粯纭', bizScene: '閲囪喘鍏ュ簱', role: '绯荤粺鑷姩鍖�', result: '閫氳繃' },
-  { time: '2025-10-05 10:03', action: '璐圭敤鍗曞鎵�', bizScene: '璐圭敤鍗�', role: '璐㈠姟瀹℃壒', result: '閫氳繃' },
-  { time: '2025-10-08 16:45', action: '鍑瘉杩囪处', bizScene: '鎬昏处', role: '浼氳瀹℃牳', result: '閫氳繃' },
-  { time: '2025-10-31 18:05', action: '鏈堢粨瀹屾垚骞堕攣璐�', bizScene: '鎬昏处', role: '绯荤粺鑷姩鍖�', result: '閫氳繃' },
-])
+// 鎶樼嚎鍥炬彁绀烘
+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 xAxis = ref([
+  {
+    type: 'category',
+    axisTick: { show: true, alignWithLabel: true },
+    data: [],
+  },
+]);
+
+const yAxis = [
+  {
+    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 typeDistributionData = ref([]);
+const departmentDistributionData = ref([]);
+
+// 楗煎浘鍥句緥
+const typeDistributionLegend = computed(() => ({
+  show: true,
+  top: 'center',
+  left: '60%',
+  orient: 'vertical',
+  icon: 'circle',
+  data: typeDistributionData.value.map(item => item.name),
+  formatter: function(name) {
+    const item = typeDistributionData.value.find(i => i.name === name);
+    if (!item) return name;
+    return `${name} | ${item.count} 鍙� | ${item.amount}`;
+  },
+  textStyle: {
+    color: '#333',
+    fontSize: 14,
+    lineHeight: 26,
+  }
+}));
+
+
+// 楗煎浘绯诲垪
+const typeDistributionSeries = computed(() => [
+  {
+    type: 'pie',
+    radius: ['50%', '65%'],
+    center: ['25%', '50%'],
+    avoidLabelOverlap: false,
+    itemStyle: {
+      borderColor: '#fff',
+      borderWidth: 2
+    },
+    label: {
+      show: false
+    },
+    data: typeDistributionData.value,
+    color: pieColors
+  }
+]);
+
+// 鎶樼嚎鍥炬暟鎹�
+const typeDistributionLineSeries = ref([]);
+
+
+// 楗煎浘鎻愮ず妗�
+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.count} 鍙�</div>
+        <div>閲戦锛�${params.data.amount}</div>
+      </div>
+    `;
+  }
+});
+
+// 閫夐」鏁版嵁
+const equipmentTypeOptions = ref([]);
+
+// 鑾峰彇鏁版嵁
+const fetchData = async () => {
+  try {
+    // 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
+    const assetInfoRes = await getAssetInfo({
+      startDate: dateRange.value ? dateRange.value[0] : null,
+      endDate: dateRange.value ? dateRange.value[1] : null,
+      equipmentType: equipmentType.value
+    });
+
+    if (assetInfoRes.code === 200) {
+      assetInfo.value = assetInfoRes.data;
+    }
+
+    // 鑾峰彇璁惧鍒楄〃
+    const equipmentListRes = await getLedgerPage({
+      current: pagination.value.currentPage,
+      size: pagination.value.pageSize,
+      startDate: dateRange.value ? dateRange.value[0] : null,
+      endDate: dateRange.value ? dateRange.value[1] : null,
+      equipmentType: equipmentType.value
+    });
+
+    if (equipmentListRes.code === 200) {
+      equipmentList.value = equipmentListRes.data.records;
+      pagination.value.total = equipmentListRes.data.total;
+
+      // 鏍规嵁 equipmentList 鎸� deviceName 杩涜鍒嗙被缁熻
+      const deviceNameMap = {};
+      equipmentList.value.forEach(item => {
+        const deviceName = item.deviceName;
+        if (!deviceNameMap[deviceName]) {
+          deviceNameMap[deviceName] = {
+            name: deviceName,
+            count: 0,
+            totalValue: 0
+          };
+        }
+        deviceNameMap[deviceName].count += item.number || 1; // 鍋囪 number 涓鸿澶囨暟閲�
+        deviceNameMap[deviceName].totalValue += item.taxIncludingPriceTotal || 0; // 绱姞鍚◣鎬讳环
+      });
+
+      // 杞崲涓� typeDistributionData 鏍煎紡
+      typeDistributionData.value = Object.values(deviceNameMap).map(item => ({
+        name: item.name,
+        value: item.count,
+        count: item.count,
+        amount: `楼${formatCurrency(item.totalValue)}`
+      }));
+
+      // 鏇存柊x杞存暟鎹�
+      xAxis.value[0].data = typeDistributionData.value.map(item => item.name);
+
+      // 鏋勫缓鎶樼嚎鍥炬暟鎹�
+      typeDistributionLineSeries.value = [
+        {
+          name: '璁惧鏁伴噺',
+          type: 'line',
+          data: typeDistributionData.value.map(item => item.count)
+        }
+      ];
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍥哄畾璧勪骇鏁版嵁澶辫触锛�', error);
+  }
+};
+
+// 鍒濆鍖�
+onMounted(() => {
+  // 鑾峰彇鍒楄〃鏁版嵁
+  fetchData();
+});
+
+// 鏍煎紡鍖栬揣甯�
+const formatCurrency = (value) => {
+  if (!value) return '0.00';
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+};
+
+// 鑾峰彇鐘舵�佹爣绛剧被鍨�
+const getStatusTagType = (status) => {
+  switch (status) {
+    case '鍦ㄧ敤':
+      return 'success';
+    case '闂茬疆':
+      return 'info';
+    case '缁翠慨涓�':
+      return 'warning';
+    case '鎶ュ簾':
+      return 'danger';
+    default:
+      return 'info';
+  }
+};
+
+// 閲嶇疆绛涢�夋潯浠�
+const resetFilters = () => {
+  dateRange.value = null;
+  equipmentType.value = '';
+  fetchData();
+};
+
+// 鍒嗛〉澶勭悊
+const handleSizeChange = (size) => {
+  pagination.value.pageSize = size;
+  fetchData();
+};
+
+const handleCurrentChange = (page) => {
+  pagination.value.currentPage = page;
+  fetchData();
+};
 </script>
 
 <style scoped lang="scss">
-.app-container {
-  padding: 16px;
+/* 鍩虹鏍峰紡琛ュ厖 */
+:root {
+  --el-color-primary: #4f46e5;
 }
-.page-header {
-  margin-bottom: 12px;
-  h2 { margin: 0 0 6px 0; font-weight: 600; }
-  p { margin: 0; color: #666; }
+
+.el-card {
+  position: relative;
+  border-radius: 12px;
+  padding: 14px 10px 10px 10px;
+  box-shadow: 0 2px 8px #eee;
+
+  :deep(.el-card__body) {
+    padding: 10px 20px !important;
+  }
+
+  &.bg1 {
+    background: url(@/assets/icons/png/1.png) no-repeat 100% 100% !important;
+  }
+
+  &.bg2 {
+    background: url(@/assets/icons/png/2.png) no-repeat 100% 100% !important;
+  }
+
+  &.bg3 {
+    background: url(@/assets/icons/png/3.png) no-repeat 100% 100% !important;
+  }
+
+  &.bg4 {
+    background: url(@/assets/icons/png/4.png) no-repeat 100% 100% !important;
+  }
+
+  &.bg5 {
+    background: url(@/assets/icons/png/5.png) no-repeat 100% 100% !important;
+  }
 }
+
+.grid-container {
+  /* grid 瀹瑰櫒鍩虹鏍峰紡 */
+  display: grid;
+  gap: 1rem; /* gap-4 瀵瑰簲 1rem (16px) */
+  margin-bottom: 2rem; /* mb-8 瀵瑰簲 2rem (32px) */
+
+  p {
+    font-size: 22px;
+    margin-top: 0px;
+    color: #fff;
+  }
+
+  h3 {
+    font-size: 36px;
+    font-weight: 500;
+    font-family: 'MyCustomFont', sans-serif;
+    margin: 10px 0;
+    color: #fff;
+  }
+}
+
+/* 绉诲姩绔粯璁ゆ牱寮� (grid-cols-1) */
+.grid-container {
+  grid-template-columns: repeat(1, minmax(0, 1fr));
+}
+
+/* 灏忓睆骞曞強浠ヤ笂 (sm:grid-cols-2) */
+@media (min-width: 640px) {
+  .grid-container {
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+  }
+}
+
+/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-5) */
+@media (min-width: 1024px) {
+  .grid-container {
+    grid-template-columns: repeat(5, minmax(0, 1fr));
+  }
+}
+
+/* 鍗$墖鎮仠鏁堟灉澧炲己 */
+.el-card:hover {
+  transform: translateY(-2px);
+}
+
+.echarts {
+  display: flex;
+  justify-content: space-between;
+}
+
+/* 鍥捐〃瀹瑰櫒鏍峰紡 */
+.el-chart {
+  width: 100%;
+  height: 100%;
+}
+
 .section-title {
   position: relative;
+  font-size: 18px;
+  color: #333;
   padding-left: 10px;
   margin-bottom: 10px;
   font-weight: 700;
 }
+
 .section-title::before {
-  content: '';
   position: absolute;
-  left: 0; top: 0.2em;
-  width: 4px; height: 1.2em;
-  background: #002FA7;
+  left: 0;
+  top: 0px;
+  content: '';
+  width: 4px;
+  height: 18px;
+  background-color: #002FA7;
   border-radius: 2px;
 }
-.mb-16 { margin-bottom: 16px; }
-.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
-.dims { display: flex; gap: 8px; margin-bottom: 10px; }
-.close-item { display: flex; align-items: center; gap: 8px; }
+
+.chart-num {
+  position: absolute;
+  z-index: 3;
+  top: 92px;
+  left: 92px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.pagination-container {
+  margin-top: 20px;
+  display: flex;
+  justify-content: center;
+}
 </style>
-
-

--
Gitblit v1.9.3