Переглянути джерело

fix: 修复急诊模式注销后黑屏问题

- 在 ExitModal.tsx 中导入 setSystemMode 和 SystemMode
- 在注销逻辑中添加系统模式重置,避免急诊模式注销后因 systemMode 未重置导致登录页面返回 null 而黑屏
- 添加详细的问题分析和修复文档
- 更新版本号至 1.1.2

改动文件:
- src/components/ExitModal.tsx
- docs/实现/急诊退出黑屏问题修复.md
- package.json
dengdx 5 днів тому
батько
коміт
cce0c5d6bb

+ 231 - 0
docs/实现/急诊退出黑屏问题修复.md

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

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "zsis",
-  "version": "1.1.1",
+  "version": "1.1.2",
   "private": true,
   "description": "医学成像系统",
   "main": "main.js",

+ 3 - 1
src/components/ExitModal.tsx

@@ -7,6 +7,7 @@ import {
 } from '@ant-design/icons';
 import { useDispatch } from 'react-redux';
 import { clearUserInfo } from '../states/user_info';
+import { setSystemMode, SystemMode } from '../states/systemModeSlice';
 
 const { Text } = Typography;
 
@@ -79,8 +80,9 @@ const ExitModal: React.FC<ExitModalProps> = ({ visible, onClose }) => {
           break;
         case 'logout':
           actionName = '注销用户';
-          // 应用级注销:清除 Redux 用户状态
+          // 应用级注销:清除 Redux 用户状态并重置系统模式
           dispatch(clearUserInfo());
+          dispatch(setSystemMode(SystemMode.Normal)); // 重置系统模式,避免急诊模式注销后黑屏
           message.success('已退出登录');
           onClose();
           return; // 直接返回,不需要后续处理