feat(chat): 新增分页查询聊天记录接口

This commit is contained in:
2026-01-26 18:38:51 +08:00
parent b887e52f55
commit aaf5d3bea4
6 changed files with 111 additions and 17 deletions

View File

@@ -112,7 +112,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
"/chat/message", "/chat/message",
"/chat/voice", "/chat/voice",
"/chat/audio/*", "/chat/audio/*",
"/ai-companion/page" "/ai-companion/page",
"/chat/history"
}; };
} }
@Bean @Bean

View File

@@ -3,19 +3,23 @@ package com.yolo.keyborad.controller;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yolo.keyborad.common.BaseResponse; import com.yolo.keyborad.common.BaseResponse;
import com.yolo.keyborad.common.ErrorCode; import com.yolo.keyborad.common.ErrorCode;
import com.yolo.keyborad.common.ResultUtils; import com.yolo.keyborad.common.ResultUtils;
import com.yolo.keyborad.exception.BusinessException; import com.yolo.keyborad.exception.BusinessException;
import com.yolo.keyborad.mapper.QdrantPayloadMapper; import com.yolo.keyborad.mapper.QdrantPayloadMapper;
import com.yolo.keyborad.model.dto.chat.ChatHistoryPageReq;
import com.yolo.keyborad.model.dto.chat.ChatMessageReq; import com.yolo.keyborad.model.dto.chat.ChatMessageReq;
import com.yolo.keyborad.model.dto.chat.ChatReq; import com.yolo.keyborad.model.dto.chat.ChatReq;
import com.yolo.keyborad.model.dto.chat.ChatSaveReq; import com.yolo.keyborad.model.dto.chat.ChatSaveReq;
import com.yolo.keyborad.model.dto.chat.ChatStreamMessage; import com.yolo.keyborad.model.dto.chat.ChatStreamMessage;
import com.yolo.keyborad.model.vo.AudioTaskVO; import com.yolo.keyborad.model.vo.AudioTaskVO;
import com.yolo.keyborad.model.vo.ChatMessageHistoryVO;
import com.yolo.keyborad.model.vo.ChatMessageVO; import com.yolo.keyborad.model.vo.ChatMessageVO;
import com.yolo.keyborad.model.vo.ChatVoiceVO; import com.yolo.keyborad.model.vo.ChatVoiceVO;
import com.yolo.keyborad.service.ChatService; import com.yolo.keyborad.service.ChatService;
import com.yolo.keyborad.service.KeyboardAiChatMessageService;
import com.yolo.keyborad.service.impl.QdrantVectorService; import com.yolo.keyborad.service.impl.QdrantVectorService;
import io.qdrant.client.grpc.JsonWithInt; import io.qdrant.client.grpc.JsonWithInt;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@@ -48,6 +52,9 @@ public class ChatController {
@Resource @Resource
private ChatService chatService; private ChatService chatService;
@Resource
private KeyboardAiChatMessageService aiChatMessageService;
@PostMapping("/message") @PostMapping("/message")
@Operation(summary = "同步对话", description = "发送消息给大模型,同步返回 AI 响应,异步生成音频") @Operation(summary = "同步对话", description = "发送消息给大模型,同步返回 AI 响应,异步生成音频")
@@ -111,4 +118,17 @@ public class ChatController {
log.info("聊天嵌入保存成功用户ID: {}, 文本长度: {}", chatSaveReq.getUserId(), chatSaveReq.getUserText().length()); log.info("聊天嵌入保存成功用户ID: {}, 文本长度: {}", chatSaveReq.getUserId(), chatSaveReq.getUserText().length());
return ResultUtils.success(true); return ResultUtils.success(true);
} }
@PostMapping("/history")
@Operation(summary = "分页查询聊天记录", description = "分页查询用户与AI陪聊角色的聊天记录")
public BaseResponse<IPage<ChatMessageHistoryVO>> pageHistory(@RequestBody ChatHistoryPageReq req) {
if (req.getCompanionId() == null) {
throw new BusinessException(ErrorCode.COMPANION_ID_EMPTY);
}
Long userId = StpUtil.getLoginIdAsLong();
IPage<ChatMessageHistoryVO> result = aiChatMessageService.pageHistory(
userId, req.getCompanionId(), req.getPageNum(), req.getPageSize());
return ResultUtils.success(result);
}
} }

