# 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，不引入新分层、不改动注册流程。
