feat(t17): 单聊同步+补拉对账+同步消息进分发;修复 get_roam_msg 60008

新增单聊(C2C)同步、补拉对账定时任务,同步消息纳入分发队列推送业务系统。
1.单聊同步④:user遍历→recentcontact/get_list收集C2C会话→会话对去重→
  get_roam_msg时间窗向前滚动全量→落库(conv_type=1/SYNC/进分发)
2.补拉对账⑤:SyncCheckTask定时(1h)+手动按钮,重跑群+单聊幂等补缺失
3.同步消息进分发:群/单聊distStatus=0入DistQueue;限速分批入队
  (next_retry_at按序号错开delay=seq/dispatchQps)
4.重构:enqueue抽到DispatchService公共方法,Pull/Sync共用

修复(get_roam_msg一直60008静默失败,C2C补拉从未工作):
-命令字 openim_admin/get_roam_msg → openim/admin_getroammsg
-字段 From/To/MaxTimeInterval → Operator_Account/Peer_Account/MaxTime
-新增 getRoamMsgRangeAs(MinTime/MaxTime+LastMsgKey续拉)+getRecentContactListAs

联调(sa 16用户):单聊链路跑通(get_list32+admin_getroammsg OK/Complete=1),
幂等正常,补拉定时工作,无死循环。enqueue实证待配callbackUrl+新消息。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
连龙刚
2026-07-10 11:21:49 +08:00
co-authored by Claude
parent 968a5f2e42
commit 7ca5bd4290
9 changed files with 536 additions and 56 deletions
+31 -3
View File
@@ -5,6 +5,8 @@
<#if msg=='sgdone'>✅ 群组同步完成(详见任务记录)
<#elseif msg=='sudone'>✅ 群成员/用户同步完成(详见任务记录)
<#elseif msg=='smdone'>✅ 群消息同步完成(详见任务记录)
<#elseif msg=='scdone'>✅ 单聊消息同步完成(详见任务记录)
<#elseif msg=='chkdone'>✅ 补拉对账完成(详见任务记录)
<#elseif msg=='syncopt'>❌ 请选择数据源(主应用时须同时选归属租户)
<#else>${msg}
</#if>
@@ -14,8 +16,8 @@
<div class="stat-card" style="margin-bottom:14px;padding:12px 18px">
<b>说明</b>
<span class="muted">:本页为<b>只读拉取</b>,把腾讯 IM 数据同步到本地表用于查看,不在腾讯侧建群/建号。
<b>群组</b>=get_appid_group_list 全量分页;<b>群成员(用户)</b>=遍历群取成员(腾讯无全量用户接口,靠群成员反推);<b>群消息</b>=逐群全量拉取。
<b>C2C 单聊消息无全量会话列表接口</b>,历史单聊请用「数据迁移」页或依赖回调增量。</span>
<b>群组</b>=get_appid_group_list 全量分页;<b>群成员(用户)</b>=遍历群取成员(腾讯无全量用户接口,靠群成员反推);<b>群消息</b>=逐群全量拉取<b>单聊</b>=recentcontact/get_list 按已同步用户反查会话 + get_roam_msg 全量翻页
<b>所有同步消息均入分发队列推送业务系统</b>(限速分批入队),本地同时留底。</span>
</div>
<#-- 公共:数据源 + 归属租户选择(三个表单各自携带) -->
@@ -60,13 +62,39 @@
<div class="stat-card" style="margin-bottom:20px">
<div class="modal-title">③ 同步群消息</div>
<p class="muted">遍历该租户已同步的群,逐群 getGroupMsg + IsFinished 滚动全量 → 写 im_messagesource=SYNC进分发队列)。<b>请先执行「同步群组」</b>。</p>
<p class="muted">遍历该租户已同步的群,逐群 getGroupMsg + IsFinished 滚动全量 → 写 im_messagesource=SYNC<b>进分发队列</b>,限速分批)。<b>请先执行「同步群组」</b>。</p>
<form method="post" action="${basePath}/admin/sync/groupmsg" style="margin-top:14px">
<div class="modal-body"><@srcSelect/></div>
<button type="submit" class="btn btn-primary">同步群消息</button>
</form>
</div>
<div class="stat-card" style="margin-bottom:20px">
<div class="modal-title">④ 同步单聊消息</div>
<p class="muted">遍历该租户已同步用户 → recentcontact/get_list 收集 C2C 会话 → 会话对去重 → get_roam_msg 全量翻页 → 写 im_messageconv_type=1source=SYNC,进分发)。<b>请先执行「同步群成员」</b>。</p>
<form method="post" action="${basePath}/admin/sync/c2cmsg" style="margin-top:14px">
<div class="modal-body"><@srcSelect/></div>
<button type="submit" class="btn btn-primary">同步单聊消息</button>
</form>
</div>
<div class="stat-card" style="margin-bottom:20px">
<div class="modal-title">⑤ 补拉对账</div>
<p class="muted">重跑群消息 + 单聊同步(幂等:本地已有的跳过、缺失的补入),确保本系统数据最全。仅主应用 + 指定租户,可定时自动或手动触发。</p>
<form method="post" action="${basePath}/admin/sync/check" style="margin-top:14px">
<div class="form-group">
<label>归属租户 <span class="muted">(主应用,对账该租户)</span></label>
<select name="tenantId">
<option value="">请选择租户</option>
<#list tenants as t>
<option value="${t.tenantId!}">${t.tenantName!}${t.tenantId!}</option>
</#list>
</select>
</div>
<button type="submit" class="btn btn-primary">补拉对账</button>
</form>
</div>
<h3 style="margin:20px 0 10px;font-size:15px;color:#2c3e50">同步/迁移任务记录</h3>
<#if tasks?has_content>
<table class="data-table">