RMO-Front/PRD/存档/网站架构.md

468 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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进行角色权限检查无权限则显示提示或重定向。
- **路由结构建议**
```tsx
<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`账号密码登录返回用户信息、角色、token
- `POST /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 权限验证层级
1. **路由级**`ProtectedRoute` 检查登录状态
2. **页面级**:页面组件内部检查角色权限,无权限则显示提示或重定向
3. **功能级**:按钮、操作等根据角色动态显示/隐藏
4. **数据级**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 权限控制实现建议
1. **AuthContext**:提供 `user`、`role`、`isAuthenticated`、`login`、`logout` 等
2. **ProtectedRoute**:检查 `isAuthenticated`,未登录重定向到 `/login`
3. **角色权限 HOC/组件**`withRolePermission(Component, allowedRoles)` 或 `<RoleGuard allowedRoles={[...]}>`
4. **API 拦截器**axios 拦截器在请求头添加 token响应拦截器处理 401 未授权
### 10.4 页面数据加载
- 工作台:加载"我的保障"、"我的项目"、"待办任务"的汇总数据
- 项目列表:根据角色调用 API后端返回该角色可见的项目
- 保障评估:仅特定角色可见,列表数据需按角色过滤
- 智能工具:各工具独立页面,提交表单后调用对应 API
---
**文档版本**:基于 2025年2月 前已完成代码整理,已更新登录后系统架构。
**维护建议**
- 路由或主导航变更时同步更新本文档第三节与第四节
- 新增全局状态或 API 层时在第七节补充说明
- 登录后系统功能变更时更新第五节5.7)与第十节
- 角色权限变更时更新第七节7.3与第十节10.2、10.3