山东大学软件学院2026项目实训个人博客(六)
项目名称:基于AI大模型的智能考研社区撰写日期:2026年5月24日本周的主要任务是进行聊天功能的后端模块的开发,根据相关数据库表和接口文档的设计,实现聊天模块功能。
项目名称:基于AI大模型的智能考研社区
撰写日期:2026年5月24日
本周的主要任务是进行聊天功能的后端模块的开发,根据相关数据库表和接口文档的设计,实现聊天模块功能。
一、设计业务流程
1.用户详情查询
聊天时通过UserController.detail查看对方资料
2.搜索用户
发起聊天前通过searchDefaultUser/searchFriend找到对方用户
3.好友请求全流程
发好友申请→查看申请列表→接受/拒绝→解除好友
4.获取会话列表
通过getMessageLists消息首页的“消息列表”
5.消息发送加强
发消息前校验是否为好友
6.合并收尾
已读标记、撤回时间修正、WebSocket通知完善
二、接口实现过程
1.实现查看用户详情-UserController.detail
(1)在 IUserService 中新增 getUserDetail 方法
UserVO getUserDetail(BaseRequest baseRequest);
(2)在 UserServiceImpl 中实现:根据 baseRequest.getId() 查用户,排除密码字段,组装 UserVO
public UserVO getUserDetail(BaseRequest baseRequest) {}
(3)在 UserController.detail 中调用并返回
UserVO userVO = userService.getUserDetail(baseRequest);
return Result.success(userVO);
2. 搜索用户
通过searchDefaultUser 和 searchFriend搜索用户,searchFriend 需要查 friend 表。
(1)新建 FriendMapper.java
(2)UserServiceImpl.java — 实现两个搜索方法
public List<UserVO> searchDefaultUser(UserQueryDTO defaultUserDTO) {}
public List<UserVO> searchFriend(UserQueryDTO friendDTO){}
3. 好友请求全流程 (发申请 → 查看列表 → 接受/拒绝 → 解除好友)
(1)IMessageService.java — 新增 3 个接口方法
void feedbackFriendRequest(FriendMakeDTO friendMakeDTO);
List<FriendRequestVO> getFriendRequestList(FriendQueryDTO friendQueryDTO);
void deleteFriend(FriendMakeDTO friendMakeDTO);
(2)MessageServiceImpl.java — 实现所有好友逻辑
private final FriendMapper friendMapper;
public void sendFriendRequest(FriendMakeDTO friendMakeDTO)
public void feedbackFriendRequest(FriendMakeDTO friendMakeDTO)
public List<FriendRequestVO> getFriendRequestList(FriendQueryDTO friendQueryDTO)
public void deleteFriend(FriendMakeDTO friendMakeDTO)
(3)MessageController.java — 接入 3 个接口
/**
* 通过WebSocket通知
* 反馈好友请求,包括接受和拒绝
*
* **/
@PostMapping("/feedbackFriendRequest")
@Operation(summary = "反馈好友请求")
public Result feedbackFriendRequest(@RequestBody FriendMakeDTO friendMakeDTO) {
log.info("反馈好友请求,{}", friendMakeDTO);
messageService.feedbackFriendRequest(friendMakeDTO);
return Result.success();
}
/**
* 通过检查friend表
* 查看好友请求列表
*
* **/
@PostMapping("/getFriendRequestList")
@Operation(summary = "查看好友请求列表")
public Result<List<FriendRequestVO>> getFriendRequestList(@RequestBody FriendQueryDTO friendDTO) {
log.info("查看好友请求列表,{}", friendDTO);
List<FriendRequestVO> list = messageService.getFriendRequestList(friendDTO);
return Result.success(list);
}
/**
* 解除好友关系
*
* **/
@PostMapping("/deleteFriend")
@Operation(summary = "解除好友关系")
public Result blackFriend(@RequestBody FriendMakeDTO friendDTO) {
log.info("解除好友关系,{}", friendDTO);
messageService.deleteFriend(friendDTO);
return Result.success();
}
4. 获取会话列表
(1)新建文件: MessageListVO.java
(2)MessageServiceImpl.java — 实现 getMessageLists
public List<MessageListVO> getMessageLists(MessageListQueryDTO messageListQueryDTO) {
//详细代码略
return result;
}
5. 消息发送加强
- 发消息前校验好友关系
- 错题消息携带题目预览信息
(1)MessageVO.java — 增加错题卡片字段
@Schema(description = "错题ID,仅错题消息时有值")
private Long topicId;
@Schema(description = "错题标题,仅错题消息时有值")
private String topicTitle;
(2)MessageServiceImpl.java — 好友校验 + 错题信息 + 已读标记
在void send(MessageDTO messageDTO)构建消息对象前:
Long senderId = messageDTO.getSenderId();
Long receiverId = messageDTO.getReceiverId();
LambdaQueryWrapper<Friend> friendCheck = new LambdaQueryWrapper<>();
friendCheck.and(w ->
w.and(a -> a.eq(Friend::getUserIdOne, senderId).eq(Friend::getUserIdTwo, receiverId))
.or(b -> b.eq(Friend::getUserIdOne, receiverId).eq(Friend::getUserIdTwo, senderId)))
.eq(Friend::getStatus, FriendConstant.FRIEND_ACCEPT);
if (friendMapper.selectCount(friendCheck) == 0) {
throw new RuntimeException("还不是好友,无法发送消息");
}
修改 send() 中 WebSocket 推送部分,让错题消息携带题目标题:
Long topicId = null;
String topicTitle = null;
if (MessageConstant.TYPE_TOPIC.equals(message.getType()) && message.getContent() != null) {
try {
Topic topic = topicMapper.selectById(Long.parseLong(message.getContent()));
if (topic != null) {
topicId = topic.getId();
topicTitle = topic.getTitle();
}
} catch (NumberFormatException e) {
log.warn("错题ID解析失败: {}", message.getContent());
}
}
修改 getMessages() 中的 VO 组装,加入错题信息 + 已读标记:
if (cachedMessages != null && !cachedMessages.isEmpty()) {
log.info("从缓存中获取消息,userId: {}, otherUserId: {}", userId, otherUserId);
markMessagesAsRead(userId, otherUserId);
return cachedMessages;
}
撤回时间逻辑

