logo头像

技术是一种信念

小程序多文件上传

在开发小程序,我们会开发一些意见反馈等等的接口,需要用户去上传图片来说明具体的情况。小程序为我们提供了文件上传的接口,但是一次只能上传一个文件,这样如果需要上传多个文件的时候对于用户的体验是非常不好的,如果解决呢?

文件上传页面

在文件上传页面中定义图片上传的按钮,以及图片选择之后的回显。

  • 页面内容
1
2
3
4
5
6
7
8
9
10
......
<view class="action-photo">
<block wx:for="{{picUrls}}" wx:key="{{item}}" wx:index="{{index}}">
<image src="{{item}}">
<icon type="cancel" data-index="{{index}}" color="red" size="18" class="del" bindtap="delPic" />
</image>
</block>
<text class="add" bindtap="bindCamera">{{actionText}}</text>
</view>
......
  • 页面样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.action-photo {
background-color: #fff;
padding: 10rpx 0px 30rpx 50rpx;
}
.action-photo image {
position: relative;
display: inline-block;
width: 120rpx;
height: 120rpx;
overflow: visible;
margin-left: 25rpx;
}
.action-photo image icon.del {
display: block;
position: absolute;
top: -20rpx;
right: -20rpx;
}
.action-photo text.add {
display: inline-block;
width: 120rpx;
height: 120rpx;
line-height: 120rpx;
text-align: center;
font-size: 24rpx;
color: #ccc;
border: 2rpx dotted #ccc;
/* margin-left: 25rpx; */
vertical-align: top;
}
  • 页面效果如下:

avatar

初始化相关值

1
2
3
4
data: {
picUrls: [], // 故障图路径数组
actionText: "拍照/相册", // 选取图片提示
}

选择图片

选择图片使用的是小程序中wx.chooseImage(Object),从本地相册选择图片或使用相机拍照。详情参见wx.chooseImage API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//拍照或选择相册,这里限制用户只能上传4张图片
bindCamera: function() {
wx.chooseImage({
count: 4,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
let tfps = res.tempFilePaths;
this.setData({
picUrls: tfps,
actionText: "+"
});
}
})
},

删除图片

1
2
3
4
5
6
7
8
9
// 删除选择的图片
delPic: function(e) {
let index = e.target.dataset.index;
let _picUrls = this.data.picUrls;
_picUrls.splice(index, 1);
this.setData({
picUrls: _picUrls
})
},

文件上传

小程序的文件上传方法只能支持单张图片上传,详情参考文件上传API 。如何实现多文件上传呢?此处使用的是递归的方法,其实本质上还是一张一张的上传,只是对于用户来说看起来像是一起上传的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 多文件上传函数
uploadFiles(filePaths, successUp, failUp, i, length) {
wx.uploadFile({
url: app.globalData.baseUrl + "/Example/bas/api/fapi0020_uploadfile.st?rkspAutoComplete=true",
filePath: filePaths[i],
name: 'file',
formData: {
'problemId': this.data.problemId,
'userId': wx.getStorageSync('userInfo').userid
},
success: (resp) => {
successUp++;
},
fail: (res) => {
failUp++;
},
complete: () => {
i++;
if (i == length) {
console.log('总共' + successUp + '张上传成功,' + failUp + '张上传失败!');
wx.showToast({
title: '操作成功',
})
wx.hideLoading();
} else { //递归调用uploadFiles函数
this.uploadFiles(filePaths, successUp, failUp, i, length);
}
},
});
}

调用

在具体的提交方法中调用文件上传函数

1
2
3
4
5
let length = this.data.picUrls.length; //总共个数
let successUp = 0; //成功个数
let failUp = 0; //失败个数
let i = 0; //第几个
this.uploadFiles(this.data.picUrls, successUp, failUp, i, length);