调用文件系统对象

第一步封装 uploadFile 组件

组件放到 components 文件夹

<template>
	<view v-if="show" class='t-toptips' :style="{top: top,background: cubgColor}" :class="[show?'t-top-show':'']">
		<view v-if="loading" class="flex flex-sub">
			<view class="cu-progress flex-sub round striped active sm">
				<view :style="{ background: color,width: value + '%'}"></view>
			</view>
			<text class="margin-left">{{value}}%</text>
		</view>
		<block v-else>{{msg}}</block>
		
	</view>
</template>

<script>
export default {
	props: {
		top: {
			type: String,
			default: 'auto'
		},
		bgColor: {
			type: String,
			default: 'rgba(49, 126, 243, 0.5)',
		},
		color: {
			type: String,
			default: '#e54d42',
		}
	},
	data() {
		return {
			cubgColor: '',
			loading: false,
			value: 5,
			show: false,
			msg: '执行完毕~',
		}
	},
	methods: {
		toast(title = '',{ duration = 2000, icon = 'none'} = {}) {
			uni.showToast({title,duration,icon});
		},
		getRequest(url) {  
			let theRequest = new Object(); 
			let index = url.indexOf("?");
			if (index != -1) {  
				let str = url.substring(index+1);  
				let strs = str.split("&");  
				for(let i = 0; i < strs.length; i ++) {  
					theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);  
				} 
			}  
			return theRequest;  
		},
		
		/*
			上传说明:
			currentWebview: 当前窗口webview对象
			url:上传接口地址
			name:上传文件key值
			header: 上传接口请求头
			...:body内其他参数
		*/
		appChooseFile({currentWebview,url,name = 'file',header,...formData} = {}) {
			console.log(url,'url')
			// #ifdef APP-PLUS
				let wv = plus.webview.create("","/hybrid/html/index.html",{
					'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
					top: 0,
					height: '100%',
					background: 'transparent'
				},{
					url,
					header,
					formData,
					key: name,
				});
				
				wv.loadURL("/hybrid/html/index.html")
				currentWebview.append(wv);
				wv.overrideUrlLoading({mode:'reject'},(e)=>{
					let {fileName,id} = this.getRequest(e.url);
					fileName = unescape(fileName);
					id = unescape(id);
					let path = unescape(e.url)
					let data = JSON.parse(id);
					return this.onCommit(this.$emit('up-success',{data}));
				});
			// #endif
		},
		wxChooseFile({url,name = 'file',header,...formData} = {}) {
			wx.chooseMessageFile({
				count: 1,
				type: 'file',
				success: ({tempFiles}) => {
					let [{path:filePath,name:fileName}] = tempFiles;
					this.setdefUI();
					
					return uni.uploadFile({
						url,
						name,
						filePath,
						formData,
						header,
						success: (res) => {
							if (res.statusCode==200) {
								let data = JSON.parse(res.data);
								
								//可自行添加后台返回状态验证
								return this.onCommit(this.$emit('up-success',{fileName,data}));
							}
							return this.errorHandler('文件上传失败',this.upErr);
						},
						fail: () => this.errorHandler('文件上传失败',this.upErr)
					});
				},
				fail: () => this.errorHandler('文件选择失败',this.upErr)
			})
		},
		htmlChooseFile({url,name='file',header,...formData}={}){
			let that = this
			var x = document.createElement('input');
			x.setAttribute('type', 'file');
			x.setAttribute('id', 'fileField');
			x.click();
			x.onchange = function() {
				uni.showLoading({
					title:'正在上传'
				})
				let file = this.files[0]
				return uni.uploadFile({
					url,
					name,
					file,
					formData:formData.formData,
					header,
					success: (res) => {
						console.log(JSON.stringify(res));
						if (res.statusCode==200) {
							let data = JSON.parse(res.data);
							uni.hideLoading()
							//可自行添加后台返回状态验证
							return that.onCommit(that.$emit('up-success',{data}));
						}
						uni.hideLoading()
						return that.errorHandler('文件上传失败',that.upErr);
					},
					fail: (error) => {
						uni.hideLoading()
						that.errorHandler('文件上传失败',that.upErr)
					} 
				});
			};
		},
		/* 
		上传
		*/
		upload(param = {}) {
			if (!param.url) {
				this.toast('上传地址不正确');
				uni.hideLoading()
				return;
			}
			
			if (this.loading) {
				this.toast('还有个文件玩命处理中,请稍候..');
				uni.hideLoading()
				return;
			}
			
			//#ifdef H5
				return this.htmlChooseFile(param)
			//#endif
			
			// #ifdef APP-PLUS
				return this.appChooseFile(param);
			// #endif
			
			// #ifdef MP-WEIXIN
				return this.wxChooseFile(param);
			// #endif
		},
		/* 
		打开文件 
		*/
		open(filePath) {
			let system = uni.getSystemInfoSync().platform;
			if(system == 'ios'){
				filePath = encodeURI(filePath);
			}
			uni.openDocument({
				filePath,
				success: (res) => {console.log('打开文档成功');}
			});
		},
		/* 
		下载
		 type: temporary=返回临时地址,local=长期保存到本地
		 */
		download(url,type = 'temporary') {
			if (this.loading) {
				this.toast('还有个文件玩命处理中,请稍候..');
				return;
			}
			this.setdefUI();
			
			return new Promise((resolve,reject)=>{
				let downloadTask = uni.downloadFile({
				    url,
				    success: ({statusCode,tempFilePath}) => {
				        if (statusCode === 200) {
							if (type == 'local') {
								uni.saveFile({
									tempFilePath,
									success:({savedFilePath}) => this.onCommit(resolve(savedFilePath)),
									fail: () => this.errorHandler('下载失败',reject)
								});
							}
							else {
								this.onCommit(resolve(tempFilePath))
							}
						}
					},
					fail: () => this.errorHandler('下载失败',reject)
				});
				
				downloadTask.onProgressUpdate(({progress = 0}) => {
					if (progress <= 100) {
						this.$nextTick(()=>{
							this.value = progress;
						});
					}
				});
			})
			
		},
		
		onCommit(resolve) {
			this.msg = '执行完毕~';
			this.loading = false;
			this.cubgColor = 'rgba(57, 181, 74, 0.5)';
			setTimeout(()=>{this.show = false;},1500);
			return resolve;
		},
		
		setdefUI() {
			this.cubgColor = this.bgColor;
			this.value = 0;
			this.loading = true;
			this.show = true;
		},
		
		upErr(errText) {
			this.$emit('up-error',errText);
		},
		
		errorHandler(errText,reject) {
			this.msg = errText;
			this.loading = false;
			this.cubgColor = 'rgba(229, 77, 66, 0.5)';
			setTimeout(()=>{this.show = false;},1500);
			return reject(errText);
		}
	}
}
</script>

