From 0bb69075f74c9c1118d6e02d7e2d90995e2ff74a Mon Sep 17 00:00:00 2001 From: KilLze Date: Wed, 7 Jan 2026 00:47:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=BF=9B=E5=85=A5=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E6=B6=88=E6=81=AF=E8=87=AA=E5=8A=A8=E5=B7=B2=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bao/dating/controller/ChatController.java | 19 ++++--- .../bao/dating/mapper/ChatRecordsMapper.java | 16 +++++- .../bao/dating/mapper/ChatSessionsMapper.java | 7 +++ .../dating/pojo/dto/ChatCursorPageDTO.java | 21 ++++++++ .../com/bao/dating/service/ChatService.java | 15 +++++- .../dating/service/impl/ChatServiceImpl.java | 53 +++++++++++-------- .../bao/dating/mapper/ChatRecordsMapper.xml | 24 +++++++-- .../bao/dating/mapper/ChatSessionsMapper.xml | 11 ++++ 8 files changed, 132 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/bao/dating/pojo/dto/ChatCursorPageDTO.java diff --git a/src/main/java/com/bao/dating/controller/ChatController.java b/src/main/java/com/bao/dating/controller/ChatController.java index b335a60..8c62c9a 100644 --- a/src/main/java/com/bao/dating/controller/ChatController.java +++ b/src/main/java/com/bao/dating/controller/ChatController.java @@ -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> getChatHistory( + public Result> getChatHistory( @PathVariable Long targetUserId, - @RequestParam(defaultValue = "1") Integer page, - @RequestParam(defaultValue = "50") Integer size){ + ChatCursorPageDTO pageDTO){ Long currentUserId = UserContext.getUserId(); - PageResult history = chatService.getChatHistory(currentUserId, targetUserId, page, size); + chatService.markChatMessagesAsRead(currentUserId, targetUserId); + List history = chatService.getChatHistory( + currentUserId, + targetUserId, + pageDTO.getCursor(), + pageDTO.getSize()); return Result.success(ResultCode.SUCCESS, "获取聊天记录成功", history); } diff --git a/src/main/java/com/bao/dating/mapper/ChatRecordsMapper.java b/src/main/java/com/bao/dating/mapper/ChatRecordsMapper.java index ba4d569..b716e5e 100644 --- a/src/main/java/com/bao/dating/mapper/ChatRecordsMapper.java +++ b/src/main/java/com/bao/dating/mapper/ChatRecordsMapper.java @@ -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 selectChatWindowHistory( + List 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 ); } diff --git a/src/main/java/com/bao/dating/mapper/ChatSessionsMapper.java b/src/main/java/com/bao/dating/mapper/ChatSessionsMapper.java index 3cc92a5..d32d91e 100644 --- a/src/main/java/com/bao/dating/mapper/ChatSessionsMapper.java +++ b/src/main/java/com/bao/dating/mapper/ChatSessionsMapper.java @@ -36,4 +36,11 @@ public interface ChatSessionsMapper { */ int updateSessionForReceiver(ChatSessions chatSessions); + /** + * 清空会话未读数 + */ + int clearUnreadCount( + @Param("userId") Long userId, + @Param("targetUserId") Long targetUserId + ); } diff --git a/src/main/java/com/bao/dating/pojo/dto/ChatCursorPageDTO.java b/src/main/java/com/bao/dating/pojo/dto/ChatCursorPageDTO.java new file mode 100644 index 0000000..d50cd35 --- /dev/null +++ b/src/main/java/com/bao/dating/pojo/dto/ChatCursorPageDTO.java @@ -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; +} diff --git a/src/main/java/com/bao/dating/service/ChatService.java b/src/main/java/com/bao/dating/service/ChatService.java index 8e84e63..0f2287b 100644 --- a/src/main/java/com/bao/dating/service/ChatService.java +++ b/src/main/java/com/bao/dating/service/ChatService.java @@ -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 getChatHistory(Long currentUserId, Long targetUserId, Integer page, Integer size); + List getChatHistory(Long currentUserId, Long targetUserId, LocalDateTime cursor, Integer size); + + + /** + * 标记聊天记录为已读 + * @param currentUserId 当前用户ID + * @param targetUserId 目标用户ID + */ + void markChatMessagesAsRead(Long currentUserId, Long targetUserId); } diff --git a/src/main/java/com/bao/dating/service/impl/ChatServiceImpl.java b/src/main/java/com/bao/dating/service/impl/ChatServiceImpl.java index 3b0d073..1f27239 100644 --- a/src/main/java/com/bao/dating/service/impl/ChatServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/ChatServiceImpl.java @@ -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 getChatHistory(Long currentUserId, Long targetUserId, Integer page, Integer size) { + public List 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 recordsList = - chatRecordsMapper.selectChatWindowHistory(currentUserId, targetUserId); + List records = + chatRecordsMapper.selectChatHistoryByCursor( + currentUserId, + targetUserId, + cursor, + size + ); - // 使用 PageInfo 封装查询结果 - PageInfo pageInfo = new PageInfo<>(recordsList); + Collections.reverse(records); - // 转换为 VO - List voList = recordsList.stream() - .map(record -> { - ChatRecordsVO vo = new ChatRecordsVO(); - BeanUtils.copyProperties(record, vo); - return vo; - }) - .collect(Collectors.toList()); + return records.stream().map(record -> { + ChatRecordsVO vo = new ChatRecordsVO(); + BeanUtils.copyProperties(record, vo); + return vo; + }).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 + ); } } diff --git a/src/main/resources/com/bao/dating/mapper/ChatRecordsMapper.xml b/src/main/resources/com/bao/dating/mapper/ChatRecordsMapper.xml index b5a5647..0238dd8 100644 --- a/src/main/resources/com/bao/dating/mapper/ChatRecordsMapper.xml +++ b/src/main/resources/com/bao/dating/mapper/ChatRecordsMapper.xml @@ -32,18 +32,36 @@ - 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 FROM chat_records WHERE message_status = 1 - AND ( + AND ( (sender_user_id = #{currentUserId} AND receiver_user_id = #{targetUserId}) OR (sender_user_id = #{targetUserId} AND receiver_user_id = #{currentUserId}) - ) + ) + + AND send_time < #{cursor} + ORDER BY send_time DESC + LIMIT #{size} + + + + 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 + \ No newline at end of file diff --git a/src/main/resources/com/bao/dating/mapper/ChatSessionsMapper.xml b/src/main/resources/com/bao/dating/mapper/ChatSessionsMapper.xml index d3d829c..6ecb9b3 100644 --- a/src/main/resources/com/bao/dating/mapper/ChatSessionsMapper.xml +++ b/src/main/resources/com/bao/dating/mapper/ChatSessionsMapper.xml @@ -59,4 +59,15 @@ AND target_user_id = #{targetUserId} + + + UPDATE chat_sessions + SET + unread_count = 0, + updated_at = NOW() + WHERE + user_id = #{userId} + AND target_user_id = #{targetUserId} + AND session_status = 1 + \ No newline at end of file