uview-plus 3.4.5 → 3.4.7

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/changelog.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 3.4.7(2025-03-26)
2
+ fix: 修复action-sheet-data和picker-data数据回显
3
+
4
+ fix: 优化upload组件视频封面兼容
5
+
6
+ ## 3.4.6(2025-03-25)
7
+ feat: checkbox触发change时携带name参数
8
+
9
+ feat: upload组件支持服务器本机和阿里云OSS自动上传功能及上传进度条
10
+
11
+ feat: upload组件支持视频预览及oss上传时获取视频封面图
12
+
13
+ feat: 新增up-action-sheet-data快捷组件
14
+
15
+ feat: 新增up-picker-data快捷组件
16
+
1
17
  ## 3.4.5(2025-03-24)
2
18
  feat: tag组件新增textSize/height/padding/borderRadius属性
3
19
 
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <view class="u-action-sheet-data">
3
+ <view class="u-action-sheet-data__trigger">
4
+ <slot name="trigger"></slot>
5
+ <up-input
6
+ v-if="!$slots['trigger']"
7
+ :modelValue="current"
8
+ disabled
9
+ disabledColor="#ffffff"
10
+ :placeholder="title"
11
+ border="none"
12
+ ></up-input>
13
+ <view @click="show = true"
14
+ class="u-action-sheet-data__trigger__cover"></view>
15
+ </view>
16
+ <up-action-sheet
17
+ :show="show"
18
+ :actions="options"
19
+ :title="title"
20
+ safeAreaInsetBottom
21
+ :description="description"
22
+ @close="show = false"
23
+ @select="select"
24
+ >
25
+ </up-action-sheet>
26
+ </view>
27
+ </template>
28
+
29
+ <script>
30
+ import {mapState} from 'vuex';
31
+ export default {
32
+ props: {
33
+ modelValue: {
34
+ type: [String, Number],
35
+ default: ''
36
+ },
37
+ title: {
38
+ type: String,
39
+ default: ''
40
+ },
41
+ description: {
42
+ type: String,
43
+ default: ''
44
+ },
45
+ options: {
46
+ type: Array,
47
+ default: () => {
48
+ return []
49
+ }
50
+ },
51
+ valueKey: {
52
+ type: String,
53
+ default: 'value'
54
+ },
55
+ labelKey: {
56
+ type: String,
57
+ default: 'name'
58
+ }
59
+ },
60
+ data() {
61
+ return {
62
+ show: false,
63
+ current: '',
64
+ }
65
+ },
66
+ created() {
67
+ if (this.modelValue) {
68
+ this.options.forEach((ele) => {
69
+ if (ele[this.valueKey] == this.modelValue) {
70
+ this.current = ele[this.labelKey]
71
+ }
72
+ })
73
+ }
74
+ },
75
+ emits: ['update:modelValue'],
76
+ watch: {
77
+ modelValue() {
78
+ this.options.forEach((ele) => {
79
+ if (ele[this.valueKey] == this.modelValue) {
80
+ this.current = ele[this.labelKey]
81
+ }
82
+ })
83
+ }
84
+ },
85
+ methods: {
86
+ hideKeyboard() {
87
+ uni.hideKeyboard()
88
+ },
89
+ select(e) {
90
+ this.$emit('update:modelValue', e[this.valueKey])
91
+ this.current = e[this.labelKey]
92
+ },
93
+ }
94
+ }
95
+ </script>
96
+
97
+ <style lang="scss" scoped>
98
+ .u-action-sheet-data {
99
+ &__trigger {
100
+ position: relative;
101
+ &__cover {
102
+ position: absolute;
103
+ top: 0;
104
+ left: 0;
105
+ right: 0;
106
+ bottom: 0;
107
+ }
108
+ }
109
+ }
110
+ </style>
@@ -248,7 +248,9 @@
248
248
  }
249
249
  },
