xydata-tools 1.1.28 → 1.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
<!-- 自定义上传按钮插槽 -->
|
|
21
21
|
<slot name="upload-button" :select="selectAndUploadFile" :count="fileList.length">
|
|
22
22
|
<!-- 默认上传按钮 -->
|
|
23
|
-
<button class="upload-btn" v-if="fileList.length < limit && !uploading"
|
|
24
|
-
@click="selectAndUploadFile">
|
|
23
|
+
<button class="upload-btn" v-if="fileList.length < limit && !uploading" @click="selectAndUploadFile">
|
|
25
24
|
{{ buttonTitle }}
|
|
26
25
|
</button>
|
|
27
26
|
</slot>
|
|
@@ -37,9 +36,7 @@
|
|
|
37
36
|
</view>
|
|
38
37
|
</view>
|
|
39
38
|
<view class="file-actions">
|
|
40
|
-
<view class="action-btn delete-btn" @click="removeFile(index)">
|
|
41
|
-
×
|
|
42
|
-
</view>
|
|
39
|
+
<view class="action-btn delete-btn" @click="removeFile(index)"> × </view>
|
|
43
40
|
</view>
|
|
44
41
|
</view>
|
|
45
42
|
</view>
|
|
@@ -62,17 +59,33 @@
|
|
|
62
59
|
</template>
|
|
63
60
|
|
|
64
61
|
<script>
|
|
65
|
-
import msWord from '../../../assets/file-icon/ms-word.png'
|
|
66
|
-
import msExcel from '../../../assets/file-icon/ms-excel.png'
|
|
67
|
-
import msPowerpoint from '../../../assets/file-icon/ms-powerpoint.png'
|
|
68
|
-
import pdfIcon from '../../../assets/file-icon/pdf.png'
|
|
69
|
-
import imageIcon from '../../../assets/file-icon/image.png'
|
|
70
|
-
import videoIcon from '../../../assets/file-icon/video.png'
|
|
71
|
-
import documentIcon from '../../../assets/file-icon/document.png'
|
|
72
|
-
import zipIcon from '../../../assets/file-icon/zip.png'
|
|
62
|
+
import msWord from '../../../assets/file-icon/ms-word.png';
|
|
63
|
+
import msExcel from '../../../assets/file-icon/ms-excel.png';
|
|
64
|
+
import msPowerpoint from '../../../assets/file-icon/ms-powerpoint.png';
|
|
65
|
+
import pdfIcon from '../../../assets/file-icon/pdf.png';
|
|
66
|
+
import imageIcon from '../../../assets/file-icon/image.png';
|
|
67
|
+
import videoIcon from '../../../assets/file-icon/video.png';
|
|
68
|
+
import documentIcon from '../../../assets/file-icon/document.png';
|
|
69
|
+
import zipIcon from '../../../assets/file-icon/zip.png';
|
|
70
|
+
|
|
73
71
|
export default {
|
|
74
72
|
name: 'FilePicker',
|
|
73
|
+
// #ifdef VUE3
|
|
74
|
+
emits: ['change', 'update:modelValue', 'fileLimitReached', 'fileTypeInvalid', 'fileSizeExceed', 'uploadSuccess', 'uploadFail', 'progress', 'click'],
|
|
75
|
+
// #endif
|
|
75
76
|
props: {
|
|
77
|
+
// #ifdef VUE3
|
|
78
|
+
modelValue: {
|
|
79
|
+
type: Array,
|
|
80
|
+
default: () => []
|
|
81
|
+
},
|
|
82
|
+
// #endif
|
|
83
|
+
// #ifndef VUE3
|
|
84
|
+
value: {
|
|
85
|
+
type: Array,
|
|
86
|
+
default: () => []
|
|
87
|
+
},
|
|
88
|
+
// #endif
|
|
76
89
|
/** 上传地址 */
|
|
77
90
|
uploadUrl: {
|
|
78
91
|
type: String,
|
|
@@ -83,7 +96,7 @@ export default {
|
|
|
83
96
|
type: Boolean,
|
|
84
97
|
default: false
|
|
85
98
|
},
|
|
86
|
-
/** 文件列表 */
|
|
99
|
+
/** 文件列表(兼容非v-model用法) */
|
|
87
100
|
files: {
|
|
88
101
|
type: Array,
|
|
89
102
|
default: () => []
|
|
@@ -96,7 +109,7 @@ export default {
|
|
|
96
109
|
/** 允许的文件扩展名 */
|
|
97
110
|
accept: {
|
|
98
111
|
type: Array,
|
|
99
|
-
default: () => ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx']
|
|
112
|
+
default: () => ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx', 'zip', 'rar', 'png', 'jpg']
|
|
100
113
|
},
|
|
101
114
|
/** 文件大小限制(MB) */
|
|
102
115
|
maxSize: {
|
|
@@ -114,34 +127,47 @@ export default {
|
|
|
114
127
|
fileList: [],
|
|
115
128
|
uploading: false,
|
|
116
129
|
uploadProgress: 0,
|
|
117
|
-
actualUploadUrl: ''
|
|
118
|
-
}
|
|
130
|
+
actualUploadUrl: '' // 实际使用的上传地址
|
|
131
|
+
};
|
|
119
132
|
},
|
|
120
133
|
computed: {
|
|
121
134
|
// 判断是否为H5环境
|
|
122
135
|
isH5() {
|
|
123
136
|
// #ifdef H5
|
|
124
|
-
return true
|
|
137
|
+
return true;
|
|
125
138
|
// #endif
|
|
126
139
|
// #ifndef H5
|
|
127
|
-
return false
|
|
140
|
+
return false;
|
|
128
141
|
// #endif
|
|
129
142
|
},
|
|
130
143
|
/** 实际使用的上传地址 */
|
|
131
144
|
finalUploadUrl() {
|
|
132
|
-
return this.actualUploadUrl || this.uploadUrl || (getApp().globalData && getApp().globalData.uploadUrl) || ''
|
|
145
|
+
return this.actualUploadUrl || this.uploadUrl || (getApp().globalData && getApp().globalData.uploadUrl) || '';
|
|
146
|
+
},
|
|
147
|
+
/** 统一读取外部值 */
|
|
148
|
+
internalValue() {
|
|
149
|
+
// #ifdef VUE3
|
|
150
|
+
return this.modelValue && this.modelValue.length ? this.modelValue : this.files;
|
|
151
|
+
// #endif
|
|
152
|
+
// #ifndef VUE3
|
|
153
|
+
return this.value && this.value.length ? this.value : this.files;
|
|
154
|
+
// #endif
|
|
133
155
|
}
|
|
134
156
|
},
|
|
135
157
|
watch: {
|
|
136
|
-
|
|
137
|
-
|
|
158
|
+
internalValue: {
|
|
159
|
+
handler(val) {
|
|
160
|
+
this.fileList = val || [];
|
|
161
|
+
},
|
|
162
|
+
deep: true,
|
|
163
|
+
immediate: true
|
|
138
164
|
}
|
|
139
165
|
},
|
|
140
166
|
mounted() {
|
|
141
|
-
this.fileList = this.
|
|
167
|
+
this.fileList = this.internalValue || [];
|
|
142
168
|
// 初始化上传地址
|
|
143
169
|
if (!this.uploadUrl) {
|
|
144
|
-
this.actualUploadUrl = (getApp().globalData && getApp().globalData.uploadUrl) || ''
|
|
170
|
+
this.actualUploadUrl = (getApp().globalData && getApp().globalData.uploadUrl) || '';
|
|
145
171
|
}
|
|
146
172
|
},
|
|
147
173
|
methods: {
|
|
@@ -152,7 +178,13 @@ export default {
|
|
|
152
178
|
* @returns {Boolean} - 是否被监听
|
|
153
179
|
*/
|
|
154
180
|
hasEventListener(eventName) {
|
|
155
|
-
|
|
181
|
+
// #ifdef VUE3
|
|
182
|
+
const onEventName = 'on' + eventName.charAt(0).toUpperCase() + eventName.slice(1);
|
|
183
|
+
return !!(this.$attrs[eventName] || this.$attrs[onEventName]);
|
|
184
|
+
// #endif
|
|
185
|
+
// #ifndef VUE3
|
|
186
|
+
return !!(this.$listeners && this.$listeners[eventName]);
|
|
187
|
+
// #endif
|
|
156
188
|
},
|
|
157
189
|
|
|
158
190
|
// ==================== 文件处理方法 ====================
|
|
@@ -160,33 +192,33 @@ export default {
|
|
|
160
192
|
* 获取文件扩展名
|
|
161
193
|
*/
|
|
162
194
|
getFileExtension(fileName) {
|
|
163
|
-
if (!fileName) return ''
|
|
164
|
-
const parts = fileName.split('.')
|
|
165
|
-
return parts.length > 1 ? parts.pop().toLowerCase() : ''
|
|
195
|
+
if (!fileName) return '';
|
|
196
|
+
const parts = fileName.split('.');
|
|
197
|
+
return parts.length > 1 ? parts.pop().toLowerCase() : '';
|
|
166
198
|
},
|
|
167
199
|
|
|
168
200
|
/**
|
|
169
201
|
* 获取文件图标
|
|
170
202
|
*/
|
|
171
203
|
getFileIcon(fileName) {
|
|
172
|
-
const ext = this.getFileExtension(fileName)
|
|
204
|
+
const ext = this.getFileExtension(fileName);
|
|
173
205
|
switch (ext) {
|
|
174
206
|
case 'doc':
|
|
175
207
|
case 'docx':
|
|
176
|
-
return msWord
|
|
208
|
+
return msWord;
|
|
177
209
|
case 'xls':
|
|
178
210
|
case 'xlsx':
|
|
179
|
-
return msExcel
|
|
211
|
+
return msExcel;
|
|
180
212
|
case 'ppt':
|
|
181
213
|
case 'pptx':
|
|
182
|
-
return msPowerpoint
|
|
214
|
+
return msPowerpoint;
|
|
183
215
|
case 'pdf':
|
|
184
|
-
return pdfIcon
|
|
216
|
+
return pdfIcon;
|
|
185
217
|
case 'png':
|
|
186
218
|
case 'jpeg':
|
|
187
219
|
case 'jpg':
|
|
188
220
|
case 'gif':
|
|
189
|
-
return imageIcon
|
|
221
|
+
return imageIcon;
|
|
190
222
|
case 'mp4':
|
|
191
223
|
case 'mov':
|
|
192
224
|
case 'avi':
|
|
@@ -197,13 +229,13 @@ export default {
|
|
|
197
229
|
case 'mpg':
|
|
198
230
|
case 'mpeg':
|
|
199
231
|
case 'm4v':
|
|
200
|
-
return videoIcon
|
|
232
|
+
return videoIcon;
|
|
201
233
|
case 'rar':
|
|
202
234
|
case 'zip':
|
|
203
235
|
case '7z':
|
|
204
|
-
return zipIcon
|
|
236
|
+
return zipIcon;
|
|
205
237
|
default:
|
|
206
|
-
return documentIcon
|
|
238
|
+
return documentIcon;
|
|
207
239
|
}
|
|
208
240
|
},
|
|
209
241
|
|
|
@@ -211,10 +243,10 @@ export default {
|
|
|
211
243
|
* 格式化文件大小
|
|
212
244
|
*/
|
|
213
245
|
formatFileSize(bytes) {
|
|
214
|
-
if (!bytes) return ''
|
|
215
|
-
if (bytes < 1024) return bytes + 'B'
|
|
216
|
-
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + 'KB'
|
|
217
|
-
return (bytes / (1024 * 1024)).toFixed(2) + 'MB'
|
|
246
|
+
if (!bytes) return '';
|
|
247
|
+
if (bytes < 1024) return bytes + 'B';
|
|
248
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + 'KB';
|
|
249
|
+
return (bytes / (1024 * 1024)).toFixed(2) + 'MB';
|
|
218
250
|
},
|
|
219
251
|
|
|
220
252
|
/**
|
|
@@ -225,57 +257,44 @@ export default {
|
|
|
225
257
|
uni.showToast({
|
|
226
258
|
title: '请先配置上传地址',
|
|
227
259
|
icon: 'none'
|
|
228
|
-
})
|
|
229
|
-
return
|
|
260
|
+
});
|
|
261
|
+
return;
|
|
230
262
|
}
|
|
231
263
|
|
|
232
264
|
if (this.fileList.length >= this.limit || this.uploading) {
|
|
233
265
|
if (this.fileList.length >= this.limit) {
|
|
234
|
-
// 触发文件数量限制事件
|
|
235
266
|
this.$emit('fileLimitReached', {
|
|
236
267
|
current: this.fileList.length,
|
|
237
268
|
limit: this.limit
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
// 如果用户未监听事件,显示默认提示
|
|
269
|
+
});
|
|
241
270
|
if (!this.hasEventListener('fileLimitReached')) {
|
|
242
271
|
uni.showToast({
|
|
243
272
|
title: `最多上传${this.limit}个文件`,
|
|
244
273
|
icon: 'none'
|
|
245
|
-
})
|
|
274
|
+
});
|
|
246
275
|
}
|
|
247
276
|
}
|
|
248
|
-
return
|
|
277
|
+
return;
|
|
249
278
|
}
|
|
250
279
|
|
|
251
280
|
// #ifdef H5
|
|
252
|
-
// H5环境使用 uni.chooseFile
|
|
253
281
|
uni.chooseFile({
|
|
254
282
|
count: 1,
|
|
255
283
|
extension: this.accept,
|
|
256
284
|
success: (res) => {
|
|
257
|
-
|
|
258
|
-
this.validateAndUpload(file)
|
|
259
|
-
},
|
|
260
|
-
fail: (err) => {
|
|
261
|
-
console.error('选择文件失败:', err)
|
|
285
|
+
this.validateAndUpload(res.tempFiles[0]);
|
|
262
286
|
}
|
|
263
|
-
})
|
|
287
|
+
});
|
|
264
288
|
// #endif
|
|
265
289
|
|
|
266
290
|
// #ifndef H5
|
|
267
|
-
// 小程序等环境使用 uni.chooseMessageFile
|
|
268
291
|
uni.chooseMessageFile({
|
|
269
292
|
count: 1,
|
|
270
293
|
extension: this.accept,
|
|
271
294
|
success: (res) => {
|
|
272
|
-
|
|
273
|
-
this.validateAndUpload(file)
|
|
274
|
-
},
|
|
275
|
-
fail: (err) => {
|
|
276
|
-
console.error('选择文件失败:', err)
|
|
295
|
+
this.validateAndUpload(res.tempFiles[0]);
|
|
277
296
|
}
|
|
278
|
-
})
|
|
297
|
+
});
|
|
279
298
|
// #endif
|
|
280
299
|
},
|
|
281
300
|
|
|
@@ -283,100 +302,67 @@ export default {
|
|
|
283
302
|
* 验证并上传文件
|
|
284
303
|
*/
|
|
285
304
|
validateAndUpload(file) {
|
|
286
|
-
|
|
287
|
-
const fileName = file.name
|
|
288
|
-
const ext = this.getFileExtension(fileName)
|
|
305
|
+
const ext = this.getFileExtension(file.name);
|
|
289
306
|
|
|
290
|
-
if (!this.accept.includes(ext)) {
|
|
291
|
-
// 触发文件类型不支持事件
|
|
307
|
+
if (this.accept && this.accept.length && !this.accept.includes(ext)) {
|
|
292
308
|
this.$emit('fileTypeInvalid', {
|
|
293
|
-
fileName:
|
|
309
|
+
fileName: file.name,
|
|
294
310
|
fileType: ext,
|
|
295
311
|
acceptTypes: this.accept,
|
|
296
|
-
file: file
|
|
297
|
-
|
|
298
|
-
})
|
|
299
|
-
|
|
300
|
-
// 如果用户未监听事件,显示默认提示
|
|
312
|
+
file: file
|
|
313
|
+
});
|
|
301
314
|
if (!this.hasEventListener('fileTypeInvalid')) {
|
|
302
315
|
uni.showToast({
|
|
303
|
-
title:
|
|
316
|
+
title: `不支持${ext}格式`,
|
|
304
317
|
icon: 'none'
|
|
305
|
-
})
|
|
318
|
+
});
|
|
306
319
|
}
|
|
307
|
-
return
|
|
320
|
+
return;
|
|
308
321
|
}
|
|
309
322
|
|
|
310
|
-
|
|
311
|
-
const maxBytes = this.maxSize * 1024 * 1024
|
|
323
|
+
const maxBytes = this.maxSize * 1024 * 1024;
|
|
312
324
|
if (file.size > maxBytes) {
|
|
313
|
-
// 触发文件大小超限事件
|
|
314
325
|
this.$emit('fileSizeExceed', {
|
|
315
326
|
size: file.size,
|
|
316
327
|
maxSize: maxBytes,
|
|
317
|
-
fileName:
|
|
318
|
-
|
|
319
|
-
message: `文件大小不能超过${this.maxSize}MB(当前:${this.formatFileSize(file.size)})`
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
// 如果用户未监听事件,显示默认提示
|
|
328
|
+
fileName: file.name
|
|
329
|
+
});
|
|
323
330
|
if (!this.hasEventListener('fileSizeExceed')) {
|
|
324
331
|
uni.showToast({
|
|
325
|
-
title:
|
|
332
|
+
title: `不能超过${this.maxSize}MB`,
|
|
326
333
|
icon: 'none'
|
|
327
|
-
})
|
|
334
|
+
});
|
|
328
335
|
}
|
|
329
|
-
return
|
|
336
|
+
return;
|
|
330
337
|
}
|
|
331
338
|
|
|
332
|
-
|
|
333
|
-
this.uploadFile(file)
|
|
339
|
+
this.uploadFile(file);
|
|
334
340
|
},
|
|
335
341
|
|
|
336
342
|
/**
|
|
337
|
-
*
|
|
343
|
+
* 上传文件核心
|
|
338
344
|
*/
|
|
339
345
|
uploadFile(file) {
|
|
340
|
-
this.uploading = true
|
|
341
|
-
this.uploadProgress = 0
|
|
342
|
-
let uploadTask = {}
|
|
343
|
-
|
|
344
|
-
// #ifdef H5
|
|
345
|
-
uploadTask = uni.uploadFile({
|
|
346
|
-
url: this.finalUploadUrl,
|
|
347
|
-
filePath: file.path,
|
|
348
|
-
name: 'file',
|
|
349
|
-
success: (uploadFileRes) => {
|
|
350
|
-
this.handleUploadSuccess(uploadFileRes, file)
|
|
351
|
-
},
|
|
352
|
-
fail: (err) => {
|
|
353
|
-
this.handleUploadError(err)
|
|
354
|
-
}
|
|
355
|
-
})
|
|
356
|
-
// #endif
|
|
346
|
+
this.uploading = true;
|
|
347
|
+
this.uploadProgress = 0;
|
|
357
348
|
|
|
358
|
-
|
|
359
|
-
uploadTask = uni.uploadFile({
|
|
349
|
+
const uploadTask = uni.uploadFile({
|
|
360
350
|
url: this.finalUploadUrl,
|
|
361
351
|
filePath: file.path,
|
|
362
352
|
name: 'file',
|
|
363
353
|
success: (uploadFileRes) => {
|
|
364
|
-
this.handleUploadSuccess(uploadFileRes, file)
|
|
354
|
+
this.handleUploadSuccess(uploadFileRes, file);
|
|
365
355
|
},
|
|
366
356
|
fail: (err) => {
|
|
367
|
-
this.handleUploadError(err)
|
|
357
|
+
this.handleUploadError(err);
|
|
368
358
|
}
|
|
369
|
-
})
|
|
370
|
-
// #endif
|
|
359
|
+
});
|
|
371
360
|
|
|
372
361
|
// 监听上传进度
|
|
373
362
|
uploadTask.onProgressUpdate((res) => {
|
|
374
|
-
this.uploadProgress = res.progress
|
|
375
|
-
this.$emit('progress',
|
|
376
|
-
|
|
377
|
-
stage: 'file'
|
|
378
|
-
})
|
|
379
|
-
})
|
|
363
|
+
this.uploadProgress = res.progress;
|
|
364
|
+
this.$emit('progress', res);
|
|
365
|
+
});
|
|
380
366
|
},
|
|
381
367
|
|
|
382
368
|
/**
|
|
@@ -384,35 +370,35 @@ export default {
|
|
|
384
370
|
*/
|
|
385
371
|
handleUploadSuccess(uploadFileRes, originalFile) {
|
|
386
372
|
try {
|
|
387
|
-
const result = JSON.parse(uploadFileRes.data)
|
|
388
|
-
console.log('文件上传成功:', result)
|
|
373
|
+
const result = JSON.parse(uploadFileRes.data);
|
|
374
|
+
console.log('文件上传成功:', result);
|
|
389
375
|
|
|
390
376
|
const fileInfo = {
|
|
391
377
|
fileName: result.data.fileName,
|
|
392
378
|
name: result.data.originFileName || originalFile.name,
|
|
393
379
|
url: result.data.pathUrl
|
|
394
|
-
}
|
|
380
|
+
};
|
|
395
381
|
|
|
396
|
-
this.fileList.push(fileInfo)
|
|
397
|
-
this.uploadProgress = 100
|
|
398
|
-
this.uploading = false
|
|
399
|
-
this.emitChange()
|
|
382
|
+
this.fileList.push(fileInfo);
|
|
383
|
+
this.uploadProgress = 100;
|
|
384
|
+
this.uploading = false;
|
|
385
|
+
this.emitChange();
|
|
400
386
|
|
|
401
387
|
// 触发上传成功事件
|
|
402
388
|
this.$emit('uploadSuccess', {
|
|
403
389
|
file: fileInfo,
|
|
404
390
|
response: result
|
|
405
|
-
})
|
|
391
|
+
});
|
|
406
392
|
|
|
407
393
|
// 如果用户未监听事件,显示默认提示
|
|
408
394
|
if (!this.hasEventListener('uploadSuccess')) {
|
|
409
395
|
uni.showToast({
|
|
410
396
|
title: '上传成功',
|
|
411
397
|
icon: 'success'
|
|
412
|
-
})
|
|
398
|
+
});
|
|
413
399
|
}
|
|
414
400
|
} catch (e) {
|
|
415
|
-
this.handleUploadError(e)
|
|
401
|
+
this.handleUploadError(e);
|
|
416
402
|
}
|
|
417
403
|
},
|
|
418
404
|
|
|
@@ -420,24 +406,24 @@ export default {
|
|
|
420
406
|
* 处理上传失败
|
|
421
407
|
*/
|
|
422
408
|
handleUploadError(err) {
|
|
423
|
-
console.error('文件上传失败:', err)
|
|
409
|
+
console.error('文件上传失败:', err);
|
|
424
410
|
|
|
425
411
|
// 触发上传失败事件
|
|
426
412
|
this.$emit('uploadFail', {
|
|
427
413
|
error: err,
|
|
428
414
|
message: '文件上传失败'
|
|
429
|
-
})
|
|
415
|
+
});
|
|
430
416
|
|
|
431
417
|
// 如果用户未监听事件,显示默认提示
|
|
432
418
|
if (!this.hasEventListener('uploadFail')) {
|
|
433
419
|
uni.showToast({
|
|
434
420
|
icon: 'none',
|
|
435
421
|
title: '文件上传失败'
|
|
436
|
-
})
|
|
422
|
+
});
|
|
437
423
|
}
|
|
438
424
|
|
|
439
|
-
this.uploading = false
|
|
440
|
-
this.uploadProgress = 0
|
|
425
|
+
this.uploading = false;
|
|
426
|
+
this.uploadProgress = 0;
|
|
441
427
|
},
|
|
442
428
|
|
|
443
429
|
/**
|
|
@@ -449,11 +435,11 @@ export default {
|
|
|
449
435
|
content: '确定要删除该文件吗?',
|
|
450
436
|
success: (res) => {
|
|
451
437
|
if (res.confirm) {
|
|
452
|
-
this.fileList.splice(index, 1)
|
|
453
|
-
this.emitChange()
|
|
438
|
+
this.fileList.splice(index, 1);
|
|
439
|
+
this.emitChange();
|
|
454
440
|
}
|
|
455
441
|
}
|
|
456
|
-
})
|
|
442
|
+
});
|
|
457
443
|
},
|
|
458
444
|
|
|
459
445
|
/**
|
|
@@ -461,26 +447,26 @@ export default {
|
|
|
461
447
|
*/
|
|
462
448
|
handleFileClick(file) {
|
|
463
449
|
if (this.hasEventListener('click')) {
|
|
464
|
-
this.$emit('click', file)
|
|
465
|
-
return
|
|
450
|
+
this.$emit('click', file);
|
|
451
|
+
return;
|
|
466
452
|
}
|
|
467
453
|
|
|
468
454
|
if (!file.url) {
|
|
469
455
|
uni.showToast({
|
|
470
456
|
title: '文件地址无效',
|
|
471
457
|
icon: 'none'
|
|
472
|
-
})
|
|
473
|
-
return
|
|
458
|
+
});
|
|
459
|
+
return;
|
|
474
460
|
}
|
|
475
461
|
|
|
476
462
|
// #ifdef H5
|
|
477
463
|
// H5环境直接下载
|
|
478
|
-
this.downloadFileH5(file)
|
|
464
|
+
this.downloadFileH5(file);
|
|
479
465
|
// #endif
|
|
480
466
|
|
|
481
467
|
// #ifndef H5
|
|
482
468
|
// 小程序等环境使用 uni.openDocument
|
|
483
|
-
this.openDocument(file)
|
|
469
|
+
this.openDocument(file);
|
|
484
470
|
// #endif
|
|
485
471
|
},
|
|
486
472
|
|
|
@@ -490,36 +476,36 @@ export default {
|
|
|
490
476
|
downloadFileH5(file) {
|
|
491
477
|
uni.showLoading({
|
|
492
478
|
title: '下载中...'
|
|
493
|
-
})
|
|
479
|
+
});
|
|
494
480
|
|
|
495
481
|
// 使用 fetch 下载文件
|
|
496
482
|
fetch(file.url)
|
|
497
|
-
.then(res => res.blob())
|
|
498
|
-
.then(blob => {
|
|
483
|
+
.then((res) => res.blob())
|
|
484
|
+
.then((blob) => {
|
|
499
485
|
// 创建 blob URL
|
|
500
|
-
const blobUrl = URL.createObjectURL(blob)
|
|
501
|
-
const a = document.createElement('a')
|
|
502
|
-
a.href = blobUrl
|
|
503
|
-
a.download = file.name
|
|
504
|
-
document.body.appendChild(a)
|
|
505
|
-
a.click()
|
|
506
|
-
document.body.removeChild(a)
|
|
486
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
487
|
+
const a = document.createElement('a');
|
|
488
|
+
a.href = blobUrl;
|
|
489
|
+
a.download = file.name;
|
|
490
|
+
document.body.appendChild(a);
|
|
491
|
+
a.click();
|
|
492
|
+
document.body.removeChild(a);
|
|
507
493
|
|
|
508
494
|
// 释放 blob URL
|
|
509
495
|
setTimeout(() => {
|
|
510
|
-
URL.revokeObjectURL(blobUrl)
|
|
511
|
-
}, 100)
|
|
496
|
+
URL.revokeObjectURL(blobUrl);
|
|
497
|
+
}, 100);
|
|
512
498
|
|
|
513
|
-
uni.hideLoading()
|
|
499
|
+
uni.hideLoading();
|
|
514
500
|
})
|
|
515
|
-
.catch(err => {
|
|
516
|
-
console.error('下载文件失败:', err)
|
|
517
|
-
uni.hideLoading()
|
|
501
|
+
.catch((err) => {
|
|
502
|
+
console.error('下载文件失败:', err);
|
|
503
|
+
uni.hideLoading();
|
|
518
504
|
uni.showToast({
|
|
519
505
|
title: '下载失败',
|
|
520
506
|
icon: 'none'
|
|
521
|
-
})
|
|
522
|
-
})
|
|
507
|
+
});
|
|
508
|
+
});
|
|
523
509
|
},
|
|
524
510
|
|
|
525
511
|
/**
|
|
@@ -527,23 +513,23 @@ export default {
|
|
|
527
513
|
*/
|
|
528
514
|
openDocument(file) {
|
|
529
515
|
// 判断文件类型是否为可打开的文档类型
|
|
530
|
-
const ext = this.getFileExtension(file.name)
|
|
531
|
-
const supportedTypes = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx']
|
|
532
|
-
const isDocument = supportedTypes.includes(ext)
|
|
533
|
-
|
|
534
|
-
const imageTypes = ['png', 'jpeg', 'jpg', 'gif']
|
|
535
|
-
console.log(ext)
|
|
516
|
+
const ext = this.getFileExtension(file.name);
|
|
517
|
+
const supportedTypes = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'];
|
|
518
|
+
const isDocument = supportedTypes.includes(ext);
|
|
519
|
+
|
|
520
|
+
const imageTypes = ['png', 'jpeg', 'jpg', 'gif'];
|
|
521
|
+
console.log(ext);
|
|
536
522
|
if (imageTypes.includes(ext)) {
|
|
537
523
|
uni.previewImage({
|
|
538
524
|
urls: [file.url]
|
|
539
|
-
})
|
|
540
|
-
return
|
|
525
|
+
});
|
|
526
|
+
return;
|
|
541
527
|
}
|
|
542
528
|
|
|
543
529
|
// 显示加载提示
|
|
544
530
|
uni.showLoading({
|
|
545
531
|
title: isDocument ? '正在打开...' : '正在下载...'
|
|
546
|
-
})
|
|
532
|
+
});
|
|
547
533
|
|
|
548
534
|
// 下载文件
|
|
549
535
|
uni.downloadFile({
|
|
@@ -556,69 +542,75 @@ export default {
|
|
|
556
542
|
filePath: res.tempFilePath,
|
|
557
543
|
fileType: ext,
|
|
558
544
|
success: () => {
|
|
559
|
-
uni.hideLoading()
|
|
545
|
+
uni.hideLoading();
|
|
560
546
|
},
|
|
561
547
|
fail: (err) => {
|
|
562
|
-
console.error('打开文档失败:', err)
|
|
563
|
-
uni.hideLoading()
|
|
548
|
+
console.error('打开文档失败:', err);
|
|
549
|
+
uni.hideLoading();
|
|
564
550
|
uni.showToast({
|
|
565
551
|
title: '打开文档失败',
|
|
566
552
|
icon: 'none'
|
|
567
|
-
})
|
|
553
|
+
});
|
|
568
554
|
}
|
|
569
|
-
})
|
|
555
|
+
});
|
|
570
556
|
} else {
|
|
571
557
|
// 保存文件到本地
|
|
572
558
|
uni.saveFile({
|
|
573
559
|
tempFilePath: res.tempFilePath,
|
|
574
560
|
success: (saveRes) => {
|
|
575
|
-
uni.hideLoading()
|
|
561
|
+
uni.hideLoading();
|
|
576
562
|
uni.showToast({
|
|
577
563
|
title: '已保存到本地',
|
|
578
564
|
icon: 'success'
|
|
579
|
-
})
|
|
565
|
+
});
|
|
580
566
|
},
|
|
581
567
|
fail: () => {
|
|
582
|
-
uni.hideLoading()
|
|
568
|
+
uni.hideLoading();
|
|
583
569
|
uni.showToast({
|
|
584
570
|
title: '保存失败',
|
|
585
571
|
icon: 'none'
|
|
586
|
-
})
|
|
572
|
+
});
|
|
587
573
|
}
|
|
588
|
-
})
|
|
574
|
+
});
|
|
589
575
|
}
|
|
590
576
|
} else {
|
|
591
|
-
uni.hideLoading()
|
|
577
|
+
uni.hideLoading();
|
|
592
578
|
uni.showToast({
|
|
593
579
|
title: '下载失败',
|
|
594
580
|
icon: 'none'
|
|
595
|
-
})
|
|
581
|
+
});
|
|
596
582
|
}
|
|
597
583
|
},
|
|
598
584
|
fail: (err) => {
|
|
599
|
-
console.error('下载失败:', err)
|
|
600
|
-
uni.hideLoading()
|
|
585
|
+
console.error('下载失败:', err);
|
|
586
|
+
uni.hideLoading();
|
|
601
587
|
uni.showToast({
|
|
602
588
|
title: '下载失败',
|
|
603
589
|
icon: 'none'
|
|
604
|
-
})
|
|
590
|
+
});
|
|
605
591
|
}
|
|
606
|
-
})
|
|
592
|
+
});
|
|
607
593
|
},
|
|
608
594
|
|
|
609
595
|
/**
|
|
610
596
|
* 触发变更事件
|
|
611
597
|
*/
|
|
612
598
|
emitChange() {
|
|
613
|
-
this.$emit('change', this.fileList)
|
|
599
|
+
this.$emit('change', this.fileList);
|
|
600
|
+
// #ifdef VUE3
|
|
601
|
+
this.$emit('update:modelValue', this.fileList);
|
|
602
|
+
// #endif
|
|
603
|
+
// #ifndef VUE3
|
|
604
|
+
this.$emit('input', this.fileList);
|
|
605
|
+
// #endif
|
|
614
606
|
},
|
|
615
607
|
|
|
616
608
|
/**
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
609
|
+
* 获取文件列表
|
|
610
|
+
* @returns {Array} 文件列表
|
|
611
|
+
*/
|
|
620
612
|
getFileList() {
|
|
621
|
-
return this.fileList
|
|
613
|
+
return this.fileList;
|
|
622
614
|
},
|
|
623
615
|
|
|
624
616
|
/**
|
|
@@ -626,14 +618,14 @@ export default {
|
|
|
626
618
|
* @returns {String} JSON 字符串
|
|
627
619
|
*/
|
|
628
620
|
getParams() {
|
|
629
|
-
const params = this.fileList.map(file => {
|
|
630
|
-
const { url, ...rest } = file
|
|
631
|
-
return rest
|
|
632
|
-
})
|
|
633
|
-
return JSON.stringify(params)
|
|
621
|
+
const params = this.fileList.map((file) => {
|
|
622
|
+
const { url, ...rest } = file;
|
|
623
|
+
return rest;
|
|
624
|
+
});
|
|
625
|
+
return JSON.stringify(params);
|
|
634
626
|
}
|
|
635
627
|
}
|
|
636
|
-
}
|
|
628
|
+
};
|
|
637
629
|
</script>
|
|
638
630
|
|
|
639
631
|
<style lang="scss">
|