temp:临时备份,完成一半知识库管理模块

This commit is contained in:
PingChuan
2025-12-01 12:33:53 +08:00
parent 754ec2c7b5
commit 0c1b81cfb2
25 changed files with 3564 additions and 560 deletions
+78
View File
@@ -0,0 +1,78 @@
/**
* Dify Dataset 知识库 API 模块
*
* 提供浏览器端调用 Dify 知识库管理 API 的函数
*
* @module api/dify-dataset/api/datasetApi
*/
import axios from 'axios';
import type { Dataset, DatasetsResponse } from '../type';
/**
* API 基础 URL
*/
const API_URL = '/api/dataset';
/**
* 获取知识库列表
*
* @param page - 页码,默认 1
* @param limit - 每页数量,默认 20
* @returns 知识库列表响应
*/
export async function fetchDatasets(
page: number = 1,
limit: number = 20
): Promise<DatasetsResponse> {
const params = new URLSearchParams({
page: page.toString(),
limit: limit.toString(),
});
const response = await axios.get<DatasetsResponse>(
`${API_URL}/datasets?${params}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 获取单个知识库详情
*
* @param datasetId - 知识库 ID
* @returns 知识库详情
*/
export async function fetchDataset(datasetId: string): Promise<Dataset> {
const response = await axios.get<Dataset>(
`${API_URL}/datasets/${datasetId}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 更新知识库名称
*
* 注意:仅允许修改知识库名称,其他字段不开放修改
*
* @param datasetId - 知识库 ID
* @param name - 新的知识库名称
* @returns 更新后的知识库详情
*/
export async function updateDatasetName(
datasetId: string,
name: string
): Promise<Dataset> {
console.log('[Dataset Client] 更新知识库名称:', { datasetId, name });
const response = await axios.patch<Dataset>(
`${API_URL}/datasets/${datasetId}`,
{ name },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
+254
View File
@@ -0,0 +1,254 @@
/**
* Dify Dataset 文档 API 模块
*
* 提供浏览器端调用 Dify 文档管理 API 的函数
*
* @module api/dify-dataset/api/documentApi
*/
import axios from 'axios';
import type {
Document,
DocumentsResponse,
IndexingStatusResponse,
UploadFileInfo,
OperationResult,
} from '../type';
/**
* API 基础 URL
*/
const API_URL = '/api/dataset';
/**
* 获取知识库文档列表
*
* @param datasetId - 知识库 ID
* @param page - 页码,默认 1
* @param limit - 每页数量,默认 20
* @param keyword - 搜索关键词
* @returns 文档列表响应
*/
export async function fetchDocuments(
datasetId: string,
page: number = 1,
limit: number = 20,
keyword?: string
): Promise<DocumentsResponse> {
const params = new URLSearchParams({
page: page.toString(),
limit: limit.toString(),
});
if (keyword) {
params.append('keyword', keyword);
}
console.log('[Dataset Client] 获取文档列表:', { datasetId, page, limit, keyword });
const response = await axios.get<DocumentsResponse>(
`${API_URL}/datasets/${datasetId}/documents?${params}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 获取单个文档详情
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @returns 文档详情
*/
export async function fetchDocument(
datasetId: string,
documentId: string
): Promise<Document> {
const response = await axios.get<Document>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 删除文档
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @returns 操作结果
*/
export async function deleteDocument(
datasetId: string,
documentId: string
): Promise<OperationResult> {
console.log('[Dataset Client] 删除文档:', { datasetId, documentId });
const response = await axios.delete<OperationResult>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 启用/禁用文档
* Dify API: PATCH /datasets/{dataset_id}/documents/status/{action}
* action: enable / disable / archive / un_archive
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param enabled - 是否启用
* @returns 操作结果
*/
export async function toggleDocumentStatus(
datasetId: string,
documentId: string,
enabled: boolean
): Promise<OperationResult> {
const action = enabled ? 'enable' : 'disable';
console.log('[Dataset Client] 切换文档状态:', { datasetId, documentId, action });
const response = await axios.patch<OperationResult>(
`${API_URL}/datasets/${datasetId}/documents/status/${action}`,
{ document_ids: [documentId] },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
/**
* 上传文件到知识库
*
* @param datasetId - 知识库 ID
* @param file - 文件对象
* @param onProgress - 上传进度回调
* @returns 创建的文档信息
*/
export async function uploadDocument(
datasetId: string,
file: File,
onProgress?: (percent: number) => void
): Promise<any> {
const formData = new FormData();
formData.append('file', file);
formData.append('data', JSON.stringify({
indexing_technique: 'high_quality',
process_rule: {
mode: 'automatic',
},
}));
console.log('[Dataset Client] 上传文档:', { datasetId, fileName: file.name });
const response = await axios.post(
`${API_URL}/datasets/${datasetId}/documents`,
formData,
{
withCredentials: true,
onUploadProgress: (progressEvent) => {
if (progressEvent.total && onProgress) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
onProgress(percent);
}
},
}
);
return response.data;
}
/**
* 获取文档嵌入状态(索引进度)
*
* @param datasetId - 知识库 ID
* @param batch - 上传文档的批次号
* @returns 索引状态列表
*/
export async function fetchIndexingStatus(
datasetId: string,
batch: string
): Promise<IndexingStatusResponse> {
console.log('[Dataset Client] 获取索引状态:', { datasetId, batch });
const response = await axios.get<IndexingStatusResponse>(
`${API_URL}/datasets/${datasetId}/documents/${batch}/indexing-status`,
{ withCredentials: true }
);
return response.data;
}
/**
* 获取文档上传文件信息
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @returns 上传文件信息
*/
export async function fetchUploadFileInfo(
datasetId: string,
documentId: string
): Promise<UploadFileInfo> {
console.log('[Dataset Client] 获取上传文件信息:', { datasetId, documentId });
const response = await axios.get<UploadFileInfo>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/upload-file`,
{ withCredentials: true }
);
return response.data;
}
/**
* 文档处理规则配置
*/
export interface ProcessRule {
mode: 'automatic' | 'custom';
rules?: {
pre_processing_rules?: Array<{
id: 'remove_extra_spaces' | 'remove_urls_emails';
enabled: boolean;
}>;
segmentation?: {
separator: string;
max_tokens: number;
};
};
}
/**
* 更新文档设置参数
*/
export interface UpdateDocumentSettings {
indexing_technique?: 'high_quality' | 'economy';
process_rule?: ProcessRule;
}
/**
* 更新文档设置并重新处理
* 注意:Dify API 不直接支持修改已有文档的分段设置
* 此函数尝试通过更新接口应用新设置
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param settings - 更新设置
* @returns 操作结果
*/
export async function updateDocumentWithSettings(
datasetId: string,
documentId: string,
settings: UpdateDocumentSettings
): Promise<OperationResult> {
console.log('[Dataset Client] 更新文档设置:', { datasetId, documentId, settings });
const response = await axios.post<OperationResult>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/update-settings`,
settings,
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
+38
View File
@@ -0,0 +1,38 @@
/**
* Dify Dataset API 客户端统一导出
*
* @module api/dify-dataset/api
*/
// 知识库 API
export {
fetchDatasets,
fetchDataset,
updateDatasetName,
} from './datasetApi';
// 文档 API
export {
fetchDocuments,
fetchDocument,
deleteDocument,
toggleDocumentStatus,
uploadDocument,
fetchIndexingStatus,
fetchUploadFileInfo,
} from './documentApi';
// 分段、子分段、检索 API
export {
fetchSegments,
fetchSegment,
createSegments,
updateSegment,
deleteSegment,
toggleSegmentStatus,
fetchChildChunks,
createChildChunk,
updateChildChunk,
deleteChildChunk,
retrieveDataset,
} from './segmentApi';
+359
View File
@@ -0,0 +1,359 @@
/**
* Dify Dataset 分段、子分段、检索 API 模块
*
* 提供浏览器端调用 Dify 分段管理和检索 API 的函数
*
* @module api/dify-dataset/api/segmentApi
*/
import axios from 'axios';
import type {
Segment,
SegmentsResponse,
CreateSegmentRequest,
UpdateSegmentRequest,
CreateSegmentsResponse,
ChildChunk,
ChildChunksResponse,
CreateChildChunkResponse,
RetrieveRequest,
RetrieveResponse,
OperationResult,
} from '../type';
/**
* API 基础 URL
*/
const API_URL = '/api/dataset';
// ============================================================================
// 分段 API
// ============================================================================
/**
* 获取文档分段列表
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param page - 页码,默认 1
* @param limit - 每页数量,默认 20
* @param keyword - 搜索关键词
* @returns 分段列表响应
*/
export async function fetchSegments(
datasetId: string,
documentId: string,
page: number = 1,
limit: number = 20,
keyword?: string
): Promise<SegmentsResponse> {
const params = new URLSearchParams({
page: page.toString(),
limit: limit.toString(),
});
if (keyword) {
params.append('keyword', keyword);
}
console.log('[Dataset Client] 获取分段列表:', { datasetId, documentId, page, limit });
const response = await axios.get<SegmentsResponse>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments?${params}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 获取单个分段详情
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @returns 分段详情
*/
export async function fetchSegment(
datasetId: string,
documentId: string,
segmentId: string
): Promise<Segment> {
console.log('[Dataset Client] 获取分段详情:', { datasetId, documentId, segmentId });
const response = await axios.get<{ data: Segment }>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`,
{ withCredentials: true }
);
return response.data.data;
}
/**
* 新增分段(批量)
* Dify API: POST /datasets/{dataset_id}/documents/{document_id}/segments
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segments - 分段列表
* @returns 创建的分段列表
*/
export async function createSegments(
datasetId: string,
documentId: string,
segments: CreateSegmentRequest[]
): Promise<CreateSegmentsResponse> {
console.log('[Dataset Client] 新增分段:', { datasetId, documentId, count: segments.length });
const response = await axios.post<CreateSegmentsResponse>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments`,
{ segments },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
/**
* 更新分段内容
* Dify API: POST /datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @param segment - 更新内容
* @returns 更新后的分段
*/
export async function updateSegment(
datasetId: string,
documentId: string,
segmentId: string,
segment: UpdateSegmentRequest
): Promise<{ data: Segment; doc_form: string }> {
console.log('[Dataset Client] 更新分段:', { datasetId, documentId, segmentId, segment });
const response = await axios.post<{ data: Segment; doc_form: string }>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`,
{ segment },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
/**
* 删除分段
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @returns 操作结果
*/
export async function deleteSegment(
datasetId: string,
documentId: string,
segmentId: string
): Promise<OperationResult> {
console.log('[Dataset Client] 删除分段:', { datasetId, documentId, segmentId });
const response = await axios.delete<OperationResult>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 启用/禁用分段
* Dify API: POST /datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}
* 通过更新分段的方式来切换状态
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @param enabled - 是否启用
* @returns 操作结果
*/
export async function toggleSegmentStatus(
datasetId: string,
documentId: string,
segmentId: string,
enabled: boolean
): Promise<OperationResult> {
console.log('[Dataset Client] 切换分段状态:', { datasetId, documentId, segmentId, enabled });
const response = await axios.post<OperationResult>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`,
{ segment: { enabled } },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
// ============================================================================
// 子分段 API(父子模式)
// ============================================================================
/**
* 获取子分段列表
* Dify API: GET /datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @param page - 页码
* @param limit - 每页数量
* @param keyword - 搜索关键词
* @returns 子分段列表响应
*/
export async function fetchChildChunks(
datasetId: string,
documentId: string,
segmentId: string,
page: number = 1,
limit: number = 20,
keyword?: string
): Promise<ChildChunksResponse> {
const params = new URLSearchParams({
page: page.toString(),
limit: limit.toString(),
});
if (keyword) {
params.append('keyword', keyword);
}
console.log('[Dataset Client] 获取子分段列表:', { datasetId, documentId, segmentId, page, limit });
const response = await axios.get<ChildChunksResponse>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}/child_chunks?${params}`,
{ withCredentials: true }
);
return response.data;
}
/**
* 新增子分段
* Dify API: POST /datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @param content - 子分段内容
* @returns 创建的子分段
*/
export async function createChildChunk(
datasetId: string,
documentId: string,
segmentId: string,
content: string
): Promise<CreateChildChunkResponse> {
console.log('[Dataset Client] 新增子分段:', { datasetId, documentId, segmentId });
const response = await axios.post<CreateChildChunkResponse>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}/child_chunks`,
{ content },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}
/**
* 更新子分段
* Dify API: PATCH /datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @param childChunkId - 子分段 ID
* @param content - 更新内容
* @returns 更新后的子分段
*/
export async function updateChildChunk(
datasetId: string,
documentId: string,
segmentId: string,
childChunkId: string,
content: string
): Promise<ChildChunk> {
console.log('[Dataset Client] 更新子分段:', { datasetId, documentId, segmentId, childChunkId });
const response = await axios.patch<{ data: ChildChunk }>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}/child_chunks/${childChunkId}`,
{ content },
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data.data;
}
/**
* 删除子分段
* Dify API: DELETE /datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}
*
* @param datasetId - 知识库 ID
* @param documentId - 文档 ID
* @param segmentId - 分段 ID
* @param childChunkId - 子分段 ID
* @returns 操作结果
*/
export async function deleteChildChunk(
datasetId: string,
documentId: string,
segmentId: string,
childChunkId: string
): Promise<OperationResult> {
console.log('[Dataset Client] 删除子分段:', { datasetId, documentId, segmentId, childChunkId });
const response = await axios.delete<OperationResult>(
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}/child_chunks/${childChunkId}`,
{ withCredentials: true }
);
return response.data;
}
// ============================================================================
// 检索 API
// ============================================================================
/**
* 检索知识库
* Dify API: POST /datasets/{dataset_id}/retrieve
*
* @param datasetId - 知识库 ID
* @param query - 检索关键词
* @param retrievalModel - 检索模型配置
* @returns 检索结果
*/
export async function retrieveDataset(
datasetId: string,
query: string,
retrievalModel?: RetrieveRequest['retrieval_model']
): Promise<RetrieveResponse> {
console.log('[Dataset Client] 检索知识库:', { datasetId, query });
const requestBody: RetrieveRequest = {
query,
retrieval_model: retrievalModel,
};
const response = await axios.post<RetrieveResponse>(
`${API_URL}/datasets/${datasetId}/retrieve`,
requestBody,
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
}
);
return response.data;
}