feat(message): 增加消息艾特功能并优化消息读取逻辑

- 在 ChatMessageVO 中添加 remindUsers 和 reminded 字段,用于表示被艾特的用户列表和是否被艾特
- 修改 SsePushService 和 TicketChatService,支持消息艾特功能
- 优化 TicketController 和 TiketController 中的消息读取逻辑,增加艾特提醒功能
- 调整消息未读状态的处理方式,提高性能和准确性
This commit is contained in:
曹鹏飞 2025-04-07 20:28:45 +08:00
parent 1a1f86c5ff
commit e8a37d2a02
5 changed files with 39 additions and 25 deletions

View File

@ -668,20 +668,21 @@ public class TicketController extends ControllerBase {
@GetMapping("getChatMessages") @GetMapping("getChatMessages")
@ApiMark(moduleName = "工单管理", apiName = "获取工单聊天记录") @ApiMark(moduleName = "工单管理", apiName = "获取工单聊天记录")
public ApiResult<MessageVO> getChatMessages(@Valid @RequestParam @NotNull Integer ticketId) { public ApiResult<MessageVO> getChatMessages(@Valid @RequestParam @NotNull Integer ticketId) {
Integer userId = AdminUserUtil.getUserId();
MessageVO vo = new MessageVO(); MessageVO vo = new MessageVO();
List<ChatMessageVO> messageVOS=ticketChatService.getMessages(ticketId); List<ChatMessageVO> messageVOS = ticketChatService.getMessages(ticketId, userId);
vo.setMessages(messageVOS); vo.setMessages(messageVOS);
String key="chatMessage:readed:"+ticketId+":admin:"+AdminUserUtil.getUserId(); String key = "chatMessage:readed:" + ticketId + ":admin:" + userId;
Set<String> readeds = redisTemplate.opsForSet().members(key); Set<String> readeds = redisTemplate.opsForSet().members(key);
Set<String> notReadeds = new LinkedHashSet<>(); Set<String> notReadeds = new LinkedHashSet<>();
if (CollectionUtil.isEmpty(readeds)) { if (CollectionUtil.isEmpty(readeds)) {
notReadeds = messageVOS.stream() notReadeds = messageVOS.stream()
.filter(m->!Objects.equals(m.getSenderId(),AdminUserUtil.getUserId())) .filter(m -> !Objects.equals(m.getSenderId(), userId))
.map(ChatMessageVO::getId) .map(ChatMessageVO::getId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} else { } else {
for (ChatMessageVO messageVO : messageVOS) { for (ChatMessageVO messageVO : messageVOS) {
if (Objects.equals(messageVO.getSenderId(),AdminUserUtil.getUserId()) || readeds.contains(messageVO.getId())){ if (Objects.equals(messageVO.getSenderId(), userId) || readeds.contains(messageVO.getId())) {
messageVO.setReaded(true); messageVO.setReaded(true);
} else { } else {
notReadeds.add(messageVO.getId()); notReadeds.add(messageVO.getId());

View File

@ -63,6 +63,7 @@ public class SsePushService {
.setCreateTime(formatter.format(message.getCreateTime())) .setCreateTime(formatter.format(message.getCreateTime()))
.setImages(message.getImages()) .setImages(message.getImages())
.setAttachments(message.getAttachments()) .setAttachments(message.getAttachments())
.setRemindUsers(message.getRemindUsers())
.setQuote(Objects.isNull(message.getQuote()) ? null : new ChatMessageVO() .setQuote(Objects.isNull(message.getQuote()) ? null : new ChatMessageVO()
.setId(message.getQuote().getId()) .setId(message.getQuote().getId())
.setFrom(message.getQuote().getFrom()) .setFrom(message.getQuote().getFrom())
@ -73,6 +74,7 @@ public class SsePushService {
.setContent(message.getQuote().getContent()) .setContent(message.getQuote().getContent())
.setAttachments(message.getQuote().getAttachments()) .setAttachments(message.getQuote().getAttachments())
.setImages(message.getQuote().getImages()) .setImages(message.getQuote().getImages())
.setRemindUsers(message.getQuote().getRemindUsers())
.setCreateTime(formatter.format(message.getQuote().getCreateTime()))); .setCreateTime(formatter.format(message.getQuote().getCreateTime())));
} }
} }

View File

@ -271,20 +271,21 @@ public class TiketController extends ControllerBase {
**/ **/
@GetMapping("getChatMessages") @GetMapping("getChatMessages")
public ApiResult<MessageVO> getChatMessages(@Valid @RequestParam @NotNull Integer ticketId) { public ApiResult<MessageVO> getChatMessages(@Valid @RequestParam @NotNull Integer ticketId) {
Integer userId = AppUserUtil.getUserId();
MessageVO vo = new MessageVO(); MessageVO vo = new MessageVO();
List<ChatMessageVO> messageVOS=ticketChatService.getMessages(ticketId); List<ChatMessageVO> messageVOS = ticketChatService.getMessages(ticketId, userId);
vo.setMessages(messageVOS); vo.setMessages(messageVOS);
String key="chatMessage:readed:"+ticketId+":app:"+AppUserUtil.getUserId(); String key = "chatMessage:readed:" + ticketId + ":app:" + userId;
Set<String> readeds = redisTemplate.opsForSet().members(key); Set<String> readeds = redisTemplate.opsForSet().members(key);
Set<String> notReadeds = new LinkedHashSet<>(); Set<String> notReadeds = new LinkedHashSet<>();
if (CollectionUtil.isEmpty(readeds)) { if (CollectionUtil.isEmpty(readeds)) {
notReadeds = messageVOS.stream() notReadeds = messageVOS.stream()
.filter(m->!Objects.equals(m.getSenderId(),AppUserUtil.getUserId())) .filter(m -> !Objects.equals(m.getSenderId(), userId))
.map(ChatMessageVO::getId) .map(ChatMessageVO::getId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} else { } else {
for (ChatMessageVO messageVO : messageVOS) { for (ChatMessageVO messageVO : messageVOS) {
if (Objects.equals(messageVO.getSenderId(),AppUserUtil.getUserId()) || readeds.contains(messageVO.getId())){ if (Objects.equals(messageVO.getSenderId(), userId) || readeds.contains(messageVO.getId())) {
messageVO.setReaded(true); messageVO.setReaded(true);
} else { } else {
notReadeds.add(messageVO.getId()); notReadeds.add(messageVO.getId());

View File

@ -1,5 +1,6 @@
package com.nflg.mobilebroken.common.pojo.vo; package com.nflg.mobilebroken.common.pojo.vo;
import com.nflg.mobilebroken.common.pojo.request.RemindUserRequest;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -43,4 +44,10 @@ public class ChatMessageVO {
// 是否已读 // 是否已读
private Boolean readed=false; private Boolean readed=false;
//被艾特的用户列表
private List<RemindUserRequest> remindUsers;
//是否被艾特
private Boolean reminded;
} }

View File

@ -30,7 +30,7 @@ public class TicketChatService {
mongoTemplate.save(ticketChatDTO); mongoTemplate.save(ticketChatDTO);
} }
public List<ChatMessageVO> getMessages(Integer ticketId) { public List<ChatMessageVO> getMessages(Integer ticketId,Integer userId) {
Query query = new Query(Criteria.where("ticketId").is(ticketId)); Query query = new Query(Criteria.where("ticketId").is(ticketId));
TicketChatDTO ticketChatDTO = mongoTemplate.findOne(query, TicketChatDTO.class); TicketChatDTO ticketChatDTO = mongoTemplate.findOne(query, TicketChatDTO.class);
if (Objects.isNull(ticketChatDTO)) { if (Objects.isNull(ticketChatDTO)) {
@ -51,6 +51,8 @@ public class TicketChatService {
.setAttachments(m.getAttachments()) .setAttachments(m.getAttachments())
.setImages(m.getImages()) .setImages(m.getImages())
.setCreateTime(formatter.format(m.getCreateTime())) .setCreateTime(formatter.format(m.getCreateTime()))
.setRemindUsers(m.getRemindUsers())
.setReminded(Objects.nonNull(m.getRemindUsers()) && m.getRemindUsers().stream().anyMatch(r -> r.getId().equals(userId)))
.setQuote(Objects.isNull(m.getQuote()) ? null : new ChatMessageVO() .setQuote(Objects.isNull(m.getQuote()) ? null : new ChatMessageVO()
.setId(m.getQuote().getId()) .setId(m.getQuote().getId())
.setFrom(m.getQuote().getFrom()) .setFrom(m.getQuote().getFrom())
@ -61,6 +63,7 @@ public class TicketChatService {
.setContent(m.getQuote().getContent()) .setContent(m.getQuote().getContent())
.setAttachments(m.getQuote().getAttachments()) .setAttachments(m.getQuote().getAttachments())
.setImages(m.getQuote().getImages()) .setImages(m.getQuote().getImages())
.setRemindUsers(m.getQuote().getRemindUsers())
.setCreateTime(formatter.format(m.getQuote().getCreateTime()))) .setCreateTime(formatter.format(m.getQuote().getCreateTime())))
) )
.collect(Collectors.toList()); .collect(Collectors.toList());