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:
2026-01-06 22:15:42 +08:00
parent b31255031e
commit 5a17d096a7
226 changed files with 14899 additions and 224 deletions

View File

@@ -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>
);
};