@netang/quasar 0.1.62 → 0.1.63

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.
package/utils/uploader.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ref, isRef, watch } from 'vue'
1
+ import { ref, isRef, } from 'vue'
2
2
  import SparkMD5 from 'spark-md5'
3
3
 
4
4
  import $n_has from 'lodash/has'
@@ -12,15 +12,14 @@ import $n_isFunction from 'lodash/isFunction'
12
12
  import $n_isValidArray from '@netang/utils/isValidArray'
13
13
  import $n_isValidObject from '@netang/utils/isValidObject'
14
14
  import $n_isValidString from '@netang/utils/isValidString'
15
- import $n_isRequired from '@netang/utils/isRequired'
16
15
  import $n_forEach from '@netang/utils/forEach'
16
+ import $n_indexOf from '@netang/utils/indexOf'
17
17
  import $n_json from '@netang/utils/json'
18
18
  import $n_join from '@netang/utils/join'
19
19
  import $n_split from '@netang/utils/split'
20
20
  import $n_trimString from '@netang/utils/trimString'
21
21
  import $n_run from '@netang/utils/run'
22
22
  import $n_isValidValue from '@netang/utils/isValidValue'
23
- import $n_copy from '@netang/utils/copy'
24
23
  import $n_http from '@netang/utils/http'
25
24
  import $n_getThrowMessage from '@netang/utils/getThrowMessage'
26
25
  import $n_runAsync from '@netang/utils/runAsync'
@@ -35,6 +34,8 @@ import $n_config from './config'
35
34
 
36
35
  import { configs } from './config'
37
36
 
37
+ import copy from './copy'
38
+
38
39
  import {
39
40
  // 文件类型映射
40
41
  FilE_TYPE,
@@ -71,6 +72,8 @@ function create(options) {
71
72
  onUpdate: null,
72
73
  }, options)
73
74
 
75
+ const optionsProps = $n_get(options, 'props')
76
+
74
77
  // 声明属性
75
78
  const props = Object.assign({
76
79
  // 值
@@ -92,14 +95,17 @@ function create(options) {
92
95
  loadInfo: false,
93
96
  // 单文件上传提示
94
97
  confirm: false,
95
- }, $n_get(options, 'props'))
98
+ }, optionsProps)
96
99
 
97
100
  // options 中是否存在 props.modelValue
98
- const hasPropsModelValue = $n_has(options, 'props.modelValue')
101
+ const hasPropsModelValue = $n_has(optionsProps, 'modelValue')
99
102
 
100
103
  // 上传文件列表
101
104
  const uploadFileLists = $n_has(options, 'uploadFileLists') && isRef(options.uploadFileLists) ? options.uploadFileLists : ref([])
102
105
 
106
+ // 上传网络外链回调
107
+ let uploadNetCallback
108
+
103
109
  /**
104
110
  * 上传配置
105
111
  */
@@ -170,6 +176,7 @@ function create(options) {
170
176
  hashsString,
171
177
  hashs,
172
178
  files,
179
+ query: uploadFileLists,
173
180
  }
174
181
  }
175
182
 
@@ -186,6 +193,9 @@ function create(options) {
186
193
 
187
194
  // 更新
188
195
  $n_run(onUpdate)(result)
196
+
197
+ // 上传网络外链回调
198
+ $n_run(uploadNetCallback)()
189
199
  }
190
200
 
