api-server/src/modules/admin-conversation/admin-conversation.service.ts

83 lines
2.8 KiB
TypeScript
Raw Normal View History

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../infrastructure/database/prisma.service';
import { randomUUID } from 'crypto';
@Injectable()
export class AdminConversationService {
constructor(private readonly prisma: PrismaService) {}
async list(adminUserId: string) {
return this.prisma.adminConversation.findMany({
where: { adminUserId, deletedAt: null },
orderBy: { updatedAt: 'desc' },
select: { id: true, title: true, createdAt: true, updatedAt: true },
});
}
async getMessages(conversationId: string, adminUserId: string) {
const conv = await this.prisma.adminConversation.findFirst({
where: { id: conversationId, adminUserId, deletedAt: null },
});
if (!conv) return [];
return this.prisma.adminMessage.findMany({
where: { conversationId },
orderBy: { createdAt: 'asc' },
select: { id: true, role: true, content: true, createdAt: true },
});
}
async create(adminUserId: string, title?: string) {
const hermesSessionId = randomUUID();
return this.prisma.adminConversation.create({
data: { adminUserId, hermesSessionId, title: title || '新对话' },
select: { id: true, title: true, hermesSessionId: true, createdAt: true },
});
}
async updateTitle(id: string, adminUserId: string, title: string) {
return this.prisma.adminConversation.updateMany({
where: { id, adminUserId, deletedAt: null },
data: { title },
});
}
async delete(id: string, adminUserId: string) {
return this.prisma.adminConversation.updateMany({
where: { id, adminUserId, deletedAt: null },
data: { deletedAt: new Date() },
});
}
async saveMessage(conversationId: string, role: string, content: string) {
await this.prisma.adminMessage.create({
data: { conversationId, role, content },
});
// Update conversation timestamp and auto-set title from first user message
if (role === 'user') {
const conv = await this.prisma.adminConversation.findUnique({
where: { id: conversationId },
select: { title: true, _count: { select: { messages: true } } },
});
// Auto-title: use first user message (truncated)
const isFirstMessage = (conv?._count?.messages ?? 0) <= 1;
const updateData: any = { updatedAt: new Date() };
if (isFirstMessage && conv?.title === '新对话') {
updateData.title = content.slice(0, 40);
}
await this.prisma.adminConversation.update({
where: { id: conversationId },
data: updateData,
});
}
}
async getSessionId(conversationId: string, adminUserId: string) {
const conv = await this.prisma.adminConversation.findFirst({
where: { id: conversationId, adminUserId, deletedAt: null },
select: { id: true, hermesSessionId: true },
});
return conv?.hermesSessionId ?? null;
}
}