新增普拉提训练系统的数据库结构和数据导入功能
- 创建普拉提分类和动作数据的SQL导入脚本,支持垫上普拉提和器械普拉提的分类管理 - 实现数据库结构迁移脚本,添加新字段以支持普拉提类型和器械名称 - 更新数据库升级总结文档,详细说明数据库结构变更和数据导入步骤 - 创建训练会话相关表,支持每日训练实例功能 - 引入训练会话管理模块,整合训练计划与实际训练会话的关系
This commit is contained in:
@@ -24,31 +24,56 @@ export class AiCoachController {
|
||||
): Promise<StreamableFile | AiChatResponseDto | void> {
|
||||
const userId = user.sub;
|
||||
const stream = body.stream !== false; // 默认流式
|
||||
const userContent = body.messages?.[body.messages.length - 1]?.content || '';
|
||||
|
||||
// 创建或沿用会话ID,并保存用户消息
|
||||
const { conversationId } = await this.aiCoachService.createOrAppendMessages({
|
||||
userId,
|
||||
conversationId: body.conversationId,
|
||||
userContent: body.messages?.[body.messages.length - 1]?.content || '',
|
||||
userContent,
|
||||
});
|
||||
|
||||
// 智能体重识别:若疑似“记体重”且传入图片,则优先识别并更新体重
|
||||
let weightInfo: { weightKg?: number } = {};
|
||||
let weightInfo: { weightKg?: number; systemNotice?: string } = {};
|
||||
|
||||
// 体重识别逻辑优化:
|
||||
// 1. 如果有图片URL,使用原有的图片识别逻辑
|
||||
// 2. 如果没有图片URL,但文本中包含体重信息,使用新的文本识别逻辑
|
||||
try {
|
||||
weightInfo = await this.aiCoachService.maybeExtractAndUpdateWeight(
|
||||
userId,
|
||||
body.imageUrl,
|
||||
body.messages?.[body.messages.length - 1]?.content,
|
||||
);
|
||||
} catch { }
|
||||
if (body.imageUrl) {
|
||||
// 原有逻辑:从图片识别体重
|
||||
const imageWeightInfo = await this.aiCoachService.maybeExtractAndUpdateWeight(
|
||||
userId,
|
||||
body.imageUrl,
|
||||
userContent,
|
||||
);
|
||||
if (imageWeightInfo.weightKg) {
|
||||
weightInfo = {
|
||||
weightKg: imageWeightInfo.weightKg,
|
||||
systemNotice: `系统提示:已从图片识别体重为${imageWeightInfo.weightKg}kg,并已为你更新到个人资料。`
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// 新逻辑:从文本识别体重,并获取历史对比信息
|
||||
const textWeightInfo = await this.aiCoachService.processWeightFromText(userId, userContent);
|
||||
if (textWeightInfo.weightKg && textWeightInfo.systemNotice) {
|
||||
weightInfo = {
|
||||
weightKg: textWeightInfo.weightKg,
|
||||
systemNotice: textWeightInfo.systemNotice
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// 体重识别失败不影响正常对话
|
||||
console.error('体重识别失败:', error);
|
||||
}
|
||||
|
||||
if (!stream) {
|
||||
// 非流式:聚合后一次性返回文本
|
||||
const readable = await this.aiCoachService.streamChat({
|
||||
userId,
|
||||
conversationId,
|
||||
userContent: body.messages?.[body.messages.length - 1]?.content || '',
|
||||
systemNotice: weightInfo.weightKg ? `系统提示:已从图片识别体重为${weightInfo.weightKg}kg,并已为你更新到个人资料。` : undefined,
|
||||
userContent,
|
||||
systemNotice: weightInfo.systemNotice,
|
||||
});
|
||||
let text = '';
|
||||
for await (const chunk of readable) {
|
||||
@@ -67,13 +92,11 @@ export class AiCoachController {
|
||||
const readable = await this.aiCoachService.streamChat({
|
||||
userId,
|
||||
conversationId,
|
||||
userContent: body.messages?.[body.messages.length - 1]?.content || '',
|
||||
systemNotice: weightInfo.weightKg ? `系统提示:已从图片识别体重为${weightInfo.weightKg}kg,并已为你更新到个人资料。` : undefined,
|
||||
userContent,
|
||||
systemNotice: weightInfo.systemNotice,
|
||||
});
|
||||
|
||||
readable.on('data', (chunk) => {
|
||||
// 流水首段可提示体重已更新
|
||||
// 简化处理:服务端不额外注入推送段,直接靠 systemNotice
|
||||
res.write(chunk);
|
||||
});
|
||||
readable.on('end', () => {
|
||||
|
||||
Reference in New Issue
Block a user