feat(admin): Add user management and upgrade to module permission system

Features - User Management (Phase 4.1):
- Database: Add user_modules table for fine-grained module permissions
- Database: Add 4 user permissions (view/create/edit/delete) to role_permissions
- Backend: UserService (780 lines) - CRUD with tenant isolation
- Backend: UserController + UserRoutes (648 lines) - 13 API endpoints
- Backend: Batch import users from Excel
- Frontend: UserListPage (412 lines) - list/filter/search/pagination
- Frontend: UserFormPage (341 lines) - create/edit with module config
- Frontend: UserDetailPage (393 lines) - details/tenant/module management
- Frontend: 3 modal components (592 lines) - import/assign/configure
- API: GET/POST/PUT/DELETE /api/admin/users/* endpoints

Architecture Upgrade - Module Permission System:
- Backend: Add getUserModules() method in auth.service
- Backend: Login API returns modules array in user object
- Frontend: AuthContext adds hasModule() method
- Frontend: Navigation filters modules based on user.modules
- Frontend: RouteGuard checks requiredModule instead of requiredVersion
- Frontend: Remove deprecated version-based permission system
- UX: Only show accessible modules in navigation (clean UI)
- UX: Smart redirect after login (avoid 403 for regular users)

Fixes:
- Fix UTF-8 encoding corruption in ~100 docs files
- Fix pageSize type conversion in userService (String to Number)
- Fix authUser undefined error in TopNavigation
- Fix login redirect logic with role-based access check
- Update Git commit guidelines v1.2 with UTF-8 safety rules

Database Changes:
- CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled)
- ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code)
- INSERT 4 permissions + role assignments
- UPDATE PUBLIC tenant with 8 module subscriptions

Technical:
- Backend: 5 new files (~2400 lines)
- Frontend: 10 new files (~2500 lines)
- Docs: 1 development record + 2 status updates + 1 guideline update
- Total: ~4900 lines of code

Status: User management 100% complete, module permission system operational
This commit is contained in:
2026-01-16 13:42:10 +08:00
parent 98d862dbd4
commit 66255368b7
560 changed files with 70424 additions and 52353 deletions

View File

@@ -2,112 +2,112 @@
**日期**: 2025-11-18
**任务**: 根据用户反馈重构前端架构
**状æ€?*: âœ?完æˆ<C3A6>
**状态**: ✅ 完成
---
## 📝 重构原因
### 用户反馈
1. â<EFBFBD>?åŽŸæ¹æ¡ˆç¼ºå°å·¦ä¾§å¯¼èˆªæ <C3A6>
2. â<EFBFBD>?需è¦<C3A8>å<EFBFBD>考原åžçš„7个模å<C2A1>—结æž?
3. â<EFBFBD>?MVPå<50>ªéœ€æ ‡é¢˜æ˜è¦<C3A8>åˆ<C3A5>ç­ï¼Œä¸<C3A4>需è¦<C3A8>项ç®ç®¡ç<C2A1>?
4. â<EFBFBD>?PICOS输入框太å°<EFBFBD>,内容显示ä¸<EFBFBD>å…¨
1. ❌ 原方案缺少左侧导航栏
2. ❌ 需要参考原型的7个模块结构
3. ❌ MVP只需标题摘要初筛不需要项目管理
4. PICOS输入框太小,内容显示不全
---
## 🔄 重构内容
### 1. 创建左侧导航布局 �
### 1. 创建左侧导航布局 ⭐
**新文�*: `components/ASLLayout.tsx`
**新文件**: `components/ASLLayout.tsx`
**功能**:
- âœ?左侧导航æ <C3A6>(200px宽度ï¼?
- âœ?7个一级è<C2A7>œå<C593>?
- ✅ 左侧导航栏200px宽度
- ✅ 7个一级菜单
1. 研究方案生成(禁用)
2. 智能æ‡çŒ®æ£€ç´¢ï¼ˆç¦<EFBFBD>用ï¼?
2. 智能文献检索(禁用)
3. 文献管理(禁用)
4. **标题æ˜è¦<EFBFBD>åˆ<EFBFBD>ç­**(✅ å<>¯ç”¨ï¼?个å­<C3A5>è<EFBFBD>œå<C593>•ï¼?
- 设置与å<EFBFBD>¯åŠ?
- 审核工作å<EFBFBD>?
4. **标题摘要初筛**(✅ 可用3个子菜单
- 设置与启动
- 审核工作台
- 初筛结果
5. 全文复筛(禁用)
6. å…¨æ‡è§£æž<EFBFBD>与数æ<EFBFBD>®æ<EFBFBD><EFBFBD>å<EFBFBD>(ç¦<EFBFBD>用ï¼?
7. æ•°æ<EFBFBD>®ç»¼å<EFBFBD>ˆåˆ†æž<EFBFBD>与报åŠï¼ˆç¦<EFBFBD>用ï¼?
- âœ?å<>³ä¾§å†…容区(Outlet渲染å­<C3A5>页é<C2B5>¢ï¼‰
6. 全文解析与数据提取(禁用)
7. 数据综合分析与报告(禁用)
- ✅ 右侧内容区Outlet渲染子页面
**布局结构**:
```
┌────────────────────────────────────────────────�
â”? AI智能æ‡çŒ® - 标题æ˜è¦<C3A8>åˆ<C3A5>ç­ MVP â”?
├─────────────┬──────────────────────────────────�
â”?左侧导航 â”? å<>³ä¾§å†…容åŒ? â”?
â”?(250px) â”? â”?
â”? â”? â”?
â”?7个模å<C2A1>? â”? (当å‰<C3A5>å­<C3A5>页é<C2B5>? â”?
â”?(标题åˆ<C3A5>ç­ â”? â”?
� 展开3� � �
â”? å­<C3A5>è<EFBFBD>œå<C593>? â”? â”?
â”? â”? â”?
└─────────────┴──────────────────────────────────�
┌────────────────────────────────────────────────┐
│ AI智能文献 - 标题摘要初筛 MVP
├─────────────┬──────────────────────────────────┤
│ 左侧导航 │ 右侧内容区
(250px)
│ 7个模块 │ (当前子页面)
│ (标题初筛 │
│ 展开3个 │
│ 子菜单)
└─────────────┴──────────────────────────────────┘
```
---
### 2. 重构3个子页面
#### 页é<EFBFBD>¢1: 设置与å<C5BD>¯åŠ?â­?
#### 页面1: 设置与启动 ⭐
**文件**: `pages/TitleScreeningSettings.tsx`
**改进**:
- �PICOS字段全部改为TextArea�-8行)
- âœ?纳入/æŽé™¤æ ‡å‡†TextAreaï¼?-10行)
- âœ?å<>ˆå¹¶äº†æ‡çŒ®å¯¼å…¥åŠŸèƒ½ï¼ˆExcel上传 + 模æ<C2A1>¿ä¸è½½ï¼?
- âœ?筛选风格选择ï¼?ç§<C3A7>:宽æ<C2BD>¾/标准/严格ï¼?
- âœ?å<>¯åЍAIç­é€‰æŒ‰é?
- PICOS字段全部改为TextArea6-8行
- ✅ 纳入/排除标准TextArea8-10行
- ✅ 合并了文献导入功能Excel上传 + 模板下载)
- ✅ 筛选风格选择3种宽松/标准/严格)
- ✅ 启动AI筛选按钮
**表单字段**:
```typescript
- P - 人群: TextArea (8� �
- I - å¹²é¢: TextArea (8è¡? â­?
- C - 对ç§: TextArea (6è¡? â­?
- O - ç»å±: TextArea (6行,å<EFBFBD>¯é? â­?
- S - ç ç©è®¾è®¡: TextArea (4è¡? â­?
- çº³å¥æ å: TextArea (10è¡? â­?
- æŽé¤æ å: TextArea (10è¡? â­?
- ç­é风æ ? Radio (宽æ<EFBFBD>¾/æ å/严格)
- P - 人群: TextArea (8)
- I - 干预: TextArea (8)
- C - 对照: TextArea (6)
- O - 结局: TextArea (6)
- S - 研究设计: TextArea (4)
- 纳入标准: TextArea (10)
- 排除标准: TextArea (10)
- 筛选风格: Radio (//)
```
**功能流程**:
```
1. 填写PICOS标准 �
2. 填写纳入/排除标准 �
3. 选择筛选风��
4. 上传Excelæ‡ä»¶ â†?
5. 点击"å¼€å§AIç­é€? â†?
1. 填写PICOS标准 →
2. 填写纳入/排除标准 →
3. 选择筛选风格 →
4. 上传Excel文件 →
5. 点击"开始AI筛选" →
6. 跳转到审核工作台
```
#### 页é<EFBFBD>¢2: 审核工作å<C593>°ï¼ˆå<CB86> ä½<C3A4>ï¼?
#### 页面2: 审核工作台(占位)
**文件**: `pages/ScreeningWorkbench.tsx`
**计划功能**(Week 2 Day 3-4�
**计划功能**Week 2 Day 3-4:
- 显示当前PICOS标准折叠面板
- 双行表格(严格按照原型)
- ç¹å‡»PICO维度 â†?弹出å<C2BA>Œè§†å¾Modal
- 修改最终决�
- 点击PICO维度 → 弹出双视图Modal
- 修改最终决策
#### 页面3: 初筛结果(占位)
**文件**: `pages/ScreeningResults.tsx`
**计划功能**(Week 2 Day 5�
- 统计å<EFBFBD>¡ç‰‡ï¼ˆæ€»æ•°/纳入/排除ï¼?
**计划功能**Week 2 Day 5:
- 统计卡片(总数/纳入/排除)
- PRISMA排除原因统计
- Tab切æ<EFBFBD>¢ï¼ˆçº³å…?排除ï¼?
- Tab切换(纳入/排除)
- 结果表格
- 批量操作
- 导出Excel
@@ -116,129 +116,129 @@
### 3. 更新路由结构
**新路�*:
**新路由**:
```
/literature (进入ASL模块)
└── ASLLayout (左侧导航布局)
└── /screening/title (标题摘要初筛)
├── /settings (默认) - 设置与å<C5BD>¯åŠ?
├── /workbench - 审核工作å<EFBFBD>?
├── /settings (默认) - 设置与启动
├── /workbench - 审核工作台
└── /results - 初筛结果
```
**路由跳转**:
- 点击"AI智能æ‡çŒ®" â†?自动跳转åˆ?`/literature/screening/title/settings`
- 点击"å¼€å§AIç­é€? â†?跳转åˆ?`/literature/screening/title/workbench`
- 点击"AI智能文献" → 自动跳转到 `/literature/screening/title/settings`
- 点击"开始AI筛选" → 跳转到 `/literature/screening/title/workbench`
---
### 4. 删除旧文�
### 4. 删除旧文件
**已删�*:
- â<EFBFBD>?`pages/ProjectManagement.tsx` - 项ç®ç®¡ç<EFBFBD>†é¡µï¼ˆMVPä¸<EFBFBD>需è¦<EFBFBD>)
- â<EFBFBD>?`components/ProjectForm.tsx` - 项ç®è¡¨å<EFBFBD>•组件
- â<EFBFBD>?`pages/LiteratureImport.tsx` - æ‡çŒ®å¯¼å…¥é¡µï¼ˆåŠŸèƒ½å<EFBFBD>ˆå¹¶ï¼?
- â<EFBFBD>?`hooks/useProjects.ts` - 项ç®ç®¡ç<EFBFBD>Hooks
**已删除**:
- `pages/ProjectManagement.tsx` - 项目管理页MVP不需要
- `components/ProjectForm.tsx` - 项目表单组件
- `pages/LiteratureImport.tsx` - 文献导入页(功能合并)
- `hooks/useProjects.ts` - 项目管理Hooks
**保留文件**:
- âœ?`types/index.ts` - ç±»åžå®šä¹‰ï¼ˆå®Œæ•´ä¿<EFBFBD>留)
- âœ?`api/index.ts` - API客户端(完整ä¿<EFBFBD>ç•™ï¼?
- �`components/ASLLayout.tsx` - 新布局组件 �
- âœ?`pages/TitleScreeningSettings.tsx` - 设置与å<EFBFBD>¯åŠ?â­?
- âœ?`pages/ScreeningWorkbench.tsx` - 审核工作å<EFBFBD>°ï¼ˆå<EFBFBD> ä½<EFBFBD>ï¼?
- âœ?`pages/ScreeningResults.tsx` - åˆ<EFBFBD>ç­ç»“果(å<EFBFBD> ä½<EFBFBD>)
- `types/index.ts` - 类型定义(完整保留)
- `api/index.ts` - API客户端(完整保留)
- `components/ASLLayout.tsx` - 新布局组件 ⭐
- `pages/TitleScreeningSettings.tsx` - 设置与启动 ⭐
- `pages/ScreeningWorkbench.tsx` - 审核工作台(占位)
- `pages/ScreeningResults.tsx` - 初筛结果(占位)
---
## 📊 重构对比
| 项目 | é‡<C3A9>æž„å‰?| é‡<C3A9>æž„å<E2809E>?|
| 项目 | 重构前 | 重构后 |
|------|--------|--------|
| **布局** | å<EFBFBD>ªæœ‰é¡¶éƒ¨å¯¼èˆª | 左侧导航 + 顶部导航 â­?|
| **第一个页é<EFBFBD>?* | 项ç®ç®¡ç<C2A1>†åˆ—表 | 设置与å<C5BD>¯åŠ¨ï¼ˆPICOS + 导入ï¼?â­?|
| **PICOS输入** | Input (å<EFBFBD>•行) | TextArea (6-8è¡? â­?|
| **导航结构** | æ‰<C3A6>å¹³ | æ ‘å½¢ï¼?个模å<C2A1>?+ å­<C3A5>è<EFBFBD>œå<C593>•) â­?|
| **项目概念** | 需è¦<C3A8>åˆå»ºé¡¹ç?| MVPä¸<C3A4>需è¦<C3A8>项ç?â­?|
| **布局** | 只有顶部导航 | 左侧导航 + 顶部导航 ⭐ |
| **第一个页面** | 项目管理列表 | 设置与启动PICOS + 导入) ⭐ |
| **PICOS输入** | Input (单行) | TextArea (6-8行) ⭐ |
| **导航结构** | 扁平 | 树形7个模块 + 子菜单) ⭐ |
| **项目概念** | 需要创建项目 | MVP不需要项目 ⭐ |
| **文献导入** | 独立页面 | 合并到设置页 |
---
## âœ?é‡<C3A9>构验收
## ✅ 重构验收
### 布局验收
- âœ?左侧导航æ <C3A6>正常显ç¤?
- âœ?7个一级è<C2A7>œå<C593>•正确展ç¤?
- âœ?标题æ˜è¦<C3A8>åˆ<C3A5>ç­å±•å¼€3个å­<C3A5>è<EFBFBD>œå<C593>
- âœ?其仿¨¡å<C2A1>—显示"敬请期待"
- âœ?å<>³ä¾§å†…容区正常渲æŸ?
- ✅ 左侧导航栏正常显示
- ✅ 7个一级菜单正确展示
- ✅ 标题摘要初筛展开3个子菜单
- ✅ 其他模块显示"敬请期待"
- ✅ 右侧内容区正常渲染
### 功能验收
- âœ?点击"AI智能æ‡çŒ®"进入设置é¡?
- �PICOS字段全部为TextArea(足够大�
- âœ?å<>¯ä»¥å¡«å†™æµè¯•æ•°æ<C2B0>®ï¼ˆé<CB86>žå¿ƒæº<C3A6>性å<C2A7>中案ä¾ï¼‰
- âœ?å<>¯ä»¥ä¸Šä¼ Excelæ‡ä»¶
- âœ?å<>¯ä»¥é€‰æ©ç­é€‰é£Žæ ?
- âœ?点击"å¼€å§AIç­é€?跳转到工作å<C593>°
- ✅ 点击"AI智能文献"进入设置页
- PICOS字段全部为TextArea足够大
- ✅ 可以填写测试数据(非心源性卒中案例)
- ✅ 可以上传Excel文件
- ✅ 可以选择筛选风格
- ✅ 点击"开始AI筛选"跳转到工作台
### 路由验收
- �`/literature` �自动跳转�`/literature/screening/title/settings`
- �`/literature/screening/title/settings` - 设置页正�
- âœ?`/literature/screening/title/workbench` - 工作å<EFBFBD>°å<EFBFBD> ä½?
- âœ?`/literature/screening/title/results` - 结果页å<EFBFBD> ä½?
- `/literature` → 自动跳转到 `/literature/screening/title/settings`
- `/literature/screening/title/settings` - 设置页正常
- `/literature/screening/title/workbench` - 工作台占位
- `/literature/screening/title/results` - 结果页占位
---
## 🎯 架构亮点
### 1. 完全符å<EFBFBD>ˆåŽŸåžè®¾è®¡ â­<C3A2>â­<C3A2>â­?
- 7个模å<EFBFBD>—结æž?
### 1. 完全符合原型设计 ⭐⭐⭐
- 7个模块结构
- 标题摘要初筛3个子页面
- 左侧导航 + 右侧内容
### 2. MVP优先策略 â­<C3A2>â­<C3A2>â­?
- å<EFBFBD>ªå¼€å<EFBFBD>标题æ˜è¦<EFBFBD>åˆ<EFBFBD>ç­?
- 其仿¨¡å<EFBFBD>—ç¦<EFBFBD>用但å<EFBFBD>¯è§?
### 2. MVP优先策略 ⭐⭐⭐
- 只开发标题摘要初筛
- 其他模块禁用但可见
- 未来扩展性强
### 3. PICOS空间优化 â­<C3A2>â­<C3A2>â­?
- Input �TextArea
- 足够显示å¤<EFBFBD>æ<EFBFBD>çš„æµè¯•æ•°æ<EFBFBD>?
### 3. PICOS空间优化 ⭐⭐⭐
- Input TextArea
- 足够显示复杂的测试数据
- 用户体验友好
### 4. 功能å<EFBFBD>ˆå¹¶ç®€åŒ?â­<C3A2>â­<C3A2>
### 4. 功能合并简化 ⭐⭐
- 文献导入合并到设置页
- 减少页面跳转
- æµ<EFBFBD>ç¨æ´é¡ºç•?
- 流程更顺畅
---
## 📝 代码统计
| 类别 | 文件æ•?| 代ç <C3A7>行数 | 说明 |
| 类别 | 文件数 | 代码行数 | 说明 |
|------|-------|---------|------|
| **新增** | | | |
| 布局组件 | 1 | 155 | ASLLayout.tsx |
| 设置页面 | 1 | 350 | TitleScreeningSettings.tsx |
| 工作å<EFBFBD>°é¡µé<EFBFBD>?| 1 | 42 | ScreeningWorkbench.tsx(å<EFBFBD> ä½<EFBFBD>)|
| 工作台页面 | 1 | 42 | ScreeningWorkbench.tsx(占位)|
| 结果页面 | 1 | 45 | ScreeningResults.tsx占位|
| 路由配置 | 1 | 58 | routes.tsx重写|
| **删除** | 4 | -800 | 旧的项目管理相关文件 |
| **净å¢?* | **5** | **-150** | 代ç <EFBFBD>æ´ç²¾ç®€äº†ï¼<EFBFBD> |
| **净增** | **5** | **-150** | 代码更精简了! |
---
## 🚀 ä¸ä¸€æ­¥å¼€å<E282AC>?
## 🚀 下一步开发
### Week 2 继续计划
**Day 2今天剩余时间**:
- âœ?Excelè§£æž<EFBFBD>逻è¾ï¼ˆå†…存解æž<EFBFBD>,ä¸<EFBFBD>è<EFBFBD>½ç˜ï¼‰
- �文献预览表格
- âœ?去é‡<C3A9>逻è¾
- âœ?Excel模æ<EFBFBD>¿ç”Ÿæˆ<EFBFBD>
- Excel解析逻辑(内存解析,不落盘)
- ✅ 文献预览表格
- ✅ 去重逻辑
- Excel模板生成
**Day 3-4**:
- 审核工作å<EFBFBD>°ï¼ˆå<EFBFBD>Œè¡Œè¡¨æ ¼ï¼?
- 审核工作台(双行表格)
- 双视图Modal
- 人工复核功能
@@ -252,27 +252,27 @@
## 🎉 重构总结
**耗时**: 30分钟
**æ‡ä»¶å<EFBFBD>˜æ´**: æ°å¢ž5个,删除4ä¸?
**代ç <EFBFBD>é‡?*: 净å‡<C3A5>å°150行(æ´ç²¾ç®€ï¼?
**文件变更**: 新增5个删除4个
**代码量**: 净减少150行更精简
**重构效果**:
- â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­?完全符å<C2A6>ˆç”¨æˆ·éœ€æ±?
- â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­<>考原åžè®¾è®?
- â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­?MVP优先ç­ç•¥
- â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­<EFBFBD>â­?PICOS空间足够
- ⭐⭐⭐⭐⭐ 完全符合用户需求
- ⭐⭐⭐⭐⭐ 参考原型设计
- ⭐⭐⭐⭐⭐ MVP优先策略
- ⭐⭐⭐⭐⭐ PICOS空间足够
- ⭐⭐⭐⭐ 代码结构清晰
**用户反馈确认**:
1. âœ?左侧导航 - 符å<C2A6>ˆåŽŸåž
2. âœ?第一个页é<C2B5>¢æ˜¯"设置与å<C5BD>¯åŠ?
3. �PICOS字段都用TextArea
4. âœ?MVPä¸<C3A4>需è¦<C3A8>é¡¹ç®æ¦å¿?
5. âœ?å<>Œè¡Œè¡¨æ ¼æŒ‰ç…§åŽŸåžè®¾è®¡
1. ✅ 左侧导航 - 符合原型
2. ✅ 第一个页面是"设置与启动"
3. PICOS字段都用TextArea
4. ✅ MVP不需要项目概念
5. ✅ 双行表格按照原型设计
---
**重构完成时间**: 2025-11-18 22:00
**下一阶段**: Week 2 Day 2 ç»§ç»­å¼€å<EFBFBD>?
**下一阶段**: Week 2 Day 2 继续开发