@netang/quasar 0.1.62 → 0.1.64

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,5 @@
1
- import { ref, isRef, watch } from 'vue'
1
+ import { ref, isRef, } from 'vue'
2
+ import { useQuasar } from 'quasar'
2
3
  import SparkMD5 from 'spark-md5'
3
4
 
4
5
  import $n_has from 'lodash/has'
@@ -12,15 +13,14 @@ import $n_isFunction from 'lodash/isFunction'
12
13
  import $n_isValidArray from '@netang/utils/isValidArray'
13
14
  import $n_isValidObject from '@netang/utils/isValidObject'
14
15
  import $n_isValidString from '@netang/utils/isValidString'
15
- import $n_isRequired from '@netang/utils/isRequired'
16
16
  import $n_forEach from '@netang/utils/forEach'
17
+ import $n_indexOf from '@netang/utils/indexOf'
17
18
  import $n_json from '@netang/utils/json'
18
19
  import $n_join from '@netang/utils/join'
19
20
  import $n_split from '@netang/utils/split'
20
21
  import $n_trimString from '@netang/utils/trimString'
21
22
  import $n_run from '@netang/utils/run'
22
23
  import $n_isValidValue from '@netang/utils/isValidValue'
23
- import $n_copy from '@netang/utils/copy'
24
24
  import $n_http from '@netang/utils/http'
25
25
  import $n_getThrowMessage from '@netang/utils/getThrowMessage'
26
26
  import $n_runAsync from '@netang/utils/runAsync'
@@ -35,6 +35,8 @@ import $n_config from './config'
35
35
 
36
36
  import { configs } from './config'
37
37
 
38
+ import copy from './copy'
39
+
38
40
  import {
39
41
  // 文件类型映射
40
42
  FilE_TYPE,
@@ -56,6 +58,9 @@ function create(options) {
56
58
 
57
59
  // ==========【数据】=========================================================================================
58
60
 
61
+ // quasar 对象
62
+ const $q = useQuasar()
63
+
59
64
  const {
60
65
  // 上传文件输入框节点
61
66
  fileRef,
@@ -71,6 +76,8 @@ function create(options) {
71
76
  onUpdate: null,
72
77
  }, options)
73
78
 
79
+ const optionsProps = $n_get(options, 'props')
80
+
74
81
  // 声明属性
75
82
  const props = Object.assign({
76
83
  // 值
@@ -92,14 +99,17 @@ function create(options) {
92
99
  loadInfo: false,
93
100
  // 单文件上传提示
94
101
  confirm: false,
95
- }, $n_get(options, 'props'))
102
+ }, optionsProps)
96
103
 
97
104
  // options 中是否存在 props.modelValue
98
- const hasPropsModelValue = $n_has(options, 'props.modelValue')
105
+ const hasPropsModelValue = $n_has(optionsProps, 'modelValue')
99
106
 
100
107
  // 上传文件列表
101
108
  const uploadFileLists = $n_has(options, 'uploadFileLists') && isRef(options.uploadFileLists) ? options.uploadFileLists : ref([])
102
109
 
110
+ // 上传网络外链回调
111
+ let uploadNetCallback
112
+
103
113
  /**
104
114
  * 上传配置
105
115
  */
@@ -170,6 +180,7 @@ function create(options) {
170
180
  hashsString,
171
181
  hashs,
172
182
  files,
183
+ query: uploadFileLists,
173
184
  }
174
185
  }
175
186
 
@@ -186,6 +197,9 @@ function create(options) {
186
197
 
187
198
  // 更新
188
199
  $n_run(onUpdate)(result)
200
+
201
+ // 上传网络外链回调
202
+ $n_run(uploadNetCallback)()
189
203
  }
190
204
 
