This commit is contained in:
@@ -21,7 +21,7 @@ const routes = (
|
||||
).routes;
|
||||
|
||||
const projectId = '01KZRXMHB04HR8Y23HTH1F7DXV';
|
||||
const visibleHeadingPageIds = new Set(['PAGE-01', 'PAGE-02', 'PAGE-08', 'PAGE-10', 'PAGE-23']);
|
||||
const visibleHeadingPageIds = new Set(['PAGE-01', 'PAGE-02', 'PAGE-08', 'PAGE-10', 'PAGE-23', 'PAGE-24']);
|
||||
|
||||
const roleNames: Record<string, string> = {
|
||||
PROJECT_MANAGER: '项目管理人员',
|
||||
@@ -42,6 +42,7 @@ function expectedHeading(route: ContractRoute) {
|
||||
if (route.pageId === 'PAGE-03') return '个人中心';
|
||||
if (route.pageId === 'PAGE-08') return '自动化验收项目';
|
||||
if (route.pageId === 'PAGE-17') return '项目档案包';
|
||||
if (route.pageId === 'PAGE-24') return '系统经营仪表盘';
|
||||
return route.breadcrumb.at(-1) || '';
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
import type { Page, Route } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
const adminSession = {
|
||||
authenticated: true,
|
||||
user: {
|
||||
publicId: '01M00000000000000000000001',
|
||||
username: 'dashboard-e2e',
|
||||
displayName: '仪表盘验收管理员',
|
||||
departmentName: '测试组',
|
||||
mustChangePassword: false,
|
||||
},
|
||||
roles: [{ code: 'SYSTEM_ADMIN', name: '超级管理员', workbenchRoute: '/dashboard' }],
|
||||
activeRole: 'SYSTEM_ADMIN',
|
||||
permissions: [
|
||||
'dashboard:overview:view',
|
||||
'project:project:view',
|
||||
'masterdata:contract:view',
|
||||
'receivable:receipt:view',
|
||||
'receivable:invoice:view',
|
||||
'payment:request:view',
|
||||
'workflow:task:view',
|
||||
'project:risk-flag:view',
|
||||
'archive:package:view',
|
||||
'archive:file:view',
|
||||
],
|
||||
};
|
||||
|
||||
const dashboard = {
|
||||
title: '系统经营仪表盘',
|
||||
refreshedAt: '2026-08-19T04:00:00Z',
|
||||
currency: 'CNY',
|
||||
system: {
|
||||
overallStatus: 'UP',
|
||||
currentVersion: '1.0.0-preview.48',
|
||||
uptimeSeconds: 7260,
|
||||
services: [
|
||||
{ code: 'APPLICATION', label: '应用服务', status: 'UP', detail: '服务运行正常' },
|
||||
{ code: 'DATABASE', label: '数据库连接', status: 'UP', detail: '业务数据库连接正常' },
|
||||
{ code: 'FILE_STORAGE', label: '文件存储', status: 'UP', detail: '存储目录可读写' },
|
||||
{ code: 'UPDATE', label: '更新服务', status: 'UP', detail: '在线更新服务已启用' },
|
||||
],
|
||||
},
|
||||
metrics: [
|
||||
{
|
||||
code: 'ACTIVE_PROJECTS',
|
||||
label: '进行中项目',
|
||||
kind: 'COUNT',
|
||||
value: '8',
|
||||
unit: '项',
|
||||
available: true,
|
||||
targetRoute: '/projects',
|
||||
},
|
||||
{
|
||||
code: 'CONTRACT_AMOUNT',
|
||||
label: '合同总额',
|
||||
kind: 'MONEY',
|
||||
value: '1234567.89',
|
||||
unit: 'CNY',
|
||||
available: true,
|
||||
targetRoute: '/finance/contracts-costs',
|
||||
},
|
||||
{
|
||||
code: 'RECEIPT_AMOUNT',
|
||||
label: '累计收款',
|
||||
kind: 'MONEY',
|
||||
value: '456789.00',
|
||||
unit: 'CNY',
|
||||
available: true,
|
||||
targetRoute: '/finance/receipts-invoices',
|
||||
},
|
||||
{
|
||||
code: 'PAYMENT_AMOUNT',
|
||||
label: '累计付款',
|
||||
kind: 'MONEY',
|
||||
value: '234567.00',
|
||||
unit: 'CNY',
|
||||
available: true,
|
||||
targetRoute: '/finance/payments',
|
||||
},
|
||||
{
|
||||
code: 'PENDING_TASKS',
|
||||
label: '待办审批',
|
||||
kind: 'COUNT',
|
||||
value: '4',
|
||||
unit: '项',
|
||||
available: true,
|
||||
targetRoute: '/tasks',
|
||||
},
|
||||
{
|
||||
code: 'ACTIVE_RISKS',
|
||||
label: '风险事项',
|
||||
kind: 'COUNT',
|
||||
value: '2',
|
||||
unit: '项',
|
||||
available: true,
|
||||
targetRoute: '/projects?riskStatus=ACTIVE',
|
||||
},
|
||||
],
|
||||
trend: {
|
||||
currency: 'CNY',
|
||||
receiptsAvailable: true,
|
||||
paymentsAvailable: true,
|
||||
invoicesAvailable: true,
|
||||
points: [
|
||||
{ period: '2026-03', receivedAmount: '100', paidAmount: '80', invoicedAmount: '90' },
|
||||
{ period: '2026-04', receivedAmount: '200', paidAmount: '120', invoicedAmount: '180' },
|
||||
{ period: '2026-05', receivedAmount: '320', paidAmount: '180', invoicedAmount: '260' },
|
||||
{ period: '2026-06', receivedAmount: '410', paidAmount: '220', invoicedAmount: '330' },
|
||||
{ period: '2026-07', receivedAmount: '500', paidAmount: '280', invoicedAmount: '420' },
|
||||
{ period: '2026-08', receivedAmount: '620', paidAmount: '360', invoicedAmount: '510' },
|
||||
],
|
||||
},
|
||||
lifecycle: [
|
||||
{ code: 'INITIATION', label: '立项', value: 2, available: true, targetRoute: '/projects?stage=INITIATION' },
|
||||
{ code: 'EXECUTION', label: '执行中', value: 4, available: true, targetRoute: '/projects?stage=EXECUTION' },
|
||||
{ code: 'SETTLEMENT', label: '结算', value: 2, available: true, targetRoute: '/projects?stage=SETTLEMENT' },
|
||||
],
|
||||
risks: [
|
||||
{
|
||||
code: 'PROJECT_RISK',
|
||||
label: '项目风险',
|
||||
severity: 'DANGER',
|
||||
count: 2,
|
||||
detail: '当前权限范围内的有效风险标记',
|
||||
available: true,
|
||||
targetRoute: '/projects?riskStatus=ACTIVE',
|
||||
},
|
||||
],
|
||||
geography: { available: false, message: '项目尚未配置统一的省市维度,当前以项目阶段分布替代地图。', regions: [] },
|
||||
activities: [],
|
||||
};
|
||||
|
||||
async function installFixture(page: Page) {
|
||||
await page.route('**/api/v1/**', async (route: Route) => {
|
||||
const request = route.request();
|
||||
const pathname = new URL(request.url()).pathname;
|
||||
if (pathname === '/api/v1/setup/status') {
|
||||
await route.fulfill({ json: { data: { required: false, locked: true } } });
|
||||
return;
|
||||
}
|
||||
if (pathname === '/api/v1/auth/session') {
|
||||
await route.fulfill({ json: { data: adminSession } });
|
||||
return;
|
||||
}
|
||||
if (pathname === '/api/v1/auth/profile') {
|
||||
await route.fulfill({ json: { data: adminSession.user } });
|
||||
return;
|
||||
}
|
||||
if (pathname === '/api/v1/dashboard/overview') {
|
||||
await route.fulfill({ json: { data: dashboard } });
|
||||
return;
|
||||
}
|
||||
await route.fulfill({ json: { data: [], meta: { page: 1, size: 20, totalElements: 0, totalPages: 0 } } });
|
||||
});
|
||||
}
|
||||
|
||||
test('hybrid dashboard renders the cockpit, safe fallback and big-screen mode', async ({ page }) => {
|
||||
await installFixture(page);
|
||||
await page.goto('/dashboard');
|
||||
|
||||
await expect(page.getByRole('heading', { name: '系统经营仪表盘', exact: true })).toBeVisible();
|
||||
await expect(page.getByText('进行中项目')).toBeVisible();
|
||||
await expect(page.getByText('项目尚未配置统一的省市维度,当前以项目阶段分布替代地图。')).toBeVisible();
|
||||
await expect(page.getByTestId('dashboard-chart').first()).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: '进入大屏' })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: '进入大屏' }).click();
|
||||
await expect(page.getByText('当前章节:经营总览')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: '退出大屏' })).toBeVisible();
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe(true);
|
||||
|
||||
await page.keyboard.press('Escape');
|
||||
await expect(page.getByRole('button', { name: '进入大屏' })).toBeVisible();
|
||||
});
|
||||
@@ -384,7 +384,7 @@ test('brand logo returns the active identity to its workbench', async ({ page })
|
||||
|
||||
await page.locator('.brand-logo').click();
|
||||
|
||||
await expect(page).toHaveURL(/\/governance\/settings$/);
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
await expect(page.getByText('选择工作身份', { exact: true })).toHaveCount(0);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user