250
250
  emitEvent() {
251
- this.$emit('change', this.isChecked)
251
+ this.$emit('change', this.isChecked, {
252
+ name: this.name
253
+ })
252
254
  // 双向绑定
253
255
  if (this.usedAlone) {
254
256
  this.$emit('update:checked', this.isChecked)
@@ -0,0 +1,124 @@
1
+ <template>
2
+ <view class="u-picker-data">
3
+ <view class="u-picker-data__trigger">
4
+ <slot name="trigger"></slot>
5
+ <up-input
6
+ v-if="!$slots['trigger']"
7
+ :modelValue="current"
8
+ disabled
9
+ disabledColor="#ffffff"
10
+ :placeholder="title"
11
+ border="none"
12
+ ></up-input>
13
+ <view @click="show = true"
14
+ class="u-picker-data__trigger__cover"></view>
15
+ </view>
16
+ <up-picker
17
+ :show="show"
18
+ :columns="optionsInner"
19
+ :keyName="labelKey"
20
+ @confirm="select"
21
+ @cancel="cancel">
22
+ </up-picker>
23
+ </view>
24
+ </template>
25
+
26
+ <script>
27
+ import {mapState} from 'vuex';
28
+ export default {
29
+ props: {
30
+ modelValue: {
31
+ type: [String, Number],
32
+ default: ''
33
+ },
34
+ title: {
35
+ type: String,
36
+ default: ''
37
+ },
38
+ description: {
39
+ type: String,
40
+ default: ''
41
+ },
42
+ options: {
43
+ type: Array,
44
+ default: () => {
45
+ return []
46
+ }
47
+ },
48
+ valueKey: {
49
+ type: String,
50
+ default: 'id'
51
+ },
52
+ labelKey: {
53
+ type: String,
54
+ default: 'name'
55
+ }
56
+ },
57
+ data() {
58
+ return {
59
+ show: false,
60
+ current: '',
61
+ }
62
+ },
63
+ created() {
64
+ if (this.modelValue) {
65
+ this.options.forEach((ele) => {
66
+ if (ele[this.valueKey] == this.modelValue) {
67
+ this.current = ele[this.labelKey]
68
+ }
69
+ })
70
+ }
71
+ },
72
+ watch: {
73
+ modelValue() {
74
+ if (this.modelValue) {
75
+ this.options.forEach((ele) => {
76
+ if (ele[this.valueKey] == this.modelValue) {
77
+ this.current = ele[this.labelKey]
78
+ }
79
+ })
80
+ }
81
+ }
82
+ },
83
+ computed: {
84
+ optionsInner() {
85
+ return [this.options];
86
+ }
87
+ },
88
+ emits: ['update:modelValue'],
89
+ methods: {
90
+ hideKeyboard() {
91
+ uni.hideKeyboard()
92
+ },
93
+ cancel() {
94
+ this.show = false;
95
+ },
96
+ select(e) {
97
+ const {
98
+ columnIndex,
99
+ index,
100
+ value,
101
+ } = e;
102
+ this.show = false;
103
+ // console.log(value);
104
+ this.$emit('update:modelValue', value[0][this.valueKey]);
105
+ this.current = value[0][this.labelKey];
106
+ },
107
+ }
108
+ }
109
+ </script>
110
+
111
+ <style lang="scss" scoped>
112
+ .u-picker-data {
113
+ &__trigger {
114
+ position: relative;
115
+ &__cover {
116
+ position: absolute;
117
+ top: 0;
118
+ left: 0;
119
+ right: 0;
120
+ bottom: 0;
121
+ }
122
+ }
123
+ }
124
+ </style>
@@ -1,5 +1,11 @@
1
1
  <template>
2
- <view class="u-popup" :class="[customClass]">
2
+ <view class="u-popup" :class="[customClass]">
3
+ <view class="u-popup__trigger">
4
+ <slot name="trigger">
5
+ </slot>
6
+ <view @click="open"
7
+ class="u-popup__trigger__cover"></view>
8
+ </view>
3
9
  <u-overlay
4
10
  :show="show"
5
11
  @click="overlayClick"
@@ -188,6 +194,9 @@
188
194
  this.$emit('close')
189
195
  }
190
196
  },
