feat:前端新增初版知识库管理页面
This commit is contained in:
@@ -1,112 +1,22 @@
|
||||
/**
|
||||
* Dify 服务端 API 模块
|
||||
* Dify Chat API 模块
|
||||
*
|
||||
* 提供 Node.js 服务端调用 FastAPI 后端的函数
|
||||
* 提供客户端调用 Dify API 的函数
|
||||
* 用于 Remix loader/action 中调用 Dify API
|
||||
*
|
||||
* 调用链路:
|
||||
* Remix Server → FastAPI /dify/* → Dify
|
||||
*
|
||||
* @module api/dify/client.server
|
||||
* @module api/dify/chat
|
||||
*/
|
||||
|
||||
import { API_BASE_URL } from '~/config/api-config';
|
||||
import { difyFetch } from './client.server';
|
||||
|
||||
// ============================================================================
|
||||
// 配置
|
||||
// Dify Chat API 客户端
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 获取环境变量的服务端函数
|
||||
*/
|
||||
const getServerEnvVar = (name: string, defaultValue: string = ''): string => {
|
||||
return process.env[name] || defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dify API 客户端配置
|
||||
* 通过 FastAPI 后端的 /dify 路由代理访问 Dify
|
||||
*/
|
||||
const DIFY_CONFIG = {
|
||||
API_URL: `${API_BASE_URL}/dify`,
|
||||
API_KEY: getServerEnvVar('NEXT_PUBLIC_APP_KEY', ''),
|
||||
APP_ID: (() => {
|
||||
const rawAppId = getServerEnvVar('NEXT_PUBLIC_APP_ID', '');
|
||||
const match = rawAppId.match(/\/app\/([a-f0-9-]{36})/);
|
||||
return match ? match[1] : rawAppId;
|
||||
})(),
|
||||
};
|
||||
|
||||
console.log('🔧 [Dify Server] 配置:', {
|
||||
apiUrl: DIFY_CONFIG.API_URL,
|
||||
apiBaseUrl: API_BASE_URL,
|
||||
appId: DIFY_CONFIG.APP_ID,
|
||||
configComplete: !!(DIFY_CONFIG.API_URL && DIFY_CONFIG.APP_ID)
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// 基础请求函数
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Dify API 基础请求函数
|
||||
* Dify Chat API 客户端
|
||||
*
|
||||
* 使用 JWT 认证通过 FastAPI 代理访问 Dify
|
||||
*
|
||||
* @param endpoint - API 端点路径
|
||||
* @param options - fetch 请求选项
|
||||
* @param jwt - JWT 认证令牌
|
||||
* @returns Response 对象
|
||||
*/
|
||||
async function difyFetch(
|
||||
endpoint: string,
|
||||
options: RequestInit = {},
|
||||
jwt?: string
|
||||
): Promise<Response> {
|
||||
const url = `${DIFY_CONFIG.API_URL}/${endpoint.replace(/^\//, '')}`;
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
if (jwt) {
|
||||
(headers as Record<string, string>)['Authorization'] = `Bearer ${jwt}`;
|
||||
} else {
|
||||
console.warn('⚠️ [Dify Server] 没有提供 JWT,请求可能失败');
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('❌ [Dify Server] Dify API 错误:', {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
error: errorText
|
||||
});
|
||||
|
||||
if (response.status === 401) {
|
||||
throw new Error('JWT认证失败,请重新登录');
|
||||
}
|
||||
|
||||
throw new Error(`Dify API Error: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Dify API 客户端
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Dify 服务端 API 客户端
|
||||
*
|
||||
* 所有方法都需要传入 JWT 进行认证
|
||||
* user 参数由后端自动从 JWT 中提取
|
||||
*/
|
||||
export const difyClient = {
|
||||
@@ -187,7 +97,7 @@ export const difyClient = {
|
||||
return response;
|
||||
}
|
||||
|
||||
console.log('[Dify Server] 解析 JSON 响应');
|
||||
console.log('[Dify Chat] 解析 JSON 响应');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
@@ -216,7 +126,7 @@ export const difyClient = {
|
||||
* 删除会话
|
||||
*/
|
||||
async deleteConversation(conversationId: string, jwt?: string): Promise<any> {
|
||||
console.log('remix后端接收到删除请求,调用fastapi:', conversationId);
|
||||
console.log('[Dify Chat] 删除会话:', conversationId);
|
||||
|
||||
try {
|
||||
const response = await difyFetch(`conversations/${conversationId}`, {
|
||||
@@ -224,10 +134,9 @@ export const difyClient = {
|
||||
body: JSON.stringify({}),
|
||||
}, jwt);
|
||||
|
||||
|
||||
// 对于 204 No Content 响应,直接返回成功
|
||||
if (response.status === 204) {
|
||||
console.log('删除会话' + conversationId + '成功');
|
||||
console.log('[Dify Chat] 删除会话成功:', conversationId);
|
||||
return { result: 'success' };
|
||||
}
|
||||
|
||||
@@ -235,16 +144,15 @@ export const difyClient = {
|
||||
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
const data = await response.json();
|
||||
console.log('🗑️ [Dify Server] 删除会话 JSON 响应:', data);
|
||||
return data;
|
||||
}
|
||||
|
||||
const text = await response.text();
|
||||
console.log('🗑️ [Dify Server] 删除会话文本响应:', text);
|
||||
console.log('[Dify Chat] 删除会话文本响应:', text);
|
||||
|
||||
return { result: 'success' };
|
||||
} catch (error: any) {
|
||||
console.warn('⚠️ [Dify Server] 删除会话请求失败,但可能已成功删除:', error.message);
|
||||
console.warn('[Dify Chat] 删除会话请求失败,但可能已成功删除:', error.message);
|
||||
return { result: 'success' };
|
||||
}
|
||||
},
|
||||
@@ -268,17 +176,3 @@ export const difyClient = {
|
||||
return response.json();
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// 工具函数
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Dify 工具函数
|
||||
*/
|
||||
export const difyUtils = {
|
||||
/**
|
||||
* 获取 Dify 配置
|
||||
*/
|
||||
getConfig: () => DIFY_CONFIG,
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Dify 服务端基础 API 模块
|
||||
*
|
||||
* 提供 Node.js 服务端调用 FastAPI 后端的基础功能
|
||||
* 包括配置管理和基础请求函数
|
||||
*
|
||||
* 调用链路:
|
||||
* Remix Server → FastAPI /dify/* → Dify
|
||||
*
|
||||
* @module api/dify/client.server
|
||||
*/
|
||||
|
||||
import { API_BASE_URL } from '~/config/api-config';
|
||||
|
||||
// ============================================================================
|
||||
// 配置
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 获取环境变量的服务端函数
|
||||
*/
|
||||
const getServerEnvVar = (name: string, defaultValue: string = ''): string => {
|
||||
return process.env[name] || defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dify API 客户端配置
|
||||
* 通过 FastAPI 后端的 /dify 路由代理访问 Dify
|
||||
*/
|
||||
const DIFY_CONFIG = {
|
||||
API_URL: `${API_BASE_URL}/dify_chat`,
|
||||
API_KEY: getServerEnvVar('NEXT_PUBLIC_APP_KEY', ''),
|
||||
APP_ID: (() => {
|
||||
const rawAppId = getServerEnvVar('NEXT_PUBLIC_APP_ID', '');
|
||||
const match = rawAppId.match(/\/app\/([a-f0-9-]{36})/);
|
||||
return match ? match[1] : rawAppId;
|
||||
})(),
|
||||
};
|
||||
|
||||
console.log('[Dify Server] 配置:', {
|
||||
apiUrl: DIFY_CONFIG.API_URL,
|
||||
apiBaseUrl: API_BASE_URL,
|
||||
appId: DIFY_CONFIG.APP_ID,
|
||||
configComplete: !!(DIFY_CONFIG.API_URL && DIFY_CONFIG.APP_ID)
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// 基础请求函数
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Dify API 基础请求函数
|
||||
*
|
||||
* 使用 JWT 认证通过 FastAPI 代理访问 Dify
|
||||
*
|
||||
* @param endpoint - API 端点路径
|
||||
* @param options - fetch 请求选项
|
||||
* @param jwt - JWT 认证令牌
|
||||
* @returns Response 对象
|
||||
*/
|
||||
export async function difyFetch(
|
||||
endpoint: string,
|
||||
options: RequestInit = {},
|
||||
jwt?: string
|
||||
): Promise<Response> {
|
||||
const url = `${DIFY_CONFIG.API_URL}/${endpoint.replace(/^\//, '')}`;
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
if (jwt) {
|
||||
(headers as Record<string, string>)['Authorization'] = `Bearer ${jwt}`;
|
||||
} else {
|
||||
console.warn('[Dify Server] 没有提供 JWT,转发fastapi请求可能失败');
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('[Dify Server] API 转发错误:', {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
error: errorText
|
||||
});
|
||||
|
||||
if (response.status === 401) {
|
||||
throw new Error('JWT认证失败,请重新登录');
|
||||
}
|
||||
|
||||
throw new Error(`Dify API Error: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 工具函数
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Dify 工具函数
|
||||
*/
|
||||
export const difyUtils = {
|
||||
/**
|
||||
* 获取 Dify 配置
|
||||
*/
|
||||
getConfig: () => DIFY_CONFIG,
|
||||
};
|
||||
|
||||
// 重新导出 chat 模块的 difyClient
|
||||
export { difyClient } from './chat';
|
||||
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* Dify Dataset 客户端 API 模块
|
||||
*
|
||||
* 提供浏览器端调用 Dify 知识库 API 的函数
|
||||
* 通过 Remix API Routes 代理请求
|
||||
*
|
||||
* @module api/dify-dataset/client
|
||||
*/
|
||||
|
||||
import axios from 'axios';
|
||||
import type {
|
||||
DatasetsResponse,
|
||||
DocumentsResponse,
|
||||
SegmentsResponse,
|
||||
Document,
|
||||
OperationResult,
|
||||
} from './types';
|
||||
|
||||
// ============================================================================
|
||||
// 基础配置
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* API 基础 URL
|
||||
* 指向 Remix API Routes(/api/dataset/*)
|
||||
*/
|
||||
const API_URL = '/api/dataset';
|
||||
|
||||
// ============================================================================
|
||||
// 知识库 API
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 获取知识库列表
|
||||
*
|
||||
* @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<any> {
|
||||
const response = await axios.get(
|
||||
`${API_URL}/datasets/${datasetId}`,
|
||||
{ withCredentials: true }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 文档 API
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 获取知识库文档列表
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用文档
|
||||
*
|
||||
* @param datasetId - 知识库 ID
|
||||
* @param documentId - 文档 ID
|
||||
* @param enabled - 是否启用
|
||||
* @returns 操作结果
|
||||
*/
|
||||
export async function toggleDocumentStatus(
|
||||
datasetId: string,
|
||||
documentId: string,
|
||||
enabled: boolean
|
||||
): Promise<OperationResult> {
|
||||
console.log('[Dataset Client] 切换文档状态:', { datasetId, documentId, enabled });
|
||||
|
||||
const response = await axios.patch<OperationResult>(
|
||||
`${API_URL}/datasets/${datasetId}/documents/${documentId}/status`,
|
||||
{ enabled },
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
withCredentials: true,
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 文档分段 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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用分段
|
||||
*
|
||||
* @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> {
|
||||
const response = await axios.patch<OperationResult>(
|
||||
`${API_URL}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}/status`,
|
||||
{ enabled },
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
withCredentials: true,
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 文件上传 API
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 上传文件到知识库
|
||||
*
|
||||
* @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/create-by-file`,
|
||||
formData,
|
||||
{
|
||||
withCredentials: true,
|
||||
onUploadProgress: (progressEvent) => {
|
||||
if (progressEvent.total && onProgress) {
|
||||
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||
onProgress(percent);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Dify Dataset API 模块统一导出
|
||||
*
|
||||
* @module api/dify-dataset
|
||||
*/
|
||||
|
||||
// 类型导出
|
||||
export type {
|
||||
Dataset,
|
||||
DatasetsResponse,
|
||||
Document,
|
||||
DocumentsResponse,
|
||||
Segment,
|
||||
SegmentsResponse,
|
||||
IndexingStatus,
|
||||
OperationResult,
|
||||
CreateDocumentResponse,
|
||||
UploadProgress,
|
||||
} from './types';
|
||||
|
||||
// 客户端 API 导出
|
||||
export {
|
||||
// 知识库
|
||||
fetchDatasets,
|
||||
fetchDataset,
|
||||
// 文档
|
||||
fetchDocuments,
|
||||
fetchDocument,
|
||||
deleteDocument,
|
||||
toggleDocumentStatus,
|
||||
uploadDocument,
|
||||
// 分段
|
||||
fetchSegments,
|
||||
deleteSegment,
|
||||
toggleSegmentStatus,
|
||||
} from './client';
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Dify Dataset API 类型定义
|
||||
*
|
||||
* @module api/dify-dataset/types
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// 知识库类型
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 知识库信息
|
||||
*/
|
||||
export interface Dataset {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
permission: 'only_me' | 'all_team_members';
|
||||
data_source_type: 'upload_file' | 'notion_import' | 'website_crawl';
|
||||
indexing_technique: 'high_quality' | 'economy';
|
||||
app_count: number;
|
||||
document_count: number;
|
||||
word_count: number;
|
||||
created_by: string;
|
||||
created_at: number;
|
||||
updated_by: string;
|
||||
updated_at: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 知识库列表响应
|
||||
*/
|
||||
export interface DatasetsResponse {
|
||||
data: Dataset[];
|
||||
has_more: boolean;
|
||||
limit: number;
|
||||
total: number;
|
||||
page: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 文档类型
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 文档索引状态
|
||||
*/
|
||||
export type IndexingStatus =
|
||||
| 'waiting'
|
||||
| 'parsing'
|
||||
| 'cleaning'
|
||||
| 'splitting'
|
||||
| 'indexing'
|
||||
| 'paused'
|
||||
| 'error'
|
||||
| 'completed';
|
||||
|
||||
/**
|
||||
* 文档信息
|
||||
*/
|
||||
export interface Document {
|
||||
id: string;
|
||||
position: number;
|
||||
data_source_type: 'upload_file' | 'notion_import' | 'website_crawl';
|
||||
data_source_info: {
|
||||
upload_file_id?: string;
|
||||
notion_page_id?: string;
|
||||
website_url?: string;
|
||||
};
|
||||
dataset_process_rule_id: string;
|
||||
name: string;
|
||||
created_from: string;
|
||||
created_by: string;
|
||||
created_at: number;
|
||||
tokens: number;
|
||||
indexing_status: IndexingStatus;
|
||||
error?: string;
|
||||
enabled: boolean;
|
||||
disabled_at?: number;
|
||||
disabled_by?: string;
|
||||
archived: boolean;
|
||||
display_status: string;
|
||||
word_count: number;
|
||||
hit_count: number;
|
||||
doc_form: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文档列表响应
|
||||
*/
|
||||
export interface DocumentsResponse {
|
||||
data: Document[];
|
||||
has_more: boolean;
|
||||
limit: number;
|
||||
total: number;
|
||||
page: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 文档分段类型
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 文档分段
|
||||
*/
|
||||
export interface Segment {
|
||||
id: string;
|
||||
position: number;
|
||||
document_id: string;
|
||||
content: string;
|
||||
answer?: string;
|
||||
word_count: number;
|
||||
tokens: number;
|
||||
keywords: string[];
|
||||
index_node_id: string;
|
||||
index_node_hash: string;
|
||||
hit_count: number;
|
||||
enabled: boolean;
|
||||
disabled_at?: number;
|
||||
disabled_by?: string;
|
||||
status: 'waiting' | 'completed' | 'error' | 'indexing';
|
||||
created_by: string;
|
||||
created_at: number;
|
||||
indexing_at?: number;
|
||||
completed_at?: number;
|
||||
error?: string;
|
||||
stopped_at?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分段列表响应
|
||||
*/
|
||||
export interface SegmentsResponse {
|
||||
data: Segment[];
|
||||
has_more: boolean;
|
||||
limit: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 操作响应类型
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 通用操作结果
|
||||
*/
|
||||
export interface OperationResult {
|
||||
result: 'success' | 'error';
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文档响应
|
||||
*/
|
||||
export interface CreateDocumentResponse {
|
||||
document: Document;
|
||||
batch: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文档上传进度
|
||||
*/
|
||||
export interface UploadProgress {
|
||||
loaded: number;
|
||||
total: number;
|
||||
percent: number;
|
||||
}
|
||||
Reference in New Issue
Block a user