191
201
  /**
@@ -203,22 +213,29 @@ function create(options) {
203
213
 
204
214
  const modelValue = hasPropsModelValue ? options.props.modelValue : props.modelValue
205
215
 
206
- if (! $n_isRequired(modelValue)) {
207
- return
208
- }
209
-
210
216
  // 值数组
211
217
  const hashs = []
212
218
 
213
219
  // hash all
214
220
  const hashAll = {}
215
221
 
216
- // 新上传文件列表
217
- const newUploadFileLists = []
218
-
219
222
  // 获取值数组
220
223
  const lists = props.valueArray ? modelValue : $n_split(modelValue, ',')
221
224
 
225
+ if (
226
+ // 如果只能上传一个
227
+ props.count === 1
228
+ // 如果为空
229
+ && ! $n_isValidArray(lists)
230
+ ) {
231
+ // 更新上传文件列表
232
+ uploadFileLists.value = []
233
+ return
234
+ }
235
+
236
+ // 新上传文件列表
237
+ const newUploadFileLists = []
238
+
222
239
  // 新列表
223
240
  const newLists = []
224
241
 
@@ -244,12 +261,14 @@ function create(options) {
244
261
 
245
262
  } else if (! $n_has(hashAll, 'hash')) {
246
263
 
247
- // 如果是 http(s):// 开头的地址
264
+ // 如果是外链
248
265
  if (/^http(s)?:\/\//i.test(hash)) {
249
266
  hashs.push(hash)
250
267
  hashAll[hash] = {
251
268
  hash,
269
+ __img: hash,
252
270
  isNet: true,
271
+ isNetUploaded: false,
253
272
  }
254
273
 
255
274
  // 否则为 hash 文件
@@ -280,6 +299,8 @@ function create(options) {
280
299
  },
281
300
  // 关闭错误
282
301
  warn: false,
302
+ // 关闭防抖(可以重复请求)
303
+ debounce: false,
283
304
  })
284
305
  if (status) {
285
306
 
@@ -348,6 +369,217 @@ function create(options) {
348
369
  }
349
370
  }
350
371
 
372
+ /**
373
+ * 初始化上传网络外链列表
374
+ */
375
+ function initUploadNetLists(callback) {
376
+
377
+ // 如果提交时禁止上传网络外链文件
378
+ if ($n_get(optionsProps, 'submitUploadNet') !== true) {
379
+ return
380
+ }
381
+
382
+ uploadNetCallback = callback
383
+
384
+ for (const fileItem of uploadFileLists.value) {
385
+ if (
386
+ fileItem.isNet
387
+ && fileItem.status === UPLOAD_STATUS.success
388
+ ) {
389
+ // 将文件状态修改为: 等待上传中
390
+ fileItem.status = UPLOAD_STATUS.waiting
391
+ }
392
+ }
393
+ }
394
+
395
+ /**
396
+ * 上传网络外链文件
397
+ */
398
+ async function uploadNet() {
399
+
400
+ // 如果提交时禁止上传网络外链文件
401
+ if ($n_get(optionsProps, 'submitUploadNet') !== true) {
402
+ return
403
+ }
404
+
405
+ const promises = []
406
+
407
+ for (const fileItem of uploadFileLists.value) {
408
+ if (
409
+ fileItem.isNet
410
+ && fileItem.status === UPLOAD_STATUS.waiting
411
+ ) {
412
+ // 设置网络图片 file
413
+ promises.push(setNetFile(fileItem))
414
+ }
415
+ }
416
+
417
+ if (! promises.length) {
418
+ return
419
+ }
420
+ await Promise.all(promises)
421
+
422
+ // 检查待上传文件在服务器上是否存在
423
+ // --------------------------------------------------
424
+ if (! await checkWaitUploadFileExists()) {
425
+ return
426
+ }
427
+
428
+ // 上传
429
+ await upload()
430
+ }
431
+
432
+ /**
433
+ * 获取上传网络外链进度
434
+ */
435
+ // function getUploadNetProgress() {
436
+ //
437
+ // let total = 0
438
+ // let loaded = 0
439
+ //
440
+ // // 如果提交时允许上传网络外链文件
441
+ // if ($n_get(optionsProps, 'submitUploadNet') === true) {
442
+ //
443
+ // for (const fileItem of uploadFileLists.value) {
444
+ // if (fileItem.isNet && fileItem.status <= UPLOAD_STATUS.success) {
445
+ // total++
446
+ // if (fileItem.isNetUploaded) {
447
+ // loaded++
448
+ // }
449
+ // }
450
+ // }
451
+ //
452
+ // // if (total && loaded < total) {
453
+ // // return {
454
+ // // loaded,
455
+ // // total,
456
+ // // // progress: Math.round(loaded * 100 / total),
457
+ // // }
458
+ // // }
459
+ // }
460
+ //
461
+ // return {
462
+ // loaded,
463
+ // total,
464
+ // // progress: 100,
465
+ // }
466
+ // }
467
+
468
+ /**
469
+ * 设置网络图片 file
470
+ */
471
+ async function setNetFile(fileItem) {
472
+
473
+ // 设置文件状态
474
+ fileItem.status = UPLOAD_STATUS.hashChecking
475
+ // 设置文件检查进度
476
+ fileItem.progress = 0
477
+
478
+ try {
479
+ const r = await fetch(fileItem.__img, {
480
+ method: 'GET',
481
+ })
482
+ const arrayBuffer = await r.arrayBuffer()
483
+ const blob = new Blob([arrayBuffer], { type: r.headers.get('Content-Type') })
484
+
485
+ // -------- axios
486
+ // const r = await axios({
487
+ // method: 'GET',
488
+ // url: fileItem.__img,
489
+ // responseType: 'arraybuffer'
490
+ // })
491
+ // console.log(r)
492
+ // const arrayBuffer = r.data
493
+ // const blob = new Blob([arrayBuffer], { type: r.headers['content-type'] })
494
+ // -------- axios
495
+
496
+ // 如果有类型
497
+ if (blob.type) {
498
+
499
+ // 后缀名
500
+ let ext = ''
501
+
502
+ // 如果为图片
503
+ if (
504
+ props.type === 'image'
505
+ || $n_indexOf(blob.type, 'image/') > -1
506
+ ) {
507
+ switch (blob.type) {
508
+ case 'image/png':
509
+ ext = 'png'
510
+ break
511
+ case 'image/gif':
512
+ ext = 'gif'
513
+ break
514
+ default:
515
+ ext = 'jpg'
516
+ break
517
+ }
518
+
519
+ // 如果为视频
520
+ } else if (props.type === 'video') {
521
+ ext = 'mp4'
522
+
523
+ // 如果为音频
524
+ } else if (props.type === 'audio') {
525
+ ext = 'mp3'
526
+
527
+ // 否则为文件
528
+ } else {
529
+ const arr = $n_split(props.type, '/')
530
+ if (arr.length > 0) {
531
+ ext = arr[1]
532
+ }
533
+ }
534
+
535
+ // 如果有后缀名
536
+ if (ext) {
537
+ // 设置文件
538
+ fileItem.file = new File([blob], '', { type: blob.type })
539
+ // 设置后缀名
540
+ fileItem.ext = ext
541
+
542
+ const {
543
+ size,
544
+ } = fileItem.file
545
+
546
+ // 文件大小
547
+ fileItem.size = size
548
+
549
+ // 检查文件错误
550
+ const errMsg = checkFileError(fileItem)
551
+ if (errMsg) {
552
+ // 设置文件上传失败
553
+ setFileFail(fileItem, errMsg)
554
+ return
555
+ }
556
+
557
+ // 初始化 SparkMD5
558
+ const spark = new SparkMD5.ArrayBuffer()
559
+ spark.append(arrayBuffer)
560
+
561
+ // 获取文件 hash
562
+ const hash = spark.end(false)
563
+ if (hash) {
564
+ // 设置文件 hash
565
+ fileItem.hash = hash
566
+ // 标题
567
+ fileItem.title = fileItem.hash
568
+ // 设置文件状态
569
+ fileItem.status = UPLOAD_STATUS.hashChecked
570
+ // 设置文件检查进度
571
+ fileItem.progress = 100
572
+ return
573
+ }
574
+ }
575
+ }
576
+
577
+ } catch (e) {}
578
+
579
+ // 设置文件上传失败
580
+ setFileFail(fileItem)
581
+ }
582
+
351
583
  /**
352
584
  * 检查是否正在上传文件
353
585
  */
