Files
AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-18-路由问题修复报告.md
HaHafeng 66255368b7 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
2026-01-16 13:42:10 +08:00

300 lines
7.0 KiB
Markdown
Raw Permalink 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.
# ASL模块 - 路由问题修复报告
**日期**: 2025-11-18
**问题**: 点击"设置与启动"按钮后页面显示空白
**状态**: ✅ 已修复
---
## 🐛 问题描述
### 用户反馈
1. ❌ 点击左侧"设置与启动"按钮
2. ❌ 页面显示空白
3. ❌ 浏览器控制台警告:`Warning: [antd: Spin] tip only work in nest or fullscreen pattern.`
---
## 🔍 问题分析
### 根本原因
发现了**2个问题**
#### 问题1: Spin组件的tip属性警告 ⚠️
**位置**: `frontend-v2/src/framework/layout/MainLayout.tsx:30`
```typescript
// ❌ 错误代码
<Spin size="large" tip="加载中..." />
```
**原因**: Ant Design 的 `Spin` 组件的 `tip` 属性只能在以下模式使用:
- `nest` 模式(嵌套在内容中)
- `fullscreen` 模式(全屏显示)
当前使用的是普通模式,不支持 `tip` 属性。
#### 问题2: 嵌套路由配置错误 ❌
**位置**: `frontend-v2/src/modules/asl/index.tsx`
```typescript
// ❌ 错误代码
<Routes>
{aslRoutes.map((route, index) => (
<Route
key={index}
path={route.path}
index={route.index}
element={route.element}
/>
))}
</Routes>
```
**原因**:
- `aslRoutes` 是一个复杂的嵌套路由结构
- `map` 方法只能渲染第一层路由,无法处理 `children` 属性
- 导致 `ASLLayout` 的子路由无法正常渲染
- 结果:页面显示空白
**路由结构**:
```
ASLLayout (父路由)
└── screening/title (子路由)
├── settings
├── workbench
└── results
```
这种嵌套结构需要在 JSX 中显式声明。
---
## ✅ 修复方案
### 修复1: 移除Spin的tip属性
**文件**: `frontend-v2/src/framework/layout/MainLayout.tsx`
```typescript
// ✅ 修复后
<Spin size="large" />
```
**效果**: 警告消失,加载动画正常显示
---
### 修复2: 重写嵌套路由结构
**文件**: `frontend-v2/src/modules/asl/index.tsx`
```typescript
// ✅ 修复后
import { Suspense, lazy } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { Spin } from 'antd';
// 懒加载组件
const ASLLayout = lazy(() => import('./components/ASLLayout'));
const TitleScreeningSettings = lazy(() => import('./pages/TitleScreeningSettings'));
const TitleScreeningWorkbench = lazy(() => import('./pages/ScreeningWorkbench'));
const TitleScreeningResults = lazy(() => import('./pages/ScreeningResults'));
const ASLModule = () => {
return (
<Suspense
fallback={
<div className="flex items-center justify-center h-screen">
<Spin size="large" />
</div>
}
>
<Routes>
{/* 父路由: ASLLayout 布局 */}
<Route path="" element={<ASLLayout />}>
{/* 默认重定向到设置页 */}
<Route index element={<Navigate to="screening/title/settings" replace />} />
{/* 标题摘要初筛子路由 */}
<Route path="screening/title">
<Route index element={<Navigate to="settings" replace />} />
<Route path="settings" element={<TitleScreeningSettings />} />
<Route path="workbench" element={<TitleScreeningWorkbench />} />
<Route path="results" element={<TitleScreeningResults />} />
</Route>
</Route>
</Routes>
</Suspense>
);
};
export default ASLModule;
```
**改进**:
- ✅ 使用嵌套的 `<Route>` 标签显式声明层级关系
-`ASLLayout` 作为父路由
-`screening/title` 作为中间层
-`settings/workbench/results` 作为叶子路由
- ✅ 两个 `<Navigate>` 实现自动重定向
---
### 修复3: 删除冗余文件
**删除**: `frontend-v2/src/modules/asl/routes.tsx`
**原因**:
- 路由配置已经直接在 `index.tsx` 中实现
- `routes.tsx` 文件不再被引用
- 避免维护两份路由配置
---
## 🎯 路由流程验证
### 完整路由路径
```
1. 点击"AI智能文献"
→ 进入 /literature
2. ASLModule 接收路径 ""
→ 渲染 ASLLayout左侧导航 + Outlet
3. index route 触发
→ <Navigate to="screening/title/settings" replace />
4. 路径变为 /literature/screening/title/settings
→ ASLLayout 保持显示
→ Outlet 渲染 TitleScreeningSettings 组件
5. 用户看到完整页面:
┌─────────────────────────────────────────┐
│ 左侧导航 │ 设置与启动页面 │
│ (ASL) │ (PICOS + Excel上传) │
└─────────────────────────────────────────┘
```
### 路由匹配测试
| 路径 | 匹配结果 | 显示组件 |
|------|---------|---------|
| `/literature` | index route | Navigate → settings |
| `/literature/screening/title` | index route | Navigate → settings |
| `/literature/screening/title/settings` | ✅ | TitleScreeningSettings |
| `/literature/screening/title/workbench` | ✅ | TitleScreeningWorkbench |
| `/literature/screening/title/results` | ✅ | TitleScreeningResults |
---
## 📊 修复效果
### 修复前 ❌
- 页面空白
- 控制台警告
- 路由无法正确渲染
### 修复后 ✅
- 左侧导航正常显示
- "设置与启动"页面完整渲染
- PICOS表单可以正常填写
- 无控制台警告
---
## 🔧 技术总结
### React Router v6 嵌套路由要点
1. **父子关系必须显式声明**:
```tsx
<Route path="parent" element={<Parent />}>
<Route path="child" element={<Child />} />
</Route>
```
2. **父组件必须有 `<Outlet />`**:
```tsx
const Parent = () => (
<div>
<Sidebar />
<Outlet /> {/* 子路由渲染位置 */}
</div>
);
```
3. **不能用 `map` 渲染嵌套路由**:
```tsx
// ❌ 错误
{routes.map(r => <Route key={r.path} {...r} />)}
// ✅ 正确
<Route path="parent" element={<Parent />}>
<Route path="child" element={<Child />} />
</Route>
```
### Ant Design Spin 组件要点
1. **`tip` 属性的限制**:
```tsx
// ❌ 普通模式不支持 tip
<Spin size="large" tip="加载中..." />
// ✅ 方案1: 移除 tip
<Spin size="large" />
// ✅ 方案2: 使用 fullscreen
<Spin size="large" tip="加载中..." fullscreen />
// ✅ 方案3: 自定义文本
<div>
<Spin size="large" />
<div className="mt-2">...</div>
</div>
```
---
## ✅ 验收清单
- [x] 点击"AI智能文献"能进入模块
- [x] 左侧导航正常显示7个菜单
- [x] "标题摘要初筛"展开3个子菜单
- [x] 默认显示"设置与启动"页面
- [x] PICOS表单完整显示6-8行TextArea
- [x] 无浏览器控制台警告/错误
- [x] 点击其他子菜单可以正常跳转
---
## 🎉 修复完成
**修复文件**:
1.`MainLayout.tsx` - 移除Spin的tip属性
2.`asl/index.tsx` - 重写嵌套路由
3. ✅ 删除 `asl/routes.tsx`
**修复时间**: 15分钟
**问题复杂度**: ⭐⭐⭐ (中等)
**修复质量**: ⭐⭐⭐⭐⭐ (完美)
---
**修复完成时间**: 2025-11-18 22:15
**下一步**: 继续 Week 2 Day 2 开发