<u-upload :fileList="imgs" :name="" @afterRead="afterRead" :deletable="true" multiple @delete="deletePic" :maxCount="4" width="112rpx" height="112rpx">
<image src="../../../static/imgs/common/uploadImg.png" mode="widthFix" style="width: 112rpx; height: 112rpx;" :previewFullImage="true"></image>
</u-upload>
<view class="save" @click="$u.throttle(clickSave,500)">保存</view>
<helang-compress ref="helangCompress"></helang-compress> //uniapp插件市场图片压缩工具(https://ext.dcloud.net.cn/plugin?id=2316)
<script>
export default {
data(){
return {
imgs: [],
},
}
},
methods:{
// 删除图片
deletePic(event) {
this.imgs.splice(event.index, 1)
},
// 新增图片
async afterRead(event) {
let lists = [].concat(event.file)
this.imgs = this.imgs.concat(lists.map(item => ({ url: item.url })));
},
async clickSave(){
let updateData = this.imgs.map(img => img.url)
uni.showLoading({
title: '资料上传中...',
mask: true
});
for (let i = 0; i < updateData.length; i++) {
const img = updateData[i]
//如果当前的图片地址是以当前域名为开头的,则表示是服务器返回的图片,无需进行处理,否则则是本地图片,需要上传到服务器,在上传之前先对图片进行压缩,压缩与上传之后将本地图片替换成网络图片,这样发给后端的时候,图片地址统一为网络地址形式的图片了
if (!img.startsWith(config.baseUrl)) {
const uploadedUrl = await this.imageUpload(img)
updateData.imgs[i] = uploadedUrl
}
}
const params = { id: this.id, pay_img: JSON.stringify(updateData) };
const result = await goodsLink(params);
uni.hideLoading();
if(result.code===1){
this.$u.toast(result.msg, 1000);
//上传成功的逻辑
}else{
this.$u.toast(result.msg)
}
},
//上传图片到服务器,由于微信小程序只支持单文件上传,传多个文件需要反复调用api
async imageUpload(filePath){
let originSize
let finallPath
//判断本地文件的大小
uni.getFileInfo({
filePath: filePath,
success:({size})=>{
originSize = size
}
});
//如果图片小于1M,则不走压缩逻辑,只是转化一下图片的格式,在H5中,图片会由blob转化为文件格式(接口需求)
if( originSize < 1024*1024){
finallPath = await exchangeFile(filePath)
}else{
//图片大于1M,走压缩
finallPath = await compressImage.call(this, filePath); // 压缩图片
}
const url = config.baseUrl + 'api.php/user/upload_sign_img';
const token = uni.getStorageSync('user').token;
//判断当前的平台
const type = uni.getSystemInfoSync().uniPlatform
if (type === 'web') {
//在h5中,使用文件的方式上传
return new Promise((resolve, reject) => {
uni.uploadFile({
url: url,
file: finallPath,
header:{"AUTHORIZATION": token},
fail: err => {
reject(err);
},
success: res => {
const data = JSON.parse(res.data);
if (data.data && data.data.file_urls) {
const imageUrl = data.data.file_urls;
resolve(imageUrl);
} else {
reject(data.data);
}
},
});
})
}else{
return new Promise((resolve,reject)=>{
uni.uploadFile({
url: url,
filePath: finallPath,
header:{"AUTHORIZATION": token},
name: 'file',
fail: err => {
this.$u.toast(err);
},
success: res => {
const data = JSON.parse(res.data);
if(data.data && data.data.file_urls){
// 上传成功的情况
const imageUrl = data.data.file_urls;
resolve(imageUrl)
}else{
this.$u.toast(data.data);
}
},
});
})}
},
}
}
</script>
const type = uni.getSystemInfoSync().uniPlatform
// 把blob转为file(h5环境使用)
function dataURLtoFile(dataUrl, filename) {
const arr = dataUrl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
function exchangeFile(imageUrl){
if(type === 'web'){
imageUrl = dataURLtoFile(imageUrl, 'filename.jpg');
}
return new Promise((resolve,reject)=>{
resolve(imageUrl)
})
}
//图片压缩处理
async function compressImage(imageUrl) {
let compressedUrl = imageUrl;
let count = 0; // 定义一个计数器,用于记录循环次数
while (count < 5) { // 最多循环5次
count++; // 对计数器加1
await new Promise((resolve, reject) => {
this.$refs.helangCompress.compress({
src: compressedUrl,
maxSize: 800,
fileType: 'jpg',
quality: 0.85,
minSize: 640
}).then((res) => {
uni.getFileInfo({
filePath: res,
success: ({size}) => {
console.log(size, '压缩后的文件大小');
if (size < 4096 * 1024) { // 小于 4MB,压缩成功
console.log('压缩成功');
compressedUrl = res; // 更新压缩后的图片路径
resolve();
} else { // 大于等于 4MB,继续压缩
compressedUrl = res; // 更新压缩后的图片路径
console.log('再次压缩');
resolve();
}
}
})
}).catch((err) => {
console.log(err);
reject(err);
});
});
if (compressedUrl) break; // 如果已经成功压缩图片,则退出循环
}
if (!compressedUrl) {
throw new Error('经过5次重试仍无法成功压缩图片');
}
if(type === 'web'){
compressedUrl = dataURLtoFile(compressedUrl, 'filename.jpg');
}
return compressedUrl;
}
export { exchangeFile, compressImage };