项目名称:基于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发来的消息。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