Compare commits
3 Commits
a4e66b39d1
...
feature-We
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf6f9b8b7c | ||
|
|
0a17eb8deb | ||
|
|
448ce1d3d6 |
@@ -11,6 +11,7 @@ import com.bao.dating.service.ChatService;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -25,6 +26,17 @@ public class ChatController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ChatService chatService;
|
private ChatService chatService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param file 文件
|
||||||
|
* @return 文件URL
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public Result<String> uploadVideo(@RequestParam MultipartFile file) {
|
||||||
|
String url = chatService.uploadChat(file);
|
||||||
|
return Result.success(ResultCode.SUCCESS, "文件上传成功", url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取聊天记录
|
* 获取聊天记录
|
||||||
* @param targetUserId 目标用户ID
|
* @param targetUserId 目标用户ID
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ public class PostController {
|
|||||||
* @param files 媒体文件数组
|
* @param files 媒体文件数组
|
||||||
* @return 上传后的文件URL列表
|
* @return 上传后的文件URL列表
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping(value = "/upload", consumes = "multipart/form-data")
|
@PostMapping(value = "/upload", consumes = "multipart/form-data")
|
||||||
public Result<List<String>> uploadMedia(@RequestParam("files") MultipartFile[] files) {
|
public Result<List<String>> uploadMedia(@RequestParam("files") MultipartFile[] files) {
|
||||||
List<String> fileUrls = postService.uploadMedia(files);
|
List<String> fileUrls = postService.uploadMedia(files);
|
||||||
@@ -43,7 +42,6 @@ public class PostController {
|
|||||||
* @param postDTO 动态信息
|
* @param postDTO 动态信息
|
||||||
* @return 发布的动态对象
|
* @return 发布的动态对象
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping( "/createPost")
|
@PostMapping( "/createPost")
|
||||||
public Result<Post> createPostJson(@RequestBody PostRequestDTO postDTO) {
|
public Result<Post> createPostJson(@RequestBody PostRequestDTO postDTO) {
|
||||||
// 调用 Service 层处理发布动态业务逻辑
|
// 调用 Service 层处理发布动态业务逻辑
|
||||||
@@ -57,7 +55,6 @@ public class PostController {
|
|||||||
* @param postIds 动态ID
|
* @param postIds 动态ID
|
||||||
* @return 删除结果
|
* @return 删除结果
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping("/deletePost")
|
@PostMapping("/deletePost")
|
||||||
public Result<String> deleteById(@RequestBody List<Long> postIds){
|
public Result<String> deleteById(@RequestBody List<Long> postIds){
|
||||||
int deletedCount = postService.deletePostById(postIds);
|
int deletedCount = postService.deletePostById(postIds);
|
||||||
@@ -81,7 +78,6 @@ public class PostController {
|
|||||||
* @param postRequestDTO 动态信息
|
* @param postRequestDTO 动态信息
|
||||||
* @return 更新后的动态对象
|
* @return 更新后的动态对象
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping("/{postId}/updatePost")
|
@PostMapping("/{postId}/updatePost")
|
||||||
public Result<PostEditVO> updatePost(@PathVariable Long postId, @RequestBody PostRequestDTO postRequestDTO) {
|
public Result<PostEditVO> updatePost(@PathVariable Long postId, @RequestBody PostRequestDTO postRequestDTO) {
|
||||||
PostEditVO result = postService.updatePost(postId, postRequestDTO);
|
PostEditVO result = postService.updatePost(postId, postRequestDTO);
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ public class UserController {
|
|||||||
* @param file 头像文件
|
* @param file 头像文件
|
||||||
* @return 上传后的文件URL列表
|
* @return 上传后的文件URL列表
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping(value = "/info/uploadAvatar", consumes = "multipart/form-data")
|
@PostMapping(value = "/info/uploadAvatar", consumes = "multipart/form-data")
|
||||||
public Result<String> uploadAvatar(@RequestParam("file") MultipartFile file) {
|
public Result<String> uploadAvatar(@RequestParam("file") MultipartFile file) {
|
||||||
String fileUrl = userService.uploadAvatar(file);
|
String fileUrl = userService.uploadAvatar(file);
|
||||||
@@ -76,7 +75,6 @@ public class UserController {
|
|||||||
* @param file 背景文件
|
* @param file 背景文件
|
||||||
* @return 上传后的文件URL列表
|
* @return 上传后的文件URL列表
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping(value = "/info/uploadBackground", consumes = "multipart/form-data")
|
@PostMapping(value = "/info/uploadBackground", consumes = "multipart/form-data")
|
||||||
public Result<String> uploadBackground(@RequestParam("file") MultipartFile file) {
|
public Result<String> uploadBackground(@RequestParam("file") MultipartFile file) {
|
||||||
String fileUrl = userService.uploadBackground(file);
|
String fileUrl = userService.uploadBackground(file);
|
||||||
@@ -88,7 +86,6 @@ public class UserController {
|
|||||||
* @param userInfoUpdateDTO 用户信息更新参数
|
* @param userInfoUpdateDTO 用户信息更新参数
|
||||||
* @return 更新后的用户信息
|
* @return 更新后的用户信息
|
||||||
*/
|
*/
|
||||||
@Log
|
|
||||||
@PostMapping("/info/update")
|
@PostMapping("/info/update")
|
||||||
public Result<UserInfoVO> userInfoUpdate(@RequestBody UserInfoDTO userInfoUpdateDTO) {
|
public Result<UserInfoVO> userInfoUpdate(@RequestBody UserInfoDTO userInfoUpdateDTO) {
|
||||||
Long userId = UserContext.getUserId();
|
Long userId = UserContext.getUserId();
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.bao.dating.controller.websocket;
|
package com.bao.dating.controller.websocket;
|
||||||
|
|
||||||
import com.bao.dating.message.WsMessage;
|
import com.bao.dating.message.WsMessage;
|
||||||
|
import com.bao.dating.pojo.dto.ChatRecallDTO;
|
||||||
import com.bao.dating.pojo.dto.ChatRecordSendDTO;
|
import com.bao.dating.pojo.dto.ChatRecordSendDTO;
|
||||||
import com.bao.dating.pojo.vo.ChatRecordsVO;
|
import com.bao.dating.pojo.vo.ChatRecordsVO;
|
||||||
import com.bao.dating.service.ChatService;
|
import com.bao.dating.service.ChatService;
|
||||||
import com.bao.dating.session.WsSessionManager;
|
import com.bao.dating.session.WsSessionManager;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -57,14 +59,23 @@ public class ChatWebSocketHandler extends TextWebSocketHandler {
|
|||||||
log.error("WebSocket session 中未找到 userId");
|
log.error("WebSocket session 中未找到 userId");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 解析消息
|
|
||||||
WsMessage<ChatRecordSendDTO> wsMessage =
|
|
||||||
objectMapper.readValue(message.getPayload(),
|
|
||||||
new TypeReference<WsMessage<ChatRecordSendDTO>>(){});
|
|
||||||
|
|
||||||
// 处理私聊消息
|
JsonNode node = objectMapper.readTree(message.getPayload());
|
||||||
if ("chat".equals(wsMessage.getType())) {
|
String type = node.get("type").asText();
|
||||||
handlePrivateChat(session, senderUserId, wsMessage.getData());
|
// 根据消息类型解析消息
|
||||||
|
WsMessage wsMessage = objectMapper.readValue(message.getPayload(), WsMessage.class);
|
||||||
|
|
||||||
|
// 先获取消息类型,再根据类型进行相应处理和转换
|
||||||
|
if ("chat".equals(type)) {
|
||||||
|
// 处理私聊消息
|
||||||
|
WsMessage<ChatRecordSendDTO> chatWsMessage =
|
||||||
|
objectMapper.convertValue(node, new TypeReference<WsMessage<ChatRecordSendDTO>>(){});
|
||||||
|
handlePrivateChat(session, senderUserId, chatWsMessage.getData());
|
||||||
|
} else if ("recall".equals(type)) {
|
||||||
|
// 处理撤回消息
|
||||||
|
WsMessage<ChatRecallDTO> recallWsMessage =
|
||||||
|
objectMapper.convertValue(node, new TypeReference<WsMessage<ChatRecallDTO>>(){});
|
||||||
|
handleRecallMessage(session, senderUserId, recallWsMessage.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +90,7 @@ public class ChatWebSocketHandler extends TextWebSocketHandler {
|
|||||||
WsMessage<String> errorMsg = new WsMessage<>();
|
WsMessage<String> errorMsg = new WsMessage<>();
|
||||||
errorMsg.setType("error");
|
errorMsg.setType("error");
|
||||||
errorMsg.setData("会话已删除,无法发送消息");
|
errorMsg.setData("会话已删除,无法发送消息");
|
||||||
|
// 返回错误信息
|
||||||
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(errorMsg)));
|
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(errorMsg)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -97,6 +109,46 @@ public class ChatWebSocketHandler extends TextWebSocketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息撤回处理
|
||||||
|
*/
|
||||||
|
private void handleRecallMessage(WebSocketSession session, Long senderUserId, Object data) throws Exception {
|
||||||
|
|
||||||
|
// 转 DTO
|
||||||
|
ChatRecallDTO dto = objectMapper.convertValue(data, ChatRecallDTO.class);
|
||||||
|
|
||||||
|
// 撤回逻辑
|
||||||
|
boolean success = chatService.recallMessage(senderUserId, dto.getChatId());
|
||||||
|
// 如果返回false,说明消息撤回失败
|
||||||
|
if (!success) {
|
||||||
|
WsMessage<String> errorMsg = new WsMessage<>();
|
||||||
|
errorMsg.setType("error");
|
||||||
|
errorMsg.setData("撤回失败,消息可能无法撤回或不存在");
|
||||||
|
// 返回错误信息
|
||||||
|
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(errorMsg)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建撤回通知消息
|
||||||
|
WsMessage<ChatRecallDTO> pushMsg = new WsMessage<>();
|
||||||
|
pushMsg.setType("recall");
|
||||||
|
pushMsg.setData(dto);
|
||||||
|
|
||||||
|
// 通知自己
|
||||||
|
if (session.isOpen()) {
|
||||||
|
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(pushMsg)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通知对方
|
||||||
|
WebSocketSession receiverSession =
|
||||||
|
sessionManager.getSession(dto.getReceiverUserId());
|
||||||
|
|
||||||
|
if (receiverSession != null && receiverSession.isOpen()) {
|
||||||
|
receiverSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(pushMsg))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户断开连接(下线)
|
* 用户断开连接(下线)
|
||||||
|
|||||||
@@ -32,4 +32,20 @@ public interface ChatRecordsMapper {
|
|||||||
* @return 影响行数
|
* @return 影响行数
|
||||||
*/
|
*/
|
||||||
int markMessagesAsRead(ChatMarkReadDTO markReadDTO);
|
int markMessagesAsRead(ChatMarkReadDTO markReadDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询聊天记录
|
||||||
|
* @param chatId 聊天记录ID
|
||||||
|
* @return 聊天记录
|
||||||
|
*/
|
||||||
|
ChatRecords selectById(@Param("chatId") Long chatId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回聊天记录
|
||||||
|
* @param chatId 聊天记录ID
|
||||||
|
* @param senderUserId 发送者ID
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int recallMessage(@Param("chatId") Long chatId,
|
||||||
|
@Param("senderUserId") Long senderUserId);
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/main/java/com/bao/dating/pojo/dto/ChatRecallDTO.java
Normal file
13
src/main/java/com/bao/dating/pojo/dto/ChatRecallDTO.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.bao.dating.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聊天记录撤回参数
|
||||||
|
* @author lenovo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ChatRecallDTO {
|
||||||
|
private Long chatId;
|
||||||
|
private Long receiverUserId;
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.bao.dating.common.result.PageResult;
|
|||||||
import com.bao.dating.pojo.dto.*;
|
import com.bao.dating.pojo.dto.*;
|
||||||
import com.bao.dating.pojo.vo.ChatRecordsVO;
|
import com.bao.dating.pojo.vo.ChatRecordsVO;
|
||||||
import com.bao.dating.pojo.vo.ChatSessionsVO;
|
import com.bao.dating.pojo.vo.ChatSessionsVO;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -21,6 +22,13 @@ public interface ChatService {
|
|||||||
*/
|
*/
|
||||||
ChatRecordsVO createSession(Long senderUserId, ChatRecordSendDTO dto);
|
ChatRecordsVO createSession(Long senderUserId, ChatRecordSendDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传媒体文件
|
||||||
|
* @param file 文件
|
||||||
|
* @return 文件URL列表
|
||||||
|
*/
|
||||||
|
String uploadChat(MultipartFile file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取聊天记录
|
* 获取聊天记录
|
||||||
* @param dto 查询参数
|
* @param dto 查询参数
|
||||||
@@ -63,4 +71,12 @@ public interface ChatService {
|
|||||||
* @param dto 免打扰参数
|
* @param dto 免打扰参数
|
||||||
*/
|
*/
|
||||||
void updateMuteStatus(Long userId, ChatSessionMuteDTO dto);
|
void updateMuteStatus(Long userId, ChatSessionMuteDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回消息
|
||||||
|
* @param senderUserId 发送方ID
|
||||||
|
* @param chatId 聊天记录ID
|
||||||
|
* @return 撤回结果
|
||||||
|
*/
|
||||||
|
boolean recallMessage(Long senderUserId, Long chatId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.bao.dating.service.impl;
|
package com.bao.dating.service.impl;
|
||||||
|
|
||||||
|
import com.bao.dating.common.aliyun.AliOssUtil;
|
||||||
|
import com.bao.dating.common.result.AliOssResult;
|
||||||
|
import com.bao.dating.context.UserContext;
|
||||||
import com.bao.dating.mapper.ChatRecordsMapper;
|
import com.bao.dating.mapper.ChatRecordsMapper;
|
||||||
import com.bao.dating.mapper.ChatSessionsMapper;
|
import com.bao.dating.mapper.ChatSessionsMapper;
|
||||||
import com.bao.dating.pojo.dto.*;
|
import com.bao.dating.pojo.dto.*;
|
||||||
@@ -9,15 +12,23 @@ import com.bao.dating.pojo.vo.ChatRecordsVO;
|
|||||||
import com.bao.dating.pojo.vo.ChatSessionsVO;
|
import com.bao.dating.pojo.vo.ChatSessionsVO;
|
||||||
import com.bao.dating.service.ChatService;
|
import com.bao.dating.service.ChatService;
|
||||||
import com.bao.dating.service.UserService;
|
import com.bao.dating.service.UserService;
|
||||||
|
import com.bao.dating.util.FileUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@@ -34,6 +45,9 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ChatSessionsMapper chatSessionsMapper;
|
private ChatSessionsMapper chatSessionsMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AliOssUtil ossUtil;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@@ -112,6 +126,49 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传媒体文件
|
||||||
|
* @return 上传后的文件URL
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String uploadChat(MultipartFile file) {
|
||||||
|
// 参数校验
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
throw new RuntimeException("文件不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
if (originalFilename == null) {
|
||||||
|
throw new RuntimeException("文件名非法");
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileType = FileUtil.getFileType(originalFilename);
|
||||||
|
// 仅支持图片和视频文件上传
|
||||||
|
if (!AliOssResult.IMAGE.equals(fileType) && !AliOssResult.VIDEO.equals(fileType)) {
|
||||||
|
throw new RuntimeException("仅支持图片和视频文件上传");
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成 OSS 路径
|
||||||
|
String extension = FileUtil.getFileExtension(originalFilename);
|
||||||
|
String fileName = UUID.randomUUID().toString().replace("-", "") + "." + extension;
|
||||||
|
Long userId = UserContext.getUserId();
|
||||||
|
String objectKey = "chat/" + userId + "/" + fileName;
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] fileBytes = file.getBytes();
|
||||||
|
String ossUrl = ossUtil.upload(fileBytes, objectKey);
|
||||||
|
|
||||||
|
if (ossUrl == null || ossUrl.isEmpty()) {
|
||||||
|
throw new RuntimeException("图片上传失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ossUrl;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("上传图片失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取聊天记录
|
* 获取聊天记录
|
||||||
* @return 聊天记录列表
|
* @return 聊天记录列表
|
||||||
@@ -137,6 +194,9 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记聊天消息为已读
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void markChatMessagesAsRead(Long currentUserId, Long targetUserId) {
|
public void markChatMessagesAsRead(Long currentUserId, Long targetUserId) {
|
||||||
@@ -221,4 +281,45 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
dto.getMuteStatus()
|
dto.getMuteStatus()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回消息
|
||||||
|
* @param senderUserId 发送者用户ID
|
||||||
|
* @param chatId 聊天记录ID
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean recallMessage(Long senderUserId, Long chatId) {
|
||||||
|
|
||||||
|
// 查询聊天记录
|
||||||
|
ChatRecords record = chatRecordsMapper.selectById(chatId);
|
||||||
|
// 消息不存在
|
||||||
|
if (record == null) {
|
||||||
|
log.info("消息不存在,chatId: {}", chatId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只能撤回自己发的
|
||||||
|
if (!record.getSenderUserId().equals(senderUserId)) {
|
||||||
|
log.info("不能撤回别人发的消息,chatId: {},当前用户: {},消息发送者: {}", chatId, senderUserId, record.getSenderUserId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已撤回或已删除
|
||||||
|
if (record.getMessageStatus() != 1) {
|
||||||
|
log.info("消息已撤回或已删除,chatId: {},当前状态: {}", chatId, record.getMessageStatus());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间限制(2 分钟)
|
||||||
|
Duration duration = Duration.between(record.getSendTime(), LocalDateTime.now());
|
||||||
|
if (duration.toMinutes() > 2) {
|
||||||
|
log.info("消息已超过 2 分钟,不能撤回,chatId: {},发送时间: {}", chatId, record.getSendTime());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatRecordsMapper.recallMessage(chatId, senderUserId) > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,4 +64,29 @@
|
|||||||
AND read_status = 0
|
AND read_status = 0
|
||||||
AND message_status = 1
|
AND message_status = 1
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<!-- 根据ID查询聊天记录 -->
|
||||||
|
<select id="selectById" resultType="com.bao.dating.pojo.entity.ChatRecords">
|
||||||
|
SELECT
|
||||||
|
chat_id,
|
||||||
|
sender_user_id,
|
||||||
|
receiver_user_id,
|
||||||
|
send_time,
|
||||||
|
message_status
|
||||||
|
FROM chat_records
|
||||||
|
WHERE chat_id = #{chatId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 撤回消息 -->
|
||||||
|
<update id="recallMessage">
|
||||||
|
UPDATE chat_records
|
||||||
|
SET
|
||||||
|
message_status = 2,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE
|
||||||
|
chat_id = #{chatId}
|
||||||
|
AND sender_user_id = #{senderUserId}
|
||||||
|
AND message_status = 1
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -57,7 +57,6 @@
|
|||||||
last_message_time, unread_count, top_status, mute_status
|
last_message_time, unread_count, top_status, mute_status
|
||||||
FROM chat_sessions
|
FROM chat_sessions
|
||||||
WHERE user_id = #{userId}
|
WHERE user_id = #{userId}
|
||||||
AND session_status = 1
|
|
||||||
AND session_status in (1,2)
|
AND session_status in (1,2)
|
||||||
ORDER BY top_status DESC, last_message_time DESC
|
ORDER BY top_status DESC, last_message_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
Reference in New Issue
Block a user