Files
TERES_web_frontend/src/hooks/knowledge-hooks.ts

385 lines
10 KiB
TypeScript
Raw Normal View History

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';
// 知识库列表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,
};
};