liyong
10 小时以前 7a23c450f3ac85de7dca1b908de273ff636ce218
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package cn.iocoder.yudao.module.im.dal.mysql.message;
 
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.group.ImGroupMessageManagerPageReqVO;
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO;
import cn.iocoder.yudao.module.im.enums.message.ImMessageReceiptStatusEnum;
import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
import org.apache.ibatis.annotations.Mapper;
 
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
 
/**
 * IM 群聊消息 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface ImGroupMessageMapper extends BaseMapperX<ImGroupMessageDO> {
 
    /**
     * 根据 minId + 时间窗口增量拉取群聊消息
     *
     * @param userId      当前用户编号
     * @param groupIds    候选群编号集合(当前在群 ∪ 窗口内退群),不能为空
     * @param minId       最小消息 id(不含)
     * @param minSendTime 最早发送时间(不含),限制离线消息时间窗口
     * @param size        拉取数量
     * @return 消息列表(按 id 升序)
     */
    default List<ImGroupMessageDO> selectListByMinId(Long userId, Collection<Long> groupIds, Long minId,
                                                     LocalDateTime minSendTime, Integer size) {
        QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>();
        wrapper.in("group_id", groupIds)
                .gt("id", minId)
                .gt("send_time", minSendTime)
                .apply(MyBatisUtils.findInSet("receiver_user_ids"), userId)
                .orderByAsc("id");
        wrapper.limitN(size);
        return selectList(wrapper);
    }
 
    /**
     * 查询群聊历史消息(游标拉取)
     *
     * @param userId 当前用户编号
     * @param groupId 群编号
     * @param maxId  起始消息 id(不含),为空则从最新开始
     * @param limit  拉取数量
     * @return 消息列表(按 id 倒序)
     */
    default List<ImGroupMessageDO> selectHistoryListByUser(Long userId, Long groupId, Long maxId, Integer limit) {
        QueryWrapperX<ImGroupMessageDO> wrapper = new QueryWrapperX<>();
        wrapper.eq("group_id", groupId)
                .lt(maxId != null, "id", maxId)
                .apply(MyBatisUtils.findInSet("receiver_user_ids"), userId)
                .orderByDesc("id");
        wrapper.limitN(limit);
        return selectList(wrapper);
    }
 
    default ImGroupMessageDO selectBySenderIdAndClientMessageId(Long senderId, String clientMessageId) {
        return selectOne(new LambdaQueryWrapperX<ImGroupMessageDO>()
                .eq(ImGroupMessageDO::getSenderId, senderId)
                .eq(ImGroupMessageDO::getClientMessageId, clientMessageId));
    }
 
    /**
     * 查询群内指定范围内待回执的消息
     * <p>
     * 仅在用户"已读位置前进"时调用,避免全量扫描:
     * 只有位于 (minId, maxId] 范围内、且仍处于 PENDING 的回执消息可能因本次已读而状态变化。
     *
     * @param groupId 群编号
     * @param minId   起始消息 id(不含,上一次已读位置)
     * @param maxId   结束消息 id(含,本次已读位置)
     * @return 待回执消息列表
     */
    default List<ImGroupMessageDO> selectListByGroupIdAndPendingReceipt(Long groupId, Long minId, Long maxId) {
        return selectList(new LambdaQueryWrapperX<ImGroupMessageDO>()
                .eq(ImGroupMessageDO::getGroupId, groupId)
                .eq(ImGroupMessageDO::getReceiptStatus, ImMessageReceiptStatusEnum.PENDING.getStatus())
                .gt(minId != null, ImGroupMessageDO::getId, minId)
                .le(ImGroupMessageDO::getId, maxId)
                .ne(ImGroupMessageDO::getStatus, ImMessageStatusEnum.RECALL.getStatus()));
    }
 
    default PageResult<ImGroupMessageDO> selectPage(ImGroupMessageManagerPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<ImGroupMessageDO>()
                .eqIfPresent(ImGroupMessageDO::getGroupId, reqVO.getGroupId())
                .eqIfPresent(ImGroupMessageDO::getSenderId, reqVO.getSenderId())
                .eqIfPresent(ImGroupMessageDO::getType, reqVO.getType())
                .likeIfPresent(ImGroupMessageDO::getContent, reqVO.getContent())
                .eqIfPresent(ImGroupMessageDO::getStatus, reqVO.getStatus())
                .betweenIfPresent(ImGroupMessageDO::getSendTime, reqVO.getSendTime())
                .orderByDesc(ImGroupMessageDO::getId));
    }
 
}