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
@@ -0,0 +1,59 @@
package com.imutil.task;
import com.imutil.entity.Tenant;
import com.imutil.mapper.TenantMapper;
import com.imutil.service.SyncService;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.scheduling.annotation.Scheduled;
import java.util.List;
/**
* 数据同步补拉对账定时任务
* <p>
* 定期重跑群消息 + 单聊同步(幂等,本地已有的跳过、缺失的补入),
* 兜底腾讯侧有而本系统暂无的消息,确保本系统数据最全、业务系统不漏收。
* 对应 app.yml 的 solon.scheduling.job.syncCheckJob。
* <p>
* 遍历所有租户,对每个用主应用密钥执行 checkAndPull(主应用数据为主)。
*
* @author imutil
*/
@Slf4j
@Component
public class SyncCheckTask {
@Inject
private SyncService syncService;
@Inject
private TenantMapper tenantMapper;
/**
* 由 app.yml syncCheckJob 驱动(默认 fixedDelay=1 小时)
*/
@Scheduled(name = "syncCheckJob")
public void run() {
List<Tenant> tenants = tenantMapper.selectList(null);
if (tenants == null || tenants.isEmpty()) {
return;
}
int ok = 0;
for (Tenant t : tenants) {
String tid = t.getTenantId();
if (tid == null || tid.isEmpty()) {
continue;
}
try {
syncService.checkAndPull(tid);
ok++;
} catch (Throwable e) {
// 单租户异常不影响其他租户
log.error("补拉对账定时任务异常 tenant={}", tid, e);
}
}
log.info("补拉对账定时任务完成 租户数={} 成功={}", tenants.size(), ok);
}
}