From b887e52f5559a468cdb8cb6fd5497b01d338983a Mon Sep 17 00:00:00 2001 From: ziin Date: Mon, 26 Jan 2026 17:11:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E6=96=B0=E5=A2=9EAI=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E8=AE=B0=E5=BD=95=E6=8C=81=E4=B9=85=E5=8C=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增KeyboardAiChatMessage实体及对应Mapper、Service,在ChatServiceImpl中同步对话时保存用户与AI消息到数据库,实现聊天记录持久化 --- .../mapper/KeyboardAiChatMessageMapper.java | 12 +++ .../model/entity/KeyboardAiChatMessage.java | 78 +++++++++++++++++++ .../service/KeyboardAiChatMessageService.java | 13 ++++ .../service/impl/ChatServiceImpl.java | 34 ++++++++ .../KeyboardAiChatMessageServiceImpl.java | 18 +++++ .../mapper/KeyboardAiChatMessageMapper.xml | 20 +++++ 6 files changed, 175 insertions(+) create mode 100644 src/main/java/com/yolo/keyborad/mapper/KeyboardAiChatMessageMapper.java create mode 100644 src/main/java/com/yolo/keyborad/model/entity/KeyboardAiChatMessage.java create mode 100644 src/main/java/com/yolo/keyborad/service/KeyboardAiChatMessageService.java create mode 100644 src/main/java/com/yolo/keyborad/service/impl/KeyboardAiChatMessageServiceImpl.java create mode 100644 src/main/resources/mapper/KeyboardAiChatMessageMapper.xml diff --git a/src/main/java/com/yolo/keyborad/mapper/KeyboardAiChatMessageMapper.java b/src/main/java/com/yolo/keyborad/mapper/KeyboardAiChatMessageMapper.java new file mode 100644 index 0000000..d62da73 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/mapper/KeyboardAiChatMessageMapper.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardAiChatMessage.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardAiChatMessage.java new file mode 100644 index 0000000..659f16c --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardAiChatMessage.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardAiChatMessageService.java b/src/main/java/com/yolo/keyborad/service/KeyboardAiChatMessageService.java new file mode 100644 index 0000000..5e509b7 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/KeyboardAiChatMessageService.java @@ -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{ + + +} diff --git a/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java index 06c5652..c48dcb3 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java @@ -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 生成响应 */ diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardAiChatMessageServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardAiChatMessageServiceImpl.java new file mode 100644 index 0000000..a3fbdef --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardAiChatMessageServiceImpl.java @@ -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 implements KeyboardAiChatMessageService{ + +} diff --git a/src/main/resources/mapper/KeyboardAiChatMessageMapper.xml b/src/main/resources/mapper/KeyboardAiChatMessageMapper.xml new file mode 100644 index 0000000..5c725bf --- /dev/null +++ b/src/main/resources/mapper/KeyboardAiChatMessageMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + id, user_id, companion_id, sender, content, emotion_detected, support_type, created_at + + \ No newline at end of file