oxy-uni-ui 1.1.0 → 1.2.3

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 (123) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +59 -1
  3. package/components/common/path.ts +9 -0
  4. package/components/common/util.ts +42 -0
  5. package/components/composables/index.ts +1 -0
  6. package/components/composables/useGlobalLoading.ts +42 -0
  7. package/components/composables/useGlobalMessage.ts +48 -0
  8. package/components/composables/useGlobalToast.ts +84 -0
  9. package/components/composables/useVirtualScroll.ts +173 -0
  10. package/components/oxy-cell/oxy-cell.vue +15 -2
  11. package/components/oxy-cell/types.ts +4 -0
  12. package/components/oxy-checkbox/index.scss +1 -1
  13. package/components/oxy-checkbox/oxy-checkbox.vue +2 -2
  14. package/components/oxy-col-picker/oxy-col-picker.vue +3 -0
  15. package/components/oxy-col-picker/types.ts +5 -1
  16. package/components/oxy-corner/index.scss +121 -1
  17. package/components/oxy-corner/oxy-corner.vue +18 -5
  18. package/components/oxy-corner/types.ts +24 -3
  19. package/components/oxy-date-strip/index.scss +10 -0
  20. package/components/oxy-date-strip/oxy-date-strip.vue +198 -0
  21. package/components/oxy-date-strip/types.ts +98 -0
  22. package/components/oxy-date-strip/utils.ts +67 -0
  23. package/components/oxy-date-strip-item/index.scss +94 -0
  24. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +102 -0
  25. package/components/oxy-date-strip-item/types.ts +53 -0
  26. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +3 -1
  27. package/components/oxy-datetime-picker/types.ts +5 -1
  28. package/components/oxy-echarts/index.scss +17 -0
  29. package/components/oxy-echarts/index.ts +1 -0
  30. package/components/oxy-echarts/oxy-echarts.vue +32 -0
  31. package/components/oxy-echarts/types.ts +12 -0
  32. package/components/oxy-file-list/index.scss +26 -0
  33. package/components/oxy-file-list/oxy-file-list.vue +208 -34
  34. package/components/oxy-file-list/types.ts +58 -2
  35. package/components/oxy-global-loading/oxy-global-loading.vue +53 -0
  36. package/components/oxy-global-message/oxy-global-message.vue +64 -0
  37. package/components/oxy-global-toast/oxy-global-toast.vue +53 -0
  38. package/components/oxy-img-lazy/index.scss +17 -0
  39. package/components/oxy-img-lazy/oxy-img-lazy.vue +332 -0
  40. package/components/oxy-img-lazy/types.ts +69 -0
  41. package/components/oxy-link/index.scss +57 -0
  42. package/components/oxy-link/oxy-link.vue +130 -0
  43. package/components/oxy-link/types.ts +81 -0
  44. package/components/oxy-list/index.scss +8 -1
  45. package/components/oxy-list/oxy-list.vue +121 -40
  46. package/components/oxy-list/types.ts +3 -15
  47. package/components/oxy-picker/oxy-picker.vue +3 -0
  48. package/components/oxy-picker/types.ts +5 -1
  49. package/components/oxy-radio/index.scss +3 -3
  50. package/components/oxy-radio/oxy-radio.vue +1 -1
  51. package/components/oxy-rich-text/icon/emjio.svg +1 -0
  52. package/components/oxy-rich-text/icon/quote.svg +1 -0
  53. package/components/oxy-rich-text/icon/text.svg +1 -0
  54. package/components/oxy-rich-text/icon/title.svg +1 -0
  55. package/components/oxy-rich-text/index.scss +159 -0
  56. package/components/oxy-rich-text/mp-html/card/card.vue +122 -0
  57. package/components/oxy-rich-text/mp-html/card/index.js +7 -0
  58. package/components/oxy-rich-text/mp-html/editable/config.js +15 -0
  59. package/components/oxy-rich-text/mp-html/editable/index.js +553 -0
  60. package/components/oxy-rich-text/mp-html/emoji/index.js +203 -0
  61. package/components/oxy-rich-text/mp-html/highlight/config.js +5 -0
  62. package/components/oxy-rich-text/mp-html/highlight/index.js +96 -0
  63. package/components/oxy-rich-text/mp-html/highlight/prism.css +1 -0
  64. package/components/oxy-rich-text/mp-html/highlight/prism.min.js +7 -0
  65. package/components/oxy-rich-text/mp-html/img-cache/index.js +138 -0
  66. package/components/oxy-rich-text/mp-html/latex/index.js +80 -0
  67. package/components/oxy-rich-text/mp-html/latex/katex.css +1 -0
  68. package/components/oxy-rich-text/mp-html/latex/katex.min.js +1 -0
  69. package/components/oxy-rich-text/mp-html/markdown/index.js +50 -0
  70. package/components/oxy-rich-text/mp-html/markdown/marked.min.js +71 -0
  71. package/components/oxy-rich-text/mp-html/mp-html.d.ts +184 -0
  72. package/components/oxy-rich-text/mp-html/mp-html.vue +675 -0
  73. package/components/oxy-rich-text/mp-html/node/node.vue +1161 -0
  74. package/components/oxy-rich-text/mp-html/parser.js +1428 -0
  75. package/components/oxy-rich-text/mp-html/search/index.js +132 -0
  76. package/components/oxy-rich-text/mp-html/style/index.js +129 -0
  77. package/components/oxy-rich-text/mp-html/style/parser.js +175 -0
  78. package/components/oxy-rich-text/mp-html/template/index.js +67 -0
  79. package/components/oxy-rich-text/mp-html/txv-video/index.js +46 -0
  80. package/components/oxy-rich-text/oxy-rich-text.vue +642 -0
  81. package/components/oxy-rich-text/types.ts +71 -0
  82. package/components/oxy-select/index.scss +255 -0
  83. package/components/oxy-select/oxy-select.vue +421 -0
  84. package/components/oxy-select/types.ts +71 -0
  85. package/components/oxy-select-picker/oxy-select-picker.vue +3 -0
  86. package/components/oxy-select-picker/types.ts +5 -1
  87. package/components/oxy-stream-render/index.scss +6 -0
  88. package/components/oxy-stream-render/oxy-stream-render.vue +204 -0
  89. package/components/oxy-stream-render/types.ts +5 -0
  90. package/components/oxy-tree/index.scss +43 -5
  91. package/components/oxy-tree/oxy-tree.vue +233 -35
  92. package/components/oxy-tree/types.ts +54 -7
  93. package/components/oxy-tree/utils.ts +51 -0
  94. package/components/oxy-virtual-scroll/index.scss +1 -1
  95. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +69 -110
  96. package/components/oxy-virtual-scroll/types.ts +95 -5
  97. package/components/oxy-waterfall/index.scss +18 -0
  98. package/components/oxy-waterfall/oxy-waterfall.vue +218 -0
  99. package/components/oxy-waterfall/types.ts +90 -0
  100. package/components/oxy-waterfall-item/index.scss +8 -0
  101. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +89 -0
  102. package/components/oxy-waterfall-item/types.ts +16 -0
  103. package/global.d.ts +7 -0
  104. package/index.ts +3 -0
  105. package/locale/lang/en-US.ts +35 -9
  106. package/locale/lang/zh-CN.ts +31 -5
  107. package/oxy-uni-ui.zip +0 -0
  108. package/package.json +1 -1
  109. package/tags.json +1 -1
  110. package/uni-echarts/changelog.md +2 -0
  111. package/uni-echarts/components/index.js +1 -0
  112. package/uni-echarts/components/uni-echarts/events.js +95 -0
  113. package/uni-echarts/components/uni-echarts/types.d.ts +183 -0
  114. package/uni-echarts/components/uni-echarts/types.js +1 -0
  115. package/uni-echarts/components/uni-echarts/uni-echarts.vue +530 -0
  116. package/uni-echarts/components/uni-echarts/uni-echarts.vue.d.ts +19 -0
  117. package/uni-echarts/global.d.ts +7 -0
  118. package/uni-echarts/index.d.ts +440 -0
  119. package/uni-echarts/index.js +2 -0
  120. package/uni-echarts/package.json +105 -0
  121. package/uni-echarts/shared-core.d.ts +269 -0
  122. package/uni-echarts/shared-core.js +900 -0
  123. package/web-types.json +1 -1
