feat(web): 路由和菜单集成 + 10 页面占位
- App.tsx 添加 10 条 lazy 路由(患者/医护/预约/随访/咨询) - MainLayout.tsx 添加健康管理菜单组(7 项菜单 + 10 条标题映射) - 创建 10 个页面占位组件
This commit is contained in:
@@ -24,6 +24,18 @@ const PluginGraphPage = lazy(() => import('./pages/PluginGraphPage').then((m) =>
|
||||
const PluginDashboardPage = lazy(() => import('./pages/PluginDashboardPage').then((m) => ({ default: m.PluginDashboardPage })));
|
||||
const PluginKanbanPage = lazy(() => import('./pages/PluginKanbanPage'));
|
||||
|
||||
// 健康管理模块
|
||||
const PatientList = lazy(() => import('./pages/health/PatientList'));
|
||||
const PatientDetail = lazy(() => import('./pages/health/PatientDetail'));
|
||||
const PatientTagManage = lazy(() => import('./pages/health/PatientTagManage'));
|
||||
const DoctorList = lazy(() => import('./pages/health/DoctorList'));
|
||||
const AppointmentList = lazy(() => import('./pages/health/AppointmentList'));
|
||||
const DoctorSchedule = lazy(() => import('./pages/health/DoctorSchedule'));
|
||||
const FollowUpTaskList = lazy(() => import('./pages/health/FollowUpTaskList'));
|
||||
const FollowUpRecordList = lazy(() => import('./pages/health/FollowUpRecordList'));
|
||||
const ConsultationList = lazy(() => import('./pages/health/ConsultationList'));
|
||||
const ConsultationDetail = lazy(() => import('./pages/health/ConsultationDetail'));
|
||||
|
||||
function PrivateRoute({ children }: { children: React.ReactNode }) {
|
||||
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
||||
return isAuthenticated ? <>{children}</> : <Navigate to="/login" replace />;
|
||||
@@ -153,6 +165,17 @@ export default function App() {
|
||||
<Route path="/plugins/:pluginId/dashboard" element={<PluginDashboardPage />} />
|
||||
<Route path="/plugins/:pluginId/kanban/:entityName" element={<PluginKanbanPage />} />
|
||||
<Route path="/plugins/:pluginId/:entityName" element={<PluginCRUDPage />} />
|
||||
{/* 健康管理 */}
|
||||
<Route path="/health/patients" element={<PatientList />} />
|
||||
<Route path="/health/patients/:id" element={<PatientDetail />} />
|
||||
<Route path="/health/tags" element={<PatientTagManage />} />
|
||||
<Route path="/health/doctors" element={<DoctorList />} />
|
||||
<Route path="/health/appointments" element={<AppointmentList />} />
|
||||
<Route path="/health/schedules" element={<DoctorSchedule />} />
|
||||
<Route path="/health/follow-up-tasks" element={<FollowUpTaskList />} />
|
||||
<Route path="/health/follow-up-records" element={<FollowUpRecordList />} />
|
||||
<Route path="/health/consultations" element={<ConsultationList />} />
|
||||
<Route path="/health/consultations/:id" element={<ConsultationDetail />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</ErrorBoundary>
|
||||
|
||||
@@ -19,6 +19,11 @@ import {
|
||||
TableOutlined,
|
||||
TagsOutlined,
|
||||
RightOutlined,
|
||||
HeartOutlined,
|
||||
CalendarOutlined,
|
||||
PhoneOutlined,
|
||||
CommentOutlined,
|
||||
MedicineBoxOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAppStore } from '../stores/app';
|
||||
@@ -47,6 +52,16 @@ const bizMenuItems: MenuItem[] = [
|
||||
{ key: '/messages', icon: <MessageOutlined />, label: '消息中心' },
|
||||
];
|
||||
|
||||
const healthMenuItems: MenuItem[] = [
|
||||
{ key: '/health/patients', icon: <TeamOutlined />, label: '患者管理' },
|
||||
{ key: '/health/doctors', icon: <MedicineBoxOutlined />, label: '医护管理' },
|
||||
{ key: '/health/appointments', icon: <CalendarOutlined />, label: '预约排班' },
|
||||
{ key: '/health/schedules', icon: <HeartOutlined />, label: '排班管理' },
|
||||
{ key: '/health/follow-up-tasks', icon: <PhoneOutlined />, label: '随访管理' },
|
||||
{ key: '/health/consultations', icon: <CommentOutlined />, label: '咨询管理' },
|
||||
{ key: '/health/tags', icon: <TagsOutlined />, label: '标签管理' },
|
||||
];
|
||||
|
||||
const sysMenuItems: MenuItem[] = [
|
||||
{ key: '/settings', icon: <SettingOutlined />, label: '系统设置' },
|
||||
{ key: '/plugins/admin', icon: <AppstoreOutlined />, label: '插件管理' },
|
||||
@@ -61,6 +76,16 @@ const routeTitleMap: Record<string, string> = {
|
||||
'/messages': '消息中心',
|
||||
'/settings': '系统设置',
|
||||
'/plugins/admin': '插件管理',
|
||||
'/health/patients': '患者管理',
|
||||
'/health/patients/:id': '患者详情',
|
||||
'/health/tags': '标签管理',
|
||||
'/health/doctors': '医护管理',
|
||||
'/health/appointments': '预约排班',
|
||||
'/health/schedules': '排班管理',
|
||||
'/health/follow-up-tasks': '随访管理',
|
||||
'/health/follow-up-records': '随访记录',
|
||||
'/health/consultations': '咨询管理',
|
||||
'/health/consultations/:id': '咨询详情',
|
||||
};
|
||||
|
||||
// 侧边栏菜单项 - 提取为独立组件避免重复渲染
|
||||
@@ -263,6 +288,20 @@ export default function MainLayout({ children }: { children: React.ReactNode })
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 菜单组:健康管理 */}
|
||||
{!sidebarCollapsed && <div className="erp-sidebar-group">健康管理</div>}
|
||||
<div className="erp-sidebar-menu">
|
||||
{healthMenuItems.map((item) => (
|
||||
<SidebarMenuItem
|
||||
key={item.key}
|
||||
item={item}
|
||||
isActive={currentPath === item.key}
|
||||
collapsed={sidebarCollapsed}
|
||||
onClick={() => navigate(item.key)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 菜单组:插件 */}
|
||||
{pluginMenuGroups.length > 0 && (
|
||||
<>
|
||||
|
||||
10
apps/web/src/pages/health/AppointmentList.tsx
Normal file
10
apps/web/src/pages/health/AppointmentList.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function AppointmentList() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>预约排班</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/ConsultationDetail.tsx
Normal file
10
apps/web/src/pages/health/ConsultationDetail.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function ConsultationDetail() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>咨询详情</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/ConsultationList.tsx
Normal file
10
apps/web/src/pages/health/ConsultationList.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function ConsultationList() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>咨询管理</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/DoctorList.tsx
Normal file
10
apps/web/src/pages/health/DoctorList.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function DoctorList() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>医护管理</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/DoctorSchedule.tsx
Normal file
10
apps/web/src/pages/health/DoctorSchedule.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function DoctorSchedule() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>排班管理</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/FollowUpRecordList.tsx
Normal file
10
apps/web/src/pages/health/FollowUpRecordList.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function FollowUpRecordList() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>随访记录</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/FollowUpTaskList.tsx
Normal file
10
apps/web/src/pages/health/FollowUpTaskList.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function FollowUpTaskList() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>随访管理</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/PatientDetail.tsx
Normal file
10
apps/web/src/pages/health/PatientDetail.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function PatientDetail() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>患者详情</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/PatientList.tsx
Normal file
10
apps/web/src/pages/health/PatientList.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function PatientList() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>患者管理</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/pages/health/PatientTagManage.tsx
Normal file
10
apps/web/src/pages/health/PatientTagManage.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Card, Typography } from 'antd';
|
||||
|
||||
export default function PatientTagManage() {
|
||||
return (
|
||||
<Card>
|
||||
<Typography.Title level={4}>标签管理</Typography.Title>
|
||||
<Typography.Text type="secondary">开发中</Typography.Text>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user