feat(类型): 添加文件上传类型定义
- 定义 FileType 类型支持多种文件格式(图片、PDF、文档、代码等) - 实现 UploadFile 接口包含完整的文件上传状态管理 - 添加 FileUploadConfig 配置接口和默认配置 - 提供 MIME 类型与文件类型映射 - 实现文件大小格式化和验证工具函数
This commit is contained in:
parent
799fb3ab58
commit
e99c72f02a
173
src/types/file-upload.ts
Normal file
173
src/types/file-upload.ts
Normal 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 };
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user