import { useMemo } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { fetchSystemNavigation, fetchWorkspaceSettings, updateWorkspaceSettings } from "../api/workspace"; import { isApiError } from "../api/types"; import { mapApiErrorMessage } from "../api/errorMessages"; import { ListWorkspace, PrimaryTable, WorkspaceHeader } from "../components/patterns/ListWorkspace"; import { Button } from "../components/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../components/ui/table"; import { toast } from "sonner"; const MODULE_LABELS: Record = { portal: "工作台", team: "团队", leaveRequests: "请假", attendance: "考勤", reimbursements: "报销", assets: "资产", weeklyReports: "周报", todos: "待办", announcements: "公告", projects: "项目", workspace: "工作区设置", people: "人员管理", organization: "组织架构", contractsRegistry: "合同台账", workflowDefinitions: "流程定义", systemSettings: "系统设置", featureFlags: "功能开关", auditLogs: "审计日志", approvalRules: "审批规则", userManagement: "用户管理", departments: "部门管理", masterData: "主数据", notificationChannels: "通知渠道", workflowTasks: "审批待办", dashboard: "仪表盘", purchaseRequests: "采购申请", travelRequests: "差旅申请", budgets: "预算管理", paymentBatches: "付款批次", apOperations: "AP 运营", invoicePool: "票据中心", inventoryChecks: "资产盘点", cutover: "切换控制台", erpIntegrations: "ERP 集成", profile: "个人设置", }; const VISIBILITY_OPTIONS = [ { value: "main", label: "主导航" }, { value: "admin", label: "管理区" }, { value: "hidden", label: "隐藏" }, ] as const; function visibilityModeLabel(mode: string) { return VISIBILITY_OPTIONS.find((item) => item.value === mode)?.label ?? mode; } export function WorkspaceSetupPage() { const queryClient = useQueryClient(); const workspaceQuery = useQuery({ queryKey: ["workspace-settings"], queryFn: fetchWorkspaceSettings }); const navigationQuery = useQuery({ queryKey: ["system-navigation"], queryFn: fetchSystemNavigation }); const mutation = useMutation({ mutationFn: updateWorkspaceSettings, onSuccess: async () => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ["workspace-settings"] }), queryClient.invalidateQueries({ queryKey: ["system-navigation"] }), queryClient.invalidateQueries({ queryKey: ["portal-home"] }), ]); toast.success("工作区设置已保存"); }, onError: (error) => { const message = isApiError(error) ? `${error.code}: ${mapApiErrorMessage(error.code, error.details, error.message)}` : error instanceof Error ? error.message : "保存失败"; toast.error(message); }, }); const workspace = workspaceQuery.data; const rolePresets = navigationQuery.data?.recommendedRolePresets ?? []; const moduleEntries = useMemo(() => Object.entries(workspace?.moduleVisibility ?? {}), [workspace?.moduleVisibility]); const workspaceStats = useMemo(() => { const entries = Object.entries(workspace?.moduleVisibility ?? {}); return { total: entries.length, main: entries.filter(([, mode]) => mode === "main").length, admin: entries.filter(([, mode]) => mode === "admin").length, hidden: entries.filter(([, mode]) => mode === "hidden").length, rolePresets: rolePresets.length, }; }, [rolePresets.length, workspace?.moduleVisibility]); if (workspaceQuery.isLoading || !workspace) { return (
加载工作区设置中...
); } return (
模块总数
{workspaceStats.total}
主导航
{workspaceStats.main}
管理区
{workspaceStats.admin}
隐藏
{workspaceStats.hidden}
初始化
{workspace.persisted ? "已完成" : "待初始化"}

工作区基线

{workspace.profile} · 单公司 · 账号密码 · 站内通知 · 桌面优先。

{workspaceStats.rolePresets} 个角色预设
{rolePresets.length ? (
{rolePresets.map((item) => (
{item.label}
{item.description}
角色:{item.roleCodes.join(" / ")}
))}
) : (
当前没有推荐角色预设。
)}

模块显隐

主导航只保留高频入口;备用模块保留代码与数据,低频功能默认收进管理区或隐藏。

模块 当前显隐 操作 {moduleEntries.map(([key, mode]) => ( {MODULE_LABELS[key] ?? key} {visibilityModeLabel(mode)}
{VISIBILITY_OPTIONS.map((option) => ( ))}
))}
); } export default WorkspaceSetupPage;