# 设备移出和邀请码优化 - 设计文档 ## 整体架构 本次修复涉及两个独立的 bug,不需要修改架构,只需要修改具体的业务逻辑层代码。 ### 组件关系图 ```mermaid graph TB subgraph "用户请求" A[客户端] --> B[HTTP Handler] end subgraph "业务逻辑层" B --> C[unbindDeviceLogic] B --> D[bindInviteCodeLogic] end subgraph "服务层" C --> E[DeviceManager.KickDevice] D --> F[UserModel.FindOneByReferCode] end subgraph "数据层" E --> G[WebSocket连接管理] F --> H[GORM/数据库] end ``` --- ## 模块详细设计 ### 模块1: UnbindDeviceLogic 修复 #### 当前数据流 ``` 1. 用户请求解绑设备 2. 验证设备属于当前用户 (device.UserId == u.Id) ✅ 3. 事务中:创建新用户,迁移设备 4. 调用 KickDevice(u.Id, identifier) ❌ <-- 用户ID错误 ``` #### 修复后数据流 ``` 1. 用户请求解绑设备 2. 验证设备属于当前用户 ✅ 3. 保存原始用户ID: originalUserId := device.UserId ✅ 4. 事务中:创建新用户,迁移设备 5. 调用 KickDevice(originalUserId, identifier) ✅ <-- 使用正确的用户ID ``` #### 接口契约 无变化,仅修改内部实现。 --- ### 模块2: BindInviteCodeLogic 修复 #### 当前错误处理 ```go if err != nil { return xerr.DatabaseQueryError // 所有错误统一处理 } ``` #### 修复后错误处理 ```go if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.InviteCodeError("无邀请码") // 记录不存在 → 友好提示 } return xerr.DatabaseQueryError // 其他错误保持原样 } ``` #### 接口契约 API 返回格式不变,但错误码从 `10001` 变为 `20009`(针对邀请码不存在的情况)。 --- ## 异常处理策略 | 场景 | 错误码 | 错误消息 | |------|--------|----------| | 邀请码不存在 | 20009 | 无邀请码 | | 数据库查询错误 | 10001 | Database query error | | 绑定自己的邀请码 | 20009 | 不允许绑定自己 | --- ## 设计原则 1. **最小改动原则**:只修改必要的代码,不重构现有逻辑 2. **向后兼容**:不改变 API 接口定义 3. **代码风格一致**:遵循项目现有的错误处理模式