如何使用阿里云OSS上传图片uview

585 阅读1分钟

效果

image.png

我这里是在request.js中封装的一个总的请求方法,由于在main.js全局引入了,所以可以在每个文件中直接使用this.$http.ossUpload(file,obj)

ossUpload(file,obj){
		let filePath=file.url;
		var pos = (file.url).lastIndexOf('.')
		var suffix = ''
		if (pos !== -1) {
			suffix = (file.url).substring(pos)
		}
		var filename = new Date().getTime()+suffix
		let key = obj.dir+filename
		return uni.uploadFile({
			url: obj.host, //阿里云的存储地址,可以后端返回给你,也可以前端自己写上
			filePath, //要上传的临时文件路径
			name: 'file',
			formData: {
				key, //文件名
				accessid:obj.accessid,
				policy: obj.policy, //后台获取超时时间
				OSSAccessKeyId: obj.accessid, //后台获取临时ID
				success_action_status: '200', //让服务端返回200,不然,默认会返回204
				signature: obj.signature //后台获取签名
			}
		}).then(data=>{
			console.log(data)
			console.log(obj)
			const [error,res] = data;
			if(res.statusCode !== 200) {
				console.log('error',res);
				uni.showToast({
					title:'数据异常',
					icon:'none'
				})
				return;
			}
			res.data={
				url:obj.host + '/' + obj.dir + filename
			}
			console.log(res)
			return response(res.data);
		}).catch(err=>{
			console.log('错误:',err)
		})
	},

image.png

这里file应该传入的格式是这样的,obj是后端给的一个接口返回的对象,从而拿到上传阿里云需要的签名

image.png

image.png 在页面使用如下:

image.png

image.png

// 读取图片后的处理函数
		afterRead(file) {
			file.file.map(val => {
				if (val.size > 52428800) {
					uni.showToast({
						title: '图片大小不能超过50M',
						icon: 'none'
					});
					return;
				}
				if (val.size > 5242880) {
					uni.showLoading({
						title: '图片压缩中...'
					});
					uni.compressImage({
						src: val.url,
						quality: 10,
						width: '50%',
						height: '50%',
						success: res => {
							this.uploadImg(res.tempFilePath);
						}
					});
				} else {
					this.uploadImg(val.url, val, file); //file
				}
			});
		},
		uploadImg(url, val, file) {
			uni.showLoading({
				title: '图片上传中...'
			});
			this.$http.get('/common/oss/ali-oss-sign').then(res => {
				this.$http.ossUpload(val, res.data).then(res=>{
					uni.hideLoading();
					let obj = { url: res.url }
					switch (file.name){
						case 'application_form':
							this.fileList.push({ ...obj })
							break;
						case 'economic_group':
							this.fileList2.push({ ...obj })
							break;
						case 'id_holder':
							this.fileList3.push({ ...obj })
							break;
						case 'family_id_holder':
							this.fileList4.push({ ...obj })
							break;
						case 'commitment':
							this.fileList5.push({ ...obj })
							break;
						case 'design':
							this.fileList6.push({ ...obj })
							break;
						default:
							break;
					}
				})
			})
		},
		deleteImg(event) {
			let index = event.index
			switch (event.name){
				case 'application_form':
					this.fileList.splice(index, 1);
					break;
				case 'economic_group':
					this.fileList2.splice(index, 1);
					break;
				case 'id_holder':
					this.fileList3.splice(index, 1);
					break;
				case 'family_id_holder':
					this.fileList4.splice(index, 1);
					break;
				case 'commitment':
					this.fileList5.splice(index, 1);
					break;
				case 'design':
					this.fileList6.splice(index, 1);
					break;
				default:
					break;
			}
		},

以上是最主要的代码,下面是所有代码:

