import { useState, useCallback } from 'react'; import { message } from 'antd'; import type { Document, IndexingStatus } from '~/api/dify-dataset/type/documentTypes'; import { deleteDocument, toggleDocumentStatus } from '~/api/dify-dataset/api/documentApi'; import { CheckCircleOutlined, SyncOutlined, ClockCircleOutlined, PauseCircleOutlined, ExclamationCircleOutlined, } from '@ant-design/icons'; import type { StatusConfig } from '~/types/dify-dataset-manager/document-list'; /** * 文档列表状态管理 Hook */ export function useDocumentList( datasetId: string, onDocumentDeleted: (documentId: string) => void, onDocumentStatusChanged: (documentId: string, enabled: boolean) => void, onRefresh: () => void ) { const [searchValue, setSearchValue] = useState(''); const [deletingId, setDeletingId] = useState(null); const [showUploadPage, setShowUploadPage] = useState(false); /** * 获取状态标签配置 */ const getStatusConfig = useCallback((status: IndexingStatus): StatusConfig => { const configs: Record = { completed: { color: 'success', icon: , text: '已完成' }, indexing: { color: 'processing', icon: , text: '索引中' }, waiting: { color: 'warning', icon: , text: '等待中' }, parsing: { color: 'processing', icon: , text: '解析中' }, cleaning: { color: 'processing', icon: , text: '清洗中' }, splitting: { color: 'processing', icon: , text: '分段中' }, paused: { color: 'default', icon: , text: '已暂停' }, error: { color: 'error', icon: , text: '错误' }, }; return configs[status] || { color: 'default', icon: null, text: status }; }, []); /** * 格式化日期 */ const formatDate = useCallback((timestamp: number) => { return new Date(timestamp * 1000).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); }, []); /** * 格式化数字 */ const formatNumber = useCallback((num: number) => { if (num >= 10000) { return (num / 10000).toFixed(1) + 'w'; } if (num >= 1000) { return (num / 1000).toFixed(1) + 'k'; } return num.toString(); }, []); /** * 处理删除文档 */ const handleDelete = useCallback(async (documentId: string) => { setDeletingId(documentId); try { await deleteDocument(datasetId, documentId); message.success('删除成功'); onDocumentDeleted(documentId); } catch (err: any) { console.error('删除文档失败:', err); message.error(err.message || '删除失败'); } finally { setDeletingId(null); } }, [datasetId, onDocumentDeleted]); /** * 处理启用/禁用文档 */ const handleToggleStatus = useCallback(async (documentId: string, enabled: boolean) => { try { await toggleDocumentStatus(datasetId, documentId, enabled); message.success(enabled ? '已启用' : '已禁用'); onDocumentStatusChanged(documentId, enabled); } catch (err: any) { console.error('切换文档状态失败:', err); message.error(err.message || '操作失败'); } }, [datasetId, onDocumentStatusChanged]); /** * 点击上传按钮,显示上传页面 */ const handleUploadClick = useCallback(() => { if (!datasetId) { message.error('请先选择知识库'); return; } setShowUploadPage(true); }, [datasetId]); /** * 关闭上传页面 */ const handleUploadClose = useCallback(() => { setShowUploadPage(false); }, []); /** * 上传成功回调 */ const handleUploadSuccess = useCallback(() => { setShowUploadPage(false); onRefresh(); }, [onRefresh]); /** * 过滤文档 */ const filterDocuments = useCallback((documents: Document[]) => { return documents.filter((doc) => doc.name.toLowerCase().includes(searchValue.toLowerCase()) ); }, [searchValue]); return { // 状态 searchValue, setSearchValue, deletingId, showUploadPage, // 方法 getStatusConfig, formatDate, formatNumber, handleDelete, handleToggleStatus, handleUploadClick, handleUploadClose, handleUploadSuccess, filterDocuments, }; } export type UseDocumentListReturn = ReturnType;