import type { FastifyRequest, FastifyReply } from 'fastify'; import * as knowledgeBaseService from '../services/knowledgeBaseService.js'; /** * 获取用户ID(从JWT Token中获取) */ function getUserId(request: FastifyRequest): string { const userId = (request as any).user?.userId; if (!userId) { throw new Error('User not authenticated'); } return userId; } /** * 创建知识库 */ export async function createKnowledgeBase( request: FastifyRequest<{ Body: { name: string; description?: string; }; }>, reply: FastifyReply ) { try { const { name, description } = request.body; if (!name || name.trim().length === 0) { return reply.status(400).send({ success: false, message: 'Knowledge base name is required', }); } const userId = getUserId(request); const knowledgeBase = await knowledgeBaseService.createKnowledgeBase( userId, name, description ); return reply.status(201).send({ success: true, data: knowledgeBase, }); } catch (error: any) { console.error('Failed to create knowledge base:', error); // 处理配额超限错误 if (error.code === 'QUOTA_EXCEEDED') { return reply.status(400).send({ success: false, code: 'QUOTA_EXCEEDED', message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || '创建知识库失败,请稍后重试', }); } } /** * 获取知识库列表 */ export async function getKnowledgeBases( request: FastifyRequest, reply: FastifyReply ) { try { const userId = getUserId(request); const knowledgeBases = await knowledgeBaseService.getKnowledgeBases( userId ); return reply.send({ success: true, data: knowledgeBases, }); } catch (error: any) { console.error('Failed to get knowledge bases:', error); return reply.status(500).send({ success: false, message: error.message || 'Failed to get knowledge bases', }); } } /** * 获取知识库详情 */ export async function getKnowledgeBaseById( request: FastifyRequest<{ Params: { id: string; }; }>, reply: FastifyReply ) { try { const { id } = request.params; const userId = getUserId(request); const knowledgeBase = await knowledgeBaseService.getKnowledgeBaseById( userId, id ); return reply.send({ success: true, data: knowledgeBase, }); } catch (error: any) { console.error('Failed to get knowledge base:', error); if (error.message.includes('not found')) { return reply.status(404).send({ success: false, message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || 'Failed to get knowledge base', }); } } /** * 更新知识库 */ export async function updateKnowledgeBase( request: FastifyRequest<{ Params: { id: string; }; Body: { name?: string; description?: string; }; }>, reply: FastifyReply ) { try { const { id } = request.params; const updateData = request.body; const userId = getUserId(request); const knowledgeBase = await knowledgeBaseService.updateKnowledgeBase( userId, id, updateData ); return reply.send({ success: true, data: knowledgeBase, }); } catch (error: any) { console.error('Failed to update knowledge base:', error); if (error.message.includes('not found')) { return reply.status(404).send({ success: false, message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || 'Failed to update knowledge base', }); } } /** * 删除知识库 */ export async function deleteKnowledgeBase( request: FastifyRequest<{ Params: { id: string; }; }>, reply: FastifyReply ) { try { const { id } = request.params; const userId = getUserId(request); await knowledgeBaseService.deleteKnowledgeBase(userId, id); return reply.send({ success: true, message: 'Knowledge base deleted successfully', }); } catch (error: any) { console.error('Failed to delete knowledge base:', error); if (error.message.includes('not found')) { return reply.status(404).send({ success: false, message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || 'Failed to delete knowledge base', }); } } /** * 检索知识库 */ export async function searchKnowledgeBase( request: FastifyRequest<{ Params: { id: string; }; Querystring: { query: string; top_k?: string; }; }>, reply: FastifyReply ) { try { const { id } = request.params; const { query, top_k } = request.query; if (!query || query.trim().length === 0) { return reply.status(400).send({ success: false, message: 'Query parameter is required', }); } const topK = top_k ? parseInt(top_k, 10) : 15; // Phase 1优化:默认从3增加到15 const userId = getUserId(request); const results = await knowledgeBaseService.searchKnowledgeBase( userId, id, query, topK ); return reply.send({ success: true, data: results, }); } catch (error: any) { console.error('Failed to search knowledge base:', error); if (error.message.includes('not found')) { return reply.status(404).send({ success: false, message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || 'Failed to search knowledge base', }); } } /** * 获取知识库统计信息 */ export async function getKnowledgeBaseStats( request: FastifyRequest<{ Params: { id: string; }; }>, reply: FastifyReply ) { try { const { id } = request.params; const userId = getUserId(request); const stats = await knowledgeBaseService.getKnowledgeBaseStats( userId, id ); return reply.send({ success: true, data: stats, }); } catch (error: any) { console.error('Failed to get knowledge base stats:', error); if (error.message.includes('not found')) { return reply.status(404).send({ success: false, message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || 'Failed to get knowledge base stats', }); } } /** * 获取知识库文档选择(Phase 2: 全文阅读模式) */ export async function getDocumentSelection( request: FastifyRequest<{ Params: { id: string; }; Querystring: { max_files?: string; max_tokens?: string; }; }>, reply: FastifyReply ) { try { const { id } = request.params; const { max_files, max_tokens } = request.query; const maxFiles = max_files ? parseInt(max_files, 10) : undefined; const maxTokens = max_tokens ? parseInt(max_tokens, 10) : undefined; const userId = getUserId(request); const selection = await knowledgeBaseService.getDocumentSelection( userId, id, maxFiles, maxTokens ); return reply.send({ success: true, data: selection, }); } catch (error: any) { console.error('Failed to get document selection:', error); if (error.message.includes('not found')) { return reply.status(404).send({ success: false, message: error.message, }); } return reply.status(500).send({ success: false, message: error.message || 'Failed to get document selection', }); } }