三、基础功能和接口效果检验
准备两个账号:userA,userB

步骤1:A向B发送添加好友请求
登录userA,/message/searchDefaultUser接口查找用户B

或/message/searchFriend查找用户B

在/message/sendFriendRequest接口输入请求添加好友的测试数据:
{
"receiverId": 2058522555127095297,
"incidentalMessage": "test_0524_你好,我是userA,请添加为好友",
"opFlag": 0,
"acceptFlag": 0
}

请求发送成功,code:200。
步骤2:B接收A的请求并反馈
现在切换为userB账号 :
/message/getFriendRequestList接收请求消息:
测试数据为空对象:{}

来自userA的请求已接收。
在/message/feedbackFriendRequest接口反馈好友请求:
{
"receiverId": 2058522311064739842,
"incidentalMessage": "string",
"opFlag": 0,
"acceptFlag": 1
}
"acceptFlag": 1表示接受好友请求。

查看后台数据,此时friend数据状态为1,表示已通过
![]()
步骤3:已添加为好友的B向A发送聊天消息
POST /message/send,由B向A发送消息:

发送成功,code:200。后台数据显示已存有该消息:
![]()
然后B进行获取消息列表测试,检查消息列表:/message/listMessageList

测试成功,code:200。B成功获取消息列表。
步骤4:A接收来自B的聊天消息
切换回A视角,获取A的消息列表:

接收成功,code:200,A成功接收B发来的消息。
更多推荐


所有评论(0)