197
+ open(e) {
198
+ this.$emit('update:show', true)
199
+ },
191
200
  close(e) {
192
201
  this.$emit('update:show', false)
193
202
  this.$emit('close')
@@ -240,6 +249,17 @@
240
249
 
241
250
  .u-popup {
242
251
  flex: $u-popup-flex;
252
+
253
+ &__trigger {
254
+ position: relative;
255
+ &__cover {
256
+ position: absolute;
257
+ top: 0;
258
+ left: 0;
259
+ right: 0;
260
+ bottom: 0;
261
+ }
262
+ }
243
263
 
244
264
  &__content {
245
265
  background-color: $u-popup-content-background-color;
@@ -125,6 +125,43 @@ export const props = defineMixin({
125
125
  previewImage: {
126
126
  type: Boolean,
127
127
  default: () => defProps.upload.previewImage
128
- }
128
+ },
129
+ // 是否自动删除
130
+ autoDelete: {
131
+ type: Boolean,
132
+ default: () => defProps.upload.autoDelete
133
+ },
134
+ // 是否自动上传需要传递action指定地址
135
+ autoUpload: {
136
+ type: Boolean,
137
+ default: () => defProps.upload.autoUpload
138
+ },
139
+ // 自动上传接口地址
140
+ autoUploadApi: {
141
+ type: String,
142
+ default: () => defProps.upload.autoUploadApi
143
+ },
144
+ // 自动上传驱动,local/oss/cos/kodo
145
+ autoUploadDriver: {
146
+ type: String,
147
+ default: () => defProps.upload.autoUploadDriver
148
+ },
149
+ // 自动上传授权接口,比如oss的签名接口。
150
+ autoUploadAuthUrl: {
151
+ type: String,
152
+ default: () => defProps.upload.autoUploadAuthUrl
153
+ },
154
+ // 自动上传携带的header
155
+ autoUploadHeader: {
156
+ type: Object,
157
+ default: () => {
158
+ return defProps.upload.autoUploadHeader
159
+ }
160
+ },
161
+ // 本地计算视频封面
162
+ getVideoThumb: {
163
+ type: Boolean,
164
+ default: () => defProps.upload.getVideoThumb
165
+ },
129
166
  }
130
167
  })
@@ -18,6 +18,38 @@
18
18
  height: addUnit(height)
19
19
  }]"
20
20
  />
21
+ <view class="u-upload__wrap__preview__video"
22
+ :style="{
23
+ width: addUnit(width),
24
+ height: addUnit(height)
25
+ }"
26
+ v-else-if="(item.isVideo || (item.type && item.type === 'video')) && getVideoThumb">
27
+ <image
28
+ v-if="item.thumb"
29
+ :src="item.thumb"
30
+ :mode="imageMode"
31
+ class="u-upload__wrap__preview__image"
32
+ @tap="onPreviewVideo(item, index)"
33
+ :style="[{
34
+ width: addUnit(width),
35
+ height: addUnit(height)
36
+ }]"
37
+ />
38
+ <u-icon
39
+ v-else
40
+ color="#80CBF9"
41
+ size="26"
42
+ :name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : 'folder'"
43
+ ></u-icon>
44
+ <view v-if="item.status === 'success'"
45
+ class="u-upload__wrap__play"
46
+ @tap="onPreviewVideo(item, index)">
47
+ <slot name="playIcon"></slot>
48
+ <up-icon v-if="!$slots['playIcon']"
49
+ class="u-upload__wrap__play__icon"
50
+ name="play-right" size="22px"></up-icon>
51
+ </view>
52
+ </view>
21
53
  <view
22
54
  v-else
23
55
  class="u-upload__wrap__preview__other"
@@ -54,6 +86,8 @@
54
86
  v-if="item.message"
55
87
  class="u-upload__status__message"
56
88
  >{{ item.message }}</text>
89
+ <up-gap class="u-upload__progress" height="3px"
90
+ :style="{width: item.progress + '%'}"></up-gap>
57
91
  </view>
58
92
  <view
