组件修改
This commit is contained in:
181
urbanLifelineWeb/packages/shared/src/utils/file.ts
Normal file
181
urbanLifelineWeb/packages/shared/src/utils/file.ts
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* 文件处理相关工具函数
|
||||
*/
|
||||
|
||||
/**
|
||||
* 验证文件类型
|
||||
*/
|
||||
export const isValidFileType = (file: File, accept: string): boolean => {
|
||||
if (!accept || accept === '*/*') return true
|
||||
|
||||
const acceptTypes = accept.split(',').map(t => t.trim())
|
||||
return acceptTypes.some(type => {
|
||||
if (type.startsWith('.')) {
|
||||
return file.name.toLowerCase().endsWith(type.toLowerCase())
|
||||
} else if (type.endsWith('/*')) {
|
||||
return file.type.startsWith(type.replace('/*', ''))
|
||||
} else {
|
||||
return file.type === type
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为图片文件
|
||||
*/
|
||||
export const isImageFile = (file: File): boolean => {
|
||||
return file.type.startsWith('image/')
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为文本文件
|
||||
*/
|
||||
export const isTextFile = (file: File): boolean => {
|
||||
return file.type.startsWith('text/')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件预览URL
|
||||
*/
|
||||
export const getFilePreviewUrl = (file: File): string => {
|
||||
return URL.createObjectURL(file)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文件大小
|
||||
*/
|
||||
export const formatFileSize = (bytes: number): string => {
|
||||
if (bytes === 0) return '0 B'
|
||||
const k = 1024
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型图标
|
||||
*/
|
||||
export const getFileTypeIcon = (file: File): string => {
|
||||
const extension = file.name.split('.').pop()?.toLowerCase()
|
||||
const iconMap: Record<string, string> = {
|
||||
// 文档类
|
||||
'pdf': '📄',
|
||||
'doc': '📝',
|
||||
'docx': '📝',
|
||||
'txt': '📄',
|
||||
'md': '📄',
|
||||
'rtf': '📄',
|
||||
|
||||
// 表格类
|
||||
'xls': '📊',
|
||||
'xlsx': '📊',
|
||||
'csv': '📊',
|
||||
|
||||
// 演示文稿
|
||||
'ppt': '📊',
|
||||
'pptx': '📊',
|
||||
|
||||
// 压缩包
|
||||
'zip': '📦',
|
||||
'rar': '📦',
|
||||
'7z': '📦',
|
||||
'tar': '📦',
|
||||
'gz': '📦',
|
||||
|
||||
// 视频
|
||||
'mp4': '🎬',
|
||||
'avi': '🎬',
|
||||
'mov': '🎬',
|
||||
'wmv': '🎬',
|
||||
'flv': '🎬',
|
||||
'mkv': '🎬',
|
||||
|
||||
// 音频
|
||||
'mp3': '🎵',
|
||||
'wav': '🎵',
|
||||
'flac': '🎵',
|
||||
'aac': '🎵',
|
||||
|
||||
// 图片
|
||||
'jpg': '🖼️',
|
||||
'jpeg': '🖼️',
|
||||
'png': '🖼️',
|
||||
'gif': '🖼️',
|
||||
'bmp': '🖼️',
|
||||
'svg': '🖼️',
|
||||
'webp': '🖼️'
|
||||
}
|
||||
return iconMap[extension || ''] || '📄'
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证文件大小
|
||||
*/
|
||||
export const validateFileSize = (file: File, maxSize: number): { valid: boolean; error?: string } => {
|
||||
if (file.size > maxSize) {
|
||||
const maxSizeMB = (maxSize / 1024 / 1024).toFixed(0)
|
||||
return {
|
||||
valid: false,
|
||||
error: `文件 ${file.name} 大小超过 ${maxSizeMB}MB`
|
||||
}
|
||||
}
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证文件类型
|
||||
*/
|
||||
export const validateFileType = (file: File, accept?: string): { valid: boolean; error?: string } => {
|
||||
if (accept && !isValidFileType(file, accept)) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `文件 ${file.name} 类型不符合要求`
|
||||
}
|
||||
}
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件是否重复
|
||||
*/
|
||||
export const checkFileDuplicate = (file: File, existingFiles: File[]): { valid: boolean; error?: string } => {
|
||||
if (existingFiles.some(f => f.name === file.name && f.size === file.size)) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `文件 ${file.name} 已添加`
|
||||
}
|
||||
}
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
/**
|
||||
* 综合验证文件
|
||||
*/
|
||||
export const validateFile = (
|
||||
file: File,
|
||||
options: {
|
||||
maxSize?: number
|
||||
accept?: string
|
||||
existingFiles?: File[]
|
||||
} = {}
|
||||
): { valid: boolean; error?: string } => {
|
||||
const { maxSize, accept, existingFiles = [] } = options
|
||||
|
||||
// 检查文件大小
|
||||
if (maxSize) {
|
||||
const sizeResult = validateFileSize(file, maxSize)
|
||||
if (!sizeResult.valid) return sizeResult
|
||||
}
|
||||
|
||||
// 检查文件类型
|
||||
if (accept) {
|
||||
const typeResult = validateFileType(file, accept)
|
||||
if (!typeResult.valid) return typeResult
|
||||
}
|
||||
|
||||
// 检查是否重复
|
||||
const duplicateResult = checkFileDuplicate(file, existingFiles)
|
||||
if (!duplicateResult.valid) return duplicateResult
|
||||
|
||||
return { valid: true }
|
||||
}
|
||||
5
urbanLifelineWeb/packages/shared/src/utils/index.ts
Normal file
5
urbanLifelineWeb/packages/shared/src/utils/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Utils 统一导出
|
||||
*/
|
||||
|
||||
export * from './file'
|
||||
Reference in New Issue
Block a user