From 3b43ddad2c28aadebc18f6781145f4ec09f8f32d Mon Sep 17 00:00:00 2001 From: EchoZenith <60392923+EchoZenith@users.noreply.github.com> Date: Sat, 23 May 2026 00:41:07 +0800 Subject: [PATCH] feat: add today cost display and test notification function, optimize stats layout and logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增测试通知接口和前端按钮,支持快速验证企业微信通知 2. 增加今日电费统计展示,优化用电计算逻辑 3. 调整统计卡片布局为4列,修复移动端样式缩进 4. 重构用电统计逻辑,修复昨日数据计算误差 5. 完善日报功能,新增昨日电费统计和更准确的区间计算 --- client/src/pages/Dashboard.jsx | 41 +++++++++++- server.js | 111 ++++++++++++++++++++------------- 2 files changed, 105 insertions(+), 47 deletions(-) diff --git a/client/src/pages/Dashboard.jsx b/client/src/pages/Dashboard.jsx index 805549a..23305cc 100644 --- a/client/src/pages/Dashboard.jsx +++ b/client/src/pages/Dashboard.jsx @@ -1,6 +1,7 @@ import { useState, useEffect, useCallback, useRef } from 'react'; import { Button, Spin, message } from 'antd'; import { LogoutOutlined, ReloadOutlined } from '@ant-design/icons'; +import { BugOutlined } from '@ant-design/icons'; import { Lightning, ChartLine, ChartHistogram, Timer } from '@icon-park/react'; import { Chart, registerables } from 'chart.js'; import { fetchCurrent, fetchHistory, triggerCollect, logout } from '../api'; @@ -9,8 +10,8 @@ Chart.register(...registerables); const styles = ` @media (max-width: 640px) { - .d-header { flex-direction: column !important; gap: 12px !important; } - .d-stats { grid-template-columns: 1fr !important; gap: 12px !important; } + .d-header { flex-direction: column !important; gap: 12px !important; } + .d-stats { grid-template-columns: 1fr !important; gap: 12px !important; } .d-stats-card { padding: 16px !important; } .d-stats-value { font-size: 28px !important; } .d-bottom { grid-template-columns: 1fr !important; gap: 12px !important; } @@ -81,6 +82,20 @@ export default function Dashboard({ onLogout }) { onLogout(); }; + const handleTestNotify = async () => { + try { + const res = await fetch('/api/test-notify'); + const data = await res.json(); + if (data.success) { + message.success('测试消息已发送,请查看企业微信'); + } else { + message.error('发送失败'); + } + } catch { + message.error('发送失败'); + } + }; + useEffect(() => { if (!currentData?.todayRecords || currentData.todayRecords.length === 0) return; hourlyInstance.current?.destroy(); @@ -276,6 +291,7 @@ export default function Dashboard({ onLogout }) { const estimatedDays = stats[`estimatedDays${statKey}`]; const todayUsage = currentData?.todayUsage ?? 0; + const todayCost = currentData?.todayCost ?? 0; const todayAvgPower = currentData?.todayAvgPower ?? null; return ( @@ -305,6 +321,19 @@ body { margin: 0; } > 手动获取 +