- Add accordion sections for general, page rank, RAPTOR, and GraphRAG configurations - Implement detailed form controls for each configuration section - Update parser config interfaces to support new configuration options
433 lines
12 KiB
TypeScript
433 lines
12 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react';
|
|
import knowledgeService from '@/services/knowledge_service';
|
|
import type { IKnowledge, IKnowledgeResult } from '@/interfaces/database/knowledge';
|
|
import type { IFetchKnowledgeListRequestParams } from '@/interfaces/request/knowledge';
|
|
|
|
/**
|
|
{
|
|
"avatar": "data:image/png;base64,iVBORw0K
|
|
"chunk_num": 1180,
|
|
"create_time": 1759986452748,
|
|
"description": " 213213",
|
|
"doc_num": 16,
|
|
"embd_id": "",
|
|
"id": "dcc2871aa4cd11f08d4116ac85b1de0a",
|
|
"language": "English",
|
|
"name": "k1123",
|
|
"pagerank": 0,
|
|
"parser_config": {
|
|
"auto_keywords": 0,
|
|
"auto_questions": 0,
|
|
"chunk_token_num": 512,
|
|
"delimiter": "\n",
|
|
"graphrag": {
|
|
"entity_types": [
|
|
"organization",
|
|
"person",
|
|
"geo",
|
|
"event",
|
|
"category"
|
|
],
|
|
"method": "light",
|
|
"use_graphrag": true
|
|
},
|
|
"html4excel": false,
|
|
"layout_recognize": "Plain Text",
|
|
"raptor": {
|
|
"max_cluster": 64,
|
|
"max_token": 256,
|
|
"prompt": "\u8bf7\u603b\u7ed3\u4ee5\u4e0b\u6bb5\u843d\u3002 \u5c0f\u5fc3\u6570\u5b57\uff0c\u4e0d\u8981\u7f16\u9020\u3002 \u6bb5\u843d\u5982\u4e0b\uff1a\n {cluster_content}\n\u4ee5\u4e0a\u5c31\u662f\u4f60\u9700\u8981\u603b\u7ed3\u7684\u5185\u5bb9\u3002",
|
|
"random_seed": 0,
|
|
"threshold": 0.1,
|
|
"use_raptor": false
|
|
},
|
|
"topn_tags": 3
|
|
},
|
|
"parser_id": "naive",
|
|
"permission": "team",
|
|
"size": 56819092,
|
|
"token_num": 293067,
|
|
"update_time": 1760436169574
|
|
}
|
|
*/
|
|
|
|
// 知识库列表Hook状态接口
|
|
export interface UseKnowledgeListState {
|
|
knowledgeBases: IKnowledge[];
|
|
total: number;
|
|
loading: boolean;
|
|
error: string | null;
|
|
currentPage: number;
|
|
pageSize: number;
|
|
keywords: string;
|
|
}
|
|
|
|
// 知识库列表Hook返回值接口
|
|
export interface UseKnowledgeListReturn extends UseKnowledgeListState {
|
|
fetchKnowledgeBases: (params?: IFetchKnowledgeListRequestParams) => Promise<void>;
|
|
setKeywords: (keywords: string) => void;
|
|
setCurrentPage: (page: number) => void;
|
|
setPageSize: (size: number) => void;
|
|
refresh: () => Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* 知识库列表数据管理Hook
|
|
* 支持关键词搜索、分页等功能
|
|
*/
|
|
export const useKnowledgeList = (
|
|
initialParams?: IFetchKnowledgeListRequestParams
|
|
): UseKnowledgeListReturn => {
|
|
const [knowledgeBases, setKnowledgeBases] = useState<IKnowledge[]>([]);
|
|
const [total, setTotal] = useState(0);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [currentPage, setCurrentPage] = useState(initialParams?.page || 1);
|
|
const [pageSize, setPageSize] = useState(initialParams?.page_size || 10);
|
|
const [keywords, setKeywords] = useState(initialParams?.keywords || '');
|
|
|
|
/**
|
|
* 获取知识库列表
|
|
*/
|
|
const fetchKnowledgeBases = useCallback(async (params?: IFetchKnowledgeListRequestParams) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
// 合并参数
|
|
const queryParams = {
|
|
keywords: params?.keywords ?? keywords,
|
|
page: params?.page ?? currentPage,
|
|
page_size: params?.page_size ?? pageSize,
|
|
};
|
|
|
|
// 构建请求体
|
|
const requestBody: any = {};
|
|
if (queryParams.keywords && queryParams.keywords.trim()) {
|
|
requestBody.keywords = queryParams.keywords.trim();
|
|
}
|
|
|
|
// 构建查询参数
|
|
const requestParams: any = {};
|
|
if (queryParams.page) {
|
|
requestParams.page = queryParams.page;
|
|
}
|
|
if (queryParams.page_size) {
|
|
requestParams.page_size = queryParams.page_size;
|
|
}
|
|
if (queryParams.keywords) {
|
|
requestParams.keywords = queryParams.keywords;
|
|
}
|
|
|
|
const response = await knowledgeService.getKnowledgeList(
|
|
Object.keys(requestParams).length > 0 ? requestParams : undefined,
|
|
Object.keys(requestBody).length > 0 ? requestBody : undefined
|
|
);
|
|
|
|
// 检查响应状态
|
|
if (response.data.code === 0) {
|
|
const data = response.data.data as IKnowledgeResult;
|
|
setKnowledgeBases(data.kbs || []);
|
|
setTotal(data.total || 0);
|
|
} else {
|
|
throw new Error(response.data.message || '获取知识库列表失败');
|
|
}
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '获取知识库列表失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to fetch knowledge bases:', err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [keywords, currentPage, pageSize]);
|
|
|
|
/**
|
|
* 刷新当前页面数据
|
|
*/
|
|
const refresh = useCallback(() => {
|
|
return fetchKnowledgeBases();
|
|
}, [fetchKnowledgeBases]);
|
|
|
|
/**
|
|
* 设置关键词并重置到第一页
|
|
*/
|
|
const handleSetKeywords = useCallback((newKeywords: string) => {
|
|
setKeywords(newKeywords);
|
|
setCurrentPage(1);
|
|
}, []);
|
|
|
|
/**
|
|
* 设置当前页
|
|
*/
|
|
const handleSetCurrentPage = useCallback((page: number) => {
|
|
setCurrentPage(page);
|
|
}, []);
|
|
|
|
/**
|
|
* 设置页面大小并重置到第一页
|
|
*/
|
|
const handleSetPageSize = useCallback((size: number) => {
|
|
setPageSize(size);
|
|
setCurrentPage(1);
|
|
}, []);
|
|
|
|
// 当关键词、页码或页面大小变化时重新获取数据
|
|
useEffect(() => {
|
|
fetchKnowledgeBases();
|
|
}, [keywords, currentPage, pageSize]);
|
|
|
|
return {
|
|
knowledgeBases,
|
|
total,
|
|
loading,
|
|
error,
|
|
currentPage,
|
|
pageSize,
|
|
keywords,
|
|
fetchKnowledgeBases,
|
|
setKeywords: handleSetKeywords,
|
|
setCurrentPage: handleSetCurrentPage,
|
|
setPageSize: handleSetPageSize,
|
|
refresh,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* 知识库详情Hook
|
|
*/
|
|
export const useKnowledgeDetail = (kbId: string) => {
|
|
const [knowledge, setKnowledge] = useState<IKnowledge | null>(null);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const fetchKnowledgeDetail = useCallback(async () => {
|
|
if (!kbId) return;
|
|
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const response = await knowledgeService.getKnowledgeDetail({ kb_id: kbId });
|
|
|
|
if (response.data.code === 0) {
|
|
setKnowledge(response.data.data);
|
|
} else {
|
|
throw new Error(response.data.message || '获取知识库详情失败');
|
|
}
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '获取知识库详情失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to fetch knowledge detail:', err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [kbId]);
|
|
|
|
useEffect(() => {
|
|
fetchKnowledgeDetail();
|
|
}, [fetchKnowledgeDetail]);
|
|
|
|
return {
|
|
knowledge,
|
|
loading,
|
|
error,
|
|
refresh: fetchKnowledgeDetail,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* 知识库操作Hook
|
|
* 提供创建、更新、删除知识库的功能
|
|
*/
|
|
export const useKnowledgeOperations = () => {
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
/**
|
|
* 创建知识库
|
|
*/
|
|
const createKnowledge = useCallback(async (data: Partial<IKnowledge>) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const response = await knowledgeService.createKnowledge(data);
|
|
|
|
if (response.data.code === 0) {
|
|
return response.data.data;
|
|
} else {
|
|
throw new Error(response.data.message || '创建知识库失败');
|
|
}
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '创建知识库失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to create knowledge:', err);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
/**
|
|
* 更新知识库基础信息
|
|
* 包括名称、描述、语言等基本信息
|
|
*/
|
|
const updateKnowledgeBasicInfo = useCallback(async (data: IKnowledge) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const response = await knowledgeService.updateKnowledge(data);
|
|
|
|
if (response.data.code === 0) {
|
|
return response.data.data;
|
|
} else {
|
|
throw new Error(response.data.message || '更新知识库基础信息失败');
|
|
}
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '更新知识库基础信息失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to update knowledge basic info:', err);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
/**
|
|
* 更新知识库模型配置
|
|
* 包括嵌入模型、解析器配置、相似度阈值等
|
|
*/
|
|
const updateKnowledgeModelConfig = useCallback(async (data: {
|
|
id: string;
|
|
embd_id?: string;
|
|
// parser_config?: Partial<ParserConfig>;
|
|
similarity_threshold?: number;
|
|
vector_similarity_weight?: number;
|
|
parser_id?: string;
|
|
}) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const updateData = {
|
|
kb_id: data.id,
|
|
...data,
|
|
};
|
|
|
|
const response = await knowledgeService.updateKnowledge(updateData);
|
|
|
|
if (response.data.code === 0) {
|
|
return response.data.data;
|
|
} else {
|
|
throw new Error(response.data.message || '更新知识库模型配置失败');
|
|
}
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '更新知识库模型配置失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to update knowledge model config:', err);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
/**
|
|
* 删除知识库
|
|
*/
|
|
const deleteKnowledge = useCallback(async (kbId: string) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const response = await knowledgeService.removeKnowledge({ kb_id: kbId });
|
|
|
|
if (response.data.code === 0) {
|
|
return response.data.data;
|
|
} else {
|
|
throw new Error(response.data.message || '删除知识库失败');
|
|
}
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '删除知识库失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to delete knowledge:', err);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
/**
|
|
* 清除错误状态
|
|
*/
|
|
const clearError = useCallback(() => {
|
|
setError(null);
|
|
}, []);
|
|
|
|
return {
|
|
loading,
|
|
error,
|
|
createKnowledge,
|
|
updateKnowledgeBasicInfo,
|
|
updateKnowledgeModelConfig,
|
|
deleteKnowledge,
|
|
clearError,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* 知识库批量操作Hook
|
|
* 提供批量删除等功能
|
|
*/
|
|
export const useKnowledgeBatchOperations = () => {
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
/**
|
|
* 批量删除知识库
|
|
*/
|
|
const batchDeleteKnowledge = useCallback(async (kbIds: string[]) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const results = await Promise.allSettled(
|
|
kbIds.map(kbId => knowledgeService.removeKnowledge({ kb_id: kbId }))
|
|
);
|
|
|
|
const failures = results
|
|
.map((result, index) => ({ result, index }))
|
|
.filter(({ result }) => result.status === 'rejected')
|
|
.map(({ index }) => kbIds[index]);
|
|
|
|
if (failures.length > 0) {
|
|
throw new Error(`删除失败的知识库: ${failures.join(', ')}`);
|
|
}
|
|
|
|
return results;
|
|
} catch (err: any) {
|
|
const errorMessage = err.response?.data?.message || err.message || '批量删除知识库失败';
|
|
setError(errorMessage);
|
|
console.error('Failed to batch delete knowledge:', err);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
/**
|
|
* 清除错误状态
|
|
*/
|
|
const clearError = useCallback(() => {
|
|
setError(null);
|
|
}, []);
|
|
|
|
return {
|
|
loading,
|
|
error,
|
|
batchDeleteKnowledge,
|
|
clearError,
|
|
};
|
|
};
|
|
|