hy-app 0.6.4 → 0.6.6

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.
Files changed (106) hide show
  1. package/attributes.json +1 -1
  2. package/components/hy-address-picker/hy-address-picker.vue +249 -249
  3. package/components/hy-address-picker/props.ts +103 -103
  4. package/components/hy-button/hy-button.vue +320 -289
  5. package/components/hy-button/props.ts +143 -143
  6. package/components/hy-button/typing.d.ts +43 -35
  7. package/components/hy-calendar/header.vue +58 -58
  8. package/components/hy-calendar/hy-calendar.vue +8 -6
  9. package/components/hy-calendar/month.vue +402 -402
  10. package/components/hy-calendar/props.ts +169 -169
  11. package/components/hy-calendar/typing.d.ts +47 -45
  12. package/components/hy-cell-item/hy-cell-item.vue +161 -161
  13. package/components/hy-cell-item/props.ts +59 -59
  14. package/components/hy-check-button/hy-check-button.vue +135 -135
  15. package/components/hy-code-input/hy-code-input.vue +231 -231
  16. package/components/hy-code-input/props.ts +90 -90
  17. package/components/hy-config-provider/hy-config-provider.vue +53 -53
  18. package/components/hy-config-provider/props.ts +30 -30
  19. package/components/hy-coupon/hy-coupon.vue +183 -183
  20. package/components/hy-coupon/props.ts +108 -108
  21. package/components/hy-datetime-picker/hy-datetime-picker.vue +41 -55
  22. package/components/hy-datetime-picker/props.ts +144 -144
  23. package/components/hy-datetime-picker/typing.d.ts +2 -0
  24. package/components/hy-divider/props.ts +83 -83
  25. package/components/hy-empty/icon.ts +72 -72
  26. package/components/hy-folding-panel/hy-folding-panel-group.vue +162 -162
  27. package/components/hy-form/hy-form.vue +220 -220
  28. package/components/hy-icon/hy-icon.vue +112 -112
  29. package/components/hy-index-bar/hy-index-bar.vue +185 -185
  30. package/components/hy-index-bar/index.scss +64 -64
  31. package/components/hy-index-bar/props.ts +94 -94
  32. package/components/hy-index-bar/typing.d.ts +36 -36
  33. package/components/hy-input/hy-input.vue +333 -333
  34. package/components/hy-input/props.ts +186 -186
  35. package/components/hy-modal/hy-modal.vue +211 -211
  36. package/components/hy-modal/props.ts +94 -94
  37. package/components/hy-modal/typing.d.ts +16 -16
  38. package/components/hy-notice-bar/hy-row-notice.vue +121 -121
  39. package/components/hy-notify/hy-notify.vue +174 -174
  40. package/components/hy-number-step/hy-number-step.vue +367 -367
  41. package/components/hy-overlay/hy-overlay.vue +61 -61
  42. package/components/hy-overlay/props.ts +38 -38
  43. package/components/hy-pagination/hy-pagination.vue +136 -136
  44. package/components/hy-pagination/props.ts +58 -58
  45. package/components/hy-parse/hy-parse.vue +550 -550
  46. package/components/hy-parse/node/node.vue +781 -781
  47. package/components/hy-parse/parser.js +1455 -1455
  48. package/components/hy-parse/props.ts +19 -19
  49. package/components/hy-parse/typing.d.ts +68 -68
  50. package/components/hy-picker/hy-picker.vue +435 -435
  51. package/components/hy-picker/props.ts +122 -122
  52. package/components/hy-picker/typing.d.ts +38 -38
  53. package/components/hy-qrcode/props.ts +72 -72
  54. package/components/hy-qrcode/qrcode.js.bak +1433 -1433
  55. package/components/hy-radio/props.ts +97 -97
  56. package/components/hy-read-more/props.ts +48 -48
  57. package/components/hy-search/props.ts +133 -133
  58. package/components/hy-signature/canvasHelper.ts +51 -51
  59. package/components/hy-signature/props.ts +121 -121
  60. package/components/hy-skeleton/hy-skeleton.vue +142 -142
  61. package/components/hy-skeleton/props.ts +46 -46
  62. package/components/hy-skeleton/typing.d.ts +31 -31
  63. package/components/hy-steps/hy-steps.vue +275 -275
  64. package/components/hy-steps/typing.d.ts +25 -25
  65. package/components/hy-swiper/hy-swiper.vue +3 -3
  66. package/components/hy-swiper/index.scss +5 -5
  67. package/components/hy-swiper/props.ts +0 -1
  68. package/components/hy-table/hy-table.vue +630 -630
  69. package/components/hy-table/props.ts +62 -62
  70. package/components/hy-table/typing.d.ts +29 -29
  71. package/components/hy-tabs/hy-tabs.vue +336 -335
  72. package/components/hy-tabs/props.ts +84 -77
  73. package/components/hy-tag/hy-tag.vue +173 -173
  74. package/components/hy-tag/props.ts +89 -89
  75. package/components/hy-text/hy-text.vue +237 -237
  76. package/components/hy-text/props.ts +115 -115
  77. package/components/hy-textarea/hy-textarea.vue +198 -198
  78. package/components/hy-toast/hy-toast.vue +200 -200
  79. package/components/hy-toast/props.ts +3 -3
  80. package/components/hy-transition/hy-transition.vue +157 -157
  81. package/components/hy-transition/props.ts +32 -32
  82. package/components/hy-upload/hy-upload.vue +384 -384
  83. package/components/hy-watermark/hy-watermark.vue +1058 -1058
  84. package/components/hy-watermark/props.ts +109 -109
  85. package/global.d.ts +94 -94
  86. package/libs/api/http.ts +119 -119
  87. package/libs/composables/index.ts +8 -8
  88. package/libs/composables/useMessage.ts +149 -149
  89. package/libs/composables/useToast.ts +45 -45
  90. package/libs/composables/useTranslate.ts +10 -10
  91. package/libs/css/_config.scss +5 -5
  92. package/libs/index.ts +8 -8
  93. package/libs/locale/index.ts +32 -32
  94. package/libs/locale/lang/en-US.ts +84 -84
  95. package/libs/locale/lang/zh-CN.ts +87 -87
  96. package/libs/typing/index.ts +2 -2
  97. package/libs/typing/modules/common.d.ts +139 -139
  98. package/libs/typing/modules/form.ts +176 -176
  99. package/libs/typing/modules/http.d.ts +19 -19
  100. package/libs/typing/modules/index.d.ts +12 -12
  101. package/libs/utils/inside.ts +340 -340
  102. package/libs/utils/inspect.ts +140 -140
  103. package/libs/utils/utils.ts +525 -525
  104. package/package.json +81 -81
  105. package/tags.json +1 -1
  106. package/web-types.json +1 -1
