2026-02-07 15:33:47 +08:00
|
|
|
|
export const formatPrice = (value) => {
|
|
|
|
|
|
return Number(value).toFixed(2)
|
2026-02-12 14:41:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 = `
|
|
|
|
|
|
<span style="font-size: 16px; color: white;">${fileName}</span>
|
|
|
|
|
|
<span style="font-size: 30px; cursor: pointer; color: white; padding: 0 10px;">×</span>
|
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
|
|
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 = `
|
|
|
|
|
|
<span style="font-size: 16px; color: #333;">${fileName}</span>
|
|
|
|
|
|
<span style="font-size: 30px; color: #999; cursor: pointer; padding: 0 10px;">×</span>
|
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
|
|
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';
|
2026-02-07 15:33:47 +08:00
|
|
|
|
}
|