@@ -1,16 +1,34 @@
1
1
  <template>
2
2
  <view :class="['oxy-file-list', { 'oxy-file-list__list': props.type === 'list' }, customClass]">
3
3
  <block v-if="props.type === 'list'">
4
- <view v-for="(file, index) in props.data" :key="index" class="oxy-file-list__list--item" @click="onPreview(file)">
4
+ <view v-for="(file, index) in props.data" :key="index" class="oxy-file-list__list--item" @click="handleClick(file, index)">
5
5
  <image :src="getUploadImage(file)" mode="aspectFill" class="oxy-file-list__icon" />
6
6
  <text class="oxy-file-list__name">{{ file.name }}</text>
7
+ <oxy-loading v-if="props.enableDownload && isDownloading(file)" size="18px" custom-class="oxy-file-list__download" />
8
+ <view @tap.stop="onDownload(file)" v-if="props.enableDownload && !isDownloading(file)">
9
+ <oxy-icon name="download" custom-class="oxy-file-list__download" />
10
+ </view>
11
+ <view v-if="props.enableDelete && !isDownloading(file)" @tap.stop="onDelete(file, index)">
12
+ <oxy-icon name="delete" custom-class="oxy-file-list__delete" />
13
+ </view>
7
14
  </view>
8
15
  </block>
