# Implementation Plan: 骑手与用户 IM 即时沟通账号接入 **Branch**: `012-im-user-integration`(按用户要求未创建 git 分支) | **Date**: 2026-06-23 | **Spec**: [spec.md](spec.md) **Input**: Feature specification from `/specs/012-im-user-integration/spec.md` ## Summary 为骑手与用户的即时沟通能力提供 IM 账号开通基础。**不改动用户注册流程**;新增一个独立的「开通 IM 账号」HTTP 接口,APP 在用户注册完成后(或首次需要沟通时)自行调用。后端通过登录 token 解析出 userId,幂等地调用 IM 平台 `POST {base-url}/bot/extCreate`(请求头带 `extToken`),将返回的 `apiKey`/`userId` 绑定存入 `info_user` 表新增的两列(`im_api_key`、`im_user_id`),并把凭证返回给 APP 用于初始化 IM SDK。IM 域名与 extToken 集中放于 `application.yml`,HTTP 调用封装为独立 `@Component` 工具类(仿 `NewebPay`)。 ## Technical Context **Language/Version**: Java(Spring Boot),项目主语言,沿用现有技术栈。 **Primary Dependencies**: Spring Boot、MyBatis-Plus(`@TableName`/`@TableField`)、MyBatis XML mapper、`org.apache.http`(HttpClient,参考 `NewebPay`)、`com.alibaba.fastjson2`(JSON 解析)、若依 `AjaxResult`/`BaseController`、`JwtUtil`(token→userId)。 **Storage**: MySQL。`info_user` 表新增两列:`im_api_key VARCHAR(64)`、`im_user_id BIGINT`。 **Testing**: 手动接口验证(Postman / curl)+ quickstart 验证指南。项目无自动化测试框架约定,沿用现有手动验证方式。 **Target Platform**: Linux 服务器(Spring Boot 后端,端口 8082,context-path `/`)。 **Project Type**: web-service(Spring Boot REST API)。 **Performance Goals**: 开通接口额外开销 < 1s(单次外部 IM 调用)。 **Constraints**: IM 平台不可用时接口明确返回失败、不写无效凭证;幂等(已有凭证直接返回);未登录拒绝。 **Scale/Scope**: 全量用户类型(普通0/商家1/骑手2/夜市3)。1 个新接口、1 个新工具类、2 个新字段、1 段配置、1 条 SQL。 ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* `.specify/memory/constitution.md` 为未填写的空模板(项目尚未定义 constitution 原则)。无约束规则可校验,**本门禁默认通过**,无违规项。建议项目后续补充 constitution。 ## Project Structure ### Documentation (this feature) ```text specs/012-im-user-integration/ ├── plan.md # 本文件 ├── research.md # Phase 0:技术决策 ├── data-model.md # Phase 1:info_user 字段 ├── contracts/ │ ├── im-extcreate.md # IM 平台 extCreate 外部契约 │ └── open-im-account.md # 平台对外「开通 IM 账号」接口契约 ├── quickstart.md # Phase 1:端到端验证指南 └── tasks.md # Phase 2(/speckit-tasks 生成,本阶段不创建) ``` ### Source Code (repository root) ```text ruoyi-admin/src/main/ ├── java/com/ruoyi/app/ │ ├── user/InfoUserController.java # 【改】新增 POST /infouser/user/im/open 开通接口(注入 ImAccountService) │ ├── service/ImAccountService.java # 【新】IM 开通编排服务(幂等+调ImClient+回写),在 admin 避开模块反向依赖 │ └── utils/im/ │ └── ImClient.java # 【新】IM 平台 HTTP 客户端(@Component),封装 extCreate └── resources/ └── application.yml # 【改】新增 im 配置段(base-url/ext-token/create-path/timeout) ruoyi-system/src/main/ ├── java/com/ruoyi/system/ │ ├── domain/InfoUser.java # 【改】新增 imApiKey、imUserId 两字段 + getter/setter │ ├── service/ │ │ └── (IInfoUserService / InfoUserServiceImpl 不改——编排移至 ruoyi-admin 的 ImAccountService) │ └── domain/vo/ImAccountVo.java # 【新】返回 apiKey + imUserId 的 VO └── resources/mapper/infouser/ └── InfoUserMapper.xml # 【改】resultMap 新增 im_api_key / im_user_id 映射 updatesql/sql.md # 【改】追加 info_user 加两列的 ALTER 语句 ``` **Structure Decision**: 沿用项目现有「ruoyi-admin(Controller/utils) + ruoyi-system(domain/service/mapper)」分层。开通接口归属于已存在的 `InfoUserController`(用户域,已具备 `infoUserService`、token 解析依赖),仅追加 1 个方法,避免新建控制器带来的冗余。外部 IM HTTP 调用封装为独立 `@Component` 工具类 `ImClient`(仿 `NewebPay`),由 service 注入调用,保持 service 可测试性与关注点分离。配置用 `@Value` 注入(仿 `NewebPayPayController`)。 ## Complexity Tracking 无 Constitution 违规,无需记录复杂度豁免。本方案保持最小改动:2 字段、1 接口、1 工具类、1 配置段、1 SQL,不引入新分层、不改动注册流程。