25 KiB
25 KiB
RMO 网站架构文档
本文档基于当前已完成的代码,描述 RMO 一站式临床试验风险管理网站的前端架构。
一、项目概述
1.1 项目定位
- 名称:RMO 一站式临床试验风险管理网站(rmo-website)
- 技术形态:单页应用(SPA),分为免登录浏览区和登录后系统区两部分。
- 免登录浏览区:首页、风险职责、风险数据、风险活动(临床试验、上市应用)、海外风险、资源中心等公开内容;主导航为三级菜单结构。
- 登录后系统区:工作台、信息资讯、项目列表、保障评估、智能工具等功能模块,根据用户角色呈现有权限的内容。
- 设计原则:统一布局与交互、简洁可维护、模块化可扩展、基于角色的权限控制。
1.2 技术栈
| 类别 | 技术 | 版本 | 说明 |
|---|---|---|---|
| 框架 | React | ^18.2.0 | UI 框架 |
| 语言 | TypeScript | ^5.2.2 | 类型与工程化 |
| 构建 | Vite | ^5.0.8 | 开发与生产构建 |
| 路由 | react-router-dom | ^6.20.0 | 客户端路由 |
| 样式 | 原生 CSS | - | 无 UI 组件库,CSS 变量 + 模块化 CSS |
说明:
- 当前无全局状态管理库(如 Redux/Pinia)、无 UI 组件库;页面级状态以 React 本地 state 为主。
- 登录后系统需要引入全局状态管理:用于存储用户信息、角色权限、登录状态等,建议使用 Context API 或 Zustand/Redux Toolkit。
- 路由守卫:登录后路由需要权限验证,未登录用户访问登录后页面应重定向到登录页。
二、目录结构
RMO网站/
├── index.html # 入口 HTML
├── package.json
├── vite.config.ts
├── tsconfig.json
├── public/ # 静态资源(复制到构建输出)
│ └── pic/ # 图片(含 logo 等)
├── pic/ # 开发阶段图片引用(与 public 对应)
├── src/
│ ├── main.tsx # 应用入口,挂载 #root
│ ├── App.tsx # 根组件:Router + Layout + Routes
│ ├── index.css # 全局样式与 CSS 变量
│ ├── styles/
│ │ └── common.css # 公共页面样式(PageContainer、PageHeader 等)
│ ├── components/ # 公共组件
│ │ ├── Layout.tsx # 整体布局(Header + main + Footer)
│ │ ├── Layout.css
│ │ ├── Header.tsx # 顶部导航(含下拉菜单)
│ │ ├── Header.css
│ │ ├── Footer.tsx # 页脚
│ │ ├── Footer.css
│ │ ├── PageContainer.tsx # 页面根容器(规范必用)
│ │ ├── PageHeader.tsx # 页面头部(标题、描述、操作区)
│ │ ├── ProtectedRoute.tsx # 路由守卫组件(登录后路由使用)
│ │ ├── DashboardLayout.tsx # 登录后系统布局(侧边栏 + 主内容区)
│ │ └── DashboardLayout.css
│ ├── contexts/ # Context API(用户状态、权限等)
│ │ └── AuthContext.tsx # 认证上下文(用户信息、角色、登录状态)
│ └── pages/ # 页面级组件(按业务模块)
│ ├── Home.tsx / Home.css
│ ├── Login.tsx / Login.css
│ ├── RiskDutiesOverview.tsx / RiskDutiesOverview.css # 风险职责总览
│ ├── Sponsor.tsx / Sponsor.css
│ ├── Holder.tsx / Holder.css
│ ├── Institution.tsx / Institution.css
│ ├── Participant.tsx / Participant.css
│ ├── ServiceProvider.tsx / ServiceProvider.css
│ ├── RmoMode.tsx / RmoMode.css # 临床试验(含子页路由)
│ ├── RmoModeOverview.tsx # 临床试验模块首页
│ ├── PostMarket.tsx / PostMarket.css
│ ├── Overseas.tsx / Overseas.css
│ ├── SmartAcquisition.tsx # 风险数据-智能获取
│ ├── PVReport.tsx # 风险数据-PV报告
│ ├── DrugSafetyDict.tsx # 风险数据-药安字典
│ ├── RiskData.css # 风险数据页面共用样式
│ ├── ResourceCenter.tsx / ResourceCenter.css # 资源中心(含子页路由)
│ ├── ResourceCenterOverview.tsx # 资源中心模块首页
│ ├── FAQ.tsx / FAQ.css
│ ├── Company.tsx / Company.css # 未接入路由
│ ├── Services.tsx / Services.css # 未接入路由
│ └── dashboard/ # 登录后系统页面
│ ├── Dashboard.tsx / Dashboard.css # 工作台
│ ├── News.tsx / News.css # 信息资讯
│ ├── ProjectList.tsx / ProjectList.css # 项目列表
│ ├── ProjectDetail.tsx / ProjectDetail.css # 项目明细
│ ├── CoverageAssessment.tsx / CoverageAssessment.css # 保障评估
│ ├── Tools.tsx / Tools.css # 智能工具
│ ├── PremiumCalculator.tsx / PremiumCalculator.css # 保费测算工具
│ ├── ICFEditor.tsx / ICFEditor.css # ICF智能修改
│ └── RiskScoring.tsx / RiskScoring.css # 方案风险评分
├── ReferenceBook/ # 参考资料(文档等)
├── RMO网站需求文档.md
├── 前端技术设计规范.md
├── 快速启动指南.md
└── 网站架构.md # 本文件
三、应用入口与路由架构
3.1 入口链路
index.html
→ <script type="module" src="/src/main.tsx">
main.tsx
→ 引入 index.css、styles/common.css
→ ReactDOM.createRoot(#root).render(<App />)
App.tsx
→ <Router> → <Layout> → <Routes>(定义所有 Route)
3.2 路由一览
| 路径 | 组件 | 说明 |
|---|---|---|
/ |
Home | 首页 |
/concern |
RiskDutiesOverview | 风险职责总览 |
/sponsor |
Sponsor | 申办者职责 |
/holder |
Holder | 持有人职责 |
/institution |
Institution | 研究中心 |
/service-provider |
ServiceProvider | CXO 职责 |
/participant |
Participant | 受试者专区 |
/risk-data/smart-acquisition |
SmartAcquisition | 风险数据-智能获取 |
/risk-data/pv-report |
PVReport | 风险数据-PV报告 |
/risk-data/drug-safety-dict |
DrugSafetyDict | 风险数据-药安字典 |
/rmo-mode |
RmoMode(内部渲染 RmoModeOverview) | 风险活动-临床试验模块首页 |
/rmo-mode/insurance |
RmoMode(内部渲染 Insurance) | 临床试验-保险方案 |
/rmo-mode/guarantee |
RmoMode(内部渲染 Guarantee) | 临床试验-保证方案 |
/rmo-mode/insurance-guarantee |
RmoMode(内部渲染 InsuranceGuarantee) | 临床试验-保险保证 |
/post-market |
PostMarket | 风险活动-上市应用 |
/overseas |
Overseas | 海外风险 |
/system-management |
ResourceCenter(内部渲染 ResourceCenterOverview) | 资源中心首页 |
/system-management/practice-guide |
ResourceCenter(内部渲染 PracticeGuide) | 实践指南 |
/system-management/training |
ResourceCenter(内部渲染 Training) | 培训材料 |
/system-management/faq |
FAQ | 常见问题(资源中心下) |
/faq |
FAQ | 常见问题(兼容旧路径) |
/login |
Login | 登录 |
3.2.1 主导航三级菜单结构
- 一级菜单:首页 | 风险职责 | 风险数据 | 风险活动 | 海外风险 | 资源中心
- 二级菜单(下拉):
- 风险职责:申办者职责、持有人职责、受试者专区、研究中心、CXO职责
- 风险数据:智能获取、PV报告、药安字典
- 风险活动:临床试验(含三级)、上市应用
- 资源中心:实践指南、培训材料、常见问题
- 三级菜单(风险活动 → 临床试验 下):
- 模块首页、保险方案、保证方案、保险保证
3.3 复合路由页(单 Route 多子视图)
- RmoMode:根据
location.pathname在 RmoModeOverview / Insurance / Guarantee / InsuranceGuarantee 间切换,无嵌套<Routes>。 - ResourceCenter:根据
location.pathname在 ResourceCenterOverview / PracticeGuide / Training 间切换;FAQ 为独立 Route,不在 ResourceCenter 内部渲染。 - Tools:智能工具入口页,内部可包含子路由或通过条件渲染切换 PremiumCalculator / ICFEditor / RiskScoring。
3.4 路由守卫与权限控制
- ProtectedRoute 组件:检查用户登录状态,未登录则重定向到
/login,已登录则渲染目标组件。 - 角色权限验证:在页面组件内部或通过高阶组件(HOC)进行角色权限检查,无权限则显示提示或重定向。
- 路由结构建议:
<Route path="/dashboard/*" element={<ProtectedRoute><DashboardLayout /></ProtectedRoute>}> <Route index element={<Dashboard />} /> <Route path="news" element={<News />} /> <Route path="projects" element={<ProjectList />} /> <Route path="projects/:id" element={<ProjectDetail />} /> <Route path="coverage" element={<CoverageAssessment />} /> <Route path="tools" element={<Tools />} /> <Route path="tools/premium-calculator" element={<PremiumCalculator />} /> <Route path="tools/icf-editor" element={<ICFEditor />} /> <Route path="tools/risk-scoring" element={<RiskScoring />} /> </Route>
四、布局与公共组件
4.1 整体布局(Layout)
- 结构:
<div class="layout">= Header +<main class="main-content">(children)+ Footer。 - 职责:所有通过路由渲染的页面均为 Layout 的 children,保证全站统一的顶栏与页脚。
- 登录后布局:登录后系统使用
DashboardLayout(侧边栏导航 + 主内容区),不使用全局 Header/Footer,或 Header 仅保留用户信息与退出登录。
4.2 Header(三级菜单)
- 内容:Logo(链接首页)、主导航(三级菜单结构,参照 vdano.com)、登录入口(未登录时显示"登录",已登录时显示用户信息与退出)。
- 导航结构(与路由对应):
- 首页(一级)
- 风险职责(一级,二级下拉):申办者职责、持有人职责、受试者专区、研究中心、CXO职责
- 风险数据(一级,二级下拉):智能获取、PV报告、药安字典
- 风险活动(一级,二级+三级下拉):临床试验(三级:模块首页、保险方案、保证方案、保险保证)、上市应用
- 海外风险(一级)
- 资源中心(一级,二级下拉):实践指南、培训材料、常见问题
- 登录/用户信息(根据登录状态切换)
- 交互:下拉菜单由本地 state(
concernOpen、riskDataOpen、riskActivitiesOpen、resourceOpen)控制,hover 展开/收起;风险活动下“临床试验”为分组标题,其下为三级子项;当前路由高亮通过useLocation与 path 匹配实现。 - 登录后:已登录用户点击 Logo 或"工作台"可进入
/dashboard;Header 显示用户角色、姓名,提供退出登录入口。
4.3 Footer
- 内容:关于我们、联系方式、合作伙伴、版权信息;静态展示,无路由或状态。
4.4 页面级规范组件
- PageContainer:页面根容器,所有页面内容应置于其内;支持
compact控制内边距。 - PageHeader:页面标题区,支持
title、description、actions;variant="module"时使用模块首页样式(如风险职责、资源中心首页)。 - ProtectedRoute:路由守卫组件,检查用户登录状态,未登录则重定向到
/login。 - DashboardLayout:登录后系统布局组件,包含侧边栏导航(工作台、信息资讯、项目列表、保障评估、智能工具)和主内容区;侧边栏根据用户角色动态显示有权限的菜单项。
五、页面模块与职责
5.1 首页与登录
- Home:Banner(保险/保证入口)、风险管理体系图示、各方职责快捷入口(卡片链向 Sponsor/Holder/Institution/Participant/ServiceProvider)。
- Login:登录页(账号、密码),登录成功后根据用户角色跳转到
/dashboard;登录失败显示错误提示。
5.7 登录后系统页面
5.7.1 工作台(Dashboard)
- 路径:
/dashboard - 布局:DashboardLayout(侧边栏 + 主内容区)
- 内容模块:
- 我的保障:卡片展示当前用户的保障信息(保障数量、保障状态等)
- 我的项目:卡片展示当前用户参与的项目数量、状态统计
- 待办任务:列表展示待处理任务(如待审核的理赔申请、待确认的保障评估等)
- 快捷方式:
- 申请保障:跳转到保障评估页面或申请表单
- 申请理赔:跳转到理赔申请页面(需关联项目)
- 权限:所有登录用户可见,但内容根据角色过滤(如投保人看到自己的保障和项目,保险人看到分配给自己的任务等)。
5.7.2 信息资讯(News)
- 路径:
/dashboard/news - 内容:仅登录后可阅读的信息列表(与公开资源中心区分)
- 列表展示:标题、发布时间、分类、摘要
- 详情页:完整内容展示
- 权限:所有登录用户可见。
5.7.3 项目列表(ProjectList)
- 路径:
/dashboard/projects - 列表字段:
- 试验项目编号
- 试验题目
- 保障范围
- 承保公司
- 承保状态(如:已承保、待审核、已过期等)
- 操作按钮:查看明细、申请理赔
- 权限控制:根据用户角色过滤可见项目
- 投保人:仅看到自己作为投保人的项目
- 保险人:看到分配给自己的项目
- 经纪人:看到自己参与的项目
- TPA:看到需要自己处理的项目
- 研究中心:看到自己机构参与的项目
- CxO:看到自己服务商参与的项目
- 患者:看到自己作为受试者参与的项目(如有)
- 交互:点击"查看明细"跳转到
/dashboard/projects/:id(ProjectDetail);点击"申请理赔"跳转到理赔申请页面(需关联项目ID)。
5.7.4 项目明细(ProjectDetail)
- 路径:
/dashboard/projects/:id - 内容:项目详细信息展示
- 基本信息:项目编号、题目、申办者、保障范围等
- 保障信息:承保公司、承保状态、保障期限、保障金额等
- 相关文档:保险合同、评估报告等(可下载或预览)
- 操作按钮:申请理赔、修改保障(需权限)
- 权限:需有项目查看权限(与项目列表的权限逻辑一致)。
5.7.5 保障评估(CoverageAssessment)
- 路径:
/dashboard/coverage - 列表字段:
- 申办者名称
- 项目编号
- 试验题目
- 保障条款
- 特别约定
- 成交情况(如:已成交、待确认、已拒绝等)
- 权限:投保人、保险人、经纪人、TPA 可见;其他角色不可见。
- 交互:可查看评估详情、修改评估(需权限)、确认成交等。
5.7.6 智能工具(Tools)
- 路径:
/dashboard/tools - 工具入口页:展示三个工具的入口卡片
- 保费测算工具
- ICF智能修改
- 方案风险评分
- 权限:所有登录用户可见工具入口页,但各工具内部有角色权限限制。
5.7.6.1 保费测算工具(PremiumCalculator)
- 路径:
/dashboard/tools/premium-calculator - 功能:根据项目信息、风险等级等参数计算保费
- 权限:投保人、保险人、经纪人可见。
5.7.6.2 ICF智能修改(ICFEditor)
- 路径:
/dashboard/tools/icf-editor - 功能:智能辅助修改知情同意书(ICF)内容
- 权限:投保人、研究中心、CxO 可见。
5.7.6.3 方案风险评分(RiskScoring)
- 路径:
/dashboard/tools/risk-scoring - 功能:对试验方案进行风险评分
- 权限:投保人、保险人、经纪人、TPA 可见。
5.2 风险职责(原“各方关注”)
- RiskDutiesOverview:模块首页,
PageHeader variant="module"+ 各方职责卡片导航。 - Sponsor / Holder / Institution / Participant / ServiceProvider:各角色职责说明页,结构为 PageContainer + PageHeader + 内容区。
5.3 临床试验(原 RMO 模式)
- RmoMode:容器页,根据 path 渲染 RmoModeOverview、Insurance、Guarantee、InsuranceGuarantee 之一。
- RmoModeOverview:模块首页,介绍临床试验保险与保证方案入口。
- Insurance / Guarantee / InsuranceGuarantee:子页,各自独立大块内容(如保险方案网格、保证基金逻辑图、服务供应商 logo 等)。
5.4 上市应用与海外风险
- PostMarket:上市应用相关说明。
- Overseas:海外风险相关说明。
5.5 资源中心(原“体系管理”)
- ResourceCenter:容器页,根据 path 渲染 ResourceCenterOverview、PracticeGuide、Training 之一。
- ResourceCenterOverview:模块首页。
- PracticeGuide / Training:子页,实践指南与培训材料内容。
- FAQ:独立页面,同时挂载在
/system-management/faq与/faq。
5.6 未接入路由的页面
- Company、Services:已实现页面组件,当前未在
App.tsx的 Routes 中配置,如需使用需新增路由并在 Header 中增加入口。
六、样式体系
6.1 样式文件分层
- index.css:全局重置、
:root下的 CSS 变量(品牌色、间距、布局高度等)、body 基础样式。 - styles/common.css:页面容器(
.page-container)、页面头部(.page-header、.module-home-header)、模块首页布局等,被main.tsx全局引入。 - 各页面 *.css:仅被对应页面组件引入,采用类名与页面根类(如
.home、.rmo-mode)限定作用域,避免污染。
6.2 设计令牌(index.css :root)
- 品牌主色:
--brand-primary、--brand-primary-dark、--brand-primary-light等。 - 文本与背景:
--brand-text-default、--text-color、--bg-color等。 - 间距:
--padding-xs~--padding-xl。 - 布局:
--navbar-height、--page-container-padding、--page-header-height、--page-body-height等,用于统一计算内容区高度。
6.3 布局约定
- 主内容区使用
.container限制宽度并居中。 - 列表/卡片区常用
.section、.card、.nav-grid、.page-body等类,与 common.css 及各页面 CSS 配合使用。
七、数据与状态
7.1 状态管理架构
7.1.1 全局状态(登录后系统必需)
- 用户认证状态:使用 Context API(
AuthContext)或 Zustand/Redux Toolkit 管理- 用户信息:用户ID、姓名、邮箱等
- 角色:投保人、保险人、经纪人、TPA、患者、研究中心、CxO
- 登录状态:
isAuthenticated、token(如使用 JWT) - 权限列表:用户拥有的功能权限(可选,也可基于角色推导)
- 状态更新时机:
- 登录成功:设置用户信息和登录状态
- 退出登录:清空用户信息和登录状态
- Token 刷新:更新 token(如使用 JWT)
- 权限变更:更新权限列表(如管理员修改用户权限)
7.1.2 路由状态
- 由 react-router-dom 的
useLocation、Link、Routes/Route管理。
7.1.3 组件状态
- 局部 state(如 Header 的下拉菜单开关、表单输入等)。
- 页面级数据:项目列表、保障评估列表等,可通过 React Query 或 SWR 管理服务端数据缓存与同步。
7.2 数据来源与接口
7.2.1 免登录浏览区
- 页面内容以静态文案与静态结构为主,未对接后端 API。
7.2.2 登录后系统
- 认证接口:
POST /api/auth/login:账号密码登录,返回用户信息、角色、tokenPOST /api/auth/logout:退出登录GET /api/auth/me:获取当前用户信息(用于刷新或验证 token)
- 业务接口(需根据实际后端设计):
- 工作台数据:
GET /api/dashboard/summary - 项目列表:
GET /api/projects(需根据角色过滤) - 项目明细:
GET /api/projects/:id - 保障评估:
GET /api/coverage-assessments - 信息资讯:
GET /api/news - 保费测算:
POST /api/tools/premium-calculator - ICF修改:
POST /api/tools/icf-editor - 风险评分:
POST /api/tools/risk-scoring - 理赔申请:
POST /api/claims
- 工作台数据:
7.3 权限控制实现
7.3.1 角色定义
- 投保人:申办者,可申请保障、查看自己的项目和保障、使用保费测算等工具
- 保险人:保险公司,可查看分配给自己的项目、进行保障评估、使用保费测算和风险评分
- 经纪人:保险经纪人,可查看参与的项目、进行保障评估、使用保费测算和风险评分
- TPA:第三方服务提供商,可查看需要处理的项目、进行保障评估、使用风险评分
- 患者:受试者,可查看自己参与的项目信息(如有)
- 研究中心:研究机构,可查看自己机构参与的项目、使用 ICF 修改工具
- CxO:CRO/CDMO/SMO 等服务商,可查看自己参与的项目、使用 ICF 修改工具
7.3.2 权限验证层级
- 路由级:
ProtectedRoute检查登录状态 - 页面级:页面组件内部检查角色权限,无权限则显示提示或重定向
- 功能级:按钮、操作等根据角色动态显示/隐藏
- 数据级:API 请求时后端根据用户角色过滤返回数据
7.4 推荐技术选型(待实现)
- 状态管理:Context API(轻量)或 Zustand(推荐,简单易用)
- 数据请求:axios + React Query 或 SWR(用于服务端数据缓存、同步、重试)
- 表单管理:React Hook Form(如需要复杂表单)
八、构建与运行
- 开发:
npm run dev(Vite,默认 port 3000,可配置 open)。 - 构建:
npm run build(先tsc再vite build,输出到dist/)。 - 预览构建结果:
npm run preview。 - 静态资源:
public/下资源在构建时原样复制到根路径,页面中引用如/pic/logo/xxx.png。
九、与需求/规范的对应关系
- 需求文档(RMO网站需求文档.md):当前路由与导航结构已按“首页、风险职责、临床试验、上市应用、海外风险、资源中心、常见问题、登录”的架构实现;命名上“风险职责”对应原“各方关注”,“资源中心”对应原“体系管理”,“临床试验”对应原 RMO 模式相关模块。
- 前端技术设计规范(前端技术设计规范.md):规范中部分内容针对 Vue/Element Plus 项目;本仓库为 React 项目,实际遵循的约定为:页面使用 PageContainer、页面头部使用 PageHeader、样式使用 CSS 变量与 common.css、路由集中在 App.tsx。
十、登录后系统实现要点
10.1 布局切换
- 免登录区:使用
Layout(Header + Footer) - 登录后系统:使用
DashboardLayout(侧边栏 + 主内容区),Header 仅保留用户信息与退出
10.2 侧边栏导航结构
工作台
信息资讯
项目列表
保障评估(需权限:投保人、保险人、经纪人、TPA)
智能工具
├── 保费测算工具(需权限:投保人、保险人、经纪人)
├── ICF智能修改(需权限:投保人、研究中心、CxO)
└── 方案风险评分(需权限:投保人、保险人、经纪人、TPA)
10.3 权限控制实现建议
- AuthContext:提供
user、role、isAuthenticated、login、logout等 - ProtectedRoute:检查
isAuthenticated,未登录重定向到/login - 角色权限 HOC/组件:
withRolePermission(Component, allowedRoles)或<RoleGuard allowedRoles={[...]}> - API 拦截器:axios 拦截器在请求头添加 token,响应拦截器处理 401 未授权
10.4 页面数据加载
- 工作台:加载"我的保障"、"我的项目"、"待办任务"的汇总数据
- 项目列表:根据角色调用 API,后端返回该角色可见的项目
- 保障评估:仅特定角色可见,列表数据需按角色过滤
- 智能工具:各工具独立页面,提交表单后调用对应 API
文档版本:基于 2025年2月 前已完成代码整理,已更新登录后系统架构。
维护建议:
- 路由或主导航变更时同步更新本文档第三节与第四节
- 新增全局状态或 API 层时在第七节补充说明
- 登录后系统功能变更时更新第五节(5.7)与第十节
- 角色权限变更时更新第七节(7.3)与第十节(10.2、10.3)