Branch: 012-im-user-integration(按用户要求未创建 git 分支) | Date: 2026-06-23 | Spec: spec.md
Input: Feature specification from /specs/012-im-user-integration/spec.md
为骑手与用户的即时沟通能力提供 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)。
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。
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
.specify/memory/constitution.md 为未填写的空模板(项目尚未定义 constitution 原则)。无约束规则可校验,本门禁默认通过,无违规项。建议项目后续补充 constitution。
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 生成,本阶段不创建)
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)。
无 Constitution 违规,无需记录复杂度豁免。本方案保持最小改动:2 字段、1 接口、1 工具类、1 配置段、1 SQL,不引入新分层、不改动注册流程。