export const formatPrice = (value) => { return Number(value).toFixed(2) } import {securityFileDownload} from '@/api/FileUpload/FileUpload.js' // 移动端文件预览优化版 - H5兼容修复 export const YuLanfile = async (filePath) => { uni.showToast({ title: '预览还在开发完善中!!', icon: 'none', duration: 2000 }) return false; console.log("预览文件:", filePath) if (!filePath) { uni.showToast({ title: '文件路径不存在', icon: 'none' }); return; } try { uni.showLoading({ title: '正在加载文件...', mask: true }); const response = await securityFileDownload({ fileName: filePath, delete: false }); const fileExtension = filePath.split('.').pop().toLowerCase(); const fileName = filePath.split('\\').pop() || 'preview.' + fileExtension; // 判断运行环境 const platform = getPlatform(); console.log('当前平台:', platform); // 根据平台和文件类型选择预览方式 if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(fileExtension)) { await previewImage(response, fileExtension, fileName, platform); } else if (fileExtension === 'pdf') { await previewPDF(response, fileName, platform); } else { await handleOtherFile(response, fileName, fileExtension, platform); } uni.hideLoading(); } catch (error) { console.error('预览失败:', error); uni.hideLoading(); uni.showToast({ title: '预览失败: ' + (error.message || '未知错误'), icon: 'none' }); } } // 获取平台 const getPlatform = () => { // #ifdef H5 return 'h5'; // #endif // #ifdef APP-PLUS return 'app'; // #endif // #ifdef MP-WEIXIN return 'weixin'; // #endif return 'h5'; // 默认 } // 图片预览 const previewImage = async (response, fileExtension, fileName, platform) => { return new Promise((resolve, reject) => { const blob = new Blob([response], { type: `image/${fileExtension === 'jpg' ? 'jpeg' : fileExtension}` }); // H5环境 - 使用简单可靠的方式 if (platform === 'h5') { const blobUrl = URL.createObjectURL(blob); // 创建图片预览模态框 showImageModalH5(blobUrl, fileName, resolve); return; } // App环境 if (platform === 'app') { const reader = new FileReader(); reader.onload = (e) => { const base64 = e.target.result; uni.previewImage({ current: 0, urls: [base64], success: () => resolve(), fail: (err) => { console.error('预览图片失败:', err); const blobUrl = URL.createObjectURL(blob); window.open(blobUrl, '_blank'); resolve(); } }); }; reader.readAsDataURL(blob); return; } // 微信小程序环境 if (platform === 'weixin') { const reader = new FileReader(); reader.onload = (e) => { const base64 = e.target.result; wx.getFileSystemManager().writeFile({ filePath: wx.env.USER_DATA_PATH + '/temp_' + Date.now() + '.' + fileExtension, data: base64.replace(/^data:image\/\w+;base64,/, ''), encoding: 'base64', success: (res) => { wx.previewImage({ current: 0, urls: [res.filePath], success: () => resolve(), fail: (err) => reject(err) }); }, fail: (err) => reject(err) }); }; reader.readAsDataURL(blob); } }); } // H5图片预览模态框 const showImageModalH5 = (imageUrl, fileName, resolve) => { // 移除已存在的模态框 const existingModal = document.getElementById('h5-preview-modal'); if (existingModal) { document.body.removeChild(existingModal); } const modal = document.createElement('div'); modal.id = 'h5-preview-modal'; modal.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.9); z-index: 999999; display: flex; justify-content: center; align-items: center; flex-direction: column; `; const header = document.createElement('div'); header.style.cssText = ` position: absolute; top: 0; left: 0; right: 0; height: 50px; background: rgba(0,0,0,0.5); color: white; display: flex; justify-content: space-between; align-items: center; padding: 0 20px; z-index: 1000000; `; header.innerHTML = ` ${fileName} × `; const img = document.createElement('img'); img.src = imageUrl; img.style.cssText = ` max-width: 100%; max-height: 100%; object-fit: contain; `; // 关闭按钮点击 header.querySelector('span:last-child').onclick = () => { document.body.removeChild(modal); URL.revokeObjectURL(imageUrl); resolve(); }; // 点击背景关闭 modal.onclick = (e) => { if (e.target === modal) { document.body.removeChild(modal); URL.revokeObjectURL(imageUrl); resolve(); } }; // 按ESC关闭 const escHandler = (e) => { if (e.key === 'Escape') { document.body.removeChild(modal); URL.revokeObjectURL(imageUrl); document.removeEventListener('keydown', escHandler); resolve(); } }; document.addEventListener('keydown', escHandler); modal.appendChild(header); modal.appendChild(img); document.body.appendChild(modal); } // PDF预览 const previewPDF = async (response, fileName, platform) => { return new Promise((resolve, reject) => { const blob = new Blob([response], {type: 'application/pdf'}); // H5环境 if (platform === 'h5') { const blobUrl = URL.createObjectURL(blob); showPDFModalH5(blobUrl, fileName, resolve); return; } // App环境 if (platform === 'app') { const reader = new FileReader(); reader.onload = (e) => { const arrayBuffer = e.target.result; const base64Data = arrayBufferToBase64(arrayBuffer); plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function (fs) { fs.root.getFile(fileName, {create: true}, function (fileEntry) { fileEntry.createWriter(function (writer) { writer.onwrite = function () { plus.runtime.openFile(fileEntry.toLocalURL()); resolve(); }; writer.onerror = reject; writer.writeAsBinary(atob(base64Data)); }, reject); }, reject); }, reject); }; reader.readAsArrayBuffer(blob); return; } // 微信小程序环境 if (platform === 'weixin') { const reader = new FileReader(); reader.onload = (e) => { const arrayBuffer = e.target.result; const base64Data = arrayBufferToBase64(arrayBuffer); wx.getFileSystemManager().writeFile({ filePath: wx.env.USER_DATA_PATH + '/' + fileName, data: base64Data, encoding: 'base64', success: (res) => { wx.openDocument({ filePath: wx.env.USER_DATA_PATH + '/' + fileName, success: () => resolve(), fail: (err) => reject(err) }); }, fail: (err) => reject(err) }); }; reader.readAsArrayBuffer(blob); } }); } // H5 PDF预览模态框 const showPDFModalH5 = (pdfUrl, fileName, resolve) => { // 移除已存在的模态框 const existingModal = document.getElementById('h5-preview-modal'); if (existingModal) { document.body.removeChild(existingModal); } const modal = document.createElement('div'); modal.id = 'h5-preview-modal'; modal.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: white; z-index: 999999; display: flex; flex-direction: column; `; const header = document.createElement('div'); header.style.cssText = ` height: 50px; background: #f5f5f5; display: flex; justify-content: space-between; align-items: center; padding: 0 20px; border-bottom: 1px solid #ddd; `; header.innerHTML = ` ${fileName} × `; const iframe = document.createElement('iframe'); iframe.src = pdfUrl; iframe.style.cssText = ` width: 100%; flex: 1; border: none; `; // 关闭按钮 header.querySelector('span:last-child').onclick = () => { document.body.removeChild(modal); URL.revokeObjectURL(pdfUrl); resolve(); }; // 按ESC关闭 const escHandler = (e) => { if (e.key === 'Escape') { document.body.removeChild(modal); URL.revokeObjectURL(pdfUrl); document.removeEventListener('keydown', escHandler); resolve(); } }; document.addEventListener('keydown', escHandler); modal.appendChild(header); modal.appendChild(iframe); document.body.appendChild(modal); } // 处理其他文件 const handleOtherFile = async (response, fileName, fileExtension, platform) => { return new Promise((resolve, reject) => { uni.showActionSheet({ itemList: ['预览文件', '保存到本地', '取消'], success: async (res) => { if (res.tapIndex === 0) { await openWithDefaultApp(response, fileName, fileExtension, platform); resolve(); } else if (res.tapIndex === 1) { await saveFile(response, fileName, platform); resolve(); } else { resolve(); } }, fail: (err) => reject(err) }); }); } // 使用默认应用打开 const openWithDefaultApp = (response, fileName, fileExtension, platform) => { return new Promise((resolve, reject) => { const blob = new Blob([response]); // H5环境 if (platform === 'h5') { const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; a.click(); URL.revokeObjectURL(blobUrl); uni.showToast({ title: '开始下载', icon: 'success' }); resolve(); return; } // App环境 if (platform === 'app') { const reader = new FileReader(); reader.onload = (e) => { const arrayBuffer = e.target.result; const base64Data = arrayBufferToBase64(arrayBuffer); plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function (fs) { fs.root.getFile(fileName, {create: true}, function (fileEntry) { fileEntry.createWriter(function (writer) { writer.onwrite = function () { plus.runtime.openFile(fileEntry.toLocalURL()); resolve(); }; writer.onerror = reject; writer.writeAsBinary(atob(base64Data)); }, reject); }, reject); }, reject); }; reader.readAsArrayBuffer(blob); return; } // 微信小程序环境 if (platform === 'weixin') { const reader = new FileReader(); reader.onload = (e) => { const arrayBuffer = e.target.result; const base64Data = arrayBufferToBase64(arrayBuffer); wx.getFileSystemManager().writeFile({ filePath: wx.env.USER_DATA_PATH + '/' + fileName, data: base64Data, encoding: 'base64', success: (res) => { wx.openDocument({ filePath: wx.env.USER_DATA_PATH + '/' + fileName, success: () => resolve(), fail: (err) => reject(err) }); }, fail: (err) => reject(err) }); }; reader.readAsArrayBuffer(blob); } }); } // 保存文件 const saveFile = (response, fileName, platform) => { return new Promise((resolve, reject) => { const blob = new Blob([response]); // H5环境 if (platform === 'h5') { const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; a.click(); URL.revokeObjectURL(blobUrl); uni.showToast({ title: '开始下载', icon: 'success' }); resolve(); return; } // App环境 if (platform === 'app') { const reader = new FileReader(); reader.onload = (e) => { const arrayBuffer = e.target.result; const base64Data = arrayBufferToBase64(arrayBuffer); plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function (fs) { fs.root.getFile(fileName, {create: true}, function (fileEntry) { fileEntry.createWriter(function (writer) { writer.onwrite = function () { uni.showToast({ title: '保存成功', icon: 'success' }); resolve(); }; writer.onerror = reject; writer.writeAsBinary(atob(base64Data)); }, reject); }, reject); }, reject); }; reader.readAsArrayBuffer(blob); return; } // 微信小程序环境 if (platform === 'weixin') { const reader = new FileReader(); reader.onload = (e) => { const arrayBuffer = e.target.result; const base64Data = arrayBufferToBase64(arrayBuffer); wx.getFileSystemManager().writeFile({ filePath: wx.env.USER_DATA_PATH + '/' + fileName, data: base64Data, encoding: 'base64', success: (res) => { uni.showToast({ title: '保存成功', icon: 'success' }); resolve(); }, fail: (err) => reject(err) }); }; reader.readAsArrayBuffer(blob); } }); } // ArrayBuffer 转 Base64 const arrayBufferToBase64 = (buffer) => { let binary = ''; const bytes = new Uint8Array(buffer); const len = bytes.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary); } // 获取MIME类型 const getMimeType = (extension) => { const mimeTypes = { 'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'gif': 'image/gif', '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', 'txt': 'text/plain' }; return mimeTypes[extension] || 'application/octet-stream'; } export const navigateTo = (path) => { uni.navigateTo({ url: path }) }