@@ -482,7 +714,10 @@ function create(options) {
482
714
  }
483
715
  }
484
716
  }
485
- await Promise.all(promises)
717
+
718
+ if (promises.length) {
719
+ await Promise.all(promises)
720
+ }
486
721
 
487
722
  // 检查待上传文件在服务器上是否存在
488
723
  // --------------------------------------------------
@@ -555,6 +790,10 @@ function create(options) {
555
790
  fileItem.msg = ''
556
791
  // 设置文件检查进度
557
792
  fileItem.progress = 0
793
+ // 是否网络文件已上传
794
+ if (fileItem.isNet) {
795
+ fileItem.isNetUploaded = true
796
+ }
558
797
 
559
798
  // // 单个文件上传结束回调
560
799
  // uploadQueryCallback(fileItem)
@@ -580,6 +819,9 @@ function create(options) {
580
819
 
581
820
  // // 单个文件上传结束回调
582
821
  // uploadQueryCallback(fileItem)
822
+
823
+ // 上传网络外链回调
824
+ $n_run(uploadNetCallback)()
583
825
  }
584
826
 
585
827
  /**
@@ -632,6 +874,13 @@ function create(options) {
632
874
 
633
875
  // 获取文件 hash
634
876
  const hash = spark.end(false)
877
+ if (! hash) {
878
+ // 设置文件上传失败
879
+ setFileFail(fileItem)
880
+ // 完成回调
881
+ resolve()
882
+ return
883
+ }
635
884
 
636
885
  // 下一步
637
886
  function next(hash) {
@@ -689,6 +938,8 @@ function create(options) {
689
938
  fileReader.onerror = function() {
690
939
  // 设置文件上传失败
691
940
  setFileFail(fileItem)
941
+ // 完成回调
942
+ resolve()
692
943
  }
693
944
 
694
945
  /**
@@ -784,6 +1035,8 @@ function create(options) {
784
1035
  },
785
1036
  // 关闭错误
786
1037
  warn: false,
1038
+ // 关闭防抖(可以重复请求)
1039
+ debounce: false,
787
1040
  })
788
1041
 
789
1042
  // 如果请求失败
@@ -821,6 +1074,9 @@ function create(options) {
821
1074
  // 设置已存在文件
822
1075
  setExistedFileItem(fileItem, existedItem)
823
1076
 
1077
+ // 设置文件为非网络外链
1078
+ fileItem.isNet = false
1079
+
824
1080
  // 单个文件上传结束回调
825
1081
  // uploadQueryCallback(fileItem)
826
1082
 
@@ -887,6 +1143,8 @@ function create(options) {
887
1143
  msg: '待上传',
888
1144
  // 是否为网络文件
889
1145
  isNet: false,
1146
+ // 是否网络文件已上传
1147
+ isNetUploaded: false,
890
1148
  // 中断上传
891
1149
  abort() {},
892
1150
  }
@@ -1139,16 +1397,18 @@ function create(options) {
1139
1397
  /**
1140
1398
  * 复制地址
1141
1399
  */
1142
- function copyUrl(fileItem) {
1143
-
1144
- const url = fileItem.type === FilE_TYPE.image ?
1145
- // 如果是图片
1146
- $n_getImage(fileItem.hash)
1147
- // 否则是文件
1148
- : $n_getFile(fileItem.hash)
1149
-
1150
- if ($n_isValidString(url)) {
1151
- $n_copy(url, '复制地址成功')
1400
+ function copyUrl({ type, hash, url, isNet }) {
1401
+
1402
+ const _url = isNet ? url : (
1403
+ type === FilE_TYPE.image ?
1404
+ // 如果是图片
1405
+ $n_getImage(hash)
1406
+ // 否则是文件
1407
+ : $n_getFile(hash)
1408
+ )
1409
+
1410
+ if ($n_isValidString(_url)) {
1411
+ copy(_url, '复制地址成功')
1152
1412
  }
1153
1413
  }
1154
1414
 
@@ -1159,6 +1419,14 @@ function create(options) {
1159
1419
  updateValue,
1160
1420
  // 初始化上传列表
1161
1421
  initUploadFileLists,
1422
+
1423
+ // 初始化上传网络外链列表
1424
+ initUploadNetLists,
1425
+ // 上传网络外链文件
1426
+ uploadNet,
1427
+ // 获取上传网络外链进度
1428
+ // getUploadNetProgress,
1429
+
1162
1430
  // 检查是否正在上传文件
1163
1431
  checkUploading,
1164
1432
  // 选择文件上传