<template>
	<view class="Sign">
		<view class="top-box">
			<view class="form-box">
				<view class="form-item d_flex a_c">
					<view class="label d_flex a_c">
						户主姓名
						<view class="req red">*</view>
					</view>
					<view class="int flex">
						<input class="flex" style="width:100%" v-model="form.holder_name" type="text" placeholder="请输入户主姓名" />
					</view>
				</view>
				<view class="form-item d_flex a_c">
					<view class="label d_flex a_c">
						联系方式
						<view class="req red">*</view>
					</view>
					<view class="int flex"><input class="flex" v-model="form.mobile" maxlength="11" type="number" placeholder="请输入联系方式" /></view>
				</view>
				<view class="form-item d_flex a_c" @click="show = true" >
					<view class="label d_flex a_c">
						村组
						<view class="req red">*</view>
					</view>
					<view class="int flex">
						<view class="city-box" v-if="fieldValue">{{fieldValue}}</view>
						<view class="city-box" style="color: rgb(128, 128, 128);" v-else>点击选择</view>
					</view>
					<text class="iconfont icon-xiangyou"></text>
				</view>
				<view class="form-item d_flex a_c">
					<view class="label d_flex a_c">
						地址信息
						<view class="req red">*</view>
					</view>
					<view class="int flex">
						<input class="flex" style="width:100%" v-model="form.address" type="text" placeholder="请输入地址信息" />
					</view>
				</view>
				<view class="form-item d_flex remark">
					<view class="label a_c">
						<view style="padding-top: 18rpx;">
							备注
						</view>
					</view>
					<view class="readme-input">
						<textarea v-model="form.readme" @input="changName" maxlength="200" type="text" placeholder="请输入备注"></textarea>
					</view>
				</view>
			</view>
		</view>
		<view class="image-all">
			<view class="sub-tit">
				<view class="label d_flex a_c">
					申请表
					<view class="req red">*</view>
				</view>
				<!-- <text>(最多3张) :maxCount="3"</text> -->
			</view>
			<view class="bg-upload">
				<view class="upload">
					<u-upload 
						:fileList="fileList" 
						@afterRead="afterRead" 
						@delete="deleteImg" 
						name="application_form" 
						multiple 
						:previewFullImage="true" 
						:maxCount="3"
					></u-upload>
					<!-- <view style="font-size:20rpx;color:#777">单张图片大小不能超过10M</view> -->
				</view>
			</view>
			<view class="sub-tit">
				<view class="label d_flex a_c">
					集体经济组认证
					<view class="req red">*</view>
				</view>
			</view>
			<view class="bg-upload">
				<view class="upload">
					<u-upload 
						:fileList="fileList2" 
						@afterRead="afterRead" 
						@delete="deleteImg" 
						name="economic_group" 
						multiple 
						:previewFullImage="true"
						:maxCount="3"
					></u-upload>
				</view>
			</view>
			<view class="sub-tit">
				<view class="label d_flex a_c">
					户主身份证户口本
					<view class="req red">*</view>
				</view>
			</view>
			<view class="bg-upload">
				<view class="upload">
					<u-upload 
						:fileList="fileList3" 
						@afterRead="afterRead"
						@delete="deleteImg" 
						name="id_holder" 
						multiple 
						:previewFullImage="true"
						:maxCount="3"
					></u-upload>
				</view>
			</view>
			<view class="sub-tit">
				<view class="label d_flex a_c">
					家庭成员身份证户口本
					<view class="req red">*</view>
				</view>
			</view>
			<view class="bg-upload">
				<view class="upload">
					<u-upload 
						:fileList="fileList4" 
						@afterRead="afterRead" 
						@delete="deleteImg" 
						name="family_id_holder" 
						multiple 
						:previewFullImage="true"
						:maxCount="20"
					></u-upload>
				</view>
			</view>
			<view class="sub-tit">
				<view class="label d_flex a_c">
					承诺书
					<view class="req red">*</view>
				</view>
			</view>
			<view class="bg-upload">
				<view class="upload">
					<u-upload 
						:fileList="fileList5" 
						@afterRead="afterRead" 
						@delete="deleteImg" 
						name="commitment" 
						multiple 
						:previewFullImage="true"
						:maxCount="3"
					></u-upload>
				</view>
			</view>
			<view class="sub-tit">
				<view class="label d_flex a_c">
					设计效果图
					<view class="req red">*</view>
				</view>
			</view>
			<view class="bg-upload bottom">
				<view class="upload">
					<u-upload 
						:fileList="fileList6" 
						@afterRead="afterRead" 
						@delete="deleteImg" 
						name="design" 
						multiple 
						:previewFullImage="true"
						:maxCount="3"
					></u-upload>
				</view>
			</view>
		</view>
		<u-picker 
			title="请选择村组" 
			:show="show" 
			ref="uPicker" 
			:columns="options" 
			@confirm="confirm" 
			@change="changeHandler"
			@cancel="cancel"
			immediateChange
			keyName="name"
		></u-picker>
		<view class="btn-pandding">
			<view class="submit-button" @click="$noMultipleClicks(submit)">提交</view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			noClick:true,
			show: false,
			id: '',
			form: {
				holder_name: '',
				mobile: '',
				village_id: '',
				group_id: '',
				address: '',
				readme: ''
			},
			fieldValue: '',//村组展示数据
			pid: '1',
			options: [],//村组数据
			groupData: [],
			fileList: [],
			fileList2: [],
			fileList3: [],
			fileList4: [],
			fileList5: [],
			fileList6: [],
		};
	},
	onLoad(options) {
		this.id = options.id;
		this.getcList();
	},
	methods: {
		changName(e) {
			e.target.value = e.target.value.replace(/[^\u4E00-\u9FA5|\d|\a-zA-Z|\r\n\s,.?!,。?!…—&$=()-+/*{}[\]]/g, '')
			//重新赋值给input
			this.$nextTick(() => {
			  this.readme = e.target.value;
			});
		},
		//获取村组信息
		async getcList() {
			//一开始展示0和1的村组数据
			this.getGroup(0)
			this.getGroup(1)
		},
		// 实现村组多列联动
		async getGroup(pid) {
			this.options[0] = []
			this.options[1] = []
			let res = await this.$http.get('/house/villages', {
				pid: pid
			})
			if(res.code == 0) {
				if(pid == 0) {
					this.options[0] = res.data
				} else if(pid == 1) {
					this.options[1] = res.data
				} else {
					this.options[1] = res.data
				}
			}
		},
		async changeHandler(e) {
			const {
				columnIndex,
				value,
				values, // values为当前变化列的数组内容
				index,
				picker = this.$refs.uPicker
			} = e
			await this.getGroup(e.value[0].id)
			//当第一列值发生变化时,变化第二列(后一列)对应的选项
			uni.$u.sleep(100).then(() => {
				picker.setColumnValues(1, this.options[1]);
			});
		},
		// 回调参数为包含columnIndex、value、values
		confirm(e) {
			this.fieldValue = e.value[0].name + '/' + e.value[1].name
			this.form.village_id = e.value[0].id;
			this.form.group_id = e.value[1].id;
			this.getGroup(0)
			this.getGroup(1)
			this.show = false
		},
		cancel() {
			this.getGroup(0)
			this.getGroup(1)
			this.show = false
		},
		// 读取图片后的处理函数
		afterRead(file) {
			file.file.map(val => {
				if (val.size > 52428800) {
					uni.showToast({
						title: '图片大小不能超过50M',
						icon: 'none'
					});
					return;
				}
				if (val.size > 5242880) {
					uni.showLoading({
						title: '图片压缩中...'
					});
					uni.compressImage({
						src: val.url,
						quality: 10,
						width: '50%',
						height: '50%',
						success: res => {
							this.uploadImg(res.tempFilePath);
						}
					});
				} else {
					this.uploadImg(val.url, val, file); //file
				}
			});
		},
		uploadImg(url, val, file) {
			uni.showLoading({
				title: '图片上传中...'
			});
			this.$http.get('/common/oss/ali-oss-sign').then(res => {
				this.$http.ossUpload(val, res.data).then(res=>{
					uni.hideLoading();
					let obj = { url: res.url }
					switch (file.name){
						case 'application_form':
							this.fileList.push({ ...obj })
							break;
						case 'economic_group':
							this.fileList2.push({ ...obj })
							break;
						case 'id_holder':
							this.fileList3.push({ ...obj })
							break;
						case 'family_id_holder':
							this.fileList4.push({ ...obj })
							break;
						case 'commitment':
							this.fileList5.push({ ...obj })
							break;
						case 'design':
							this.fileList6.push({ ...obj })
							break;
						default:
							break;
					}
				})
			})
		},
		deleteImg(event) {
			let index = event.index
			switch (event.name){
				case 'application_form':
					this.fileList.splice(index, 1);
					break;
				case 'economic_group':
					this.fileList2.splice(index, 1);
					break;
				case 'id_holder':
					this.fileList3.splice(index, 1);
					break;
				case 'family_id_holder':
					this.fileList4.splice(index, 1);
					break;
				case 'commitment':
					this.fileList5.splice(index, 1);
					break;
				case 'design':
					this.fileList6.splice(index, 1);
					break;
				default:
					break;
			}
		},
		//表单提交
		async submit() {
			let data = { ...this.form };
			if (!this.form.holder_name) {
				uni.showToast({
					title: '请输入户主姓名',
					icon: 'none'
				});
				return;
			}
			if (!this.form.mobile) {
				uni.showToast({
					title: '请输入联系方式',
					icon: 'none'
				});
				return;
			}
			if (!this.fieldValue) {
				uni.showToast({
					title: '请选择村组',
					icon: 'none'
				});
				return;
			}
			if (!this.form.address) {
				uni.showToast({
					title: '请输入地址信息',
					icon: 'none'
				});
				return;
			}
			if (this.fileList.length == 0) {
				uni.showToast({
					title: '请上传申请表',
					icon: 'none'
				});
				return;
			}
			if (this.fileList2.length == 0) {
				uni.showToast({
					title: '请上传集体经济组认证',
					icon: 'none'
				});
				return;
			}
			if (this.fileList3.length == 0) {
				uni.showToast({
					title: '请上传户主身份证户口本',
					icon: 'none'
				});
				return;
			}
			if (this.fileList4.length == 0) {
				uni.showToast({
					title: '请上传家庭成员身份证户口本',
					icon: 'none'
				});
				return;
			}
			if (this.fileList5.length == 0) {
				uni.showToast({
					title: '请上传承诺书',
					icon: 'none'
				});
				return;
			}
			if (this.fileList6.length == 0) {
				uni.showToast({
					title: '请上传设计效果图',
					icon: 'none'
				});
				return;
			}
			let imageList = {
				application_form: JSON.stringify(this.fileList),
				economic_group: JSON.stringify(this.fileList2),
				id_holder: JSON.stringify(this.fileList3),
				family_id_holder: JSON.stringify(this.fileList4),
				commitment: JSON.stringify(this.fileList5),
				design: JSON.stringify(this.fileList6),
			}
			let res = await this.$http.post('/house/build-house/registered', {...data, ...imageList})
			if (res.code == 0) {
				uni.showToast({
					title: res.msg
				});
				setTimeout(() => {
					uni.reLaunch({
						url: '/pages/index/index'
					});
				}, 1000);
			} else {
				uni.showToast({
					title:res.msg,
					icon:'none'
				})
			}
		},
		
	}
};
</script>