<style scoped>
	.t-toptips {
		width: 100%;
		padding: 18upx 30upx;
		box-sizing: border-box;
		position: fixed;
		z-index: 90;
		color: #fff;
		font-size: 30upx;
		left: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		word-break: break-all;
		opacity: 0;
		transform: translateZ(0) translateY(-100%);
		transition: all 0.3s ease-in-out;
	}
	
	.t-top-show {
		transform: translateZ(0) translateY(0);
		opacity: 1;
	}
	
</style>

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

第二步封装 formFile 组件

组件放到 components 文件夹

<template>
	<view>
		<view class="cu-form-group">
			<view class="header-view">
		
			</view>
			<view class="file-view-add-btn"   @tap="chooseFile">
				{{title}}
		
			</view>
		</view>
		<view class="file-view" v-if="isTip&&fileList && fileList.length > 0">
			<view class="menu" v-for="(item,index) in fileList" :key="index">
				<view class="flex justify-between align-center text-df" style="padding:30rpx 32rpx;">
					<!-- #ifdef H5 -->
				
					<!-- #endif -->
					<view class="text-blue text-cut" style="overflow: hidden;text-overflow: ellipsis;width: 400rpx;"
						@tap="previewFile($event,item.fileUrl)">{{item.originalName}}</view>
					<view class="text-999 text-cut" style="overflow: hidden;text-overflow: ellipsis;">
						<text>{{item.formatSize}}</text>
						<text style="padding-left: 20rpx;" @tap="deleteFile($event,item.ossId, index)">删除</text>
					</view>
				</view>
			</view>
		</view>
		<uploadFile ref="loadFileView" @up-success="onSuccess" style="margin-top: 120rpx;">
			
		</uploadFile>
	</view>
</template>

