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 分钟自动刷新一次,同时保留手动刷新按钮。
## 指标口径