9
16
  <block v-else>
10
17
  <view v-for="(file, index) in props.data" :key="index" class="oxy-file-list__item">
11
18
  <view class="oxy-file-list__content">
12
- <image v-if="isImage(file)" :src="file.url" mode="aspectFill" class="oxy-file-list__picture" @click="onPreview(file)" />
13
- <image v-else :src="getUploadImage(file)" mode="aspectFill" class="oxy-file-list__icon" @click="onPreview(file)" />
19
+ <image v-if="isImage(file)" :src="file.url" mode="aspectFill" class="oxy-file-list__picture" @click="handleClick(file, index)" />
20
+ <image v-else :src="getUploadImage(file)" mode="aspectFill" class="oxy-file-list__icon" @click="handleClick(file, index)" />
21
+ <view v-if="props.enableDownload || props.enableDelete" class="oxy-file-list__download-btn">
22
+ <template v-if="props.enableDownload">
23
+ <oxy-loading v-if="isDownloading(file)" size="18px" color="#ffffff" custom-class="oxy-file-list__download" />
24
+ <view @tap.stop="onDownload(file)">
25
+ <oxy-icon name="download" custom-class="oxy-file-list__download" />
26
+ </view>
27
+ </template>
28
+ <view v-if="props.enableDelete && !isDownloading(file)" @tap.stop="onDelete(file, index)">
29
+ <oxy-icon name="delete" custom-class="oxy-file-list__delete" />
30
+ </view>
31
+ </view>
14
32
  </view>
15
33
  <oxy-tooltip placement="top" :content="file.name">
16
34
  <text class="oxy-file-list__name">{{ file.name }}</text>
@@ -18,6 +36,8 @@
18
36
  </view>
19
37
  </block>
20
38
  </view>
39
+ <oxy-toast selector="oxy-file-list" />
40
+ <oxy-message-box selector="oxy-file-list" />
21
41
  <oxy-video-preview ref="videoPreview"></oxy-video-preview>
22
42
  </template>
23
43
 
@@ -39,7 +59,13 @@ import ImgVideo from '../oxy-upload/images/video.png'
39
59
  import ImgPic from '../oxy-upload/images/pic.png'
40
60
  import ImgOther from '../oxy-upload/images/other.png'
41
61
  import OxyVideoPreview from '../oxy-video-preview/oxy-video-preview.vue'
42
- import { ref } from 'vue'
62
+ import OxyIcon from '../oxy-icon/oxy-icon.vue'
63
+ import OxyLoading from '../oxy-loading/oxy-loading.vue'
64
+ import OxyToast from '../oxy-toast/oxy-toast.vue'
65
+ import OxyMessageBox from '../oxy-message-box/oxy-message-box.vue'
66
+ import { useToast } from '../oxy-toast'
67
+ import { useMessage } from '../oxy-message-box'
68
+ import { ref, nextTick } from 'vue'
43
69
  import { isImageUrl, isVideoUrl, isAudioUrl, isPdfUrl, isDocUrl } from '../common/util'
