# Data Model: 骑手与用户 IM 即时沟通账号接入 **Phase**: 1 | **Date**: 2026-06-23 ## 变更表:info_user(用户信息) 现有用户表,本期**新增两列**存储 IM 平台返回的凭证。 ### 新增字段 | 列名 | Java 属性 | 类型 | 可空 | 说明 | |------|-----------|------|------|------| | `im_api_key` | `imApiKey` | VARCHAR(64) | 是 | IM 平台 extCreate 返回的 `data.apiKey`(如 `f7a49f9745114462a3333e5698aac9ae`,32 位十六进制)。用户尚未开通 IM 时为 NULL。 | | `im_user_id` | `imUserId` | BIGINT | 是 | IM 平台 extCreate 返回的 `data.userId`(如 `2069305587785445400`,19 位长整型)。用户尚未开通时为 NULL。 | ### 关系 - 一个 `info_user` 对应 **0 或 1** 组 IM 凭证(imApiKey 与 imUserId 同时为空,或同时有值)。 - 凭证由 IM 平台生成,平台侧不可变;写入后不再更新(幂等返回)。 ### 验证规则(来自需求) - `imApiKey` 非空 ⇔ `imUserId` 非空(成对写入,避免脏数据)。 - 写入前必须 IM 平台 `code == 200` 且 `data` 含非空 apiKey/userId,否则不写库。 - 已有凭证的用户再次调用开通接口:不写库,直接返回现有凭证(幂等)。 ### Java 实体改动 `InfoUser.java`(`com.ruoyi.system.domain`)新增: ```java /** IM 平台 API 密钥(extCreate 返回) */ @Excel(name = "IM apiKey") private String imApiKey; /** IM 平台用户ID(extCreate 返回,长整型) */ @Excel(name = "IM userId") private Long imUserId; ``` > 因实体已用 Lombok `@Data`,无需手写 getter/setter;但该类仍保留大量手写 getter/setter,按现有风格在末尾补 `getImApiKey/setImApiKey`、`getImUserId/setImUserId` 保持一致(可选,@Data 已覆盖)。 ### Mapper 改动 `InfoUserMapper.xml` 的 `InfoUserResult` resultMap 新增两行映射: ```xml ``` > `selectInfoUserVo` 为 `select * from info_user`,自动覆盖新列,无需改 SQL。 ### SQL 迁移 写入 `updatesql/sql.md`(不直接执行): ```sql -- 2026-06-23 IM 即时沟通账号接入:info_user 新增 IM 凭证两列 ALTER TABLE info_user ADD COLUMN im_api_key VARCHAR(64) DEFAULT NULL COMMENT 'IM平台API密钥(extCreate返回)'; ALTER TABLE info_user ADD COLUMN im_user_id BIGINT DEFAULT NULL COMMENT 'IM平台用户ID(extCreate返回)'; ``` ## 新增 VO:ImAccountVo `com.ruoyi.system.domain.vo.ImAccountVo` —— 开通接口返回体。 | 字段 | 类型 | 说明 | |------|------|------| | `apiKey` | String | IM 平台返回的 apiKey | | `imUserId` | String | IM 平台返回的 userId(**String 规避前端 Long 精度丢失**) | > service 内部 `InfoUser.imUserId` 为 Long;组装 VO 时 `String.valueOf(imUserId)` 转字符串返回。