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
218 lines
5.0 KiB
TypeScript
218 lines
5.0 KiB
TypeScript
/**
|
||
* PKB个人知识库 API(v2版本)
|
||
* 更新API路径为 /api/v2/pkb/knowledge
|
||
*/
|
||
|
||
import axios from 'axios';
|
||
|
||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000';
|
||
|
||
const api = axios.create({
|
||
baseURL: `${API_BASE_URL}/api/v2/pkb/knowledge`,
|
||
timeout: 30000,
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
});
|
||
|
||
/**
|
||
* 知识库类型定义
|
||
*/
|
||
export interface KnowledgeBase {
|
||
id: string;
|
||
userId: string;
|
||
name: string;
|
||
description?: string;
|
||
difyDatasetId: string;
|
||
fileCount: number;
|
||
totalSizeBytes: number;
|
||
createdAt: string;
|
||
updatedAt: string;
|
||
_count?: {
|
||
documents: number;
|
||
};
|
||
}
|
||
|
||
export interface Document {
|
||
id: string;
|
||
kbId: string;
|
||
userId: string;
|
||
filename: string;
|
||
fileType: string;
|
||
fileSizeBytes: number;
|
||
fileUrl: string;
|
||
difyDocumentId: string;
|
||
status: 'uploading' | 'parsing' | 'indexing' | 'completed' | 'error';
|
||
progress: number;
|
||
errorMessage?: string;
|
||
segmentsCount?: number;
|
||
tokensCount?: number;
|
||
uploadedAt: string;
|
||
processedAt?: string;
|
||
}
|
||
|
||
export interface CreateKnowledgeBaseRequest {
|
||
name: string;
|
||
description?: string;
|
||
}
|
||
|
||
export interface UpdateKnowledgeBaseRequest {
|
||
name?: string;
|
||
description?: string;
|
||
}
|
||
|
||
export interface KnowledgeBaseStats {
|
||
totalDocuments: number;
|
||
completedDocuments: number;
|
||
processingDocuments: number;
|
||
errorDocuments: number;
|
||
totalSizeBytes: number;
|
||
totalTokens: number;
|
||
}
|
||
|
||
/**
|
||
* 知识库管理API
|
||
*/
|
||
export const knowledgeBaseApi = {
|
||
/**
|
||
* 获取知识库列表
|
||
*/
|
||
async getList(): Promise<KnowledgeBase[]> {
|
||
const response = await api.get('/knowledge-bases');
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 获取知识库详情
|
||
*/
|
||
async getById(id: string): Promise<KnowledgeBase> {
|
||
const response = await api.get(`/knowledge-bases/${id}`);
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 创建知识库
|
||
*/
|
||
async create(data: CreateKnowledgeBaseRequest): Promise<KnowledgeBase> {
|
||
const response = await api.post('/knowledge-bases', data);
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 更新知识库
|
||
*/
|
||
async update(id: string, data: UpdateKnowledgeBaseRequest): Promise<KnowledgeBase> {
|
||
const response = await api.put(`/knowledge-bases/${id}`, data);
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 删除知识库
|
||
*/
|
||
async delete(id: string): Promise<void> {
|
||
await api.delete(`/knowledge-bases/${id}`);
|
||
},
|
||
|
||
/**
|
||
* 获取知识库统计信息
|
||
*/
|
||
async getStats(id: string): Promise<KnowledgeBaseStats> {
|
||
const response = await api.get(`/knowledge-bases/${id}/stats`);
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 检索知识库(RAG)
|
||
*/
|
||
async search(id: string, query: string, topK: number = 3): Promise<any> {
|
||
const response = await api.get(`/knowledge-bases/${id}/search`, {
|
||
params: { query, top_k: topK },
|
||
});
|
||
return response.data.data;
|
||
},
|
||
};
|
||
|
||
/**
|
||
* 文档管理API
|
||
*/
|
||
export const documentApi = {
|
||
/**
|
||
* 获取文档列表
|
||
*/
|
||
async getList(kbId: string): Promise<Document[]> {
|
||
const response = await api.get(`/knowledge-bases/${kbId}/documents`);
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 获取文档详情
|
||
*/
|
||
async getById(id: string): Promise<Document> {
|
||
const response = await api.get(`/documents/${id}`);
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 上传文档
|
||
*/
|
||
async upload(kbId: string, file: File, onProgress?: (progress: number) => void): Promise<Document> {
|
||
const formData = new FormData();
|
||
formData.append('file', file);
|
||
|
||
const response = await api.post(`/knowledge-bases/${kbId}/documents`, formData, {
|
||
headers: {
|
||
'Content-Type': 'multipart/form-data',
|
||
},
|
||
onUploadProgress: (progressEvent) => {
|
||
if (progressEvent.total && onProgress) {
|
||
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||
onProgress(percentCompleted);
|
||
}
|
||
},
|
||
});
|
||
return response.data.data;
|
||
},
|
||
|
||
/**
|
||
* 删除文档
|
||
*/
|
||
async delete(id: string): Promise<void> {
|
||
await api.delete(`/documents/${id}`);
|
||
},
|
||
|
||
/**
|
||
* 重新处理文档
|
||
*/
|
||
async reprocess(id: string): Promise<void> {
|
||
await api.post(`/documents/${id}/reprocess`);
|
||
},
|
||
|
||
/**
|
||
* 获取文档全文(用于逐篇精读模式)
|
||
*/
|
||
async getFullText(id: string): Promise<any> {
|
||
const response = await api.get(`/documents/${id}/full-text`);
|
||
return response.data;
|
||
},
|
||
};
|
||
|
||
/**
|
||
* 文档选择API(用于全文阅读模式)
|
||
*/
|
||
export const documentSelectionApi = {
|
||
/**
|
||
* 获取知识库的文档选择结果
|
||
*/
|
||
async getSelection(kbId: string, maxFiles?: number, maxTokens?: number): Promise<any> {
|
||
const params = new URLSearchParams();
|
||
if (maxFiles) params.append('max_files', maxFiles.toString());
|
||
if (maxTokens) params.append('max_tokens', maxTokens.toString());
|
||
|
||
const url = `/knowledge-bases/${kbId}/document-selection${params.toString() ? '?' + params.toString() : ''}`;
|
||
const response = await api.get(url);
|
||
return response.data.data;
|
||
},
|
||
};
|
||
|
||
|