Files
han-ai-robot-backend/src/main/java/com/hanserwei/airobot/service/impl/ChatServiceImpl.java
Hanserwei fdab553ba1 feat(chat): 实现联网搜索与对话管理功能
- 新增 OkHttp 客户端配置及依赖
- 添加 SearXNG 搜索引擎集成配置
- 创建基础分页查询类 BasePageQuery
- 实现网络搜索增强顾问 NetworkSearchAdvisor
- 增加聊天历史消息和对话的分页查询接口
- 添加对话摘要重命名与删除功能
- 配置 MyBatis Plus 分页插件支持
- 引入 Jsoup用于网页内容解析
- 新增 Hutool 工具库依赖
- 实现搜索结果内容抓取服务
- 添加搜索结果 DTO 和相关服务接口
- 扩展响应码枚举支持对话不存在情况
- 新增多个 VO 类用于请求和响应数据传输
2025-11-03 22:08:26 +08:00

155 lines
5.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.hanserwei.airobot.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hanserwei.airobot.domain.dos.ChatDO;
import com.hanserwei.airobot.domain.dos.ChatMessageDO;
import com.hanserwei.airobot.domain.mapper.ChatMapper;
import com.hanserwei.airobot.domain.mapper.ChatMessageMapper;
import com.hanserwei.airobot.enums.ResponseCodeEnum;
import com.hanserwei.airobot.exception.BizException;
import com.hanserwei.airobot.model.vo.chat.*;
import com.hanserwei.airobot.service.ChatService;
import com.hanserwei.airobot.utils.PageResponse;
import com.hanserwei.airobot.utils.Response;
import com.hanserwei.airobot.utils.StringUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
public class ChatServiceImpl implements ChatService {
@Resource
private ChatMapper chatMapper;
@Resource
private ChatMessageMapper chatMessageMapper;
@Override
public Response<NewChatRspVO> newChat(NewChatReqVO newChatReqVO) {
// 用户发来的消息
String message = newChatReqVO.getMessage();
// 生成对话的UUID
String uuid = UUID.randomUUID().toString();
// 截取用户发送的消息,作为对话的摘要
String summary = StringUtil.truncate(message, 20);
// 存储对话记录到数据库中
chatMapper.insert(ChatDO.builder()
.summary(summary)
.uuid(uuid)
.createTime(LocalDateTime.now())
.updateTime(LocalDateTime.now())
.build());
// 将摘要、UUID 返回给前端
return Response.success(NewChatRspVO.builder()
.uuid(uuid)
.summary(summary)
.build());
}
@Override
public PageResponse<FindChatHistoryMessagePageListRspVO> findChatHistoryMessagePageList(FindChatHistoryMessagePageListReqVO findChatHistoryMessagePageListReqVO) {
// 获取当前页、以及每页需要展示的数据数量
Long current = findChatHistoryMessagePageListReqVO.getCurrent();
Long size = findChatHistoryMessagePageListReqVO.getSize();
String chatId = findChatHistoryMessagePageListReqVO.getChatId();
// 执行分页查询
Page<ChatMessageDO> chatMessageDOPage = chatMessageMapper.selectPageList(current, size, chatId);
List<ChatMessageDO> chatMessageDOS = chatMessageDOPage.getRecords();
// DO 转 VO
List<FindChatHistoryMessagePageListRspVO> vos = null;
if (CollUtil.isNotEmpty(chatMessageDOS)) {
vos = chatMessageDOS.stream()
.map(chatMessageDO -> FindChatHistoryMessagePageListRspVO.builder() // 构建返参 VO 实体类
.id(chatMessageDO.getId())
.chatId(chatMessageDO.getChatUuid())
.content(chatMessageDO.getContent())
.role(chatMessageDO.getRole())
.createTime(chatMessageDO.getCreateTime())
.build())
// 升序排序
.sorted(Comparator.comparing(FindChatHistoryMessagePageListRspVO::getCreateTime))
.collect(Collectors.toList());
}
return PageResponse.success(chatMessageDOPage, vos);
}
@Override
public PageResponse<FindChatHistoryPageListRspVO> findChatHistoryPageList(FindChatHistoryPageListReqVO findChatHistoryPageListReqVO) {
// 获取当前页、以及每页需要展示的数据数量
Long current = findChatHistoryPageListReqVO.getCurrent();
Long size = findChatHistoryPageListReqVO.getSize();
// 执行分页查询
Page<ChatDO> chatDOPage = chatMapper.selectPageList(current, size);
// 获取查询结果
List<ChatDO> chatDOS = chatDOPage.getRecords();
// DO 转 VO
List<FindChatHistoryPageListRspVO> vos = null;
if (CollUtil.isNotEmpty(chatDOS)) {
vos = chatDOS.stream()
.map(chatDO -> FindChatHistoryPageListRspVO.builder() // 构建返参 VO
.id(chatDO.getId())
.uuid(chatDO.getUuid())
.summary(chatDO.getSummary())
.updateTime(chatDO.getUpdateTime())
.build())
.collect(Collectors.toList());
}
return PageResponse.success(chatDOPage, vos);
}
@Override
public Response<?> renameChatSummary(RenameChatReqVO renameChatReqVO) {
// 对话 ID
Long chatId = renameChatReqVO.getId();
// 摘要
String summary = renameChatReqVO.getSummary();
// 根据主键 ID 更新摘要
chatMapper.updateById(ChatDO.builder()
.id(chatId)
.summary(summary)
.build());
return Response.success();
}
@Override
@Transactional(rollbackFor = Exception.class)
public Response<?> deleteChat(DeleteChatReqVO deleteChatReqVO) {
// 对话 UUID
String uuid = deleteChatReqVO.getUuid();
// 删除对话
int count = chatMapper.delete(Wrappers.<ChatDO>lambdaQuery()
.eq(ChatDO::getUuid, uuid));
// 如果删除操作影响的行数为 0说明想要删除的对话不存在
if (count == 0) {
throw new BizException(ResponseCodeEnum.CHAT_NOT_EXISTED);
}
// 批量删除对话下的所有消息
chatMessageMapper.delete(Wrappers.<ChatMessageDO>lambdaQuery()
.eq(ChatMessageDO::getChatUuid, uuid));
return Response.success();
}
}