44
70
  import { type FileListItem, fileListProps } from './types'
45
71
  import type { VideoPreviewInstance } from '../oxy-video-preview/types'
@@ -54,25 +80,41 @@ const imgs: AnyObject = {
54
80
  }
55
81
 
56
82
  const props = defineProps(fileListProps)
83
+ const emit = defineEmits(['delete', 'click'])
57
84
 
58
85
  const videoPreview = ref<VideoPreviewInstance>()
86
+ const toast = useToast('oxy-file-list')
87
+ const message = useMessage('oxy-file-list')
88
+ const downloading = ref<Record<string, boolean>>({})
89
+
90
+ function isDownloading(file: FileListItem) {
91
+ return !!downloading.value[file.url]
92
+ }
59
93
  /**
60
94
  * 预览图片
61
95
  * @param file
62
96
  */
63
97
  function handlePreviewImage(file: FileListItem) {
64
98
  const { onPreviewFail } = props
99
+ toast.loading({ msg: '正在打开预览...', direction: 'vertical', position: 'middle' })
65
100
  uni.previewImage({
66
101
  urls: [file.url],
67
102
  current: 0,
103
+ success() {
104
+ toast.close()
105
+ },
68
106
  fail() {
69
107
  if (onPreviewFail) {
70
108
  onPreviewFail({
71
109
  file
72
110
  })
73
111
  } else {
74
- uni.showToast({ title: '预览图片失败', icon: 'none' })
112
+ toast.error({ msg: '预览图片失败', direction: 'vertical', position: 'middle' })
75
113
  }
114
+ toast.close()
115
+ },
116
+ complete() {
117
+ toast.close()
76
118
  }
77
119
  })
78
120
  }