191
205
  /**
@@ -203,22 +217,29 @@ function create(options) {
203
217
 
204
218
  const modelValue = hasPropsModelValue ? options.props.modelValue : props.modelValue
205
219
 
206
- if (! $n_isRequired(modelValue)) {
207
- return
208
- }
209
-
210
220
  // 值数组
211
221
  const hashs = []
212
222
 
213
223
  // hash all
214
224
  const hashAll = {}
215
225
 
216
- // 新上传文件列表
217
- const newUploadFileLists = []
218
-
219
226
  // 获取值数组
220
227
  const lists = props.valueArray ? modelValue : $n_split(modelValue, ',')
221
228
 
229
+ if (
230
+ // 如果只能上传一个
231
+ props.count === 1
232
+ // 如果为空
233
+ && ! $n_isValidArray(lists)
234
+ ) {
235
+ // 更新上传文件列表
236
+ uploadFileLists.value = []
237
+ return
238
+ }
239
+
240
+ // 新上传文件列表
241
+ const newUploadFileLists = []
242
+
222
243
  // 新列表
223
244
  const newLists = []
224
245
 
@@ -244,12 +265,14 @@ function create(options) {
244
265
 
245
266
  } else if (! $n_has(hashAll, 'hash')) {
246
267
 
247
- // 如果是 http(s):// 开头的地址
268
+ // 如果是外链
248
269
  if (/^http(s)?:\/\//i.test(hash)) {
249
270
  hashs.push(hash)
250
271
  hashAll[hash] = {
251
272
  hash,
273
+ __img: hash,
252
274
  isNet: true,
275
+ isNetUploaded: false,
253
276
  }
254
277
 
255
278
  // 否则为 hash 文件
@@ -280,6 +303,8 @@ function create(options) {
280
303
  },
281
304
  // 关闭错误
282
305
  warn: false,
306
+ // 关闭防抖(可以重复请求)
307
+ debounce: false,
283
308
  })
284
309
  if (status) {
285
310
 
@@ -348,6 +373,217 @@ function create(options) {
348
373
  }
349
374
  }
350
375
 
376
+ /**
377
+ * 初始化上传网络外链列表
378
+ */
379
+ function initUploadNetLists(callback) {
380
+
381
+ // 如果提交时禁止上传网络外链文件
382
+ if ($n_get(optionsProps, 'submitUploadNet') !== true) {
383
+ return
384
+ }
385
+
386
+ uploadNetCallback = callback
387
+
388
+ for (const fileItem of uploadFileLists.value) {
389
+ if (
390
+ fileItem.isNet
391
+ && fileItem.status === UPLOAD_STATUS.success
392
+ ) {
393
+ // 将文件状态修改为: 等待上传中
394
+ fileItem.status = UPLOAD_STATUS.waiting
395
+ }
396
+ }
397
+ }
398
+
399
+ /**
400
+ * 上传网络外链文件
401
+ */
402
+ async function uploadNet() {
403
+
404
+ // 如果提交时禁止上传网络外链文件
405
+ if ($n_get(optionsProps, 'submitUploadNet') !== true) {
406
+ return
407
+ }
408
+
409
+ const promises = []
410
+
411
+ for (const fileItem of uploadFileLists.value) {
412
+ if (
413
+ fileItem.isNet
414
+ && fileItem.status === UPLOAD_STATUS.waiting
415
+ ) {
416
+ // 设置网络图片 file
417
+ promises.push(setNetFile(fileItem))
418
+ }
419
+ }
420
+
421
+ if (! promises.length) {
422
+ return
423
+ }
424
+ await Promise.all(promises)
425
+
426
+ // 检查待上传文件在服务器上是否存在
427
+ // --------------------------------------------------
428
+ if (! await checkWaitUploadFileExists()) {
429
+ return
430
+ }
431
+
432
+ // 上传
433
+ await upload()
434
+ }
435
+
436
+ /**
437
+ * 获取上传网络外链进度
438
+ */
439
+ // function getUploadNetProgress() {
440
+ //
441
+ // let total = 0
442
+ // let loaded = 0
443
+ //
444
+ // // 如果提交时允许上传网络外链文件
445
+ // if ($n_get(optionsProps, 'submitUploadNet') === true) {
446
+ //
447
+ // for (const fileItem of uploadFileLists.value) {
448
+ // if (fileItem.isNet && fileItem.status <= UPLOAD_STATUS.success) {
449
+ // total++
450
+ // if (fileItem.isNetUploaded) {
451
+ // loaded++
452
+ // }
453
+ // }
454
+ // }
455
+ //
456
+ // // if (total && loaded < total) {
457
+ // // return {
458
+ // // loaded,
459
+ // // total,
460
+ // // // progress: Math.round(loaded * 100 / total),
461
+ // // }
462
+ // // }
463
+ // }
464
+ //
465
+ // return {
466
+ // loaded,
467
+ // total,
468
+ // // progress: 100,
469
+ // }
470
+ // }
471
+
472
+ /**
473
+ * 设置网络图片 file
474
+ */
475
+ async function setNetFile(fileItem) {
476
+
477
+ // 设置文件状态
478
+ fileItem.status = UPLOAD_STATUS.hashChecking
479
+ // 设置文件检查进度
480
+ fileItem.progress = 0
481
+
482
+ try {
483
+ const r = await fetch(fileItem.__img, {
484
+ method: 'GET',
485
+ })
486
+ const arrayBuffer = await r.arrayBuffer()
487
+ const blob = new Blob([arrayBuffer], { type: r.headers.get('Content-Type') })
488
+
489
+ // -------- axios
490
+ // const r = await axios({
491
+ // method: 'GET',
492
+ // url: fileItem.__img,
493
+ // responseType: 'arraybuffer'
494
+ // })
495
+ // console.log(r)
496
+ // const arrayBuffer = r.data
497
+ // const blob = new Blob([arrayBuffer], { type: r.headers['content-type'] })
498
+ // -------- axios
499
+
500
+ // 如果有类型
501
+ if (blob.type) {
502
+
503
+ // 后缀名
504
+ let ext = ''
505
+
506
+ // 如果为图片
507
+ if (
508
+ props.type === 'image'
509
+ || $n_indexOf(blob.type, 'image/') > -1
510
+ ) {
511
+ switch (blob.type) {
512
+ case 'image/png':
513
+ ext = 'png'
514
+ break
515
+ case 'image/gif':
516
+ ext = 'gif'
517
+ break
518
+ default:
519
+ ext = 'jpg'
520
+ break
521
+ }
522
+
523
+ // 如果为视频
524
+ } else if (props.type === 'video') {
525
+ ext = 'mp4'
526
+
527
+ // 如果为音频
528
+ } else if (props.type === 'audio') {
529
+ ext = 'mp3'
530
+
531
+ // 否则为文件
532
+ } else {
533
+ const arr = $n_split(props.type, '/')
534
+ if (arr.length > 0) {
535
+ ext = arr[1]
536
+ }
537
+ }
538
+
539
+ // 如果有后缀名
540
+ if (ext) {
541
+ // 设置文件
542
+ fileItem.file = new File([blob], '', { type: blob.type })
543
+ // 设置后缀名
544
+ fileItem.ext = ext
545
+
546
+ const {
547
+ size,
548
+ } = fileItem.file
549
+
550
+ // 文件大小
551
+ fileItem.size = size
552
+
553
+ // 检查文件错误
554
+ const errMsg = checkFileError(fileItem)
555
+ if (errMsg) {
556
+ // 设置文件上传失败
557
+ setFileFail(fileItem, errMsg)
558
+ return
559
+ }
560
+
561
+ // 初始化 SparkMD5
562
+ const spark = new SparkMD5.ArrayBuffer()
563
+ spark.append(arrayBuffer)
564
+
565
+ // 获取文件 hash
566
+ const hash = spark.end(false)
567
+ if (hash) {
568
+ // 设置文件 hash
569
+ fileItem.hash = hash
570
+ // 标题
571
+ fileItem.title = fileItem.hash
572
+ // 设置文件状态
573
+ fileItem.status = UPLOAD_STATUS.hashChecked
574
+ // 设置文件检查进度
575
+ fileItem.progress = 100
576
+ return
577
+ }
578
+ }
579
+ }
580
+
581
+ } catch (e) {}
582
+
583
+ // 设置文件上传失败
584
+ setFileFail(fileItem)
585
+ }
586
+
351
587
  /**
352
588
  * 检查是否正在上传文件
353
589
  */
