feat(pkb): Complete PKB module frontend migration with V3 design
Summary: - Implement PKB Dashboard and Workspace pages based on V3 prototype - Add single-layer header with integrated Tab navigation - Implement 3 work modes: Full Text, Deep Read, Batch Processing - Integrate Ant Design X Chat component for AI conversations - Create BatchModeComplete with template selection and document processing - Add compact work mode selector with dropdown design Backend: - Migrate PKB controllers and services to /modules/pkb structure - Register v2 API routes at /api/v2/pkb/knowledge - Maintain dual API routes for backward compatibility Technical details: - Use Zustand for state management - Handle SSE streaming responses for AI chat - Support document selection for Deep Read mode - Implement batch processing with progress tracking Known issues: - Batch processing API integration pending - Knowledge assets page navigation needs optimization Status: Frontend functional, pending refinement
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* 逐篇精读模式组件 - ChatGPT风格全屏聊天
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Empty } from 'antd';
|
||||
import { FileText } from 'lucide-react';
|
||||
import { ChatContainer } from '@/shared/components/Chat';
|
||||
import type { KnowledgeBase, Document } from '../../api/knowledgeBaseApi';
|
||||
|
||||
interface DeepReadModeProps {
|
||||
kbId: string;
|
||||
kbInfo: KnowledgeBase;
|
||||
selectedDocuments: Document[];
|
||||
}
|
||||
|
||||
export const DeepReadMode: React.FC<DeepReadModeProps> = ({
|
||||
kbId,
|
||||
selectedDocuments
|
||||
}) => {
|
||||
if (!selectedDocuments || selectedDocuments.length === 0) {
|
||||
return (
|
||||
<div className="h-full flex items-center justify-center bg-slate-50">
|
||||
<div className="text-center">
|
||||
<div className="w-16 h-16 mx-auto bg-purple-50 rounded-full flex items-center justify-center mb-4">
|
||||
<FileText className="w-8 h-8 text-purple-400" />
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-slate-700 mb-2">选择文档开始精读</h3>
|
||||
<p className="text-sm text-slate-500 max-w-xs">
|
||||
请在上方"逐篇精读"下拉框中选择一篇文档进行深度分析
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const selectedDoc = selectedDocuments[0];
|
||||
const selectedDocIds = selectedDocuments.map(d => d.id);
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col bg-white">
|
||||
{/* Chat组件 - 全屏展开 */}
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<ChatContainer
|
||||
conversationType="pkb"
|
||||
conversationKey={`kb-deepread-${kbId}-${selectedDoc.id}`}
|
||||
defaultMessages={[{
|
||||
id: 'welcome',
|
||||
role: 'assistant',
|
||||
content: `您好!我已准备好深度解读文档《${selectedDoc.filename}》。\n\n我可以帮您:\n- 📖 逐段解读文献内容\n- 🎯 提炼核心观点和结论\n- 💡 分析研究方法和局限性\n\n请告诉我您想深入了解哪方面?`,
|
||||
status: 'success',
|
||||
timestamp: Date.now(),
|
||||
}]}
|
||||
providerConfig={{
|
||||
apiEndpoint: '/api/v1/chat/stream',
|
||||
requestFn: async (message: string) => {
|
||||
const response = await fetch('/api/v1/chat/stream', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'text/event-stream',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: message,
|
||||
modelType: 'qwen-long',
|
||||
knowledgeBaseIds: [kbId],
|
||||
documentIds: selectedDocIds, // 🌟 关键参数:限定文档范围
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API请求失败: ${response.status}`);
|
||||
}
|
||||
|
||||
// 处理流式响应
|
||||
const reader = response.body?.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let fullContent = '';
|
||||
|
||||
if (reader) {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
const chunk = decoder.decode(value);
|
||||
const lines = chunk.split('\n');
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.slice(6);
|
||||
if (data === '[DONE]') break;
|
||||
|
||||
try {
|
||||
const json = JSON.parse(data);
|
||||
if (json.content) {
|
||||
fullContent += json.content;
|
||||
}
|
||||
} catch (e) {
|
||||
// 忽略解析错误
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
content: fullContent,
|
||||
messageId: Date.now().toString(),
|
||||
};
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user