@@ -81,8 +123,9 @@ function handlePreviewImage(file: FileListItem) {
81
123
  * 预览视频
82
124
  * @param file
83
125
  */
84
- function handlePreviewVieo(file: FileListItem) {
126
+ function handlePreviewVideo(file: FileListItem) {
85
127
  const { onPreviewFail } = props
128
+ toast.loading({ msg: '正在打开预览...', direction: 'vertical', position: 'middle' })
86
129
  // #ifdef MP-WEIXIN
87
130
  uni.previewMedia({
88
131
  current: 0,
@@ -93,19 +136,29 @@ function handlePreviewVieo(file: FileListItem) {
93
136
  poster: file.thumb
94
137
  }
95
138
  ],
139
+ success() {
140
+ toast.close()
141
+ },
96
142
  fail() {
97
143
  if (onPreviewFail) {
98
144
  onPreviewFail({
99
145
  file
100
146
  })
101
147
  } else {
102
- uni.showToast({ title: '预览视频失败', icon: 'none' })
148
+ toast.error({ msg: '预览视频失败', direction: 'vertical', position: 'middle' })
103
149
  }
150
+ toast.close()
151
+ },
152
+ complete() {
153
+ toast.close()
104
154
  }
105
155
  })
106
156
  // #endif
107
157
  // #ifndef MP-WEIXIN
108
158
  videoPreview.value?.open({ url: file.url, poster: file.thumb, title: file.name })
159
+ nextTick(() => {
160
+ toast.close()
161
+ })
109
162
  // #endif
110
163
  }
111
164
 
@@ -114,62 +167,183 @@ function handlePreviewVieo(file: FileListItem) {
114
167
  * @param file
115
168
  */
116
169
  function handlePreviewFile(file: FileListItem) {
170
+ const { onPreviewFail } = props
171
+ toast.loading({ msg: '正在打开预览...', direction: 'vertical', position: 'middle' })
117
172
  uni.openDocument({
118
173
  filePath: file.url,
119
- showMenu: true
174
+ showMenu: true,
175
+ success() {
176
+ toast.close()
177
+ },
178
+ fail() {
179
+ if (onPreviewFail) {
180
+ onPreviewFail({
181
+ file
182
+ })
183
+ } else {
184
+ toast.error({ msg: '预览文件失败', direction: 'vertical', position: 'middle' })
185
+ }
186
+ toast.close()
187
+ },
188
+ complete() {
189
+ toast.close()
190
+ }
120
191
  })
121
192
  }
122
193
 
123
- function onPreviewImage(file: FileListItem) {
194
+ function handleClick(file: FileListItem, index: number) {
195
+ emit('click', { file, index })
196
+ if (!props.enablePreview) return
197
+ const execPreview = () => {
198
+ if (isImage(file)) {
199
+ handlePreviewImage(file)
200
+ } else if (isVideo(file)) {
201
+ handlePreviewVideo(file)
202
+ } else {
203
+ handlePreviewFile(file)
204
+ }
205
+ }
206
+
124
207
  const { beforePreview } = props
125
208
  if (beforePreview) {
126
209
  beforePreview({
127
210
  file,
128
211
  resolve: (isPass: boolean) => {
129
- isPass && handlePreviewImage(file)
212
+ isPass && execPreview()
130
213
  }
131
214
  })
132
215
  } else {
133
- handlePreviewImage(file)
216
+ execPreview()
134
217
  }
135
218
  }
136
219
 
137
- function onPreviewVideo(file: FileListItem) {
138
- const { beforePreview } = props
139
- if (beforePreview) {
140
- beforePreview({
141
- file,
142
- resolve: (isPass: boolean) => {
143
- isPass && handlePreviewVieo(file)
220
+ function onDownload(file: FileListItem) {
221
+ const { beforeDownload, onDownloadSuccess, onDownloadFail } = props
222
+
223
+ const execDownload = () => {
224
+ const filename = file.name || file.url
225
+ downloading.value[file.url] = true
226
+ // #ifdef MP-WEIXIN
227
+ uni.downloadFile({
228
+ url: file.url,
229
+ success(res) {
230
+ const tempFilePath = res.tempFilePath
231
+ uni.saveFile({
232
+ tempFilePath,
233
+ success() {
234
+ if (onDownloadSuccess) {
235
+ onDownloadSuccess({ file, tempFilePath })
236
+ } else {
237
+ toast.success({ msg: `下载成功:${filename}`, direction: 'vertical', position: 'middle' })
238
+ }
239
+ downloading.value[file.url] = false
240
+ },
241
+ fail() {
242
+ if (onDownloadFail) {
243
+ onDownloadFail({ file })
244
+ } else {
245
+ toast.error({ msg: `下载失败:${filename}`, direction: 'vertical', position: 'middle' })
246
+ }
247
+ downloading.value[file.url] = false
248
+ }
249
+ })
250
+ },
251
+ fail() {
252
+ if (onDownloadFail) {
253
+ onDownloadFail({ file })
254
+ } else {
255
+ toast.error({ msg: `下载失败:${filename}`, direction: 'vertical', position: 'middle' })
256
+ }
257
+ downloading.value[file.url] = false
144
258
  }
145
259
  })
146
- } else {
147
- handlePreviewVieo(file)
260
+ // #endif
261
+ // #ifdef H5
262
+ try {
263
+ const a = document.createElement('a')
264
+ a.href = file.url
265
+ a.download = file.name || ''
266
+ a.target = '_blank'
267
+ document.body.appendChild(a)
268
+ a.click()
269
+ document.body.removeChild(a)
270
+ if (onDownloadSuccess) {
271
+ onDownloadSuccess({ file })
272
+ } else {
273
+ toast.success({ msg: `下载成功:${filename}`, direction: 'vertical', position: 'middle' })
274
+ }
275
+ downloading.value[file.url] = false
276
+ } catch (e) {
277
+ if (onDownloadFail) {
278
+ onDownloadFail({ file })
279
+ } else {
280
+ toast.error({ msg: `下载失败:${filename}`, direction: 'vertical', position: 'middle' })
281
+ }
282
+ downloading.value[file.url] = false
283
+ }
284
+ // #endif
285
+ // #ifdef APP-PLUS
286
+ uni.downloadFile({
287
+ url: file.url,
288
+ success(res) {
289
+ const tempFilePath = res.tempFilePath
290
+ uni.saveFile({
291
+ tempFilePath,
292
+ success() {
293
+ if (onDownloadSuccess) {
294
+ onDownloadSuccess({ file, tempFilePath })
295
+ } else {
296
+ toast.success({ msg: `下载成功:${filename}`, direction: 'vertical', position: 'middle' })
297
+ }
298
+ downloading.value[file.url] = false
299
+ },
300
+ fail() {
301
+ if (onDownloadFail) {
302
+ onDownloadFail({ file })
303
+ } else {
304
+ toast.error({ msg: `下载失败:${filename}`, direction: 'vertical', position: 'middle' })
305
+ }
306
+ downloading.value[file.url] = false
307
+ }
308
+ })
309
+ },
310
+ fail() {
311
+ if (onDownloadFail) {
312
+ onDownloadFail({ file })
313
+ } else {
314
+ toast.error({ msg: `下载失败:${filename}`, direction: 'vertical', position: 'middle' })
315
+ }
316
+ downloading.value[file.url] = false
317
+ }
318
+ })
319
+ // #endif
148
320
  }
149
- }
150
321
 
151
- function onPreviewFile(file: FileListItem) {
152
- const { beforePreview } = props
153
- if (beforePreview) {
154
- beforePreview({
322
+ if (beforeDownload) {
323
+ beforeDownload({
155
324
  file,
156
325
  resolve: (isPass: boolean) => {
157
- isPass && handlePreviewFile(file)
326
+ isPass && execDownload()
158
327
  }
159
328
  })
160
329
  } else {
161
- handlePreviewFile(file)
330
+ execDownload()
162
331
  }
163
332
  }
164
333
 
165
- function onPreview(file: FileListItem) {
166
- if (isImage(file)) {
167
- onPreviewImage(file)
168
- } else if (isVideo(file)) {
169
- onPreviewVideo(file)
170
- } else {
171
- onPreviewFile(file)
334
+ function onDelete(file: FileListItem, index: number) {
335
+ const execDelete = () => {
336
+ const title = '确认删除文件'
337
+ const msg = file.name || '确认删除该文件?'
338
+ message
339
+ .confirm({ title, msg, confirmButtonText: '删除', cancelButtonText: '取消' })
340
+ .then(() => {
341
+ emit('delete', { file, index })
342
+ })
343
+ .catch(() => {})
172
344
  }
345
+
346
+ execDelete()
173
347
  }
174
348
 
175
349
  function isVideo(file: FileListItem) {
@@ -1,5 +1,5 @@
1
1
  import type { ExtractPropTypes, PropType } from 'vue'
2
- import { baseProps, makeArrayProp, makeStringProp } from '../common/props'
2
+ import { baseProps, makeArrayProp, makeStringProp, makeBooleanProp } from '../common/props'
3
3
 
4
4
  export type FileListItem = {
5
5
  [key: string]: any
@@ -22,6 +22,29 @@ export type FileListOnPreviewFailOption = {
22
22
  }
23
23
  export type FileListOnPreviewFail = (option: FileListOnPreviewFailOption) => void
24
24
 
25
+ export type FileListBeforeDownloadOption = {
26
+ file: FileListItem
27
+ resolve: (isPass: boolean) => void
28
+ }
29
+ export type FileListBeforeDownload = (option: FileListBeforeDownloadOption) => void
30
+
31
+ export type FileListOnDownloadSuccessOption = {
32
+ file: FileListItem
33
+ tempFilePath?: string
34
+ }
35
+ export type FileListOnDownloadSuccess = (option: FileListOnDownloadSuccessOption) => void
36
+
37
+ export type FileListOnDownloadFailOption = {
38
+ file: FileListItem
39
+ }
40
+ export type FileListOnDownloadFail = (option: FileListOnDownloadFailOption) => void
41
+
42
+ export type FileListBeforeDeleteOption = {
43
+ file: FileListItem
44
+ resolve: (isPass: boolean) => void
45
+ }
46
+ export type FileListBeforeDelete = (option: FileListBeforeDeleteOption) => void
47
+
25
48
  export const fileListProps = {
26
49
  ...baseProps,
27
50
 
@@ -37,6 +60,24 @@ export const fileListProps = {
37
60
  * 默认值:'card'
38
61
  */
39
62
  type: makeStringProp<FileListType>('list'),
63
+ /**
64
+ * 是否启用文件预览
65
+ * 类型:boolean
66
+ * 默认值:true
67
+ */
68
+ enablePreview: makeBooleanProp(true),
69
+ /**
70
+ * 是否启用文件下载
71
+ * 类型:boolean
72
+ * 默认值:true
73
+ */
74
+ enableDownload: makeBooleanProp(true),
75
+ /**
76
+ * 是否启用删除按钮
77
+ * 类型:boolean
78
+ * 默认值:true
79
+ */
80
+ enableDelete: makeBooleanProp(true),
40
81
  /**
41
82
  * 文件预览前的钩子,参数为预览的文件,若返回false或者返回Promise且被reject,则停止预览。
42
83
  * 类型:function({file,resolve})
@@ -48,7 +89,22 @@ export const fileListProps = {
48
89
  * 类型:function({file})
49
90
  * 默认值:-
50
91
  */
51
- onPreviewFail: Function as PropType<FileListOnPreviewFail>
92
+ onPreviewFail: Function as PropType<FileListOnPreviewFail>,
93
+ /**
94
+ * 文件下载前钩子
95
+ * 类型:function({file,resolve})
96
+ */
97
+ beforeDownload: Function as PropType<FileListBeforeDownload>,
98
+ /**
99
+ * 文件下载成功回调
100
+ * 类型:function({file,tempFilePath})
101
+ */
102
+ onDownloadSuccess: Function as PropType<FileListOnDownloadSuccess>,
103
+ /**
104
+ * 文件下载失败回调
105
+ * 类型:function({file})
106
+ */
107
+ onDownloadFail: Function as PropType<FileListOnDownloadFail>
52
108
  }
53
109
 
54
110
  export type CornerProps = ExtractPropTypes<typeof fileListProps>
@@ -0,0 +1,53 @@
1
+ <script lang="ts" setup>
2
+ import { ref, nextTick, watch } from 'vue'
3
+ import { useToast } from '../oxy-toast'
4
+ import { storeToRefs } from 'pinia'
5
+ import { useGlobalLoading } from '../composables/useGlobalLoading'
6
+ import { getCurrentPath } from '../common/path'
7
+
8
+ const { loadingOptions, currentPage } = storeToRefs(useGlobalLoading())
9
+
10
+ const { close: closeGlobalLoading } = useGlobalLoading()
11
+
12
+ const loading = useToast('globalLoading')
13
+
14
+ // #ifdef MP-ALIPAY
15
+ const hackAlipayVisible = ref(false)
16
+
17
+ nextTick(() => {
18
+ hackAlipayVisible.value = true
19
+ })
20
+ // #endif
21
+
22
+ watch(
23
+ () => loadingOptions.value,
24
+ (newVal) => {
25
+ if (newVal && newVal.show) {
26
+ if (currentPage.value === getCurrentPath()) {
27
+ loading.loading(loadingOptions.value)
28
+ }
29
+ } else {
30
+ loading.close()
31
+ }
32
+ }
33
+ )
34
+ </script>
35
+
36
+ <script lang="ts">
37
+ export default {
38
+ options: {
39
+ virtualHost: true,
40
+ addGlobalClass: true,
41
+ styleIsolation: 'shared'
42
+ }
43
+ }
44
+ </script>
45
+
46
+ <template>
47
+ <!-- #ifdef MP-ALIPAY -->
48
+ <oxy-toast v-if="hackAlipayVisible" selector="globalLoading" :closed="closeGlobalLoading" />
49
+ <!-- #endif -->
50
+ <!-- #ifndef MP-ALIPAY -->
51
+ <oxy-toast selector="globalLoading" :closed="closeGlobalLoading" />
52
+ <!-- #endif -->
53
+ </template>
@@ -0,0 +1,64 @@
1
+ <script lang="ts" setup>
2
+ import { ref, nextTick, watch } from 'vue'
3
+ import { useMessage } from '../oxy-message-box'
4
+ import { deepClone, isFunction } from '../common/util'
5
+ import { storeToRefs } from 'pinia'
6
+ import { useGlobalMessage } from '../composables/useGlobalMessage'
7
+ import { getCurrentPath } from '../common/path'
8
+
9
+ const { messageOptions, currentPage } = storeToRefs(useGlobalMessage())
10
+
11
+ const messageBox = useMessage('globalMessage')
12
+
13
+ // #ifdef MP-ALIPAY
14
+ const hackAlipayVisible = ref(false)
15
+
16
+ nextTick(() => {
17
+ hackAlipayVisible.value = true
18
+ })
19
+ // #endif
20
+
21
+ watch(
22
+ () => messageOptions.value,
23
+ (newVal) => {
24
+ if (newVal) {
25
+ if (currentPage.value === getCurrentPath()) {
26
+ const option = deepClone(newVal)
27
+ messageBox
28
+ .show(option)
29
+ .then((res) => {
30
+ if (isFunction(option.success)) {
31
+ option.success(res)
32
+ }
33
+ })
34
+ .catch((err) => {
35
+ if (isFunction(option.fail)) {
36
+ option.fail(err)
37
+ }
38
+ })
39
+ }
40
+ } else {
41
+ messageBox.close()
42
+ }
43
+ }
44
+ )
45
+ </script>
46
+
47
+ <script lang="ts">
48
+ export default {
49
+ options: {
50
+ virtualHost: true,
51
+ addGlobalClass: true,
52
+ styleIsolation: 'shared'
53
+ }
54
+ }
55
+ </script>
56
+
57
+ <template>
58
+ <!-- #ifdef MP-ALIPAY -->
59
+ <oxy-message-box v-if="hackAlipayVisible" selector="globalMessage" />
60
+ <!-- #endif -->
61
+ <!-- #ifndef MP-ALIPAY -->
62
+ <oxy-message-box selector="globalMessage" />
63
+ <!-- #endif -->
64
+ </template>
@@ -0,0 +1,53 @@
1
+ <script lang="ts" setup>
2
+ import { ref, nextTick, watch } from 'vue'
3
+ import { useToast } from '../oxy-toast'
4
+ import { storeToRefs } from 'pinia'
5
+ import { useGlobalToast } from '../composables/useGlobalToast'
6
+ import { getCurrentPath } from '../common/path'
7
+
8
+ const { toastOptions, currentPage } = storeToRefs(useGlobalToast())
9
+
10
+ const { close: closeGlobalToast } = useGlobalToast()
11
+
12
+ const toast = useToast('globalToast')
13
+
14
+ // #ifdef MP-ALIPAY
15
+ const hackAlipayVisible = ref(false)
16
+
17
+ nextTick(() => {
18
+ hackAlipayVisible.value = true
19
+ })
20
+ // #endif
21
+
22
+ watch(
23
+ () => toastOptions.value,
24
+ (newVal) => {
25
+ if (newVal && newVal.show) {
26
+ if (currentPage.value === getCurrentPath()) {
27
+ toast.show(toastOptions.value)
28
+ }
29
+ } else {
30
+ toast.close()
31
+ }
32
+ }
33
+ )
34
+ </script>
35
+
36
+ <script lang="ts">
37
+ export default {
38
+ options: {
39
+ virtualHost: true,
40
+ addGlobalClass: true,
41
+ styleIsolation: 'shared'
42
+ }
43
+ }
44
+ </script>
45
+
46
+ <template>
47
+ <!-- #ifdef MP-ALIPAY -->
48
+ <oxy-toast v-if="hackAlipayVisible" selector="globalToast" :closed="closeGlobalToast" />
49
+ <!-- #endif -->
50
+ <!-- #ifndef MP-ALIPAY -->
51
+ <oxy-toast selector="globalToast" :closed="closeGlobalToast" />
52
+ <!-- #endif -->
53
+ </template>
@@ -0,0 +1,17 @@
1
+ @import "./../common/abstracts/_mixin.scss";
2
+ @import "./../common/abstracts/variable.scss";
3
+
4
+ @include b(img-lazy) {
5
+ // overflow: hidden;
6
+ position: relative;
7
+ @include e(image) {
8
+ display: block;
9
+ will-change: transform;
10
+ }
11
+
12
+ @include e(load) {
13
+ position: absolute;
14
+ left: 0;
15
+ top: 0;
16
+ }
17
+ }