# tencent-im-util 腾讯 IM 回调分发工具:接收腾讯 IM 的消息回调,落库后按租户/源应用分发。配套管理后台、用量统计、关系链/消息迁移等。 > 本文件为**项目级技术上下文**(行为准则见全局 `~/.claude/CLAUDE.md`)。密钥一律不写在此处,配置项以 `app.yml` 为准。 ## 技术栈 - **框架**:Solon(`solon-parent`,非 Spring),Java 21,`solon-web` - **鉴权**:Sa-Token(`sa-token-solon-plugin`) - **持久层**:MyBatis-Plus(`mybatis-plus-extension-solon-plugin`)+ PostgreSQL + HikariCP - **缓存/队列**:Redis(Jedis)+ Caffeine 本地缓存 - **视图**:FreeMarker(`solon-view-freemarker`) - **日志**:logback(`solon-logging-logback-jakarta`) - **腾讯 IM**:`tls-sig-api-v2`(UserSig 签名)+ 自封装 `TencentImClient`(REST API) - **定时**:`solon-scheduling-simple`;**工作线程**:自实现 `worker/DispatchWorker` ## 构建与运行 ```bash # 打包(离线模式,跳过测试) mvn -o package -DskipTests # 运行 java -jar target/tencent-im-util.jar ``` > ⚠️ **不要用 `mvn solon:solon`**(本项目下不可用,会失败)。详见 `.claude/memory/run-app-jar.md`。 > 端口 `8092`,contextPath `/imutil`(即所有路由前缀 `/imutil`)。控制台中文需 UTF-8 终端(已在 `logback.xml` 修正 charset)。 ## 目录结构(`src/main/java/com/imutil`) | 包 | 职责 | |---|---| | `controller` | `AdminController`(`/admin/*` 后台)、`CallbackController`(`/callback/im` 回调入口)、`HealthController`、`SigController`(UserSig 下发) | | `service` + `service/impl` | 业务逻辑(接口 + 实现) | | `entity` | MyBatis-Plus 实体:`Tenant`/`SourceApp`/`ImMessage`/`DistQueue`/`UsageStat`/`MigrateTask`/`UserMapping`/`GroupMapping`/`Recording`/`TrtcRoom`/`CrossTenantGrant`/`CrossTenantAudit`/`PullWatermark`/`ApiCallLog`/`AdminUser` | | `mapper` | MyBatis 映射,含 `PartitionMapper`(PG 分区管理) | | `filter` | `AdminAuthFilter`(后台鉴权)、`TenantAuthFilter`(租户鉴权)、`GlobalExceptionFilter`(全局异常) | | `task` | 定时任务:`DispatchRecoverTask`(死信重投)、`PartitionCreateTask`(分区创建)、`PullCheckTask`、`UsageStatTask` | | `tencent` | `TencentImClient`(REST API + 429 限速重试)、`TencentCallbackSign`(回调签名校验)、`UserSigUtil` | | `worker` | `DispatchWorker`(消费分发队列) | | `common` | 工具类:`PasswordUtil`(PBKDF2)、`RedisService`、`LocalCache`、`RateLimiter`、`Jsons`、`Httpx`、`Ids`、`MsgKeys`、`TenantContext`、`HealthService`、`BizException` | | `model` | `Result`(统一响应体) | ## 核心调用链 1. **回调分发(主链路)**:腾讯服务器 → `CallbackController#callback`(`/imutil/callback/im`) → `CallbackServiceImpl`(验签 + 落 `ImMessage` + 入 `DistQueue`)→ `DispatchWorker` 消费 → 分发到目标租户/源应用;失败由 `DispatchRecoverTask` 重投。 2. **管理后台**:`AdminController`(Sa-Token 会话)+ FreeMarker 页面(`resources/templates/*.ftl`):login / home / tenant / sourceapp / grant / queue / usage / password / messages / migrate。 3. **数据迁移**:`MigrateService`(C2C 全量分页 + 群消息,`msgLookbackDays` 回溯天数,429 自动重试)。 4. **跨租户授权**:`CrossTenantService`(`CrossTenantGrant` 授权 + `CrossTenantAudit` 审计)。 5. **分区与统计**:`PartitionService`(按 `msg_time` 分区裁剪)+ `PartitionCreateTask`;`UsageStatService` + `UsageStatTask`。 ## 项目约定(务必遵守) - **Long ID → String**:雪花 ID 等 `Long` 序列化给前端**必须** `String.valueOf()`,否则 JS 精度丢失(全局规则 10.1)。 - **FreeMarker + java.time 坑**:ftl 里**禁止**对 `LocalDateTime`/`OffsetDateTime` 用 `?string(pattern)`(抛 `NonMethodException`)。改为 Controller 端 `DateTimeFormatter.format` 预格式化成 `xxxStr` 字段,ftl 用 `${obj.xxxStr!}`。详见 `.claude/memory/freemarker-java-time.md`。 - **LocalDate / DateTimeFormatter**:pattern 含 `H/m/s` 时只能用 `LocalDateTime`,禁用 `LocalDate.now()`(全局规则 10.2)。 - **中文注释**:所有注释用简体中文,标识符保持英文(全局规则 9)。 - **密码**:`PasswordUtil` PBKDF2 哈希存 `admin_user.password_hash`(`iterations:salt:hash`);改密走 `/admin/password`。 - **配置不提交**:`app.yml` 含密钥(Redis 密码 / `tencent.secretKey` / admin 默认密码),长期处于未提交状态,**勿提交**;如需本地覆盖敏感值用 `app-env.yml`(已 gitignore)。 ## 关键配置(`src/main/resources/app.yml`,值为准) - `server.port` / `server.contextPath` - `solon.dataSources.db1`(PostgreSQL 连接) - `imutil.redis`(host/port/password/database) - `imutil.tencent`(`sdkAppId`/`secretKey`/`adminUserId`/`apiHost`/`usersigExpireDays`/`callbackToken`——`callbackToken` 留空则跳过回调签名校验,仅联调用) - `imutil.admin`(`defaultUsername`/`defaultPassword`——仅首次初始化 `admin_user`) - `imutil.migrate`(`msgLookbackDays` 等) - `sa-token.*` ## 文档与外部资源 - **实施记录与测试用例**:Obsidian 库 `8 腾讯IM&音视频分发\实施记录与测试用例.md`(项目外,按 T1–T16 任务编号组织;**不进 git**)。 - **项目记忆**:`.claude/memory/`(已 gitignore,含账号/密码/密钥提醒等;索引见其 `MEMORY.md`)。召回失效时跑 `/memory-sync` 重新同步到会话目录。 - **数据库操作**:本机无 `psql`,用 DBX MCP(`192.168.10.118-pg`,database `tencen_im`)查改数据。详见 `.claude/memory/pg-via-dbx.md`。 - **回调测试**:端点 `/imutil/callback/im`,本地可用 curl 模拟(见 `.claude/memory/tencent-callback-test.md`)。 ## 当前进度 核心功能 T1–T15 已完成(T12/T13 TRTC 音视频按需暂缓),T14 消息迁移 V1–V4、T16 消息记录查看已完成。详见实施记录文档与 `.claude/memory/git-author-and-progress.md`。