From 2c43e2accc57e73eb327a5f2c5a64d500333fd9b Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 27 Jun 2026 18:13:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Dashboard=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E5=9F=BA=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 让本日本周本月以真实当天计算日期范围 补充从本月切回本日的回归测试 同步后台Dashboard运营看板文档 --- .../src/pages/AdminDashboardPage.test.tsx | 48 +++++++++++++++---- .../src/pages/AdminDashboardPage.tsx | 5 +- ...台管理】Dashboard运营看板方案-2026-06-23.md | 2 +- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/apps/admin-web/src/pages/AdminDashboardPage.test.tsx b/apps/admin-web/src/pages/AdminDashboardPage.test.tsx index 781a2862f..1951814b6 100644 --- a/apps/admin-web/src/pages/AdminDashboardPage.test.tsx +++ b/apps/admin-web/src/pages/AdminDashboardPage.test.tsx @@ -2,7 +2,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { beforeEach, expect, test, vi } from 'vitest'; +import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import { getAdminDashboard } from '../api/adminApiClient'; import type { AdminDashboardResponse } from '../api/adminApiTypes'; @@ -64,11 +64,17 @@ const dashboardResponse: AdminDashboardResponse = { beforeEach(() => { vi.clearAllMocks(); + vi.useFakeTimers({ shouldAdvanceTime: true }); + vi.setSystemTime(new Date('2026-06-27T08:00:00+08:00')); vi.mocked(getAdminDashboard).mockResolvedValue(dashboardResponse); }); +afterEach(() => { + vi.useRealTimers(); +}); + test('Dashboard 默认加载今日指标并支持运营汇总页签', async () => { - const user = userEvent.setup(); + const user = setupUser(); render(); expect(await screen.findByText('总计数据')).toBeTruthy(); @@ -87,8 +93,8 @@ test('Dashboard 默认加载今日指标并支持运营汇总页签', async () = expect(screen.getByText('访问模块分布')).toBeTruthy(); }); -test('Dashboard 选择本周时按当前终止日期填充整周范围', async () => { - const user = userEvent.setup(); +test('Dashboard 选择本周时按今天填充整周范围', async () => { + const user = setupUser(); render(); await screen.findByText('本日生产素材数'); @@ -101,14 +107,14 @@ test('Dashboard 选择本周时按当前终止日期填充整周范围', async ( expect(getAdminDashboard).toHaveBeenLastCalledWith('admin-token', { granularity: 'period', anchor: undefined, - startDate: '2026-06-29', - endDate: '2026-07-05', + startDate: '2026-06-22', + endDate: '2026-06-28', }); }); }); -test('Dashboard 选择本月时按当前终止日期填充整月范围', async () => { - const user = userEvent.setup(); +test('Dashboard 选择本月时按今天填充整月范围', async () => { + const user = setupUser(); render(); await screen.findByText('本日生产素材数'); @@ -121,8 +127,26 @@ test('Dashboard 选择本月时按当前终止日期填充整月范围', async ( expect(getAdminDashboard).toHaveBeenLastCalledWith('admin-token', { granularity: 'period', anchor: undefined, - startDate: '2026-07-01', - endDate: '2026-07-31', + startDate: '2026-06-01', + endDate: '2026-06-30', + }); + }); +}); + +test('Dashboard 从本月切回本日时回到今天', async () => { + const user = setupUser(); + render(); + + await screen.findByText('本日生产素材数'); + await user.click(screen.getByRole('button', { name: '本月' })); + await user.click(screen.getByRole('button', { name: '本日' })); + + await waitFor(() => { + expect(getAdminDashboard).toHaveBeenLastCalledWith('admin-token', { + granularity: 'period', + anchor: undefined, + startDate: '2026-06-27', + endDate: '2026-06-27', }); }); }); @@ -148,3 +172,7 @@ test('Dashboard 手动选择起止日期时使用本时段查询', async () => { }); expect(screen.getByText('本时段新增用户数')).toBeTruthy(); }); + +function setupUser() { + return userEvent.setup({ advanceTimers: vi.advanceTimersByTime }); +} diff --git a/apps/admin-web/src/pages/AdminDashboardPage.tsx b/apps/admin-web/src/pages/AdminDashboardPage.tsx index 7c942ea54..88fd78a15 100644 --- a/apps/admin-web/src/pages/AdminDashboardPage.tsx +++ b/apps/admin-web/src/pages/AdminDashboardPage.tsx @@ -325,7 +325,10 @@ export function AdminDashboardPage({ function handleGranularityChange( nextGranularity: Exclude, ) { - const nextRange = buildPresetDateRange(nextGranularity, dateRange.endDate); + const nextRange = buildPresetDateRange( + nextGranularity, + formatDateInput(new Date()), + ); const rangeChanged = nextRange.startDate !== dateRange.startDate || nextRange.endDate !== dateRange.endDate; diff --git a/docs/technical/【后台管理】Dashboard运营看板方案-2026-06-23.md b/docs/technical/【后台管理】Dashboard运营看板方案-2026-06-23.md index 506e6a04d..13c9cce2e 100644 --- a/docs/technical/【后台管理】Dashboard运营看板方案-2026-06-23.md +++ b/docs/technical/【后台管理】Dashboard运营看板方案-2026-06-23.md @@ -13,7 +13,7 @@ - `granularity` 默认为 `day`。 - `anchor` 使用北京时间日历日期,保留给 `day` / `week` / `month` 兼容旧查询口径。`week` 和 `month` 选择包含该日期的自然周 / 自然月。 - `period` 使用 `startDate` / `endDate` 作为闭区间自定义时段,最多 366 天。 -- 前端统一展示起始日期和终止日期两个日期选择器;点击“本日 / 本周 / 本月”只按当前终止日期自动填充对应自然日 / 自然周 / 自然月范围并刷新,手动修改起止日期后按当前日期范围查询。 +- 前端统一展示起始日期和终止日期两个日期选择器;点击“本日 / 本周 / 本月”按当天真实日期自动填充对应自然日 / 自然周 / 自然月范围并刷新,手动修改起止日期后按当前日期范围查询。 - 前端每 5 分钟自动刷新一次,同时保留手动刷新按钮。 ## 指标口径