const dangerousFileTypes = new Set([ 'exe', 'dll', 'bat', 'cmd', 'com', 'scr', 'msi', 'pif', 'js', 'jsp', 'jspx', 'jse', 'vbs', 'vbe', 'ps1', 'psm1', 'sh', 'jar', 'apk', 'ipa', 'lnk', 'hta', 'reg', 'cpl', 'msc', 'wsf', 'wsh', 'scf', 'inf', 'url', 'sh' ]) // ...所有支持的icon const iconList = [ 'amb-color-icon-XLS', 'amb-color-icon-XLSX', 'amb-color-icon-DOC', 'amb-color-icon-DOCX', 'amb-color-icon-PPT', 'amb-color-icon-PDF', 'amb-color-icon-TXT', 'amb-color-icon-JPG', 'amb-color-icon-PNG', 'amb-color-icon-ZIP', 'amb-color-icon-AVI', 'amb-color-icon-MP4', 'amb-color-icon-qita' ] export function formatFileSize(size: number | undefined | null): string { if (size == null || isNaN(size)) return '' if (size < 1024) return size + 'B' if (size < 1024 * 1024) return (size / 1024).toFixed(1).replace(/\.0$/, '') + 'K' if (size < 1024 * 1024 * 1024) return (size / 1024 / 1024).toFixed(1).replace(/\.0$/, '') + 'M' return (size / 1024 / 1024 / 1024).toFixed(1).replace(/\.0$/, '') + 'G' } // 列表_5215278368.xls export function getFileIconByName(fileName: string): string { const qitaIcon = 'amb-color-icon-qita' if (!fileName) { return qitaIcon } let fileType = fileName.substring(fileName.lastIndexOf('.') + 1) // 获取文件名 if (!fileType) { return qitaIcon } switch (fileType) { case 'xlsx': fileType = 'XLS' break case 'docx': fileType = 'DOC' break case 'pptx': fileType = 'PPT' break } const finalIconName = 'amb-color-icon-' + fileType.toUpperCase() if (iconList.includes(finalIconName)) { return finalIconName } return qitaIcon } /** * 校验是否是合法的文件名。不能包含 < >" '&|/ \`?*: */ export function isValidFileName(fileName: string): boolean { if (!fileName || !fileName.trim()) { return false } const invalidCharsPattern = /[<>:"'\/\\|?*&`]/ return !invalidCharsPattern.test(fileName) } export function isMaliciousUploadFile(file: File) { const fileName = (file?.name || '').trim().toLowerCase() if (!fileName) { return false } return fileName.split('.').some((part) => dangerousFileTypes.has(part)) } export const checkFileAccept = (file: File, acceptStr: string) => { if (!acceptStr || !file) return true const accepts = acceptStr.split(',').map((s) => s.trim()) const fileExt = '.' + (file.name.split('.').pop()?.toLowerCase() || '') const fileType = file.type return accepts.some((item) => { // 扩展名匹配:".jpg"、".pdf" if (item.startsWith('.')) { return fileExt === item.toLowerCase() } // MIME 通配符匹配:"image/*"、"video/*" if (item.endsWith('/*')) { const typePrefix = item.slice(0, -1) // 'image/', 'video/' return fileType.startsWith(typePrefix) } // 精确 MIME 匹配:"image/png"、"application/pdf" return fileType === item }) }