# 急诊退出黑屏问题修复
## 问题描述
以急诊身份登录系统后,点击退出按钮注销账号时,系统出现黑屏。
## 问题现象
1. 用户以急诊身份登录系统
2. 点击退出按钮
3. 在退出 Modal 中点击"注销用户"
4. 系统显示"已退出登录"消息
5. **系统出现黑屏,无法返回登录页面**
## 根本原因分析
### 急诊登录时的状态设置
在 `src/domain/patient/handleEmergencyOperation.ts` 中,急诊登录时会设置两个关键状态:
```typescript
// Step 2: Set system mode to Emergency
dispatch(setSystemMode(SystemMode.Emergency));
// Step 3: Set temporary user info with guest token
dispatch(setUserInfo({
token: guestToken,
expire: Date.now() + 24 * 60 * 60 * 1000,
uid: -1, // Special uid to identify emergency mode
name: 'Emergency User',
avatar: '',
}));
```
### 注销时的问题
在 `src/components/ExitModal.tsx` 的注销逻辑中,只清除了用户信息:
```typescript
case 'logout':
actionName = '注销用户';
dispatch(clearUserInfo()); // ← 只清除了用户信息
message.success('已退出登录');
onClose();
return;
```
**关键问题**:`systemMode` 仍然保持为 `Emergency`,没有被重置!
### 黑屏的原因链
```
注销操作
↓
clearUserInfo()
↓
src/pages/index/index.tsx 检测到 !loggedIn
↓
返回
↓
Login.tsx 检测到 systemMode === SystemMode.Emergency
↓
返回 null(第 37-39 行)
↓
黑屏!
```
### 代码证据
在 `src/pages/security/Login.tsx` 第 37-39 行:
```typescript
if (systemMode === SystemMode.Emergency) {
return null; // ← 这里导致黑屏
}
```
这个逻辑是为了在急诊模式下隐藏登录页面,因为急诊模式不需要显示登录界面。但当注销后,如果 `systemMode` 没有重置,就会导致登录页面无法显示。
## 解决方案
### 修改内容
在 `src/components/ExitModal.tsx` 中:
1. **导入必要的依赖**:
```typescript
import { setSystemMode } from '../states/systemModeSlice';
import { SystemMode } from '../states/systemModeSlice';
```
2. **在注销逻辑中添加 systemMode 重置**:
```typescript
case 'logout':
actionName = '注销用户';
dispatch(clearUserInfo());
dispatch(setSystemMode(SystemMode.Normal)); // ← 添加这一行
message.success('已退出登录');
onClose();
return;
```
### 修改后的完整流程
```
注销操作
↓
clearUserInfo() + setSystemMode(SystemMode.Normal)
↓
src/pages/index/index.tsx 检测到 !loggedIn
↓
返回
↓
Login.tsx 检测到 systemMode === SystemMode.Normal
↓
正常显示登录界面
✓
```
## 修改文件
### 1. src/components/ExitModal.tsx
**修改前**:
```typescript
import { clearUserInfo } from '../states/user_info';
// ...
case 'logout':
actionName = '注销用户';
dispatch(clearUserInfo());
message.success('已退出登录');
onClose();
return;
```
**修改后**:
```typescript
import { clearUserInfo } from '../states/user_info';
import { setSystemMode, SystemMode } from '../states/systemModeSlice';
// ...
case 'logout':
actionName = '注销用户';
dispatch(clearUserInfo());
dispatch(setSystemMode(SystemMode.Normal)); // 重置系统模式
message.success('已退出登录');
onClose();
return;
```
## 测试验证
### 测试步骤
1. 启动应用
2. 点击"急诊"按钮以急诊身份登录
3. 验证进入主界面
4. 点击退出按钮
5. 在退出 Modal 中点击"注销用户"
6. 点击确认
### 预期结果
- ✅ 显示"已退出登录"消息
- ✅ Modal 关闭
- ✅ **正常显示登录页面**(不再黑屏)
- ✅ 可以重新登录或再次使用急诊功能
### 状态验证
注销后应确保:
- ✅ `userInfo.token` = ''
- ✅ `userInfo.uid` = 0
- ✅ `systemMode` = 'Normal'
- ✅ `loggedIn` = false
## 影响范围
### 修改的文件
- `src/components/ExitModal.tsx`
### 影响的功能
- ✅ 急诊注销流程
- ✅ 不影响普通用户注销流程
- ✅ 不影响其他退出方式(关闭程序、关机)
## 注意事项
1. **此修复只影响注销逻辑**,不影响:
- 关闭程序功能
- 关机功能
- 普通用户登录/注销
2. **系统模式重置的必要性**:
- 急诊模式是一种特殊的系统状态
- 注销时必须将系统恢复到正常模式
- 否则会导致 UI 渲染异常
3. **与已有注销功能的兼容性**:
- 此修改与现有的注销逻辑完全兼容
- 不会影响普通用户的注销体验
- 增强了急诊模式的完整性
## 相关文档
- [注销功能实现总结](../logout-implementation-summary.md)
- [急诊流程](./急诊流程.md)
## 完成状态
- [x] 问题分析
- [x] 解决方案设计
- [x] 代码修改
- [ ] 测试验证(待手动测试)
## 后续优化建议
1. **添加 Cypress 测试**:
- 创建急诊注销的端到端测试
- 验证 systemMode 状态正确重置
2. **错误处理增强**:
- 考虑在错误情况下也重置 systemMode
- 确保系统状态的一致性
3. **状态管理优化**:
- 考虑在 clearUserInfo 中自动处理 systemMode 重置
- 减少状态同步的复杂度