Files
tencent-im-util/src/main/java/com/imutil/mapper/PullWatermarkMapper.java
T
yixiongandClaude d22fdcfaad feat: 初始化腾讯IM分发工具骨架,含回调分发链路与历史消息补拉
- 应用骨架: Solon + MyBatis-Plus + PostgreSQL + Redis + Sa-Token
- 核心链路: 回调网关 → 消息落库(幂等) → 分发队列(FOR UPDATE SKIP LOCKED) → worker消费/重试/死信
- 多租户隔离: 前缀法账号映射, 所有业务表带 tenant_id
- 管理后台: FreeMarker 渲染, 租户/授权/队列/用量管理页面
- 历史消息补拉: 水位线驱动, getRoamMsg/getGroupMsg 增量拉取, 兜底回调丢失
- msg_key 统一算法(回调/补拉共享, 跨路径去重)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-08 20:28:32 +08:00

62 lines
2.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.imutil.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.imutil.entity.PullWatermark;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.time.OffsetDateTime;
import java.util.List;
/**
* 补拉水位线 Mapper
* <p>
* upsert 用 PG ON CONFLICTselectNeedCheck 按 updated_at 升序取最久未补拉的会话,
* 配合补拉成功后推进 updated_at,实现会话轮询公平覆盖。
*
* @author imutil
*/
public interface PullWatermarkMapper extends BaseMapper<PullWatermark> {
/**
* 水位线 upsertPG ON CONFLICT
* <p>
* 回调落库 / 补拉推进时调用。last_seq、last_time 取 GREATEST 不回退(防乱序回调回退游标),
* updated_at 始终刷新为 now(驱动 selectNeedCheck 的轮询顺序)。
*
* @param tenantId 租户ID
* @param convId 会话ID
* @param convType 会话类型 1=C2C 2=GROUP
* @param lastSeq 最新消息 Seq
* @param lastTime 最新消息时间
* @param now 当前时间(updated_at
* @return 影响行数(1=新增或更新)
*/
@Insert("INSERT INTO pull_watermark (tenant_id, conv_id, conv_type, last_seq, last_time, updated_at) " +
"VALUES (#{tenantId}, #{convId}, #{convType}, #{lastSeq}, #{lastTime}, #{now}) " +
"ON CONFLICT (tenant_id, conv_id) DO UPDATE SET " +
"last_seq = GREATEST(pull_watermark.last_seq, EXCLUDED.last_seq), " +
"last_time = GREATEST(pull_watermark.last_time, EXCLUDED.last_time), " +
"updated_at = EXCLUDED.updated_at")
int upsert(@Param("tenantId") String tenantId,
@Param("convId") String convId,
@Param("convType") int convType,
@Param("lastSeq") long lastSeq,
@Param("lastTime") OffsetDateTime lastTime,
@Param("now") OffsetDateTime now);
/**
* 取最久未补拉的 N 个会话(按 updated_at 升序)
* <p>
* 补拉任务每轮调用,updated_at 最老的优先;补拉后 updated_at 推进到 now
* 该会话自然排到队尾,实现轮询式公平覆盖。
*
* @param limit 每轮会话数
* @return 待补拉会话列表
*/
@Select("SELECT tenant_id, conv_id, conv_type, last_seq, last_time, updated_at " +
"FROM pull_watermark ORDER BY updated_at ASC LIMIT #{limit}")
List<PullWatermark> selectNeedCheck(@Param("limit") int limit);
}