@@ -482,7 +718,10 @@ function create(options) {
482
718
  }
483
719
  }
484
720
  }
485
- await Promise.all(promises)
721
+
722
+ if (promises.length) {
723
+ await Promise.all(promises)
724
+ }
486
725
 
487
726
  // 检查待上传文件在服务器上是否存在
488
727
  // --------------------------------------------------
@@ -555,6 +794,10 @@ function create(options) {
555
794
  fileItem.msg = ''
556
795
  // 设置文件检查进度
557
796
  fileItem.progress = 0
797
+ // 是否网络文件已上传
798
+ if (fileItem.isNet) {
799
+ fileItem.isNetUploaded = true
800
+ }
558
801
 
559
802
  // // 单个文件上传结束回调
560
803
  // uploadQueryCallback(fileItem)
@@ -580,6 +823,9 @@ function create(options) {
580
823
 
581
824
  // // 单个文件上传结束回调
582
825
  // uploadQueryCallback(fileItem)
826
+
827
+ // 上传网络外链回调
828
+ $n_run(uploadNetCallback)()
583
829
  }
584
830
 
585
831
  /**
@@ -632,6 +878,13 @@ function create(options) {
632
878
 
633
879
  // 获取文件 hash
634
880
  const hash = spark.end(false)
881
+ if (! hash) {
882
+ // 设置文件上传失败
883
+ setFileFail(fileItem)
884
+ // 完成回调
885
+ resolve()
886
+ return
887
+ }
635
888
 
636
889
  // 下一步
637
890
  function next(hash) {
@@ -689,6 +942,8 @@ function create(options) {
689
942
  fileReader.onerror = function() {
690
943
  // 设置文件上传失败
691
944
  setFileFail(fileItem)
945
+ // 完成回调
946
+ resolve()
692
947
  }
693
948
 
694
949
  /**
@@ -784,6 +1039,8 @@ function create(options) {
784
1039
  },
785
1040
  // 关闭错误
786
1041
  warn: false,
1042
+ // 关闭防抖(可以重复请求)
1043
+ debounce: false,
787
1044
  })
788
1045
 
789
1046
  // 如果请求失败
@@ -821,6 +1078,9 @@ function create(options) {
821
1078
  // 设置已存在文件
822
1079
  setExistedFileItem(fileItem, existedItem)
823
1080
 
1081
+ // 设置文件为非网络外链
1082
+ fileItem.isNet = false
1083
+
824
1084
  // 单个文件上传结束回调
825
1085
  // uploadQueryCallback(fileItem)
826
1086
 
@@ -887,6 +1147,8 @@ function create(options) {
887
1147
  msg: '待上传',
888
1148
  // 是否为网络文件
889
1149
  isNet: false,
1150
+ // 是否网络文件已上传
1151
+ isNetUploaded: false,
890
1152
  // 中断上传
891
1153
  abort() {},
892
1154
  }
@@ -1129,26 +1391,53 @@ function create(options) {
1129
1391
  /**
1130
1392
  * 播放
1131
1393
  */
1132
- function play(fileItem) {
1133
- // 轻提示
1134
- $n_toast({
1135
- message: '播放还没做',
1394
+ function play({ hash, __img }) {
1395
+
1396
+ const src = __img ? __img : $n_getFile(hash)
1397
+
1398
+ let width
1399
+ let height
1400
+ let fullWidth = false
1401
+ let fullHeight = false
1402
+ let ok = true
1403
+ let style = ''
1404
+
1405
+ if ($q.platform.is.mobile) {
1406
+ width = $q.screen.width - 48 - 32
1407
+ height = $q.screen.height - 48 - 32 - 6 - 52
1408
+ fullWidth = true
1409
+ fullHeight = true
1410
+ } else {
1411
+ width = 800 - 32
1412
+ height = 400 - 32 - 6
1413
+ ok = false
1414
+ style = 'width:800px;max-width:800px;height:400px;max-height:400px;'
1415
+ }
1416
+
1417
+ $q.dialog({
1418
+ message: `<video style="width:${width}px;height:${height}px;" playsinline autoplay controls src="${src}" type="video/mp4" muted="muted"></video>`,
1419
+ style,
1420
+ html: true,
1421
+ dark: true,
1422
+ ok,
1423
+ fullWidth,
1424
+ fullHeight,
1136
1425
  })
1137
1426
  }
1138
1427
 
1139
1428
  /**
1140
1429
  * 复制地址
1141
1430
  */
1142
- function copyUrl(fileItem) {
1431
+ function copyUrl({ type, hash }) {
1143
1432
 
1144
- const url = fileItem.type === FilE_TYPE.image ?
1433
+ const _url = type === FilE_TYPE.image ?
1145
1434
  // 如果是图片
1146
- $n_getImage(fileItem.hash)
1435
+ $n_getImage(hash)
1147
1436
  // 否则是文件
1148
- : $n_getFile(fileItem.hash)
1437
+ : $n_getFile(hash)
1149
1438
 
1150
- if ($n_isValidString(url)) {
1151
- $n_copy(url, '复制地址成功')
1439
+ if ($n_isValidString(_url)) {
1440
+ copy(_url, '复制地址成功')
1152
1441
  }
1153
1442
  }
1154
1443
 
@@ -1159,6 +1448,14 @@ function create(options) {
1159
1448
  updateValue,
1160
1449
  // 初始化上传列表
1161
1450
  initUploadFileLists,
1451
+
1452
+ // 初始化上传网络外链列表
1453
+ initUploadNetLists,
1454
+ // 上传网络外链文件
1455
+ uploadNet,
1456
+ // 获取上传网络外链进度
1457
+ // getUploadNetProgress,
1458
+
1162
1459
  // 检查是否正在上传文件
1163
1460
  checkUploading,
1164
1461
  // 选择文件上传