59
93
  class="u-upload__deletable"
@@ -68,30 +102,45 @@
68
102
  ></u-icon>
69
103
  </view>
70
104
  </view>
71
- <view
72
- class="u-upload__success"
73
- v-if="item.status === 'success'"
74
- >
75
- <!-- #ifdef APP-NVUE -->
76
- <image
77
- :src="successIcon"
78
- class="u-upload__success__icon"
79
- ></image>
80
- <!-- #endif -->
81
- <!-- #ifndef APP-NVUE -->
82
- <view class="u-upload__success__icon">
83
- <u-icon
84
- name="checkmark"
85
- color="#ffffff"
86
- size="12"
87
- ></u-icon>
105
+ <slot name="success">
106
+ <view
107
+ class="u-upload__success"
108
+ v-if="item.status === 'success'"
109
+ >
110
+ <!-- #ifdef APP-NVUE -->
111
+ <image
112
+ :src="successIcon"
113
+ class="u-upload__success__icon"
114
+ ></image>
115
+ <!-- #endif -->
116
+ <!-- #ifndef APP-NVUE -->
117
+ <view class="u-upload__success__icon">
118
+ <u-icon
119
+ name="checkmark"
120
+ color="#ffffff"
121
+ size="12"
122
+ ></u-icon>
123
+ </view>
124
+ <!-- #endif -->
88
125
  </view>
89
- <!-- #endif -->
90
- </view>
126
+ </slot>
91
127
  </view>
92
-
128
+ <up-popup
129
+ mode="center"
130
+ v-model:show="popupShow">
131
+ <video id="myVideo"
132
+ :src="currentItemIndex >= 0 ? lists[currentItemIndex].url : ''"
133
+ @error="videoErrorCallback" show-center-play-btn
134
+ object-fit='cover' show-fullscreen-btn='true'
135
+ enable-play-gesture controls
136
+ :autoplay="true" auto-pause-if-open-native
137
+ @loadedmetadata="loadedVideoMetadata"
138
+ :initial-time='0.1'>
139
+ </video>
140
+ </up-popup>
93
141
  </template>
94
-
142
+ <canvas id="myCanvas" type="2d"
143
+ style="width: 100px; height: 150px;display: none;"></canvas>
95
144
  <template v-if="isInCount">
96
145
  <view
97
146
  v-if="$slots.trigger"
@@ -185,6 +234,8 @@
185
234
  // #endif
186
235
  lists: [],
187
236
  isInCount: true,
237
+ popupShow: false,
238
+ currentItemIndex: -1
188
239
  }
189
240
  },
190
241
  watch: {
@@ -204,14 +255,74 @@
204
255
  },
205
256
  accept(newVal) {
206
257
  this.formatFileList()
258
+ },
259
+ popupShow(newVal) {
260
+ if (!newVal) {
261
+ this.currentItemIndex = -1;
262
+ }
207
263
  }
208
264
  },
209
265
  // #ifdef VUE3
210
- emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview'],
266
+ emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview', 'update:fileList'],
211
267
  // #endif
