+
模块显隐
-
主导航只保留高频入口;备用模块保留代码与数据,但默认放在管理员备用区。
+
+ 主导航只保留高频入口;备用模块保留代码与数据,低频功能默认收进管理区或隐藏。
+
-
-
-
- 模块
- 当前显隐
- 操作
-
-
-
- {moduleEntries.map(([key, mode]) => (
-
- {MODULE_LABELS[key] ?? key}
- {mode}
-
-
- {(["main", "admin", "hidden"] as const).map((nextMode) => (
-
- ))}
-
-
+
+
+
+
+ 模块
+ 当前显隐
+ 操作
- ))}
-
-
-
-
+
+
+ {moduleEntries.map(([key, mode]) => (
+
+ {MODULE_LABELS[key] ?? key}
+ {visibilityModeLabel(mode)}
+
+
+ {VISIBILITY_OPTIONS.map((option) => (
+
+ ))}
+
+
+
+ ))}
+
+
+
+
+
);
}
diff --git a/client/tests/e2e/pc-finance-admin-visual-wave4.spec.ts b/client/tests/e2e/pc-finance-admin-visual-wave4.spec.ts
index b65fcb99..2c8b0061 100644
--- a/client/tests/e2e/pc-finance-admin-visual-wave4.spec.ts
+++ b/client/tests/e2e/pc-finance-admin-visual-wave4.spec.ts
@@ -30,8 +30,11 @@ const allPermissions = [
"risk.review.manage",
"travel.payment.manage",
"system.user.manage",
+ "system.users",
"system.settings",
"system.audit.view",
+ "masterdata.manage",
+ "notification.channel.manage",
];
const visualMe = {
@@ -517,9 +520,13 @@ async function mockWave4Apis(page: Page, options: Wave4MockOptions = {}) {
navigationItem("invoice-pool", "/invoice-pool", "票据中心", "receipt_long"),
],
admin: [
+ navigationItem("people", "/people", "人员管理", "badge", "admin"),
+ navigationItem("organization", "/organization", "组织架构", "account_tree", "admin"),
+ navigationItem("workspace", "/system/workspace", "工作区设置", "dashboard_customize", "admin"),
navigationItem("users", "/system/users", "用户管理", "group", "admin"),
navigationItem("master-data", "/system/master-data", "主数据", "database", "admin"),
navigationItem("notification-channels", "/system/notification-channels", "通知渠道", "notifications", "admin"),
+ navigationItem("approval-rules", "/system/approval-rules", "审批规则", "account_tree", "admin"),
navigationItem("settings", "/system/settings", "系统设置", "settings", "admin"),
navigationItem("feature-flags", "/system/feature-flags", "功能开关", "toggle_on", "admin"),
navigationItem("workflow-definitions", "/system/workflow-definitions", "流程定义", "schema", "admin"),
@@ -532,6 +539,35 @@ async function mockWave4Apis(page: Page, options: Wave4MockOptions = {}) {
return;
}
+ if (pathName === "/api/system/workspace") {
+ await fulfillJson(route, {
+ id: "workspace-wave4",
+ persisted: true,
+ profile: "small_team_internal",
+ orgMode: "single_company",
+ primaryEntryMode: "password",
+ notificationStrategy: "in_app",
+ devicePriority: "desktop",
+ moduleVisibility: {
+ portal: "main",
+ workflowTasks: "main",
+ reimbursements: "main",
+ paymentBatches: "admin",
+ apOperations: "admin",
+ invoicePool: "admin",
+ people: "admin",
+ organization: "admin",
+ approvalRules: "admin",
+ featureFlags: "admin",
+ travelRequests: "hidden",
+ },
+ createdAt: null,
+ updatedAt: "2026-05-29T08:00:00.000Z",
+ updatedBy: visualMe.id,
+ });
+ return;
+ }
+
if (pathName === "/api/notifications") {
await fulfillJson(route, { page: 1, pageSize: 5, total: 0, unreadOnly: false, unreadCount: 0, items: [] });
return;
@@ -803,6 +839,97 @@ async function mockWave4Apis(page: Page, options: Wave4MockOptions = {}) {
return;
}
+ if (pathName === "/api/employees/organization") {
+ await fulfillJson(route, {
+ items: [
+ {
+ department: departments[0],
+ roots: [
+ {
+ id: visualMe.id,
+ employeeNo: visualMe.employeeNo,
+ name: visualMe.name,
+ title: "管理员",
+ status: "active",
+ avatarUrl: null,
+ department: departments[0],
+ externalManager: null,
+ children: [],
+ },
+ ],
+ },
+ {
+ department: departments[1],
+ roots: [],
+ },
+ ],
+ });
+ return;
+ }
+
+ if (pathName === "/api/employees/wecom-hr-master-sync/runs") {
+ await fulfillJson(route, {
+ items: [
+ {
+ id: "wecom-hr-run-wave4",
+ mode: "dry_run",
+ status: "success",
+ tokenSource: null,
+ requestedUserids: null,
+ limit: 50,
+ summary: { total: 1, created: 0, updated: 1, skipped: 0, conflicts: 0, failed: 0 },
+ errorCode: null,
+ errorMessage: null,
+ triggeredBy: visualMe.id,
+ startedAt: "2026-05-29T07:50:00.000Z",
+ finishedAt: "2026-05-29T07:51:00.000Z",
+ createdAt: "2026-05-29T07:50:00.000Z",
+ updatedAt: "2026-05-29T07:51:00.000Z",
+ itemCount: 1,
+ items: [],
+ },
+ ],
+ });
+ return;
+ }
+
+ if (pathName === "/api/approval-rules") {
+ await fulfillJson(route, {
+ enabled: null,
+ items: [
+ {
+ id: "approval-rule-wave5-1",
+ name: "5000 以下经理审批",
+ minAmount: "0.00",
+ maxAmount: "5000.00",
+ level1Role: "manager",
+ level2Role: null,
+ level3Role: null,
+ ownerSelfFallbackRole: "finance_mgr",
+ enabled: true,
+ priority: 1,
+ createdAt: "2026-05-29T08:00:00.000Z",
+ updatedAt: "2026-05-29T08:00:00.000Z",
+ },
+ {
+ id: "approval-rule-wave5-2",
+ name: "高额财务负责人复核",
+ minAmount: "5000.01",
+ maxAmount: null,
+ level1Role: "manager",
+ level2Role: "finance_mgr",
+ level3Role: "ceo",
+ ownerSelfFallbackRole: null,
+ enabled: false,
+ priority: 2,
+ createdAt: "2026-05-29T08:00:00.000Z",
+ updatedAt: "2026-05-29T08:00:00.000Z",
+ },
+ ],
+ });
+ return;
+ }
+
if (pathName === "/api/master-data/legal-entities") {
await fulfillJson(route, { includeArchived: false, items: legalEntities });
return;
@@ -886,16 +1013,20 @@ const pages = [
{ path: "/payment-batches", summary: "payment-batches-summary", proof: "text=批次列表", screenshot: "01-payment-batches" },
{ path: "/ap-operations", summary: "ap-operations-summary", proof: "text=异常付款", screenshot: "02-ap-operations" },
{ path: "/invoice-pool", summary: "invoice-pool-summary", proof: "data-testid=invoice-pool-table", screenshot: "03-invoice-pool" },
- { path: "/system/users", summary: "users-summary", proof: "data-testid=users-table", screenshot: "04-users" },
- { path: "/system/master-data", summary: "master-data-summary", proof: "text=法体列表", screenshot: "05-master-data" },
- { path: "/system/notification-channels", summary: "notification-channels-summary", proof: "data-testid=notification-channels-table", screenshot: "06-notification-channels" },
- { path: "/system/settings", summary: "system-settings-summary", proof: "text=系统设置", screenshot: "07-system-settings" },
- { path: "/system/feature-flags", summary: "feature-flags-summary", proof: "data-testid=feature-flags-table", screenshot: "08-feature-flags" },
- { path: "/system/workflow-definitions", summary: "workflow-definitions-summary", proof: "text=版本列表", screenshot: "09-workflow-definitions" },
- { path: "/audit-logs", summary: "audit-summary", proof: "text=PAYMENT_BATCH_REVIEW", screenshot: "10-audit-logs" },
+ { path: "/system/approval-rules", summary: "approval-rules-summary", proof: "data-testid=approval-rules-table", screenshot: "04-approval-rules" },
+ { path: "/people", summary: "people-summary", proof: "data-testid=people-table", screenshot: "05-people" },
+ { path: "/organization", summary: "organization-summary", proof: "text=研发部", screenshot: "06-organization" },
+ { path: "/system/workspace", summary: "workspace-settings-summary", proof: "data-testid=workspace-modules-table", screenshot: "07-workspace" },
+ { path: "/system/users", summary: "users-summary", proof: "data-testid=users-table", screenshot: "08-users" },
+ { path: "/system/master-data", summary: "master-data-summary", proof: "text=法体列表", screenshot: "09-master-data" },
+ { path: "/system/notification-channels", summary: "notification-channels-summary", proof: "data-testid=notification-channels-table", screenshot: "10-notification-channels" },
+ { path: "/system/settings", summary: "system-settings-summary", proof: "text=系统设置", screenshot: "11-system-settings" },
+ { path: "/system/feature-flags", summary: "feature-flags-summary", proof: "data-testid=feature-flags-table", screenshot: "12-feature-flags" },
+ { path: "/system/workflow-definitions", summary: "workflow-definitions-summary", proof: "text=版本列表", screenshot: "13-workflow-definitions" },
+ { path: "/audit-logs", summary: "audit-summary", proof: "text=PAYMENT_BATCH_REVIEW", screenshot: "14-audit-logs" },
];
-test("PC 财务与管理页 Wave4 视觉冒烟", async ({ page }) => {
+test("PC 财务与管理页 Wave4-5 视觉冒烟", async ({ page }) => {
await mockWave4Apis(page);
await page.setViewportSize({ width: 1440, height: 960 });
await login(page);