<script>

	// 引入配置
	import {removeFiles} from '@/api/modules/system.js'
	import {baseUrl} from '@/common/config'
	export default {
		model: {
		  prop: 'value',
		  event: 'change',
		},
		props: {
			icon:{
				type: String,
					default:"cuIcon-add"
			},
			isTip:{
				type: Boolean,
					default:true
			},
			title: {
				type: String,
					default:""
			},
			value: {
				type: [String,Array],
				default:()=>[]
			},
			module:{
					type: String,
					default:""
			},
			moduleId:{
					type: String,
					default:""
			},
			
		},
		data() {
			return {
				fileList:[]
			}
		},
		watch:{
			value:{
				handler(val){
					if(typeof val == 'object'){
						this.fileList=val
						// this.$emit('change', this.fileList.map(v => v.id).toString())
					}
				},
				 immediate: true
			}
		},
		methods: {
			//选择文件
			chooseFile() {
				this.$refs.loadFileView.upload({
					// #ifdef APP-PLUS
					currentWebview: this.$mp.page.$getAppWebview(),
					// #endif
					url:baseUrl + 'oss/upload/public',
					name: 'uploadFile',
					header: {
						"Authorization": uni.getStorageSync('token'),
					// 'X-Requested-With': 'XMLHttpRequest',
					// "Accept": "application/x-www-form-urlencoded; charset=UTF-8",
					},
					formData: {
						module: this.module,
						moduleId:this.moduleId
					},
				});
			},
			//文件上传回调
			onSuccess(res) {
				let data =  res.data.data
				console.log(res.data);
					if(res.data.code==200){
						this.fileList = this.fileList.concat(data)
						this.$emit('change', this.fileList)
					}
					
	
				// this.getFileById(res.data.data.id)
			},
			getFileById(id) {
				// let req = {
				// 	id: id
				// }
				// api.getFileById(req).then(response => {
				// 	this.fileList.push(response.data)
				// 	this.fileList.forEach(v => {
				// 		v.formatSize = this.$mHelper.bytesToSize(v.size)
				// 	})
				// 	this.$emit('change', this.fileList.map(v => v.id).toString())
				// })
			},
			//预览文件
			previewFile(e, path) {
				//如果是图片,用previewImage预览
				if (this.checkImgType(path)) {
					let urls = [path]
					uni.previewImage({
						urls: urls
					});
				} else { //如果是文件,分平台处理
					//#ifdef APP-PLUS
					uni.downloadFile({
						url: path,
						success: (res) => {
							var filePath = res.tempFilePath;
							if (uni.getSystemInfoSync().platform == 'android') {
								uni.showModal({
									content: '文件已保存在:' + filePath,
								})
							} //ios可在当前应用内打开;Android调用系统相关应用打开,无相关应用则不能打开
							uni.openDocument({
								filePath: filePath,
								success: function(res1) {
									console.log('openDocumentsuccess:' + JSON.stringify(res1));
								},
								fail: function(err) {
									console.log('openDocumentfail:' + JSON.stringify(err));
								}
							});
						},
						fail: function(res) {
							console.log('fail:' + JSON.stringify(res));
						}
					});
					//#endif
					//#ifdef H5
					// console.log('sssssss:' +path);
					// let ele = document.createElement('a')
					//      ele.style.display = 'none'
					//      ele.href = path
					//      document.body.appendChild(ele)
					//      ele.click()
					//      // document.body.removeChild(ele)
					// 	 console.log('aaaaaaaa:' +path);
					uni.navigateTo({
		
						url: '../iframe/index?url=' + path
					})
					//#endif
				}
			},
			//删除文件
			deleteFile(e, id, index) {
				let that = this
				uni.showModal({
					content: '确认要删除该附件?',
					success: (res) =>{
						removeFiles([id]).then((res) => {
																uni.showToast({
																	icon: 'none',
																	title: "删除成功"
																})
						     this.fileList.splice(index, 1)
						     this.$emit('change', this.fileList)
						   })
					}
				})
			},
			//判断是否是图片
			checkImgType(file) {
				if (!/\.(jpg|jpeg|png|GIF|JPG|PNG)$/.test(file)) {
					return false;
				} else {
					return true;
				}
			}
		}
	}
</script>

<style scoped>
	.file-view {
		background: #F5F8FF;
		border-radius: 6rpx;
	}
	.file-view-add-btn {
			width: 120rpx;
			height: 52rpx;
			background: #0061BC;
			text-align: center;
			line-height: 52rpx;
			font-size: 26rpx;
			border-radius: 4px;
			color: #FFFFFF;
		}
</style>

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

第三步引入hybrid 文件夹 放到uniapp根目录

hybrid 地址

使用案例

	<formFile title="选择文件"  module="product"
				  v-model="item.ossDo"
				 />
1
2
3