# 急诊退出黑屏问题修复 ## 问题描述 以急诊身份登录系统后,点击退出按钮注销账号时,系统出现黑屏。 ## 问题现象 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 重置 - 减少状态同步的复杂度