import React, { useState, useEffect } from 'react'; import DashboardLayout from '../../components/Layout/DashboardLayout'; import { DocumentDuplicateIcon, MagnifyingGlassIcon, PlusIcon, EyeIcon, PencilIcon, TrashIcon, ArrowDownTrayIcon, FolderIcon, DocumentTextIcon, PhotoIcon, FilmIcon, MusicalNoteIcon, ArchiveBoxIcon, ChevronLeftIcon, ChevronRightIcon, CalendarIcon, UserIcon, TagIcon, StarIcon, ClockIcon, CheckCircleIcon, XCircleIcon } from '@heroicons/react/24/outline'; interface Document { id: string; name: string; originalName: string; type: 'pdf' | 'word' | 'excel' | 'ppt' | 'image' | 'video' | 'audio' | 'text' | 'other'; category: 'contract' | 'translation' | 'template' | 'manual' | 'certificate' | 'report' | 'other'; size: number; uploadedBy: string; uploadedAt: string; lastModified: string; status: 'active' | 'archived' | 'deleted'; tags: string[]; description?: string; version: string; downloadCount: number; isPublic: boolean; language?: string; relatedOrderId?: string; thumbnailUrl?: string; url: string; } export default function Documents() { const [documents, setDocuments] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); const [filterType, setFilterType] = useState<'all' | 'pdf' | 'word' | 'excel' | 'ppt' | 'image' | 'video' | 'audio' | 'text' | 'other'>('all'); const [filterCategory, setFilterCategory] = useState<'all' | 'contract' | 'translation' | 'template' | 'manual' | 'certificate' | 'report' | 'other'>('all'); const [filterStatus, setFilterStatus] = useState<'all' | 'active' | 'archived' | 'deleted'>('all'); const [currentPage, setCurrentPage] = useState(1); const [selectedDocuments, setSelectedDocuments] = useState([]); const [viewMode, setViewMode] = useState<'list' | 'grid'>('list'); const documentsPerPage = 12; useEffect(() => { loadDocuments(); }, [searchTerm, filterType, filterCategory, filterStatus, currentPage]); const loadDocuments = async () => { try { setLoading(true); // 模拟API调用 setTimeout(() => { const mockData: Document[] = [ { id: '1', name: '服务合同模板-2024版', originalName: 'service_contract_template_2024.pdf', type: 'pdf', category: 'contract', size: 2048576, // 2MB uploadedBy: '管理员', uploadedAt: '2024-01-15 10:30', lastModified: '2024-01-20 14:45', status: 'active', tags: ['合同', '模板', '服务'], description: '标准服务合同模板,适用于翻译服务业务', version: '2.1', downloadCount: 156, isPublic: true, language: '中文', url: '/documents/service_contract_template_2024.pdf' }, { id: '2', name: '翻译质量评估报告', originalName: 'quality_assessment_report.docx', type: 'word', category: 'report', size: 1536000, // 1.5MB uploadedBy: '张经理', uploadedAt: '2024-01-18 16:20', lastModified: '2024-01-19 09:15', status: 'active', tags: ['质量', '评估', '报告'], description: '2024年第一季度翻译质量评估报告', version: '1.0', downloadCount: 89, isPublic: false, language: '中文', relatedOrderId: 'ORD-2024-001', url: '/documents/quality_assessment_report.docx' }, { id: '3', name: '翻译员认证证书', originalName: 'translator_certificate.jpg', type: 'image', category: 'certificate', size: 512000, // 512KB uploadedBy: '李翻译', uploadedAt: '2024-01-10 11:45', lastModified: '2024-01-10 11:45', status: 'active', tags: ['证书', '认证', '翻译员'], description: '专业翻译员资格认证证书', version: '1.0', downloadCount: 23, isPublic: false, thumbnailUrl: '/thumbnails/translator_certificate_thumb.jpg', url: '/documents/translator_certificate.jpg' }, { id: '4', name: '用户操作手册', originalName: 'user_manual_v3.pdf', type: 'pdf', category: 'manual', size: 3072000, // 3MB uploadedBy: '产品经理', uploadedAt: '2024-01-12 13:30', lastModified: '2024-01-16 10:20', status: 'active', tags: ['手册', '用户指南', '操作'], description: '系统用户操作手册第三版', version: '3.0', downloadCount: 234, isPublic: true, language: '中文', url: '/documents/user_manual_v3.pdf' }, { id: '5', name: '翻译项目演示视频', originalName: 'project_demo.mp4', type: 'video', category: 'other', size: 15728640, // 15MB uploadedBy: '市场部', uploadedAt: '2024-01-08 14:15', lastModified: '2024-01-08 14:15', status: 'active', tags: ['演示', '视频', '项目'], description: '翻译项目流程演示视频', version: '1.0', downloadCount: 67, isPublic: true, thumbnailUrl: '/thumbnails/project_demo_thumb.jpg', url: '/documents/project_demo.mp4' }, { id: '6', name: '财务报表模板', originalName: 'financial_template.xlsx', type: 'excel', category: 'template', size: 1024000, // 1MB uploadedBy: '财务部', uploadedAt: '2024-01-05 09:45', lastModified: '2024-01-14 16:30', status: 'archived', tags: ['财务', '模板', '报表'], description: '月度财务报表模板', version: '2.5', downloadCount: 45, isPublic: false, url: '/documents/financial_template.xlsx' }, { id: '7', name: '产品介绍PPT', originalName: 'product_introduction.pptx', type: 'ppt', category: 'other', size: 5120000, // 5MB uploadedBy: '销售部', uploadedAt: '2024-01-03 15:20', lastModified: '2024-01-11 11:10', status: 'active', tags: ['产品', '介绍', '演示'], description: '公司产品介绍演示文稿', version: '1.3', downloadCount: 112, isPublic: true, language: '中文', url: '/documents/product_introduction.pptx' }, { id: '8', name: '客户反馈音频', originalName: 'customer_feedback.mp3', type: 'audio', category: 'other', size: 2560000, // 2.5MB uploadedBy: '客服部', uploadedAt: '2024-01-01 10:00', lastModified: '2024-01-01 10:00', status: 'active', tags: ['客户', '反馈', '音频'], description: '客户服务质量反馈录音', version: '1.0', downloadCount: 34, isPublic: false, url: '/documents/customer_feedback.mp3' } ]; // 应用过滤器 let filteredData = mockData; if (searchTerm) { const term = searchTerm.toLowerCase(); filteredData = filteredData.filter(doc => doc.name.toLowerCase().includes(term) || doc.originalName.toLowerCase().includes(term) || doc.description?.toLowerCase().includes(term) || doc.tags.some(tag => tag.toLowerCase().includes(term)) ); } if (filterType !== 'all') { filteredData = filteredData.filter(doc => doc.type === filterType); } if (filterCategory !== 'all') { filteredData = filteredData.filter(doc => doc.category === filterCategory); } if (filterStatus !== 'all') { filteredData = filteredData.filter(doc => doc.status === filterStatus); } setDocuments(filteredData); setLoading(false); }, 1000); } catch (error) { console.error('加载文档数据失败:', error); setLoading(false); } }; const handleSelectDocument = (documentId: string) => { setSelectedDocuments(prev => prev.includes(documentId) ? prev.filter(id => id !== documentId) : [...prev, documentId] ); }; const handleSelectAll = () => { if (selectedDocuments.length === documents.length) { setSelectedDocuments([]); } else { setSelectedDocuments(documents.map(doc => doc.id)); } }; const getTypeIcon = (type: string) => { switch (type) { case 'pdf': case 'word': case 'text': return ; case 'excel': return ; case 'ppt': return ; case 'image': return ; case 'video': return ; case 'audio': return ; default: return ; } }; const getTypeColor = (type: string) => { switch (type) { case 'pdf': return 'text-red-600'; case 'word': return 'text-blue-600'; case 'excel': return 'text-green-600'; case 'ppt': return 'text-orange-600'; case 'image': return 'text-purple-600'; case 'video': return 'text-pink-600'; case 'audio': return 'text-indigo-600'; case 'text': return 'text-gray-600'; default: return 'text-gray-600'; } }; const getCategoryText = (category: string) => { switch (category) { case 'contract': return '合同'; case 'translation': return '翻译'; case 'template': return '模板'; case 'manual': return '手册'; case 'certificate': return '证书'; case 'report': return '报告'; case 'other': return '其他'; default: return category; } }; const getCategoryColor = (category: string) => { switch (category) { case 'contract': return 'bg-red-100 text-red-800'; case 'translation': return 'bg-blue-100 text-blue-800'; case 'template': return 'bg-green-100 text-green-800'; case 'manual': return 'bg-yellow-100 text-yellow-800'; case 'certificate': return 'bg-purple-100 text-purple-800'; case 'report': return 'bg-indigo-100 text-indigo-800'; case 'other': return 'bg-gray-100 text-gray-800'; default: return 'bg-gray-100 text-gray-800'; } }; const getStatusText = (status: string) => { switch (status) { case 'active': return '正常'; case 'archived': return '已归档'; case 'deleted': return '已删除'; default: return status; } }; const getStatusColor = (status: string) => { switch (status) { case 'active': return 'bg-green-100 text-green-800'; case 'archived': return 'bg-yellow-100 text-yellow-800'; case 'deleted': return 'bg-red-100 text-red-800'; default: return 'bg-gray-100 text-gray-800'; } }; const formatFileSize = (bytes: number) => { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; const totalPages = Math.ceil(documents.length / documentsPerPage); const currentDocuments = documents.slice( (currentPage - 1) * documentsPerPage, currentPage * documentsPerPage ); if (loading) { return (
加载文档数据中...
); } return (
{/* 页面标题 */}

文档管理

管理系统文档、合同模板、翻译资料等各类文件,支持分类存储和权限控制。

{/* 统计卡片 */}
文档总数
{documents.length}
正常文档
{documents.filter(d => d.status === 'active').length}
已归档
{documents.filter(d => d.status === 'archived').length}
总下载次数
{documents.reduce((sum, d) => sum + d.downloadCount, 0)}
{/* 搜索和过滤 */}
{/* 搜索框 */}
setSearchTerm(e.target.value)} />
{/* 文件类型过滤 */}
{/* 分类过滤 */}
{/* 状态过滤 */}
{/* 批量操作 */} {selectedDocuments.length > 0 && (
已选择 {selectedDocuments.length} 个文档
)}
{/* 文档列表/网格 */} {viewMode === 'list' ? (
{currentDocuments.map((document) => ( ))}
0 && selectedDocuments.length === documents.length} onChange={handleSelectAll} /> 文档信息 分类 大小 上传信息 状态 下载次数 操作
handleSelectDocument(document.id)} />
{getTypeIcon(document.type)}
{document.name}
{document.originalName}
{document.description && (
{document.description}
)}
{getCategoryText(document.category)} {formatFileSize(document.size)}
{document.uploadedBy}
{document.uploadedAt}
{getStatusText(document.status)} {document.isPublic && (
公开
)}
{document.downloadCount}
) : (
{currentDocuments.map((document) => (
handleSelectDocument(document.id)} />
{document.thumbnailUrl ? ( {document.name} ) : (
{getTypeIcon(document.type)}
)}

{document.name}

{formatFileSize(document.size)}

{getCategoryText(document.category)}
{document.uploadedBy}
{document.uploadedAt}
下载 {document.downloadCount} 次
))}
)} {/* 分页 */} {totalPages > 1 && (

显示第 {(currentPage - 1) * documentsPerPage + 1} 到{' '} {Math.min(currentPage * documentsPerPage, documents.length)} 条, 共 {documents.length} 条记录

)}
); }