/** * 系统知识库控制器 */ import { FastifyRequest, FastifyReply } from 'fastify'; import { getSystemKbService } from './systemKbService.js'; import { prisma } from '../../../config/database.js'; import { logger } from '../../../common/logging/index.js'; // ==================== 类型定义 ==================== interface CreateKbBody { code: string; name: string; description?: string; category?: string; } interface UpdateKbBody { name?: string; description?: string; category?: string; } interface ListKbQuery { category?: string; status?: string; } interface KbIdParams { id: string; } interface DocIdParams { id: string; docId: string; } // ==================== 控制器函数 ==================== /** * 获取知识库列表 */ export async function listKnowledgeBases( request: FastifyRequest<{ Querystring: ListKbQuery }>, reply: FastifyReply ) { try { const { category, status } = request.query; const service = getSystemKbService(prisma); const kbs = await service.listKnowledgeBases({ category, status }); return reply.send({ success: true, data: kbs, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('获取知识库列表失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 获取知识库详情 */ export async function getKnowledgeBase( request: FastifyRequest<{ Params: KbIdParams }>, reply: FastifyReply ) { try { const { id } = request.params; const service = getSystemKbService(prisma); const kb = await service.getKnowledgeBase(id); if (!kb) { return reply.status(404).send({ success: false, error: '知识库不存在', }); } return reply.send({ success: true, data: kb, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('获取知识库详情失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 创建知识库 */ export async function createKnowledgeBase( request: FastifyRequest<{ Body: CreateKbBody }>, reply: FastifyReply ) { try { const { code, name, description, category } = request.body; if (!code || !name) { return reply.status(400).send({ success: false, error: '编码和名称为必填项', }); } const service = getSystemKbService(prisma); const kb = await service.createKnowledgeBase({ code, name, description, category }); return reply.status(201).send({ success: true, data: kb, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('创建知识库失败', { error: message }); if (message.includes('已存在')) { return reply.status(409).send({ success: false, error: message, }); } return reply.status(500).send({ success: false, error: message, }); } } /** * 更新知识库 */ export async function updateKnowledgeBase( request: FastifyRequest<{ Params: KbIdParams; Body: UpdateKbBody }>, reply: FastifyReply ) { try { const { id } = request.params; const { name, description, category } = request.body; const service = getSystemKbService(prisma); const kb = await service.updateKnowledgeBase(id, { name, description, category }); return reply.send({ success: true, data: kb, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('更新知识库失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 删除知识库 */ export async function deleteKnowledgeBase( request: FastifyRequest<{ Params: KbIdParams }>, reply: FastifyReply ) { try { const { id } = request.params; const service = getSystemKbService(prisma); await service.deleteKnowledgeBase(id); return reply.send({ success: true, message: '删除成功', }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('删除知识库失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 获取文档列表 */ export async function listDocuments( request: FastifyRequest<{ Params: KbIdParams }>, reply: FastifyReply ) { try { const { id } = request.params; const service = getSystemKbService(prisma); const docs = await service.listDocuments(id); return reply.send({ success: true, data: docs, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('获取文档列表失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 上传文档 */ export async function uploadDocument( request: FastifyRequest<{ Params: KbIdParams }>, reply: FastifyReply ) { try { const { id: kbId } = request.params; // 处理 multipart 文件上传 const data = await request.file(); if (!data) { return reply.status(400).send({ success: false, error: '请上传文件', }); } const filename = data.filename; const fileBuffer = await data.toBuffer(); // 验证文件类型 const allowedTypes = ['pdf', 'docx', 'doc', 'txt', 'md']; const ext = filename.toLowerCase().split('.').pop(); if (!ext || !allowedTypes.includes(ext)) { return reply.status(400).send({ success: false, error: `不支持的文件类型: ${ext},支持: ${allowedTypes.join(', ')}`, }); } // 验证文件大小(最大 50MB) const maxSize = 50 * 1024 * 1024; if (fileBuffer.length > maxSize) { return reply.status(400).send({ success: false, error: '文件大小超过限制(最大 50MB)', }); } const service = getSystemKbService(prisma); const result = await service.uploadDocument(kbId, filename, fileBuffer); return reply.status(201).send({ success: true, data: { docId: result.docId, filename, chunkCount: result.ingestResult.chunkCount, tokenCount: result.ingestResult.tokenCount, duration: result.ingestResult.duration, }, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('上传文档失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 删除文档 */ export async function deleteDocument( request: FastifyRequest<{ Params: DocIdParams }>, reply: FastifyReply ) { try { const { id: kbId, docId } = request.params; const service = getSystemKbService(prisma); await service.deleteDocument(kbId, docId); return reply.send({ success: true, message: '删除成功', }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('删除文档失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } } /** * 下载文档 */ export async function downloadDocument( request: FastifyRequest<{ Params: DocIdParams }>, reply: FastifyReply ) { try { const { id: kbId, docId } = request.params; const service = getSystemKbService(prisma); const result = await service.getDocumentDownloadUrl(kbId, docId); return reply.send({ success: true, data: result, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); logger.error('获取下载链接失败', { error: message }); return reply.status(500).send({ success: false, error: message, }); } }