完成进入会话消息自动已读

This commit is contained in:
KilLze
2026-01-07 00:47:38 +08:00
parent 1d179da910
commit 0bb69075f7
8 changed files with 132 additions and 34 deletions

View File

@@ -4,12 +4,15 @@ import com.bao.dating.common.Result;
import com.bao.dating.common.ResultCode;
import com.bao.dating.common.result.PageResult;
import com.bao.dating.context.UserContext;
import com.bao.dating.pojo.dto.ChatCursorPageDTO;
import com.bao.dating.pojo.vo.ChatRecordsVO;
import com.bao.dating.service.ChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 聊天控制器
* @author lenovo
@@ -24,16 +27,20 @@ public class ChatController {
/**
* 获取聊天记录
* @param targetUserId 目标用户ID
* @param page 页码
* @param size 页大小
* @param pageDTO 分页参数
* @return 聊天记录列表
*/
@GetMapping("/history/{targetUserId}")
public Result<PageResult<ChatRecordsVO>> getChatHistory(
public Result<List<ChatRecordsVO>> getChatHistory(
@PathVariable Long targetUserId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "50") Integer size){
ChatCursorPageDTO pageDTO){
Long currentUserId = UserContext.getUserId();
PageResult<ChatRecordsVO> history = chatService.getChatHistory(currentUserId, targetUserId, page, size);
chatService.markChatMessagesAsRead(currentUserId, targetUserId);
List<ChatRecordsVO> history = chatService.getChatHistory(
currentUserId,
targetUserId,
pageDTO.getCursor(),
pageDTO.getSize());
return Result.success(ResultCode.SUCCESS, "获取聊天记录成功", history);
}

View File

@@ -5,6 +5,7 @@ import com.bao.dating.pojo.entity.ChatRecords;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
@Mapper
@@ -17,8 +18,19 @@ public interface ChatRecordsMapper {
/**
* 根据用户ID和接收方用户ID查询聊天记录
*/
List<ChatRecords> selectChatWindowHistory(
List<ChatRecords> selectChatHistoryByCursor(
@Param("currentUserId") Long currentUserId,
@Param("targetUserId") Long targetUserId
@Param("targetUserId") Long targetUserId,
@Param("cursor") LocalDateTime cursor,
@Param("size") Integer size
);
/**
* 标记消息为已读
*/
int markMessagesAsRead(
@Param("senderUserId") Long senderUserId,
@Param("receiverUserId") Long receiverUserId,
@Param("readTime") LocalDateTime readTime
);
}

View File

@@ -36,4 +36,11 @@ public interface ChatSessionsMapper {
*/
int updateSessionForReceiver(ChatSessions chatSessions);
/**
* 清空会话未读数
*/
int clearUnreadCount(
@Param("userId") Long userId,
@Param("targetUserId") Long targetUserId
);
}

View File

@@ -0,0 +1,21 @@
package com.bao.dating.pojo.dto;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Data
public class ChatCursorPageDTO {
/**
* 时间游标:最后一条消息的发送时间
*/
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime cursor;
/**
* 拉取条数
*/
private Integer size;
}

View File

@@ -4,6 +4,9 @@ import com.bao.dating.common.result.PageResult;
import com.bao.dating.pojo.dto.ChatRecordSendDTO;
import com.bao.dating.pojo.vo.ChatRecordsVO;
import java.time.LocalDateTime;
import java.util.List;
/**
* 聊天服务
* @author lenovo
@@ -21,9 +24,17 @@ public interface ChatService {
* 获取聊天记录
* @param currentUserId 当前用户ID
* @param targetUserId 目标用户ID
* @param page 页码
* @param cursor 时间游标
* @param size 页大小
* @return 聊天记录列表
*/
PageResult<ChatRecordsVO> getChatHistory(Long currentUserId, Long targetUserId, Integer page, Integer size);
List<ChatRecordsVO> getChatHistory(Long currentUserId, Long targetUserId, LocalDateTime cursor, Integer size);
/**
* 标记聊天记录为已读
* @param currentUserId 当前用户ID
* @param targetUserId 目标用户ID
*/
void markChatMessagesAsRead(Long currentUserId, Long targetUserId);
}

View File

@@ -19,6 +19,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -116,36 +117,46 @@ public class ChatServiceImpl implements ChatService {
* @return 聊天记录列表
*/
@Override
public PageResult<ChatRecordsVO> getChatHistory(Long currentUserId, Long targetUserId, Integer page, Integer size) {
public List<ChatRecordsVO> getChatHistory(Long currentUserId, Long targetUserId, LocalDateTime cursor, Integer size) {
if (page == null || page < 1) {
page = 1;
}
if (size == null || size < 1 || size > 100) {
size = 50;
}
// 分页
PageHelper.startPage(page, size);
// 查询
List<ChatRecords> recordsList =
chatRecordsMapper.selectChatWindowHistory(currentUserId, targetUserId);
List<ChatRecords> records =
chatRecordsMapper.selectChatHistoryByCursor(
currentUserId,
targetUserId,
cursor,
size
);
// 使用 PageInfo 封装查询结果
PageInfo<ChatRecords> pageInfo = new PageInfo<>(recordsList);
Collections.reverse(records);
// 转换为 VO
List<ChatRecordsVO> voList = recordsList.stream()
.map(record -> {
return records.stream().map(record -> {
ChatRecordsVO vo = new ChatRecordsVO();
BeanUtils.copyProperties(record, vo);
return vo;
})
.collect(Collectors.toList());
}).collect(Collectors.toList());
}
// 使用 PageInfo 的信息创建 PageResult
return new PageResult<>(pageInfo.getTotal(), pageInfo.getPageNum(), pageInfo.getPageSize(), voList);
@Override
@Transactional(rollbackFor = Exception.class)
public void markChatMessagesAsRead(Long currentUserId, Long targetUserId) {
// 1. 更新 chat_records把对方发给我的未读消息设为已读
chatRecordsMapper.markMessagesAsRead(
targetUserId,
currentUserId,
LocalDateTime.now()
);
// 2. 更新 chat_sessions清空当前会话的未读数
chatSessionsMapper.clearUnreadCount(
currentUserId,
targetUserId
);
}
}

View File

@@ -32,7 +32,7 @@
</insert>
<!-- 根据两个用户ID查询聊天记录 (按发送时间倒序) - PageHelper 会自动处理分页 -->
<select id="selectChatWindowHistory" resultType="com.bao.dating.pojo.entity.ChatRecords">
<select id="selectChatHistoryByCursor" resultType="com.bao.dating.pojo.entity.ChatRecords">
SELECT
chat_id, sender_user_id, receiver_user_id, message_content, message_type,
read_status, read_time, send_time, message_status, created_at, updated_at
@@ -44,6 +44,24 @@
OR
(sender_user_id = #{targetUserId} AND receiver_user_id = #{currentUserId})
)
<if test="cursor != null">
AND send_time &lt; #{cursor}
</if>
ORDER BY send_time DESC
LIMIT #{size}
</select>
<!-- 标记消息为已读 -->
<update id="markMessagesAsRead">
UPDATE chat_records
SET
read_status = 1,
read_time = #{readTime},
updated_at = NOW()
WHERE
sender_user_id = #{senderUserId}
AND receiver_user_id = #{receiverUserId}
AND read_status = 0
AND message_status = 1
</update>
</mapper>

View File

@@ -59,4 +59,15 @@
AND target_user_id = #{targetUserId}
</update>
<!-- 清空未读消息数 -->
<update id="clearUnreadCount">
UPDATE chat_sessions
SET
unread_count = 0,
updated_at = NOW()
WHERE
user_id = #{userId}
AND target_user_id = #{targetUserId}
AND session_status = 1
</update>
</mapper>