View File

@@ -0,0 +1,22 @@
package com.yolo.keyborad.model.dto.chat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/*
* @author: ziin
* @date: 2026/1/26
*/
@Data
@Schema(description = "聊天记录分页查询请求")
public class ChatHistoryPageReq {
@Schema(description = "AI陪聊角色ID", requiredMode = Schema.RequiredMode.REQUIRED)
private Long companionId;
@Schema(description = "页码", example = "1")
private Integer pageNum = 1;
@Schema(description = "每页数量", example = "20")
private Integer pageSize = 20;
}

View File

@@ -0,0 +1,27 @@
package com.yolo.keyborad.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/*
* @author: ziin
* @date: 2026/1/26
*/
@Data
@Schema(description = "聊天消息VO")
public class ChatMessageHistoryVO {
@Schema(description = "消息ID")
private Long id;
@Schema(description = "消息发送方1=用户2=AI")
private Short sender;
@Schema(description = "聊天消息内容")
private String content;
@Schema(description = "消息创建时间")
private Date createdAt;
}

View File

@@ -1,13 +1,24 @@
package com.yolo.keyborad.service; package com.yolo.keyborad.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yolo.keyborad.model.entity.KeyboardAiChatMessage; import com.yolo.keyborad.model.entity.KeyboardAiChatMessage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
/* import com.yolo.keyborad.model.vo.ChatMessageHistoryVO;
* @author: ziin
* @date: 2026/1/26 17:00
*/
public interface KeyboardAiChatMessageService extends IService<KeyboardAiChatMessage>{
/*
* @author: ziin
* @date: 2026/1/26 17:00
*/
public interface KeyboardAiChatMessageService extends IService<KeyboardAiChatMessage> {
/**
* 分页查询用户与AI的聊天记录
*
* @param userId 用户ID
* @param companionId AI陪聊角色ID
* @param pageNum 页码
* @param pageSize 每页数量
* @return 分页结果
*/
IPage<ChatMessageHistoryVO> pageHistory(Long userId, Long companionId, Integer pageNum, Integer pageSize);
} }

View File

@@ -1,18 +1,31 @@
package com.yolo.keyborad.service.impl; package com.yolo.keyborad.service.impl;
import org.springframework.stereotype.Service; import cn.hutool.core.bean.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.List; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yolo.keyborad.mapper.KeyboardAiChatMessageMapper; import com.yolo.keyborad.mapper.KeyboardAiChatMessageMapper;
import com.yolo.keyborad.model.entity.KeyboardAiChatMessage; import com.yolo.keyborad.model.entity.KeyboardAiChatMessage;
import com.yolo.keyborad.model.vo.ChatMessageHistoryVO;
import com.yolo.keyborad.service.KeyboardAiChatMessageService; import com.yolo.keyborad.service.KeyboardAiChatMessageService;
/* import org.springframework.stereotype.Service;
* @author: ziin
* @date: 2026/1/26 17:00
*/
@Service
public class KeyboardAiChatMessageServiceImpl extends ServiceImpl<KeyboardAiChatMessageMapper, KeyboardAiChatMessage> implements KeyboardAiChatMessageService{
/*
* @author: ziin
* @date: 2026/1/26 17:00
*/
@Service
public class KeyboardAiChatMessageServiceImpl extends ServiceImpl<KeyboardAiChatMessageMapper, KeyboardAiChatMessage> implements KeyboardAiChatMessageService {
@Override
public IPage<ChatMessageHistoryVO> pageHistory(Long userId, Long companionId, Integer pageNum, Integer pageSize) {
Page<KeyboardAiChatMessage> page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper<KeyboardAiChatMessage> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(KeyboardAiChatMessage::getUserId, userId)
.eq(KeyboardAiChatMessage::getCompanionId, companionId)
.orderByDesc(KeyboardAiChatMessage::getCreatedAt);
IPage<KeyboardAiChatMessage> entityPage = this.page(page, queryWrapper);
return entityPage.convert(entity -> BeanUtil.copyProperties(entity, ChatMessageHistoryVO.class));
}
} }