212
268
  methods: {
213
269
  addUnit,
214
270
  addStyle,
271
+ videoErrorCallback() {},
272
+ loadedVideoMetadata(e) {
273
+ if (this.currentItemIndex < 0) {
274
+ return;
275
+ }
276
+ if (this.autoUploadDriver != 'local') {
277
+ return;
278
+ }
279
+ if (!this.getVideoThumb) {
280
+ return;
281
+ }
282
+ // 截取第一帧作为封面,oss等云存储场景直接使用拼接参数。
283
+ let w = this.lists[this.currentItemIndex].width;
284
+ let h = this.lists[this.currentItemIndex].height;
285
+ const dpr = uni.getSystemInfoSync().pixelRatio;
286
+ uni.createSelectorQuery().select('#myVideo').context(res => {
287
+ console.log('select video', res)
288
+ const myVideo = res.context
289
+ uni.createSelectorQuery()
290
+ .select('#myCanvas')
291
+ .fields({ node: true, size: true })
292
+ .exec(([res]) => {
293
+ console.log('select canvas', res)
294
+ const ctx1 = res[0].node.getContext('2d')
295
+ res[0].node.width = w * dpr
296
+ res[0].node.height = h * dpr
297
+ // Draw the first frame and export it as an image
298
+ // myVideo.onPlay(() => {
299
+ setTimeout(() => {
300
+ captureFirstFrame()
301
+ }, 500)
302
+ // })
303
+ const captureFirstFrame = () => {
304
+ ctx1.drawImage(myVideo, 0, 0, w * dpr, h * dpr)
305
+ wx.canvasToTempFilePath({
306
+ canvas: res[0].node,
307
+ success: (result) => {
308
+ console.log('First frame image path:', result
309
+ .tempFilePath)
310
+ // Now you can use the image path (result.tempFilePath)
311
+ this.fileList['currentItemIndex'].thumb = result.tempFilePath
312
+ },
313
+ fail: (err) => {
314
+ console.error('Failed to export image:', err)
315
+ }
316
+ })
317
+ }
318
+
319
+ // Capture the first frame
320
+ setInterval(() => {
321
+ ctx1.drawImage(myVideo, 0, 0, w * dpr, h * dpr);
322
+ }, 1000 / 24)
323
+ }).exec()
324
+ }).exec()
325
+ },
215
326
  formatFileList() {
216
327
  const {
217
328
  fileList = [], maxCount
@@ -304,7 +415,7 @@
304
415
  index: index == null ? this.fileList.length : index,
305
416
  };
306
417
  },
307
- onAfterRead(file) {
418
+ async onAfterRead(file) {
308
419
  const {
309
420
  maxSize,
310
421
  afterRead
@@ -313,25 +424,158 @@
313
424
  file.some((item) => item.size > maxSize) :
314
425
  file.size > maxSize;
315
426
  if (oversize) {
427
+ uni.showToast({
428
+ title: '超过大小限制'
429
+ })
316
430
  this.$emit('oversize', Object.assign({
317
431
  file
318
432
  }, this.getDetail()));
319
433
  return;
320
434
  }
321
- if (typeof afterRead === 'function') {
322
- afterRead(file, this.getDetail());
435
+ let len = this.fileList.length;
436
+ if (this.autoUpload) {
437
+ // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
438
+ let lists = [].concat(file);
439
+ let fileListLen = this.fileList.length;
440
+ lists.map((item) => {
441
+ this.fileList.push({
442
+ ...item,
443
+ status: 'uploading',
444
+ message: '上传中',
445
+ progress: 0
446
+ });
447
+ });
448
+ let that = this;
449
+ this.$emit('update:fileList', this.fileList);
450
+ for (let i = 0; i < lists.length; i++) {
451
+ let j = i;
452
+ let result = '';
453
+ switch(this.autoUploadDriver) {
454
+ case 'cos': // 腾讯云
455
+ break;
456
+ case 'kodo': // 七牛云
457
+ break;
458
+ case 'oss':
459
+ case 'upload_oss':
460
+ // 阿里云前端直传
461
+ // 获取签名
462
+ console.log()
463
+ let formData = {};
464
+ let ret = await uni.request({
465
+ url: this.autoUploadAuthUrl,
466
+ method: 'get',
467
+ header: this.autoUploadHeader,
468
+ data: {
469
+ filename: lists[j].name
470
+ }
471
+ });
472
+ // console.log(ret);
473
+ let res0 = ret.data;
474
+ if (res0.code == 200) {
475
+ // 路径 + 文件名 + 扩展名
476
+ // 不传递filename就要拼接key
477
+ // res0.data.params.key = res0.data.params.dir + res0.data.params.uniqidName + fileExt;
478
+ formData = res0.data.params;
479
+ } else {
480
+ uni.showToast({
481
+ title: res0.msg,
482
+ duration: 1500
483
+ });
484
+ return;
485
+ }
486
+ var uploadTask = uni.uploadFile({
487
+ url: res0.data.params.host,
488
+ filePath: lists[j].url,
489
+ name: 'file',
490
+ // fileType: 'video', // 仅支付宝小程序,且必填。
491
+ // header: header,
492
+ formData: formData,
493
+ success: (uploadFileRes) => {
494
+ result = res0.data.params.host + '/' + res0.data.params.key;
495
+ let thumb = '';
496
+ if (this.accept === 'video' || test.video(result)) {
497
+ thumb = result + '?x-oss-process=video/snapshot,t_10000,m_fast';
498
+ }
499
+ that.succcessUpload(len + j, result, thumb);
500
+ }
501
+ });
502
+ uploadTask.onProgressUpdate((res) => {
503
+ that.updateUpload(len + j, {
504
+ progress: res.progress
505
+ });
506
+ // console.log('上传进度' + res.progress);
507
+ // console.log('已经上传的数据长度' + res.totalBytesSent);
508
+ // console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
509
+ });
510
+ break;
511
+ case 'local':
512
+ default:
513
+ // 服务器本机上传
514
+ var uploadTask = uni.uploadFile({
515
+ url: this.autoUploadApi,
516
+ filePath: lists[j].url,
517
+ name: 'file',
518
+ // fileType: 'video', // 仅支付宝小程序,且必填。
519
+ header: this.autoUploadHeader,
520
+ success: (r) => {
521
+ result = res0.data.params.host + '/' + res0.data.params.key;
522
+ that.succcessUpload(len + j, result);
523
+ }
524
+ });
525
+ uploadTask.onProgressUpdate((res) => {
526
+ that.updateUpload(len + j, {
527
+ progress: res.progress
528
+ });
529
+ // console.log('上传进度' + res.progress);
530
+ // console.log('已经上传的数据长度' + res.totalBytesSent);
531
+ // console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
532
+ });
533
+ break;
534
+ }
535
+ }
536
+ } else {
537
+ if (typeof afterRead === 'function') {
538
+ afterRead(file, this.getDetail());
539
+ }
540
+ this.$emit('afterRead', Object.assign({
541
+ file
542
+ }, this.getDetail()));
323
543
  }
324
- this.$emit('afterRead', Object.assign({
325
- file
326
- }, this.getDetail()));
544
+ },
545
+ updateUpload(index, param) {
546
+ let item = this.fileList[index];
547
+ this.fileList.splice(index, 1, {
548
+ ...item,
549
+ status: 'uploading',
550
+ message: '',
551
+ progress: param.progress
552
+ });
553
+ this.$emit('update:fileList', this.fileList);
554
+ },
555
+ succcessUpload(index, url, thumb = '') {
556
+ let item = this.fileList[index];
557
+ this.fileList.splice(index, 1, {
558
+ ...item,
559
+ status: 'success',
560
+ message: '',
561
+ url: url,
562
+ progress: 100,
563
+ thumb: thumb
564
+ });
565
+ this.$emit('update:fileList', this.fileList);
327
566
  },
328
567
  deleteItem(index) {
329
- this.$emit(
330
- 'delete',
331
- Object.assign(Object.assign({}, this.getDetail(index)), {
332
- file: this.fileList[index],
333
- })
334
- );
568
+ if (this.autoDelete) {
569
+ this.fileList.splice(index, 1);
570
+ this.$emit('update:fileList', this.fileList);
571
+ } else {
572
+ this.$emit(
573
+ 'delete',
574
+ Object.assign(Object.assign({}, this.getDetail(index)), {
575
+ file: this.fileList[index],
576
+ })
577
+ );
578
+ }
335
579
  },
336
580
  // 预览图片
337
581
  onPreviewImage(previewItem, index) {
@@ -360,7 +604,7 @@
360
604
  },
361
605
  });
362
606
  },
363
- onPreviewVideo(index) {
607
+ onPreviewVideo(previewItem, index) {
364
608
  if (!this.previewFullImage) return;
365
609
  let current = 0;
366
610
  const sources = [];
@@ -380,6 +624,11 @@
380
624
  if (sources.length < 1) {
381
625
  return;
382
626
  }
627
+ // #ifndef MP-WEIXIN
628
+ this.popupShow = true;
629
+ this.currentItemIndex = index;
630
+ console.log(this.lists[this.currentItemIndex])
631
+ // #endif
383
632
  // #ifdef MP-WEIXIN
384
633
  wx.previewMedia({
385
634
  sources: sources,
@@ -483,6 +732,7 @@
483
732
  height: $u-upload-image-height;
484
733
  }
485
734
 
735
+ &__video,
486
736
  &__other {
487
737
  width: $u-upload-image-width;
488
738
  height: $u-upload-image-height;
@@ -500,6 +750,21 @@
500
750
  }
501
751
  }
502
752
  }
753
+ &__wrap__play {
754
+ position: absolute;
755
+ top: 0px;
756
+ left: 0px;
757
+ bottom: 0px;
758
+ right: 0px;
759
+ display: flex;
760
+ justify-content: center;
761
+ align-items: center;
762
+ &__icon {
763
+ background: #fff;
764
+ border-radius: 100px;
765
+ opacity: 0.8;
766
+ };
767
+ }
503
768
 
504
769
  &__deletable {
505
770
  position: absolute;
@@ -557,6 +822,12 @@
557
822
  /* #endif */
558
823
  }
559
824
  }
825
+ &__progress {
826
+ background-color: $u-primary !important;
827
+ position: absolute;
828
+ bottom: 0;
829
+ left: 0;
830
+ }
560
831
 
561
832
  &__status {
562
833
  position: absolute;
@@ -32,6 +32,13 @@ export default {
32
32
  uploadText: '',
33
33
  width: 80,
34
34
  height: 80,
35
- previewImage: true
35
+ previewImage: true,
36
+ autoDelete: false,
37
+ autoUpload: false,
38
+ autoUploadApi: '',
39
+ autoUploadAuthUrl: '',
40
+ autoUploadDriver: '',
41
+ autoUploadHeader: {},
42
+ getVideoThumb: false
36
43
  }
37
44
  }
@@ -21,21 +21,30 @@ function formatImage(res) {
21
21
  // #ifdef H5
22
22
  name: item.name,
23
23
  file: item
24
+ // #endif
25
+ // #ifndef H5
26
+ name: res.tempFilePath.split('/').pop() + '.png',
24
27
  // #endif
25
28
  }))
