// utils/file-adapter.ts /** * 创建统一的文件对象(多平台兼容) * @param {Object} rawFile - 原始文件数据 * @returns {Object} 统一格式的文件对象 */ export const createFileFromUniFile = (rawFile: any): any => { // 检查环境 // #ifdef H5 if (rawFile instanceof File) { return rawFile } // #endif const path = rawFile.path || rawFile.tempFilePath || rawFile.apFilePaths?.[0] const name = rawFile.name || getFileNameFromPath(path) const size = rawFile.size || 0 const type = rawFile.type || getFileTypeFromPath(name) // 创建统一的文件对象 const unifiedFile = { // 基础属性 path, name, size, type, lastModified: rawFile.lastModified || Date.now(), // 原始数据 raw: rawFile, // 方法(模拟 File 对象的部分行为) slice(start: any, end: any) { // 小程序环境不支持实际切片,返回一个标记对象 return { path: this.path, name: this.name, size: end - start, type: this.type, slice: () => { } } }, // 转换为 base64(异步) toBase64() { return new Promise((resolve: any, reject: any) => { // #ifdef MP-WEIXIN wx.getFileSystemManager().readFile({ filePath: this.path, encoding: 'base64', success: (res: any) => resolve(res.data), fail: reject }) // #endif // #ifdef H5 const reader = new FileReader() reader.onload = () => resolve(reader.result.split(',')[1]) reader.onerror = reject reader.readAsDataURL(this) // #endif // #ifdef APP-PLUS plus.io.resolveLocalFileSystemURL(this.path, (entry: any) => { entry.file((file: any) => { const reader = new plus.io.FileReader() reader.onload = (e: any) => resolve(e.target.result.split(',')[1]) reader.onerror = reject reader.readAsDataURL(file) }) }) // #endif }) }, // 转换为 ArrayBuffer(异步) toArrayBuffer() { return new Promise((resolve: any, reject: any) => { // #ifdef MP-WEIXIN wx.getFileSystemManager().readFile({ filePath: this.path, success: (res: any) => resolve(res.data), fail: reject }) // #endif // #ifdef H5 const reader = new FileReader() reader.onload = () => resolve(reader.result) reader.onerror = reject reader.readAsArrayBuffer(this) // #endif }) }, // 获取文件 URL(用于预览等) getURL() { // #ifdef H5 if (this.raw instanceof File) { return URL.createObjectURL(this.raw) } // #endif return this.path }, // 释放资源 revoke() { // #ifdef H5 if (this.raw instanceof File && this._objectURL) { URL.revokeObjectURL(this._objectURL) } // #endif } } // 如果是 H5 环境,尝试包装成 File 对象 // #ifdef H5 if (typeof File !== 'undefined' && !(rawFile instanceof File)) { try { // 尝试创建 File 对象(需要 fetch 支持) return Object.assign(new Blob(), unifiedFile) } catch (e) { console.warn('无法创建 File 对象,使用统一格式:', e) } } // #endif return unifiedFile } /** * 从文件路径提取文件名 */ const getFileNameFromPath = (path: any): any => { if (!path) return 'unnamed' return path.split('/').pop().split('?')[0] } /** * 从文件名获取文件类型 */ const getFileTypeFromPath = (filename: any): any => { if (!filename) return 'application/octet-stream' const extension = filename.split('.').pop().toLowerCase() const typeMap: any = { // 图片 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'gif': 'image/gif', 'bmp': 'image/bmp', 'webp': 'image/webp', 'svg': 'image/svg+xml', // 视频 'mp4': 'video/mp4', 'avi': 'video/x-msvideo', 'mov': 'video/quicktime', 'wmv': 'video/x-ms-wmv', 'flv': 'video/x-flv', 'mkv': 'video/x-matroska', // 音频 'mp3': 'audio/mpeg', 'wav': 'audio/wav', 'aac': 'audio/aac', 'ogg': 'audio/ogg', 'flac': 'audio/flac', // 文档 'pdf': 'application/pdf', 'doc': 'application/msword', 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'xls': 'application/vnd.ms-excel', 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ppt': 'application/vnd.ms-powerpoint', 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'txt': 'text/plain' } return typeMap[extension] || 'application/octet-stream' } /** * 批量转换文件对象 */ export const createFilesFromUniFiles = (rawFiles: any): any => { if (!Array.isArray(rawFiles)) { rawFiles = [rawFiles] } return rawFiles.map((file: any) => createFileFromUniFile(file)) } /** * 环境检测 */ export const isBrowserEnv = (): any => { // #ifdef H5 return typeof File !== 'undefined' // #endif return false } export const isWeChatEnv = (): any => { // #ifdef MP-WEIXIN return true // #endif return false }