feat(类型): 添加文件上传类型定义

- 定义 FileType 类型支持多种文件格式(图片、PDF、文档、代码等)
- 实现 UploadFile 接口包含完整的文件上传状态管理
- 添加 FileUploadConfig 配置接口和默认配置
- 提供 MIME 类型与文件类型映射
- 实现文件大小格式化和验证工具函数
This commit is contained in:
gaoziman 2025-12-20 12:12:54 +08:00
parent 799fb3ab58
commit e99c72f02a

173
src/types/file-upload.ts Normal file
View File

@ -0,0 +1,173 @@
/**
*
*/
// 支持的文件类型
export type FileType =
| 'image' // 图片jpg, png, gif, webp
| 'pdf' // PDF 文档
| 'document' // Word 文档
| 'spreadsheet'// Excel 表格
| 'code' // 代码文件
| 'text' // 纯文本
| 'markdown' // Markdown 文件
| 'archive' // 压缩包
| 'unknown'; // 未知类型
// 上传文件信息
export interface UploadFile {
id: string;
file: File;
name: string;
size: number;
type: FileType;
mimeType: string;
previewUrl?: string; // 图片预览URL仅图片类型
uploadProgress: number; // 上传进度 0-100
status: 'pending' | 'uploading' | 'success' | 'error';
error?: string; // 错误信息
uploadedUrl?: string; // 上传成功后的URL
}
// 文件上传配置
export interface FileUploadConfig {
maxFileSize: number; // 最大文件大小(字节)
maxFiles: number; // 最大文件数量
allowedTypes: FileType[]; // 允许的文件类型
allowedMimeTypes: string[];// 允许的 MIME 类型
}
// 默认配置
export const DEFAULT_UPLOAD_CONFIG: FileUploadConfig = {
maxFileSize: 20 * 1024 * 1024, // 20MB
maxFiles: 10,
allowedTypes: ['image', 'pdf', 'document', 'spreadsheet', 'code', 'text', 'markdown'],
allowedMimeTypes: [
// 图片
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
'image/svg+xml',
// PDF
'application/pdf',
// Word
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
// Excel
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
// 文本
'text/plain',
'text/markdown',
'text/csv',
// 代码
'text/javascript',
'text/typescript',
'text/html',
'text/css',
'application/json',
'application/xml',
],
};
// 文件类型映射
export const MIME_TO_FILE_TYPE: Record<string, FileType> = {
'image/jpeg': 'image',
'image/png': 'image',
'image/gif': 'image',
'image/webp': 'image',
'image/svg+xml': 'image',
'application/pdf': 'pdf',
'application/msword': 'document',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'document',
'application/vnd.ms-excel': 'spreadsheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'spreadsheet',
'text/plain': 'text',
'text/markdown': 'markdown',
'text/csv': 'spreadsheet',
'text/javascript': 'code',
'text/typescript': 'code',
'text/html': 'code',
'text/css': 'code',
'application/json': 'code',
'application/xml': 'code',
'application/zip': 'archive',
'application/x-rar-compressed': 'archive',
'application/x-7z-compressed': 'archive',
};
// 根据 MIME 类型获取文件类型
export function getFileTypeFromMime(mimeType: string): FileType {
return MIME_TO_FILE_TYPE[mimeType] || 'unknown';
}
// 根据文件扩展名获取文件类型
export function getFileTypeFromExtension(filename: string): FileType {
const ext = filename.split('.').pop()?.toLowerCase() || '';
const extensionMap: Record<string, FileType> = {
// 图片
jpg: 'image', jpeg: 'image', png: 'image', gif: 'image', webp: 'image', svg: 'image',
// PDF
pdf: 'pdf',
// 文档
doc: 'document', docx: 'document',
// 表格
xls: 'spreadsheet', xlsx: 'spreadsheet', csv: 'spreadsheet',
// 文本
txt: 'text',
// Markdown
md: 'markdown', markdown: 'markdown',
// 代码
js: 'code', ts: 'code', jsx: 'code', tsx: 'code',
py: 'code', java: 'code', c: 'code', cpp: 'code', h: 'code',
go: 'code', rs: 'code', rb: 'code', php: 'code',
html: 'code', css: 'code', scss: 'code', less: 'code',
json: 'code', xml: 'code', yaml: 'code', yml: 'code',
sql: 'code', sh: 'code', bash: 'code',
// 压缩包
zip: 'archive', rar: 'archive', '7z': 'archive', tar: 'archive', gz: 'archive',
};
return extensionMap[ext] || 'unknown';
}
// 格式化文件大小
export function formatFileSize(bytes: number): string {
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];
}
// 验证文件
export interface FileValidationResult {
valid: boolean;
error?: string;
}
export function validateFile(
file: File,
config: FileUploadConfig = DEFAULT_UPLOAD_CONFIG
): FileValidationResult {
// 检查文件大小
if (file.size > config.maxFileSize) {
return {
valid: false,
error: `文件大小超过限制(最大 ${formatFileSize(config.maxFileSize)}`,
};
}
// 检查 MIME 类型
const fileType = getFileTypeFromMime(file.type) || getFileTypeFromExtension(file.name);
if (!config.allowedTypes.includes(fileType) && fileType !== 'unknown') {
return {
valid: false,
error: `不支持的文件类型:${file.type}`,
};
}
return { valid: true };
}