import { Injectable, NotFoundException, Logger, Optional } from '@nestjs/common'; import { PrismaService } from '../../infrastructure/database/prisma.service'; import { ContentSafetyService } from '../content-safety/content-safety.service'; @Injectable() export class RagChatService { private readonly logger = new Logger(RagChatService.name); constructor( private readonly prisma: PrismaService, @Optional() private readonly safety?: ContentSafetyService, ) {} async createSession(userId: string, knowledgeBaseId: string, title?: string) { return this.prisma.chatSession.create({ data: { userId, knowledgeBaseId, title: title || '新对话' }, }); } async listSessions(userId: string, kbId?: string) { return this.prisma.chatSession.findMany({ where: { userId, ...(kbId ? { knowledgeBaseId: kbId } : {}) }, orderBy: { updatedAt: 'desc' }, }); } async getMessages(sessionId: string) { return this.prisma.chatMessage.findMany({ where: { sessionId }, orderBy: { createdAt: 'asc' }, include: { citations: true }, }); } async sendMessage(userId: string, sessionId: string, content: string) { const session = await this.prisma.chatSession.findUnique({ where: { id: sessionId } }); if (!session || session.userId !== userId) throw new NotFoundException('对话不存在'); // Content safety check on user input const inputCheck = await this.safety?.check(content, { userId, contentType: 'rag_input' }); if (inputCheck && !inputCheck.safe) { return { blocked: true, message: '输入包含违规内容,请修改后重试' }; } // Save user message await this.prisma.chatMessage.create({ data: { sessionId, role: 'user', content }, }); // Generate AI response (simplified — real RAG pipeline in M3) const reply = `感谢提问。基于知识库内容,我暂时无法生成完整回答(RAG 检索管道将在后续版本完善)。`; const aiMsg = await this.prisma.chatMessage.create({ data: { sessionId, role: 'ai', content: reply, tokens: reply.length }, }); // Update session timestamp await this.prisma.chatSession.update({ where: { id: sessionId }, data: { updatedAt: new Date() } }); return { message: aiMsg, citations: [] }; } async deleteSession(sessionId: string) { await this.prisma.chatCitation.deleteMany({ where: { message: { sessionId } } }); await this.prisma.chatMessage.deleteMany({ where: { sessionId } }); await this.prisma.chatSession.delete({ where: { id: sessionId } }); return { success: true }; } }