@@ -1,384 +1,384 @@
1
- <template>
2
- <view class="hy-upload" :style="[customStyle]">
3
- <view class="hy-upload__wrap">
4
- <template v-if="previewImage">
5
- <view class="hy-upload__wrap--preview" v-for="(item, index) in lists" :key="index">
6
- <image
7
- v-if="item.isImage || (item.type && item.type === 'image')"
8
- :src="item.thumb || item.url"
9
- :mode="imageMode"
10
- class="hy-upload__wrap--preview__image"
11
- @tap="onPreviewImage(item, index)"
12
- :style="[
13
- {
14
- width: addUnit(width),
15
- height: addUnit(height)
16
- }
17
- ]"
18
- />
19
- <view
20
- v-else
21
- class="hy-upload__wrap--preview__other"
22
- @tap="onClickPreview(item, index)"
23
- >
24
- <hy-icon
25
- color="#80CBF9"
26
- size="26"
27
- :name="
28
- item.isVideo || (item.type && item.type === 'video')
29
- ? 'movie'
30
- : 'folder'
31
- "
32
- ></hy-icon>
33
- <text class="hy-upload__wrap--preview__other--text">
34
- {{
35
- item.isVideo || (item.type && item.type === 'video')
36
- ? '视频'
37
- : '文件'
38
- }}
39
- </text>
40
- </view>
41
-
42
- <!-- 上传进度条 -->
43
- <view
44
- class="hy-upload__wrap--preview__progress"
45
- v-if="item.status === 'loading'"
46
- >
47
- <hy-line-progress
48
- custom-class="hy-upload__wrap--preview__progress--number"
49
- :percentage="item.schedule"
50
- height="6"
51
- />
52
- <view class="hy-upload__wrap--preview__progress--value">{{
53
- t('progressLabel', item.schedule)
54
- }}</view>
55
- </view>
56
- <!-- 上传进度条 -->
57
-
58
- <!-- 删除图片图标 -->
59
- <view
60
- class="hy-upload__deletable"
61
- v-if="item.status !== 'loading' && (deletable || item.deletable)"
62
- @tap.stop="deleteItem(index)"
63
- >
64
- <view class="hy-upload__deletable--icon">
65
- <hy-icon :name="IconConfig.CLOSE" color="#ffffff" size="14"></hy-icon>
66
- </view>
67
- </view>
68
- <!-- 删除图片图标 -->
69
-
70
- <!-- 上传成功图标 -->
71
- <view class="hy-upload__success" v-if="item.status === 'success'">
72
- <view class="hy-upload__success--icon">
73
- <hy-icon
74
- :name="IconConfig.CHECK_MASK"
75
- color="#ffffff"
76
- size="12"
77
- ></hy-icon>
78
- </view>
79
- </view>
80
- <!-- 上传成功图标 -->
81
- </view>
82
- </template>
83
-
84
- <template v-if="isInCount">
85
- <view v-if="$slots.trigger" @tap="chooseFileFn">
86
- <slot name="trigger" />
87
- </view>
88
- <view
89
- v-else-if="!$slots.trigger && ($slots.default || $slots.$default)"
90
- @tap="chooseFileFn"
91
- >
92
- <slot />
93
- </view>
94
- <view
95
- v-else
96
- class="hy-upload__button"
97
- :hover-class="!disabled ? 'hy-upload__button--hover' : ''"
98
- hover-stay-time="150"
99
- @tap="chooseFileFn"
100
- :class="[disabled && 'hy-upload__button--disabled']"
101
- :style="[
102
- {
103
- width: addUnit(width),
104
- height: addUnit(height)
105
- }
106
- ]"
107
- >
108
- <hy-icon :name="uploadIcon" size="26" :color="uploadIconColor"></hy-icon>
109
- <text v-if="uploadText" class="hy-upload__button--text">{{ uploadText }}</text>
110
- </view>
111
- </template>
112
- </view>
113
- </view>
114
- </template>
115
-
116
- <script lang="ts">
117
- export default {
118
- name: 'hy-upload',
119
- options: {
120
- addGlobalClass: true,
121
- virtualHost: true,
122
- styleIsolation: 'shared'
123
- }
124
- }
125
- </script>
126
-
127
- <script setup lang="ts">
128
- import { ref, watch } from 'vue'
129
- import type { FileVo, IUploadEmits } from './typing'
130
- import { addUnit, chooseFile, isArray, IconConfig, useTranslate } from '../../libs'
131
- import uploadProps from './props'
132
- // 组件
133
- import HyIcon from '../hy-icon/hy-icon.vue'
134
- import HyLineProgress from '../hy-line-progress/hy-line-progress.vue'
135
-
136
- /**
137
- * 该组件用于上传图片或者视频等场景
138
- * @displayName hy-upload
139
- */
140
- defineOptions({})
141
-
142
- const props = defineProps(uploadProps)
143
- const emit = defineEmits<IUploadEmits>()
144
-
145
- const { t } = useTranslate('upload')
146
- const lists = ref<FileVo[]>([])
147
- // 上传按钮
148
- const isInCount = ref<boolean>(true)
149
- // 遮罩框
150
- const previewImage = ref<boolean>(true)
151
-
152
- const formatFileList = () => {
153
- lists.value = props.fileList.map((item: FileVo) =>
154
- Object.assign(Object.assign({}, item), {
155
- // 如果item.url为本地选择的blob文件的话,无法判断其为video还是image,此处优先通过accept做判断处理
156
- isImage: props.accept === 'image',
157
- isVideo: props.accept === 'video',
158
- deletable: item.deletable || props.deletable
159
- })
160
- )
161
- isInCount.value = lists.value.length < props.maxCount
162
- }
163
-
164
- watch(
165
- () => props.fileList,
166
- () => {
167
- formatFileList()
168
- },
169
- { immediate: true, deep: true }
170
- )
171
-
172
- watch(
173
- () => props.deletable,
174
- () => {
175
- formatFileList()
176
- }
177
- )
178
-
179
- watch(
180
- () => props.maxCount,
181
- () => {
182
- formatFileList()
183
- }
184
- )
185
-
186
- watch(
187
- () => props.accept,
188
- () => {
189
- formatFileList()
190
- }
191
- )
192
-
193
- const chooseFileFn = () => {
194
- if (props.disabled) return
195
- // 如果用户传入的是字符串,需要格式化成数组
196
- chooseFile(
197
- Object.assign(
198
- {
199
- accept: props.accept,
200
- extension: props.extension,
201
- multiple: props.multiple,
202
- capture: props.capture,
203
- compressed: props.compressed,
204
- maxDuration: props.maxDuration,
205
- sizeType: props.sizeType,
206
- camera: props.camera
207
- },
208
- {
209
- maxCount: props.maxCount - lists.value.length
210
- }
211
- )
212
- )
213
- .then((res: any) => {
214
- onBeforeRead(props.multiple ? res : res[0])
215
- })
216
- .catch((error) => {
217
- emit('error', error)
218
- })
219
- }
220
- // 文件读取之前
221
- const onBeforeRead = (file: FileVo) => {
222
- let res: any = true
223
- // beforeRead是否为一个方法
224
- if (typeof props.beforeRead === 'function') {
225
- // 如果用户定义了此方法,则去执行此方法,并传入读取的文件回调
226
- res = props.beforeRead(file, getDetail())
227
- }
228
- if (props.useBeforeRead) {
229
- res = new Promise((resolve, reject) => {
230
- emit(
231
- 'beforeRead',
232
- Object.assign(
233
- Object.assign(
234
- {
235
- file
236
- },
237
- getDetail()
238
- ),
239
- {
240
- callback: (ok: any) => {
241
- ok ? resolve(ok) : reject()
242
- }
243
- }
244
- )
245
- )
246
- })
247
- }
248
- if (!res) return
249
- if (typeof res === 'function') {
250
- res.then((data: any) => onAfterRead(data || file))
251
- } else {
252
- onAfterRead(file)
253
- }
254
- }
255
- const getDetail = (index?: number) => {
256
- return {
257
- name: props.name,
258
- index: index == null ? props.fileList.length : index
259
- }
260
- }
261
- const onAfterRead = (file: FileVo) => {
262
- const oversize = isArray(file)
263
- ? file.some((item) => item.size > props.maxSize)
264
- : Number(file.size) > props.maxSize
265
- if (oversize) {
266
- emit(
267
- 'oversize',
268
- Object.assign(
269
- {
270
- file
271
- },
272
- getDetail()
273
- )
274
- )
275
- return
276
- }
277
- if (typeof props.afterRead === 'function') {
278
- props.afterRead(file, getDetail())
279
- }
280
- emit(
281
- 'afterRead',
282
- Object.assign(
283
- {
284
- file
285
- },
286
- getDetail()
287
- )
288
- )
289
- }
290
-
291
- /**
292
- * @description 删除文件
293
- * */
294
- const deleteItem = (index: number) => {
295
- props.fileList.splice(index, 1)
296
- isInCount.value = lists.value.length < props.maxCount
297
- emit(
298
- 'delete',
299
- Object.assign(Object.assign({}, getDetail(index)), {
300
- file: props.fileList[index]
301
- })
302
- )
303
- }
304
-
305
- /**
306
- * @description 预览图片
307
- * */
308
- const onPreviewImage = (previewItem: FileVo, index: number) => {
309
- if (!previewItem.isImage || !props.previewFullImage) return
310
- let current = 0
311
- const urls: string[] = []
312
- let imageIndex = 0
313
- for (let i = 0; i < lists.value.length; i++) {
314
- const item: FileVo = lists.value[i]
315
- if (item.isImage || (item.type && item.type === 'image')) {
316
- urls.push(item.url || (item.thumb as string))
317
- if (i === index) {
318
- current = imageIndex
319
- }
320
- imageIndex += 1
321
- }
322
- }
323
- if (!urls || urls.length < 1) return
324
- uni.previewImage({
325
- urls: urls,
326
- current: current,
327
- fail() {
328
- uni.showToast({ title: '预览图片失败' })
329
- }
330
- })
331
- }
332
-
333
- /**
334
- * @description 预览视频
335
- * */
336
- const onPreviewVideo = (index: number) => {
337
- if (!props.previewFullImage) return
338
- let current = 0
339
- const sources: any[] = []
340
- let videoIndex = 0
341
- for (let i = 0; i < lists.value.length; i++) {
342
- const item: FileVo = lists.value[i]
343
- if (item.isVideo || (item.type && item.type === 'video')) {
344
- sources.push(
345
- Object.assign(Object.assign({}, item), {
346
- type: 'video'
347
- })
348
- )
349
- if (i === index) {
350
- current = videoIndex
351
- }
352
- videoIndex += 1
353
- }
354
- }
355
- if (sources.length < 1) {
356
- return
357
- }
358
- // #ifdef MP-WEIXIN
359
- wx.previewMedia({
360
- sources: sources,
361
- current: current,
362
- fail() {
363
- uni.showToast({ title: '预览视频失败' })
364
- }
365
- })
366
- // #endif
367
- }
368
-
369
- const onClickPreview = (item: FileVo, index: number) => {
370
- if (!props.previewFullImage) return
371
- switch (item.type) {
372
- case 'video':
373
- onPreviewVideo(index)
374
- break
375
- default:
376
- break
377
- }
378
- emit('clickPreview', Object.assign(Object.assign({}, item), getDetail(index)))
379
- }
380
- </script>
381
-
382
- <style lang="scss" scoped>
383
- @import './index.scss';
384
- </style>
1
+ <template>
2
+ <view class="hy-upload" :style="[customStyle]">
3
+ <view class="hy-upload__wrap">
4
+ <template v-if="previewImage">
5
+ <view class="hy-upload__wrap--preview" v-for="(item, index) in lists" :key="index">
6
+ <image
7
+ v-if="item.isImage || (item.type && item.type === 'image')"
8
+ :src="item.thumb || item.url"
9
+ :mode="imageMode"
10
+ class="hy-upload__wrap--preview__image"
11
+ @tap="onPreviewImage(item, index)"
12
+ :style="[
13
+ {
14
+ width: addUnit(width),
15
+ height: addUnit(height)
16
+ }
17
+ ]"
18
+ />
19
+ <view
20
+ v-else
21
+ class="hy-upload__wrap--preview__other"
22
+ @tap="onClickPreview(item, index)"
23
+ >
24
+ <hy-icon
25
+ color="#80CBF9"
26
+ size="26"
27
+ :name="
28
+ item.isVideo || (item.type && item.type === 'video')
29
+ ? 'movie'
30
+ : 'folder'
31
+ "
32
+ ></hy-icon>
33
+ <text class="hy-upload__wrap--preview__other--text">
34
+ {{
35
+ item.isVideo || (item.type && item.type === 'video')
36
+ ? '视频'
37
+ : '文件'
38
+ }}
39
+ </text>
40
+ </view>
41
+
42
+ <!-- 上传进度条 -->
43
+ <view
44
+ class="hy-upload__wrap--preview__progress"
45
+ v-if="item.status === 'loading'"
46
+ >
47
+ <hy-line-progress
48
+ custom-class="hy-upload__wrap--preview__progress--number"
49
+ :percentage="item.schedule"
50
+ height="6"
51
+ />
52
+ <view class="hy-upload__wrap--preview__progress--value">{{
53
+ t('progressLabel', item.schedule)
54
+ }}</view>
55
+ </view>
56
+ <!-- 上传进度条 -->
57
+
58
+ <!-- 删除图片图标 -->
59
+ <view
60
+ class="hy-upload__deletable"
61
+ v-if="item.status !== 'loading' && (deletable || item.deletable)"
62
+ @tap.stop="deleteItem(index)"
63
+ >
64
+ <view class="hy-upload__deletable--icon">
65
+ <hy-icon :name="IconConfig.CLOSE" color="#ffffff" size="14"></hy-icon>
66
+ </view>
67
+ </view>
68
+ <!-- 删除图片图标 -->
69
+
70
+ <!-- 上传成功图标 -->
71
+ <view class="hy-upload__success" v-if="item.status === 'success'">
72
+ <view class="hy-upload__success--icon">
73
+ <hy-icon
74
+ :name="IconConfig.CHECK_MASK"
75
+ color="#ffffff"
76
+ size="12"
77
+ ></hy-icon>
78
+ </view>
79
+ </view>
80
+ <!-- 上传成功图标 -->
81
+ </view>
82
+ </template>
83
+
84
+ <template v-if="isInCount">
85
+ <view v-if="$slots.trigger" @tap="chooseFileFn">
86
+ <slot name="trigger" />
87
+ </view>
88
+ <view
89
+ v-else-if="!$slots.trigger && ($slots.default || $slots.$default)"
90
+ @tap="chooseFileFn"
91
+ >
92
+ <slot />
93
+ </view>
94
+ <view
95
+ v-else
96
+ class="hy-upload__button"
97
+ :hover-class="!disabled ? 'hy-upload__button--hover' : ''"
98
+ hover-stay-time="150"
99
+ @tap="chooseFileFn"
100
+ :class="[disabled && 'hy-upload__button--disabled']"
101
+ :style="[
102
+ {
103
+ width: addUnit(width),
104
+ height: addUnit(height)
105
+ }
106
+ ]"
107
+ >
108
+ <hy-icon :name="uploadIcon" size="26" :color="uploadIconColor"></hy-icon>
109
+ <text v-if="uploadText" class="hy-upload__button--text">{{ uploadText }}</text>
110
+ </view>
111
+ </template>
112
+ </view>
113
+ </view>
114
+ </template>
115
+
116
+ <script lang="ts">
117
+ export default {
118
+ name: 'hy-upload',
119
+ options: {
120
+ addGlobalClass: true,
121
+ virtualHost: true,
122
+ styleIsolation: 'shared'
123
+ }
124
+ }
125
+ </script>
126
+
127
+ <script setup lang="ts">
128
+ import { ref, watch } from 'vue'
129
+ import type { FileVo, IUploadEmits } from './typing'
130
+ import { addUnit, chooseFile, isArray, IconConfig, useTranslate } from '../../libs'
131
+ import uploadProps from './props'
132
+ // 组件
133
+ import HyIcon from '../hy-icon/hy-icon.vue'
134
+ import HyLineProgress from '../hy-line-progress/hy-line-progress.vue'
135
+
136
+ /**
137
+ * 该组件用于上传图片或者视频等场景
138
+ * @displayName hy-upload
139
+ */
140
+ defineOptions({})
141
+
142
+ const props = defineProps(uploadProps)
143
+ const emit = defineEmits<IUploadEmits>()
144
+
145
+ const { t } = useTranslate('upload')
146
+ const lists = ref<FileVo[]>([])
147
+ // 上传按钮
148
+ const isInCount = ref<boolean>(true)
149
+ // 遮罩框
150
+ const previewImage = ref<boolean>(true)
151
+
152
+ const formatFileList = () => {
153
+ lists.value = props.fileList.map((item: FileVo) =>
154
+ Object.assign(Object.assign({}, item), {
155
+ // 如果item.url为本地选择的blob文件的话,无法判断其为video还是image,此处优先通过accept做判断处理
156
+ isImage: props.accept === 'image',
157
+ isVideo: props.accept === 'video',
158
+ deletable: item.deletable || props.deletable
159
+ })
160
+ )
161
+ isInCount.value = lists.value.length < props.maxCount
162
+ }
163
+
164
+ watch(
165
+ () => props.fileList,
166
+ () => {
167
+ formatFileList()
168
+ },
169
+ { immediate: true, deep: true }
170
+ )
171
+
172
+ watch(
173
+ () => props.deletable,
174
+ () => {
175
+ formatFileList()
176
+ }
177
+ )
178
+
179
+ watch(
180
+ () => props.maxCount,
181
+ () => {
182
+ formatFileList()
183
+ }
184
+ )
185
+
186
+ watch(
187
+ () => props.accept,
188
+ () => {
189
+ formatFileList()
190
+ }
191
+ )
192
+
193
+ const chooseFileFn = () => {
194
+ if (props.disabled) return
195
+ // 如果用户传入的是字符串,需要格式化成数组
196
+ chooseFile(
197
+ Object.assign(
198
+ {
199
+ accept: props.accept,
200
+ extension: props.extension,
201
+ multiple: props.multiple,
202
+ capture: props.capture,
203
+ compressed: props.compressed,
204
+ maxDuration: props.maxDuration,
205
+ sizeType: props.sizeType,
206
+ camera: props.camera
207
+ },
208
+ {
209
+ maxCount: props.maxCount - lists.value.length
210
+ }
211
+ )
212
+ )
213
+ .then((res: any) => {
214
+ onBeforeRead(props.multiple ? res : res[0])
215
+ })
216
+ .catch((error) => {
217
+ emit('error', error)
218
+ })
219
+ }
220
+ // 文件读取之前
221
+ const onBeforeRead = (file: FileVo) => {
222
+ let res: any = true
223
+ // beforeRead是否为一个方法
224
+ if (typeof props.beforeRead === 'function') {
225
+ // 如果用户定义了此方法,则去执行此方法,并传入读取的文件回调
226
+ res = props.beforeRead(file, getDetail())
227
+ }
228
+ if (props.useBeforeRead) {
229
+ res = new Promise((resolve, reject) => {
230
+ emit(
231
+ 'beforeRead',
232
+ Object.assign(
233
+ Object.assign(
234
+ {
235
+ file
236
+ },
237
+ getDetail()
238
+ ),
239
+ {
240
+ callback: (ok: any) => {
241
+ ok ? resolve(ok) : reject()
242
+ }
243
+ }
244
+ )
245
+ )
246
+ })
247
+ }
248
+ if (!res) return
249
+ if (typeof res === 'function') {
250
+ res.then((data: any) => onAfterRead(data || file))
251
+ } else {
252
+ onAfterRead(file)
253
+ }
254
+ }
255
+ const getDetail = (index?: number) => {
256
+ return {
257
+ name: props.name,
258
+ index: index == null ? props.fileList.length : index
259
+ }
260
+ }
261
+ const onAfterRead = (file: FileVo) => {
262
+ const oversize = isArray(file)
263
+ ? file.some((item) => item.size > props.maxSize)
264
+ : Number(file.size) > props.maxSize
265
+ if (oversize) {
266
+ emit(
267
+ 'oversize',
268
+ Object.assign(
269
+ {
270
+ file
271
+ },
272
+ getDetail()
273
+ )
274
+ )
275
+ return
276
+ }
277
+ if (typeof props.afterRead === 'function') {
278
+ props.afterRead(file, getDetail())
279
+ }
280
+ emit(
281
+ 'afterRead',
282
+ Object.assign(
283
+ {
284
+ file
285
+ },
286
+ getDetail()
287
+ )
288
+ )
289
+ }
290
+
291
+ /**
292
+ * @description 删除文件
293
+ * */
294
+ const deleteItem = (index: number) => {
295
+ props.fileList.splice(index, 1)
296
+ isInCount.value = lists.value.length < props.maxCount
297
+ emit(
298
+ 'delete',
299
+ Object.assign(Object.assign({}, getDetail(index)), {
300
+ file: props.fileList[index]
301
+ })
302
+ )
303
+ }
304
+
305
+ /**
306
+ * @description 预览图片
307
+ * */
308
+ const onPreviewImage = (previewItem: FileVo, index: number) => {
309
+ if (!previewItem.isImage || !props.previewFullImage) return
310
+ let current = 0
311
+ const urls: string[] = []
312
+ let imageIndex = 0
313
+ for (let i = 0; i < lists.value.length; i++) {
314
+ const item: FileVo = lists.value[i]
315
+ if (item.isImage || (item.type && item.type === 'image')) {
316
+ urls.push(item.url || (item.thumb as string))
317
+ if (i === index) {
318
+ current = imageIndex
319
+ }
320
+ imageIndex += 1
321
+ }
322
+ }
323
+ if (!urls || urls.length < 1) return
324
+ uni.previewImage({
325
+ urls: urls,
326
+ current: current,
327
+ fail() {
328
+ uni.showToast({ title: '预览图片失败' })
329
+ }
330
+ })
331
+ }
332
+
333
+ /**
334
+ * @description 预览视频
335
+ * */
336
+ const onPreviewVideo = (index: number) => {
337
+ if (!props.previewFullImage) return
338
+ let current = 0
339
+ const sources: any[] = []
340
+ let videoIndex = 0
341
+ for (let i = 0; i < lists.value.length; i++) {
342
+ const item: FileVo = lists.value[i]
343
+ if (item.isVideo || (item.type && item.type === 'video')) {
344
+ sources.push(
345
+ Object.assign(Object.assign({}, item), {
346
+ type: 'video'
347
+ })
348
+ )
349
+ if (i === index) {
350
+ current = videoIndex
351
+ }
352
+ videoIndex += 1
353
+ }
354
+ }
355
+ if (sources.length < 1) {
356
+ return
357
+ }
358
+ // #ifdef MP-WEIXIN
359
+ wx.previewMedia({
360
+ sources: sources,
361
+ current: current,
362
+ fail() {
363
+ uni.showToast({ title: '预览视频失败' })
364
+ }
365
+ })
366
+ // #endif
367
+ }
368
+
369
+ const onClickPreview = (item: FileVo, index: number) => {
370
+ if (!props.previewFullImage) return
371
+ switch (item.type) {
372
+ case 'video':
373
+ onPreviewVideo(index)
374
+ break
375
+ default:
376
+ break
377
+ }
378
+ emit('clickPreview', Object.assign(Object.assign({}, item), getDetail(index)))
379
+ }
380
+ </script>
381
+
382
+ <style lang="scss" scoped>
383
+ @import './index.scss';
384
+ </style>