这个学期有一个大作业要求是做一个项目的,本人就做了一个微信小程序失物招领的项目,主要负责后端的内容,其中遇到的最大的问题就是图片的处理了。首先需要用户选择图片,然后就是将图片保存到数据库中。但是这里有个问题,就是如果直接将这个图片的filepath上传到数据库的话是不可行的,因为使用wxchooseMidia()这个函数得到的路径只是一个临时路径,也就是说如果我把这个路径上传,那么下次取数据的话可能就加载不出来图片了,而且其他用户访问的时候是看不到别人发布的图片的,因为临时路径是针对个人的,别的用户自然看不到我的临时文件的数据。甚至如果我清理了微信小程序的缓存之后,临时文件被清理掉,那么数据库里面存放的数据就是无效的数据。由于本人使用的是微信小程序云开发,没有自搭建后台,所以解决方法就是将获取到的图片上床到微信小程序云服务的云存储中,这样图片就会被保存,同时调用后会返回fileid,我们只需要将这个fileid保存到数据库中就可以实现图片的存储了。下次我们再次访问这张图片的时候,我们只需要访问fileid即可,因为我设置了权限,所有用户可读,所以图片就可以被所有用户读取,同时也不用担心缓存清理的问题,因为存储到云文件中时图片已经被保存,原来的临时路径无所谓了。下面给出代码展示。
因为微信官方给出的文档指出现在已经不维护wx.chooseImage这个接口了,所以只能使用这个接口来获取图片。我们也可以通过打印res.tempFiles的信息来查看图片路径是不是临时路径。
chooseImage() {
wx.chooseMedia({
count: 3, // 可选择的图片数量
sizeType: ['compressed'], // 压缩图片
sourceType: ['album', 'camera'], // 来源:相册或相机
success: (res)=> {
this.imageNumber=res.tempFiles.length
var length=res.tempFiles.length
var urls=[]
for(var i=0;i<length;i++){
var url=res.tempFiles[i].tempFilePath
urls.push(url)
}
this.imageUrl=urls
this.setData({
imageUrl:urls
})
console.log('图片为',this.imageUrl)
}
})
},
下一步就是将图片上传到云储存中,调用微信给出的官方接口即可。接口中的filePath是指当前图片的路径,可以是临时路径,也可以是互联网上可以访问的图片路径。而cloudPath则是图片上传之后所在的路径,这个打开云存储之后就可以查看到了。要注意wx.uploadFile是一个异步接口,如果不使用同步操作的话可能会造成数据不匹配的问题。所以本人在这里使用的Promise的风格进行异步转同步处理,这样就可以保证每一张图片都可以上传到云存储,同时在后面上传数据库时fileid的内容不是空的(如果没有经过同步处理,很有可能出现数据库上传数据时fileid'还没有返回或者返回了几个,剩下的图片还没有上传成功,那么对应的数据项自然就是空的或者不完整的)。在每一个图片上传成功后都会返回一个fileID,通过这个我们就可以访问已经存储的图片或者其他文件了。剩下的就是将fileID存储到云数据库或者自己的数据库中,这个就不再赘述了。
imageupLoad(tempFilePath) {
return new Promise((resolve, reject) => {
wx.cloud.uploadFile({
cloudPath: 'images/' + Date.now() + '-' + Math.floor(Math.random() * 1000) + '.png',
filePath: tempFilePath,
success: uploadRes => {
// console.log('上传成功,文件ID为:', uploadRes.fileID);
urls.push(uploadRes.fileID)
resolve(uploadRes.fileID);
},
fail: err => {
reject(err);
}
});
});
},
async execImage() {
if(!this.imageUrl){
//console.log("没有图片")
return
}
try {
// 假设 this.imageNum 和 this.imageUrl 已正确定义和赋值
for (var i of this.imageUrl){
await this.imageupLoad(i);
}
this.data.fileid = urls;
// console.log('所有文件上传完成,fileid:', this.data.fileid);
// 将 fileid 和其他信息保存到云数据库
// 您可以在此处编写保存到数据库的逻辑
} catch (err) {
// console.error('执行图片上传出错:', err);
// 在出错情况下可能需要处理失败的逻辑
}
},
这个就是显示的效果图,当然由于云服务自身的限制,在存储大量的数据之后这样的来回访问有点慢,开源使用微信的缓存来加快页面的加载。
在这里本人踩了很多坑:一个是接口,当初不知道看了哪篇博文,说从云数据库中获取到fileid时,还需要从云存储中通过fileID下载图片到本地才能访问,虽然这种方法理论上可行,但是耗时极大,即使图片的存储量不大,也会有很明显的延迟,甚至图片加载不出来(这个可能是同步性的问题)。其次就是同步和异步过程没有搞明白,有机会出一篇文章来讲一下这个同步和异步过程。