feat(t14-s1s2): 数据迁移基础设施 + 用户迁移

T14 数据迁移工具 S1/S2 阶段:

S1 基础设施:
- source_app/migrate_task 建表 + 实体 + Mapper
- TencentImClient 双密钥 callApiAs(老应用拉取,不走主应用限流,审计记 migrate)
- 后台「老应用配置」页(CRUD + 测试连通)

S2 用户迁移:
- batchImport(multiaccount_import,每批≤100)
- MigrateService.migrateUsers(前缀转换+导入+映射+校验,幂等)
- 后台「数据迁移」页(上传清单文件/粘贴列表 + 任务记录)

联调通过:3用户清单→加sa前缀→腾讯导入OK→user_mapping→校验3/3/3。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yixiong
2026-07-09 11:12:25 +08:00
co-authored by Claude
parent b4c6652f66
commit 7b1385e160
14 changed files with 754 additions and 11 deletions
@@ -0,0 +1,54 @@
package com.imutil.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.OffsetDateTime;
/**
* 迁移任务记录实体(支持断点续传与校验)
* <p>
* 一次迁移对应一条记录:按对象类型(USER/GROUP/MSG/ROSTER)从老应用迁到主应用。
* pos_cursor 记录断点游标,任务中断后可从游标续传;verify_result 存老 vs 新条数对比。
*
* @author imutil
*/
@Data
@TableName("migrate_task")
public class MigrateTask {
@TableId(type = IdType.AUTO)
private Long id;
/** 关联 source_app.id */
private Long sourceAppId;
/** 对象类型:USER/GROUP/MSG/ROSTER */
private String objectType;
/** 0=pending 1=running 2=paused 3=done 4=failed */
private Integer status;
/** 应处理总数 */
private Long totalCount;
/** 已处理数 */
private Long processedCount;
/** 断点游标(时间戳/会话+seq,按对象类型语义不同) */
private String posCursor;
/** 校验结果 JSON(老 vs 新 条数对比) */
private String verifyResult;
/** 失败原因 */
private String errorMsg;
private OffsetDateTime startedAt;
private OffsetDateTime finishedAt;
private OffsetDateTime createdAt;
}