Otsuka-APP/utils/utils.js
2026-02-12 14:41:15 +08:00

545 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = `
<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';
}