26
29
  }
27
30
 
28
- function formatVideo(res) {
31
+ function formatVideo(res) {
32
+ // console.log(res)
29
33
  return [
30
34
  {
31
35
  ...pickExclude(res, ['tempFilePath', 'thumbTempFilePath', 'errMsg']),
32
36
  type: 'video',
33
37
  url: res.tempFilePath,
34
38
  thumb: res.thumbTempFilePath,
35
- size: res.size,
39
+ size: res.size,
40
+ width: res.width || 0, // APP 2.1.0+、H5、微信小程序、京东小程序
41
+ height: res.height || 0, // APP 2.1.0+、H5、微信小程序、京东小程序
36
42
  // #ifdef H5
37
43
  name: res.name,
38
44
  file: res
45
+ // #endif
46
+ // #ifndef H5
47
+ name: res.tempFilePath.split('/').pop() + '.mp4',
39
48
  // #endif
40
49
  }
41
50
  ]
@@ -50,6 +59,9 @@ function formatMedia(res) {
50
59
  size: item.size,
51
60
  // #ifdef H5
52
61
  file: item
62
+ // #endif
63
+ // #ifndef H5
64
+ name: res.tempFilePath.split('/').pop() + (res.type === 'video' ? '.mp4': '.png'),
53
65
  // #endif
54
66
  }))
55
67
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "id": "uview-plus",
3
3
  "name": "uview-plus",
4
4
  "displayName": "零云®uview-plus3.0重磅发布,全面的Vue3鸿蒙移动组件库。",
5
- "version": "3.4.5",
5
+ "version": "3.4.7",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
7
7
  "keywords": [
8
8
  "uview",