feat(chat): 新增AI聊天记录持久化功能
新增KeyboardAiChatMessage实体及对应Mapper、Service,在ChatServiceImpl中同步对话时保存用户与AI消息到数据库,实现聊天记录持久化
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
package com.yolo.keyborad.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yolo.keyborad.model.entity.KeyboardAiChatMessage;
|
||||
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2026/1/26 17:00
|
||||
*/
|
||||
|
||||
public interface KeyboardAiChatMessageMapper extends BaseMapper<KeyboardAiChatMessage> {
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.yolo.keyborad.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2026/1/26 17:00
|
||||
*/
|
||||
|
||||
/**
|
||||
* 用户与AI情感陪伴角色的聊天记录表
|
||||
*/
|
||||
@Schema(description="用户与AI情感陪伴角色的聊天记录表")
|
||||
@Data
|
||||
@TableName(value = "keyboard_ai_chat_message")
|
||||
public class KeyboardAiChatMessage {
|
||||
/**
|
||||
* 聊天消息唯一ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@Schema(description="聊天消息唯一ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableField(value = "user_id")
|
||||
@Schema(description="用户ID")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 陪伴角色ID
|
||||
*/
|
||||
@TableField(value = "companion_id")
|
||||
@Schema(description="陪伴角色ID")
|
||||
private Long companionId;
|
||||
|
||||
/**
|
||||
* 消息发送方:1=用户,2=AI
|
||||
*/
|
||||
@TableField(value = "sender")
|
||||
@Schema(description="消息发送方:1=用户,2=AI")
|
||||
private Short sender;
|
||||
|
||||
/**
|
||||
* 聊天消息内容
|
||||
*/
|
||||
@TableField(value = "content")
|
||||
@Schema(description="聊天消息内容")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* AI识别到的用户情绪
|
||||
*/
|
||||
@TableField(value = "emotion_detected")
|
||||
@Schema(description="AI识别到的用户情绪")
|
||||
private String emotionDetected;
|
||||
|
||||
/**
|
||||
* AI提供的支持类型(倾听/共情/安抚等)
|
||||
*/
|
||||
@TableField(value = "support_type")
|
||||
@Schema(description="AI提供的支持类型(倾听/共情/安抚等)")
|
||||
private String supportType;
|
||||
|
||||
/**
|
||||
* 消息创建时间
|
||||
*/
|
||||
@TableField(value = "created_at")
|
||||
@Schema(description="消息创建时间")
|
||||
private Date createdAt;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.yolo.keyborad.service;
|
||||
|
||||
import com.yolo.keyborad.model.entity.KeyboardAiChatMessage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2026/1/26 17:00
|
||||
*/
|
||||
|
||||
public interface KeyboardAiChatMessageService extends IService<KeyboardAiChatMessage>{
|
||||
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import com.yolo.keyborad.config.NacosAppConfigCenter;
|
||||
import com.yolo.keyborad.exception.BusinessException;
|
||||
import com.yolo.keyborad.model.dto.chat.ChatReq;
|
||||
import com.yolo.keyborad.model.dto.chat.ChatStreamMessage;
|
||||
import com.yolo.keyborad.model.entity.KeyboardAiChatMessage;
|
||||
import com.yolo.keyborad.model.entity.KeyboardCharacter;
|
||||
import com.yolo.keyborad.model.entity.KeyboardUser;
|
||||
import com.yolo.keyborad.model.entity.KeyboardUserCallLog;
|
||||
@@ -77,6 +78,9 @@ public class ChatServiceImpl implements ChatService {
|
||||
@Resource
|
||||
private KeyboardAiCompanionService aiCompanionService;
|
||||
|
||||
@Resource
|
||||
private KeyboardAiChatMessageService aiChatMessageService;
|
||||
|
||||
@Resource
|
||||
private ElevenLabsService elevenLabsService;
|
||||
|
||||
@@ -372,6 +376,9 @@ public class ChatServiceImpl implements ChatService {
|
||||
long llmDuration = System.currentTimeMillis() - startTime;
|
||||
log.info("LLM 完成, userId: {}, 耗时: {}ms, 响应长度: {}", userId, llmDuration, response.length());
|
||||
|
||||
// 保存用户消息和AI响应到聊天记录
|
||||
saveChatMessages(Long.parseLong(userId), companionId, content, response);
|
||||
|
||||
// 生成音频任务 ID
|
||||
String audioId = UUID.randomUUID().toString().replace("-", "");
|
||||
|
||||
@@ -388,6 +395,33 @@ public class ChatServiceImpl implements ChatService {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户消息和AI响应到聊天记录
|
||||
*/
|
||||
private void saveChatMessages(Long userId, Long companionId, String userContent, String aiResponse) {
|
||||
Date now = new Date();
|
||||
|
||||
// 保存用户消息 (sender=1)
|
||||
KeyboardAiChatMessage userMessage = new KeyboardAiChatMessage();
|
||||
userMessage.setUserId(userId);
|
||||
userMessage.setCompanionId(companionId);
|
||||
userMessage.setSender((short) 1);
|
||||
userMessage.setContent(userContent);
|
||||
userMessage.setCreatedAt(now);
|
||||
|
||||
// 保存AI响应 (sender=2)
|
||||
KeyboardAiChatMessage aiMessage = new KeyboardAiChatMessage();
|
||||
aiMessage.setUserId(userId);
|
||||
aiMessage.setCompanionId(companionId);
|
||||
aiMessage.setSender((short) 2);
|
||||
aiMessage.setContent(aiResponse);
|
||||
aiMessage.setCreatedAt(now);
|
||||
|
||||
// 批量保存
|
||||
aiChatMessageService.saveBatch(List.of(userMessage, aiMessage));
|
||||
log.info("聊天记录保存成功, userId: {}, companionId: {}", userId, companionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用 LLM 生成响应
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.yolo.keyborad.service.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yolo.keyborad.mapper.KeyboardAiChatMessageMapper;
|
||||
import com.yolo.keyborad.model.entity.KeyboardAiChatMessage;
|
||||
import com.yolo.keyborad.service.KeyboardAiChatMessageService;
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2026/1/26 17:00
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class KeyboardAiChatMessageServiceImpl extends ServiceImpl<KeyboardAiChatMessageMapper, KeyboardAiChatMessage> implements KeyboardAiChatMessageService{
|
||||
|
||||
}
|
||||
20
src/main/resources/mapper/KeyboardAiChatMessageMapper.xml
Normal file
20
src/main/resources/mapper/KeyboardAiChatMessageMapper.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.yolo.keyborad.mapper.KeyboardAiChatMessageMapper">
|
||||
<resultMap id="BaseResultMap" type="com.yolo.keyborad.model.entity.KeyboardAiChatMessage">
|
||||
<!--@mbg.generated-->
|
||||
<!--@Table keyboard_ai_chat_message-->
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="user_id" jdbcType="BIGINT" property="userId" />
|
||||
<result column="companion_id" jdbcType="BIGINT" property="companionId" />
|
||||
<result column="sender" jdbcType="SMALLINT" property="sender" />
|
||||
<result column="content" jdbcType="VARCHAR" property="content" />
|
||||
<result column="emotion_detected" jdbcType="VARCHAR" property="emotionDetected" />
|
||||
<result column="support_type" jdbcType="VARCHAR" property="supportType" />
|
||||
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
<!--@mbg.generated-->
|
||||
id, user_id, companion_id, sender, content, emotion_detected, support_type, created_at
|
||||
</sql>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user