背景:用户选定方案 A 主从分栏,A4 需要落地字典与配置页。\n改动:新增 /system/dicts、/system/dicts/:type、/system/settings;主从类型列表 + 三层合并 + 树/词表切换 + 条目/类型弹层;6 组配置 + 命名预览 + 阈值二次确认 + 变更记录;客户字段上限改读 effective config;路由/样式/OpenAPI 类型同步。\n影响面:管理中心新增两个菜单页;客户页上限显示改为配置读取(fallback 共享常量)。\n回滚:回滚本提交并恢复 AppLayout / routes / main 样式 import。\n验证:web typecheck/lint/build;单测 154;浏览器自检 1440/1024 无溢出。
263 lines
8.1 KiB
TypeScript
263 lines
8.1 KiB
TypeScript
/* eslint-disable react-refresh/only-export-components -- 路由配置模块,lazy 组件仅作为路由元素,不做热更新边界 */
|
||
import { Permission } from '@lingxi/shared';
|
||
import { PageSkeleton } from '@lingxi/ui';
|
||
import { lazy, type ReactNode, Suspense } from 'react';
|
||
import { createBrowserRouter, Navigate } from 'react-router';
|
||
|
||
import { RequireAuth } from '@/components/auth/RequireAuth';
|
||
import { RequirePermission } from '@/components/auth/RequirePermission';
|
||
import { AppLayout } from '@/layout/AppLayout';
|
||
import { LegacySystemRedirect, LegacyUsersRedirect } from '@/navigation/legacy-redirect';
|
||
import { ForbiddenPage } from '@/pages/errors/ForbiddenPage';
|
||
import { NotFoundPage } from '@/pages/errors/NotFoundPage';
|
||
import { ServerErrorPage } from '@/pages/errors/ServerErrorPage';
|
||
import { UnauthorizedPage } from '@/pages/errors/UnauthorizedPage';
|
||
import { ROUTES } from '@/routes';
|
||
|
||
const UsersPage = lazy(async () => {
|
||
const module = await import('@/pages/system/users/UsersPage');
|
||
return { default: module.UsersPage };
|
||
});
|
||
|
||
const UserNewPage = lazy(async () => {
|
||
const module = await import('@/pages/system/users/UserNewPage');
|
||
return { default: module.UserNewPage };
|
||
});
|
||
|
||
const DepartmentsPage = lazy(async () => {
|
||
const module = await import('@/pages/system/departments/DepartmentsPage');
|
||
return { default: module.DepartmentsPage };
|
||
});
|
||
|
||
const RolesPage = lazy(async () => {
|
||
const module = await import('@/pages/system/roles/RolesPage');
|
||
return { default: module.RolesPage };
|
||
});
|
||
|
||
const RoleEditorPage = lazy(async () => {
|
||
const module = await import('@/pages/system/roles/RoleEditorPage');
|
||
return { default: module.RoleEditorPage };
|
||
});
|
||
|
||
const RoleNewPage = lazy(async () => {
|
||
const module = await import('@/pages/system/roles/RoleNewPage');
|
||
return { default: module.RoleNewPage };
|
||
});
|
||
|
||
const IndustriesPage = lazy(async () => {
|
||
const module = await import('@/pages/system/industries/IndustriesPage');
|
||
return { default: module.IndustriesPage };
|
||
});
|
||
|
||
const CustomersPage = lazy(async () => {
|
||
const module = await import('@/pages/system/customers/CustomersPage');
|
||
return { default: module.CustomersPage };
|
||
});
|
||
|
||
const CustomerNewPage = lazy(async () => {
|
||
const module = await import('@/pages/system/customers/CustomerNewPage');
|
||
return { default: module.CustomerNewPage };
|
||
});
|
||
|
||
const CustomerDetailPage = lazy(async () => {
|
||
const module = await import('@/pages/system/customers/CustomerDetailPage');
|
||
return { default: module.CustomerDetailPage };
|
||
});
|
||
|
||
const CustomerGroupsPage = lazy(async () => {
|
||
const module = await import('@/pages/system/customer-groups/CustomerGroupsPage');
|
||
return { default: module.CustomerGroupsPage };
|
||
});
|
||
|
||
const CustomerFieldsPage = lazy(async () => {
|
||
const module = await import('@/pages/system/customer-fields/CustomerFieldsPage');
|
||
return { default: module.CustomerFieldsPage };
|
||
});
|
||
|
||
const DictsPage = lazy(async () => {
|
||
const module = await import('@/pages/system/dicts/DictsPage');
|
||
return { default: module.DictsPage };
|
||
});
|
||
|
||
const SettingsPage = lazy(async () => {
|
||
const module = await import('@/pages/system/settings/SettingsPage');
|
||
return { default: module.SettingsPage };
|
||
});
|
||
|
||
function withSkeleton(node: ReactNode): ReactNode {
|
||
return <Suspense fallback={<PageSkeleton rows={8} />}>{node}</Suspense>;
|
||
}
|
||
|
||
export const router = createBrowserRouter([
|
||
// 旧地址兼容:/users* → /system/users*,/platform* → /system*
|
||
{ path: 'users', element: <LegacyUsersRedirect /> },
|
||
{ path: 'users/*', element: <LegacyUsersRedirect /> },
|
||
{ path: 'platform', element: <LegacySystemRedirect /> },
|
||
{ path: 'platform/*', element: <LegacySystemRedirect /> },
|
||
{
|
||
path: ROUTES.login,
|
||
lazy: async () => ({
|
||
Component: (await import('@/pages/login/LoginPage')).default,
|
||
}),
|
||
},
|
||
{
|
||
path: '/',
|
||
element: (
|
||
<RequireAuth>
|
||
<AppLayout />
|
||
</RequireAuth>
|
||
),
|
||
children: [
|
||
{
|
||
index: true,
|
||
lazy: async () => ({
|
||
Component: (await import('@/pages/dashboard/HomePage')).default,
|
||
}),
|
||
},
|
||
{
|
||
path: 'system',
|
||
element: <Navigate to={ROUTES.system.users} replace />,
|
||
},
|
||
{
|
||
path: 'system/users',
|
||
element: (
|
||
<RequirePermission permission={Permission.USER_VIEW}>
|
||
{withSkeleton(<UsersPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/users/new',
|
||
element: (
|
||
<RequirePermission permission={Permission.USER_MANAGE}>
|
||
{withSkeleton(<UserNewPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/users/:id',
|
||
element: (
|
||
<RequirePermission permission={Permission.USER_VIEW}>
|
||
{withSkeleton(<UsersPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/departments',
|
||
element: (
|
||
<RequirePermission permission={Permission.USER_VIEW}>
|
||
{withSkeleton(<DepartmentsPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/roles',
|
||
element: (
|
||
<RequirePermission permission={Permission.ROLE_VIEW}>
|
||
{withSkeleton(<RolesPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/roles/new',
|
||
element: (
|
||
<RequirePermission permission={Permission.ROLE_MANAGE}>
|
||
{withSkeleton(<RoleNewPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/roles/:id',
|
||
element: (
|
||
<RequirePermission permission={Permission.ROLE_VIEW}>
|
||
{withSkeleton(<RoleEditorPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/industries',
|
||
element: (
|
||
<RequirePermission permission={Permission.CUSTOMER_READ}>
|
||
{withSkeleton(<IndustriesPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/customers',
|
||
element: (
|
||
<RequirePermission permission={Permission.CUSTOMER_READ}>
|
||
{withSkeleton(<CustomersPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/customers/new',
|
||
element: (
|
||
<RequirePermission permission={Permission.CUSTOMER_MANAGE}>
|
||
{withSkeleton(<CustomerNewPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/customers/:id',
|
||
element: (
|
||
<RequirePermission permission={Permission.CUSTOMER_READ}>
|
||
{withSkeleton(<CustomerDetailPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/customer-groups',
|
||
element: (
|
||
<RequirePermission permission={Permission.CUSTOMER_GROUP_MANAGE}>
|
||
{withSkeleton(<CustomerGroupsPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/customer-fields/approvals',
|
||
element: (
|
||
<RequirePermission permission={Permission.CUSTOMER_FIELD_APPROVE}>
|
||
{withSkeleton(<CustomerFieldsPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/dicts',
|
||
element: (
|
||
<RequirePermission permission={Permission.DICT_MANAGE}>
|
||
{withSkeleton(<DictsPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/dicts/:type',
|
||
element: (
|
||
<RequirePermission permission={Permission.DICT_MANAGE}>
|
||
{withSkeleton(<DictsPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: 'system/settings',
|
||
element: (
|
||
<RequirePermission permission={Permission.SYSTEM_CONFIGURE}>
|
||
{withSkeleton(<SettingsPage />)}
|
||
</RequirePermission>
|
||
),
|
||
},
|
||
{
|
||
path: ':moduleKey/:itemKey?',
|
||
lazy: async () => ({
|
||
Component: (await import('@/pages/workspace/WorkspacePage')).default,
|
||
}),
|
||
},
|
||
],
|
||
},
|
||
{ path: ROUTES.unauthorized, element: <UnauthorizedPage /> },
|
||
{ path: ROUTES.forbidden, element: <ForbiddenPage /> },
|
||
{ path: ROUTES.notFound, element: <NotFoundPage /> },
|
||
{ path: ROUTES.serverError, element: <ServerErrorPage /> },
|
||
{ path: '*', element: <NotFoundPage /> },
|
||
]);
|