oxy-uni-ui 2.1.2 → 2.1.4
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/attributes.json +1 -1
- package/components/common/AbortablePromise.ts +4 -0
- package/components/common/abstracts/variable.scss +172 -66
- package/components/common/base64.ts +6 -0
- package/components/common/clickoutside.ts +5 -0
- package/components/common/interceptor.ts +9 -0
- package/components/common/path.ts +4 -0
- package/components/common/props.ts +23 -0
- package/components/common/util.ts +18 -1
- package/components/composables/index.ts +2 -0
- package/components/composables/useCell.ts +8 -1
- package/components/composables/useChildren.ts +27 -1
- package/components/composables/useCountDown.ts +10 -1
- package/components/composables/useDynamicVirtualScroll.ts +9 -0
- package/components/composables/useGlobalLoading.ts +6 -0
- package/components/composables/useGlobalMessage.ts +6 -0
- package/components/composables/useGlobalToast.ts +6 -0
- package/components/composables/useLockScroll.ts +9 -0
- package/components/composables/useParent.ts +65 -14
- package/components/composables/usePopover.ts +9 -0
- package/components/composables/useQueue.ts +8 -0
- package/components/composables/useRaf.ts +10 -0
- package/components/composables/useSharedState.ts +284 -0
- package/components/composables/useTouch.ts +8 -0
- package/components/composables/useTranslate.ts +9 -0
- package/components/composables/useUpload.ts +83 -11
- package/components/composables/useVirtualScroll.ts +7 -0
- package/components/composables/useWindowResize.ts +9 -0
- package/components/oxy-action-sheet/index.scss +5 -5
- package/components/oxy-action-sheet/oxy-action-sheet.vue +11 -0
- package/components/oxy-backtop/index.scss +2 -2
- package/components/oxy-backtop/oxy-backtop.vue +2 -0
- package/components/oxy-badge/oxy-badge.vue +2 -0
- package/components/oxy-badge/types.ts +3 -0
- package/components/oxy-button/index.scss +13 -13
- package/components/oxy-button/oxy-button.vue +11 -0
- package/components/oxy-button/types.ts +3 -3
- package/components/oxy-calendar/index.scss +17 -17
- package/components/oxy-calendar/oxy-calendar.vue +31 -0
- package/components/oxy-calendar/types.ts +3 -0
- package/components/oxy-calendar-view/month/month.vue +2 -0
- package/components/oxy-calendar-view/monthPanel/month-panel.vue +3 -1
- package/components/oxy-calendar-view/monthPanel/types.ts +10 -7
- package/components/oxy-calendar-view/oxy-calendar-view.vue +2 -0
- package/components/oxy-calendar-view/types.ts +3 -1
- package/components/oxy-calendar-view/year/types.ts +33 -1
- package/components/oxy-calendar-view/year/year.vue +2 -0
- package/components/oxy-calendar-view/yearPanel/year-panel.vue +2 -0
- package/components/oxy-card/index.scss +1 -1
- package/components/oxy-card/oxy-card.vue +2 -0
- package/components/oxy-cell/index.scss +3 -1
- package/components/oxy-cell/oxy-cell.vue +6 -4
- package/components/oxy-cell-group/oxy-cell-group.vue +2 -0
- package/components/oxy-checkbox/index.scss +7 -7
- package/components/oxy-checkbox/oxy-checkbox.vue +22 -16
- package/components/oxy-checkbox/types.ts +9 -0
- package/components/oxy-checkbox-group/index.scss +1 -1
- package/components/oxy-checkbox-group/oxy-checkbox-group.vue +2 -0
- package/components/oxy-circle/oxy-circle.vue +2 -0
- package/components/oxy-col/oxy-col.vue +3 -1
- package/components/oxy-col-picker/index.scss +3 -3
- package/components/oxy-col-picker/oxy-col-picker.vue +17 -1
- package/components/oxy-col-picker/types.ts +3 -0
- package/components/oxy-collapse/index.scss +2 -2
- package/components/oxy-collapse/oxy-collapse.vue +9 -0
- package/components/oxy-collapse-item/oxy-collapse-item.vue +4 -2
- package/components/oxy-config-provider/oxy-config-provider.vue +18 -0
- package/components/oxy-config-provider/types.ts +18 -0
- package/components/oxy-corner/index.scss +50 -32
- package/components/oxy-corner/oxy-corner.vue +2 -0
- package/components/oxy-count-down/oxy-count-down.vue +2 -0
- package/components/oxy-count-to/oxy-count-to.vue +12 -1
- package/components/oxy-count-to/types.ts +14 -4
- package/components/oxy-curtain/index.scss +10 -9
- package/components/oxy-curtain/oxy-curtain.vue +2 -0
- package/components/oxy-date-strip/oxy-date-strip.vue +22 -1
- package/components/oxy-date-strip-item/index.scss +4 -4
- package/components/oxy-date-strip-item/oxy-date-strip-item.vue +2 -0
- package/components/oxy-datetime-picker/index.scss +3 -3
- package/components/oxy-datetime-picker/oxy-datetime-picker.vue +11 -1
- package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +2 -0
- package/components/oxy-divider/oxy-divider.vue +2 -0
- package/components/oxy-drop-menu/index.scss +2 -2
- package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -0
- package/components/oxy-drop-menu-item/index.scss +1 -1
- package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +17 -9
- package/components/oxy-echarts/oxy-echarts.vue +4 -2
- package/components/oxy-fab/index.scss +1 -1
- package/components/oxy-fab/oxy-fab.vue +27 -0
- package/components/oxy-file-list/index.scss +9 -9
- package/components/oxy-file-list/oxy-file-list.vue +29 -17
- package/components/oxy-floating-panel/oxy-floating-panel.vue +34 -10
- package/components/oxy-footer/index.scss +7 -0
- package/components/oxy-footer/oxy-footer.vue +4 -2
- package/components/oxy-footer/types.ts +9 -6
- package/components/oxy-form/oxy-form.vue +13 -1
- package/components/oxy-form-item/oxy-form-item.vue +5 -3
- package/components/oxy-gap/oxy-gap.vue +2 -0
- package/components/oxy-global-loading/oxy-global-loading.vue +18 -5
- package/components/oxy-global-message/oxy-global-message.vue +30 -17
- package/components/oxy-global-toast/oxy-global-toast.vue +18 -5
- package/components/oxy-grid/oxy-grid.vue +6 -0
- package/components/oxy-grid-item/index.scss +1 -1
- package/components/oxy-grid-item/oxy-grid-item.vue +22 -20
- package/components/oxy-guidance/index.scss +9 -9
- package/components/oxy-guidance/oxy-guidance.vue +22 -16
- package/components/oxy-icon/oxy-icon.vue +2 -0
- package/components/oxy-icon/types.ts +3 -0
- package/components/oxy-image-preview/index.scss +75 -0
- package/components/oxy-image-preview/index.ts +56 -0
- package/components/oxy-image-preview/oxy-image-preview.vue +221 -0
- package/components/oxy-image-preview/types.ts +164 -0
- package/components/oxy-img/oxy-img.vue +2 -0
- package/components/oxy-img-cropper/index.scss +2 -2
- package/components/oxy-img-cropper/oxy-img-cropper.vue +6 -0
- package/components/oxy-img-lazy/oxy-img-lazy.vue +9 -0
- package/components/oxy-index-anchor/index.scss +1 -1
- package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
- package/components/oxy-index-bar/index.scss +1 -1
- package/components/oxy-index-bar/oxy-index-bar.vue +18 -0
- package/components/oxy-input/index.scss +2 -1
- package/components/oxy-input/oxy-input.vue +18 -4
- package/components/oxy-input/types.ts +6 -0
- package/components/oxy-input-number/index.scss +3 -1
- package/components/oxy-input-number/oxy-input-number.vue +2 -0
- package/components/oxy-keyboard/index.scss +3 -3
- package/components/oxy-keyboard/key/index.vue +2 -0
- package/components/oxy-keyboard/oxy-keyboard.vue +11 -2
- package/components/oxy-link/index.scss +8 -4
- package/components/oxy-link/oxy-link.vue +9 -3
- package/components/oxy-link/types.ts +2 -2
- package/components/oxy-list/oxy-list.vue +2 -0
- package/components/oxy-list/types.ts +7 -0
- package/components/oxy-loading/oxy-loading.vue +6 -0
- package/components/oxy-loadmore/index.scss +1 -1
- package/components/oxy-loadmore/oxy-loadmore.vue +2 -0
- package/components/oxy-long-press-menu/index.scss +1 -1
- package/components/oxy-long-press-menu/oxy-long-press-menu.vue +42 -13
- package/components/oxy-message-box/index.scss +223 -36
- package/components/oxy-message-box/index.ts +49 -23
- package/components/oxy-message-box/oxy-message-box.vue +181 -56
- package/components/oxy-message-box/types.ts +60 -2
- package/components/oxy-navbar/index.scss +1 -1
- package/components/oxy-navbar/oxy-navbar.vue +9 -6
- package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +2 -0
- package/components/oxy-notice-bar/index.scss +1 -1
- package/components/oxy-notice-bar/oxy-notice-bar.vue +29 -0
- package/components/oxy-notify/index.ts +16 -12
- package/components/oxy-notify/oxy-notify.vue +11 -4
- package/components/oxy-overlay/oxy-overlay.vue +34 -2
- package/components/oxy-pagination/oxy-pagination.vue +2 -0
- package/components/oxy-password-input/oxy-password-input.vue +2 -0
- package/components/oxy-picker/index.scss +7 -7
- package/components/oxy-picker/oxy-picker.vue +11 -0
- package/components/oxy-picker-view/index.scss +1 -1
- package/components/oxy-picker-view/oxy-picker-view.vue +2 -0
- package/components/oxy-popover/index.scss +2 -2
- package/components/oxy-popover/oxy-popover.vue +4 -1
- package/components/oxy-popup/oxy-popup.vue +8 -0
- package/components/oxy-progress/index.scss +2 -2
- package/components/oxy-progress/oxy-progress.vue +7 -0
- package/components/oxy-qrcode/draw.ts +15 -1
- package/components/oxy-qrcode/oxy-qrcode.vue +10 -3
- package/components/oxy-radio/index.scss +8 -8
- package/components/oxy-radio/oxy-radio.vue +13 -11
- package/components/oxy-radio-group/index.scss +1 -1
- package/components/oxy-radio-group/oxy-radio-group.vue +2 -0
- package/components/oxy-rate/oxy-rate.vue +5 -0
- package/components/oxy-rate/types.ts +2 -2
- package/components/oxy-resize/oxy-resize.vue +12 -0
- package/components/oxy-rich-text/index.scss +9 -9
- package/components/oxy-rich-text/oxy-rich-text.vue +6 -0
- package/components/oxy-rich-text/types.ts +15 -0
- package/components/oxy-root-portal/oxy-root-portal.vue +23 -15
- package/components/oxy-row/oxy-row.vue +2 -0
- package/components/oxy-search/index.scss +3 -3
- package/components/oxy-search/oxy-search.vue +19 -0
- package/components/oxy-segmented/index.scss +4 -4
- package/components/oxy-segmented/oxy-segmented.vue +2 -0
- package/components/oxy-select/index.scss +25 -25
- package/components/oxy-select/oxy-select.vue +27 -0
- package/components/oxy-select/types.ts +3 -0
- package/components/oxy-select-picker/index.scss +5 -5
- package/components/oxy-select-picker/oxy-select-picker.vue +7 -0
- package/components/oxy-sidebar/oxy-sidebar.vue +2 -0
- package/components/oxy-sidebar-item/index.scss +3 -3
- package/components/oxy-sidebar-item/oxy-sidebar-item.vue +17 -31
- package/components/oxy-signature/oxy-signature.vue +17 -0
- package/components/oxy-skeleton/oxy-skeleton.vue +7 -1
- package/components/oxy-slide-verify/index.scss +95 -0
- package/components/oxy-slide-verify/oxy-slide-verify.vue +244 -0
- package/components/oxy-slide-verify/types.ts +98 -0
- package/components/oxy-slider/oxy-slider.vue +3 -0
- package/components/oxy-sort-button/index.scss +10 -8
- package/components/oxy-sort-button/oxy-sort-button.vue +6 -0
- package/components/oxy-splitter/index.scss +9 -0
- package/components/oxy-splitter/oxy-splitter.vue +23 -2
- package/components/oxy-splitter-panel/index.scss +7 -5
- package/components/oxy-splitter-panel/oxy-splitter-panel.vue +93 -89
- package/components/oxy-status-tip/index.scss +3 -3
- package/components/oxy-status-tip/oxy-status-tip.vue +2 -0
- package/components/oxy-step/index.scss +4 -4
- package/components/oxy-step/oxy-step.vue +15 -13
- package/components/oxy-steps/oxy-steps.vue +2 -0
- package/components/oxy-sticky/oxy-sticky.vue +5 -3
- package/components/oxy-stream-render/oxy-stream-render.vue +29 -0
- package/components/oxy-swipe-action/oxy-swipe-action.vue +8 -0
- package/components/oxy-swiper/oxy-swiper.vue +6 -0
- package/components/oxy-swiper-nav/index.scss +4 -4
- package/components/oxy-switch/index.scss +6 -3
- package/components/oxy-switch/oxy-switch.vue +10 -0
- package/components/oxy-tab/index.scss +1 -7
- package/components/oxy-tab/oxy-tab.vue +12 -10
- package/components/oxy-tabbar/oxy-tabbar.vue +5 -0
- package/components/oxy-tabbar-item/oxy-tabbar-item.vue +11 -9
- package/components/oxy-table/index.scss +1 -1
- package/components/oxy-table/oxy-table.vue +8 -0
- package/components/oxy-table/types.ts +3 -0
- package/components/oxy-table-col/oxy-table-col.vue +21 -19
- package/components/oxy-tabs/index.scss +11 -11
- package/components/oxy-tabs/oxy-tabs.vue +17 -0
- package/components/oxy-tag/index.scss +24 -5
- package/components/oxy-tag/oxy-tag.vue +17 -2
- package/components/oxy-tag/types.ts +7 -0
- package/components/oxy-text/oxy-text.vue +12 -1
- package/components/oxy-textarea/index.scss +3 -2
- package/components/oxy-textarea/oxy-textarea.vue +10 -4
- package/components/oxy-toast/index.ts +21 -20
- package/components/oxy-toast/oxy-toast.vue +30 -5
- package/components/oxy-toast/types.ts +20 -9
- package/components/oxy-tooltip/index.scss +1 -1
- package/components/oxy-tooltip/oxy-tooltip.vue +2 -0
- package/components/oxy-transition/index.scss +3 -1
- package/components/oxy-transition/oxy-transition.vue +14 -0
- package/components/oxy-tree/index.scss +3 -3
- package/components/oxy-tree/oxy-tree.vue +28 -5
- package/components/oxy-tree/types.ts +57 -1
- package/components/oxy-upload/index.scss +9 -9
- package/components/oxy-upload/oxy-upload.vue +5 -3
- package/components/oxy-verification-code/oxy-verification-code.vue +24 -0
- package/components/oxy-video-preview/index.scss +12 -7
- package/components/oxy-video-preview/index.ts +64 -0
- package/components/oxy-video-preview/oxy-video-preview.vue +102 -31
- package/components/oxy-video-preview/types.ts +54 -8
- package/components/oxy-virtual-scroll/index.scss +1 -1
- package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +2 -0
- package/components/oxy-voice-player/index.scss +64 -64
- package/components/oxy-voice-player/oxy-voice-player.vue +38 -10
- package/components/oxy-waterfall/oxy-waterfall.vue +13 -0
- package/components/oxy-waterfall/types.ts +7 -0
- package/components/oxy-waterfall-item/oxy-waterfall-item.vue +9 -0
- package/components/oxy-watermark/oxy-watermark.vue +2 -0
- package/global.d.ts +2 -0
- package/index.ts +2 -0
- package/locale/lang/en-US.ts +51 -2
- package/locale/lang/zh-CN.ts +51 -2
- package/package.json +2 -2
- package/styles/all.scss +125 -0
- package/tags.json +1 -1
- package/vite-plugins/vite-plugin-host-class.ts +166 -0
- package/web-types.json +1 -1
|
@@ -46,7 +46,9 @@ export default {
|
|
|
46
46
|
name: 'oxy-file-list',
|
|
47
47
|
options: {
|
|
48
48
|
addGlobalClass: true,
|
|
49
|
+
// #ifndef MP-TOUTIAO
|
|
49
50
|
virtualHost: true,
|
|
51
|
+
// #endif
|
|
50
52
|
styleIsolation: 'shared'
|
|
51
53
|
}
|
|
52
54
|
}
|
|
@@ -69,6 +71,7 @@ import { ref, nextTick } from 'vue'
|
|
|
69
71
|
import { isImageUrl, isVideoUrl, isAudioUrl, isPdfUrl, isDocUrl } from '../common/util'
|
|
70
72
|
import { type FileListItem, fileListProps } from './types'
|
|
71
73
|
import type { VideoPreviewInstance } from '../oxy-video-preview/types'
|
|
74
|
+
import { useTranslate } from '../composables/useTranslate'
|
|
72
75
|
|
|
73
76
|
const imgs: AnyObject = {
|
|
74
77
|
pdf: ImgPdf,
|
|
@@ -81,6 +84,7 @@ const imgs: AnyObject = {
|
|
|
81
84
|
|
|
82
85
|
const props = defineProps(fileListProps)
|
|
83
86
|
const emit = defineEmits(['delete', 'click'])
|
|
87
|
+
const { translate } = useTranslate('fileList')
|
|
84
88
|
|
|
85
89
|
const videoPreview = ref<VideoPreviewInstance>()
|
|
86
90
|
const toast = useToast('oxy-file-list')
|
|
@@ -96,7 +100,7 @@ function isDownloading(file: FileListItem) {
|
|
|
96
100
|
*/
|
|
97
101
|
function handlePreviewImage(file: FileListItem) {
|
|
98
102
|
const { onPreviewFail } = props
|
|
99
|
-
toast.loading({ msg: '
|
|
103
|
+
toast.loading({ msg: translate('openingPreview'), direction: 'vertical', position: 'middle' })
|
|
100
104
|
uni.previewImage({
|
|
101
105
|
urls: [file.url],
|
|
102
106
|
current: 0,
|
|
@@ -109,7 +113,7 @@ function handlePreviewImage(file: FileListItem) {
|
|
|
109
113
|
file
|
|
110
114
|
})
|
|
111
115
|
} else {
|
|
112
|
-
toast.error({ msg: '
|
|
116
|
+
toast.error({ msg: translate('previewImageFail'), direction: 'vertical', position: 'middle' })
|
|
113
117
|
}
|
|
114
118
|
toast.close()
|
|
115
119
|
},
|
|
@@ -125,7 +129,7 @@ function handlePreviewImage(file: FileListItem) {
|
|
|
125
129
|
*/
|
|
126
130
|
function handlePreviewVideo(file: FileListItem) {
|
|
127
131
|
const { onPreviewFail } = props
|
|
128
|
-
toast.loading({ msg: '
|
|
132
|
+
toast.loading({ msg: translate('openingPreview'), direction: 'vertical', position: 'middle' })
|
|
129
133
|
// #ifdef MP-WEIXIN
|
|
130
134
|
uni.previewMedia({
|
|
131
135
|
current: 0,
|
|
@@ -145,7 +149,7 @@ function handlePreviewVideo(file: FileListItem) {
|
|
|
145
149
|
file
|
|
146
150
|
})
|
|
147
151
|
} else {
|
|
148
|
-
toast.error({ msg: '
|
|
152
|
+
toast.error({ msg: translate('previewVideoFail'), direction: 'vertical', position: 'middle' })
|
|
149
153
|
}
|
|
150
154
|
toast.close()
|
|
151
155
|
},
|
|
@@ -168,7 +172,7 @@ function handlePreviewVideo(file: FileListItem) {
|
|
|
168
172
|
*/
|
|
169
173
|
function handlePreviewFile(file: FileListItem) {
|
|
170
174
|
const { onPreviewFail } = props
|
|
171
|
-
toast.loading({ msg: '
|
|
175
|
+
toast.loading({ msg: translate('openingPreview'), direction: 'vertical', position: 'middle' })
|
|
172
176
|
uni.openDocument({
|
|
173
177
|
filePath: file.url,
|
|
174
178
|
showMenu: true,
|
|
@@ -181,7 +185,7 @@ function handlePreviewFile(file: FileListItem) {
|
|
|
181
185
|
file
|
|
182
186
|
})
|
|
183
187
|
} else {
|
|
184
|
-
toast.error({ msg: '
|
|
188
|
+
toast.error({ msg: translate('previewFileFail'), direction: 'vertical', position: 'middle' })
|
|
185
189
|
}
|
|
186
190
|
toast.close()
|
|
187
191
|
},
|
|
@@ -217,6 +221,14 @@ function handleClick(file: FileListItem, index: number) {
|
|
|
217
221
|
}
|
|
218
222
|
}
|
|
219
223
|
|
|
224
|
+
/**
|
|
225
|
+
* 下载文件。跨平台实现:
|
|
226
|
+
* - 微信小程序:uni.downloadFile → uni.saveFile
|
|
227
|
+
* - H5:创建隐藏 <a> 标签触发下载
|
|
228
|
+
* - App:uni.downloadFile → uni.saveFile
|
|
229
|
+
* 支持 beforeDownload 拦截,通过 resolve(true) 继续下载。
|
|
230
|
+
* @param file - 文件项
|
|
231
|
+
*/
|
|
220
232
|
function onDownload(file: FileListItem) {
|
|
221
233
|
const { beforeDownload, onDownloadSuccess, onDownloadFail } = props
|
|
222
234
|
|
|
@@ -234,7 +246,7 @@ function onDownload(file: FileListItem) {
|
|
|
234
246
|
if (onDownloadSuccess) {
|
|
235
247
|
onDownloadSuccess({ file, tempFilePath })
|
|
236
248
|
} else {
|
|
237
|
-
toast.success({ msg:
|
|
249
|
+
toast.success({ msg: translate('downloadSuccess') + filename, direction: 'vertical', position: 'middle' })
|
|
238
250
|
}
|
|
239
251
|
downloading.value[file.url] = false
|
|
240
252
|
},
|
|
@@ -242,7 +254,7 @@ function onDownload(file: FileListItem) {
|
|
|
242
254
|
if (onDownloadFail) {
|
|
243
255
|
onDownloadFail({ file })
|
|
244
256
|
} else {
|
|
245
|
-
toast.error({ msg:
|
|
257
|
+
toast.error({ msg: translate('downloadFail') + filename, direction: 'vertical', position: 'middle' })
|
|
246
258
|
}
|
|
247
259
|
downloading.value[file.url] = false
|
|
248
260
|
}
|
|
@@ -252,7 +264,7 @@ function onDownload(file: FileListItem) {
|
|
|
252
264
|
if (onDownloadFail) {
|
|
253
265
|
onDownloadFail({ file })
|
|
254
266
|
} else {
|
|
255
|
-
toast.error({ msg:
|
|
267
|
+
toast.error({ msg: translate('downloadFail') + filename, direction: 'vertical', position: 'middle' })
|
|
256
268
|
}
|
|
257
269
|
downloading.value[file.url] = false
|
|
258
270
|
}
|
|
@@ -270,14 +282,14 @@ function onDownload(file: FileListItem) {
|
|
|
270
282
|
if (onDownloadSuccess) {
|
|
271
283
|
onDownloadSuccess({ file })
|
|
272
284
|
} else {
|
|
273
|
-
toast.success({ msg:
|
|
285
|
+
toast.success({ msg: translate('downloadSuccess') + filename, direction: 'vertical', position: 'middle' })
|
|
274
286
|
}
|
|
275
287
|
downloading.value[file.url] = false
|
|
276
288
|
} catch (e) {
|
|
277
289
|
if (onDownloadFail) {
|
|
278
290
|
onDownloadFail({ file })
|
|
279
291
|
} else {
|
|
280
|
-
toast.error({ msg:
|
|
292
|
+
toast.error({ msg: translate('downloadFail') + filename, direction: 'vertical', position: 'middle' })
|
|
281
293
|
}
|
|
282
294
|
downloading.value[file.url] = false
|
|
283
295
|
}
|
|
@@ -293,7 +305,7 @@ function onDownload(file: FileListItem) {
|
|
|
293
305
|
if (onDownloadSuccess) {
|
|
294
306
|
onDownloadSuccess({ file, tempFilePath })
|
|
295
307
|
} else {
|
|
296
|
-
toast.success({ msg:
|
|
308
|
+
toast.success({ msg: translate('downloadSuccess') + filename, direction: 'vertical', position: 'middle' })
|
|
297
309
|
}
|
|
298
310
|
downloading.value[file.url] = false
|
|
299
311
|
},
|
|
@@ -301,7 +313,7 @@ function onDownload(file: FileListItem) {
|
|
|
301
313
|
if (onDownloadFail) {
|
|
302
314
|
onDownloadFail({ file })
|
|
303
315
|
} else {
|
|
304
|
-
toast.error({ msg:
|
|
316
|
+
toast.error({ msg: translate('downloadFail') + filename, direction: 'vertical', position: 'middle' })
|
|
305
317
|
}
|
|
306
318
|
downloading.value[file.url] = false
|
|
307
319
|
}
|
|
@@ -311,7 +323,7 @@ function onDownload(file: FileListItem) {
|
|
|
311
323
|
if (onDownloadFail) {
|
|
312
324
|
onDownloadFail({ file })
|
|
313
325
|
} else {
|
|
314
|
-
toast.error({ msg:
|
|
326
|
+
toast.error({ msg: translate('downloadFail') + filename, direction: 'vertical', position: 'middle' })
|
|
315
327
|
}
|
|
316
328
|
downloading.value[file.url] = false
|
|
317
329
|
}
|
|
@@ -333,10 +345,10 @@ function onDownload(file: FileListItem) {
|
|
|
333
345
|
|
|
334
346
|
function onDelete(file: FileListItem, index: number) {
|
|
335
347
|
const execDelete = () => {
|
|
336
|
-
const title = '
|
|
337
|
-
const msg = file.name || '
|
|
348
|
+
const title = translate('confirmDeleteTitle')
|
|
349
|
+
const msg = file.name || translate('confirmDeleteMsg')
|
|
338
350
|
message
|
|
339
|
-
.confirm({ title, msg, confirmButtonText: '
|
|
351
|
+
.confirm({ title, msg, confirmButtonText: translate('delete'), cancelButtonText: translate('cancel') })
|
|
340
352
|
.then(() => {
|
|
341
353
|
emit('delete', { file, index })
|
|
342
354
|
})
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<view :class="`oxy-floating-panel__header`">
|
|
2
|
+
<view :class="`oxy-floating-panel ${customClass} ${safeAreaInsetBottom ? 'is-safe' : ''}`" :style="rootStyle">
|
|
3
|
+
<view
|
|
4
|
+
:class="`oxy-floating-panel__header`"
|
|
5
|
+
@touchstart.passive="handleTouchStart"
|
|
6
|
+
@touchmove.stop.prevent="handleTouchMove"
|
|
7
|
+
@touchend="handleTouchEnd"
|
|
8
|
+
@touchcancel="handleTouchEnd"
|
|
9
|
+
>
|
|
11
10
|
<view :class="`oxy-floating-panel__header-bar`"></view>
|
|
12
11
|
</view>
|
|
13
12
|
|
|
@@ -16,7 +15,10 @@
|
|
|
16
15
|
data-id="content"
|
|
17
16
|
:show-scrollbar="showScrollbar"
|
|
18
17
|
scroll-y
|
|
18
|
+
@touchstart.stop.passive="handleTouchStart"
|
|
19
19
|
@touchmove.stop.prevent="handleTouchMove"
|
|
20
|
+
@touchend.stop="handleTouchEnd"
|
|
21
|
+
@touchcancel.stop="handleTouchEnd"
|
|
20
22
|
>
|
|
21
23
|
<slot />
|
|
22
24
|
</scroll-view>
|
|
@@ -27,7 +29,9 @@
|
|
|
27
29
|
export default {
|
|
28
30
|
name: 'oxy-floating-panel',
|
|
29
31
|
options: {
|
|
32
|
+
// #ifndef MP-TOUTIAO
|
|
30
33
|
virtualHost: true,
|
|
34
|
+
// #endif
|
|
31
35
|
addGlobalClass: true,
|
|
32
36
|
styleIsolation: 'shared'
|
|
33
37
|
}
|
|
@@ -49,7 +53,7 @@ const emit = defineEmits(['update:height', 'height-change'])
|
|
|
49
53
|
const heightValue = ref<number>(props.height)
|
|
50
54
|
|
|
51
55
|
const DAMP = 0.2 // 阻尼系数
|
|
52
|
-
let startY
|
|
56
|
+
let startY = 0 // 起始位置
|
|
53
57
|
const windowHeight = ref<number>(0)
|
|
54
58
|
const dragging = ref<boolean>(false) // 是否正在拖拽
|
|
55
59
|
|
|
@@ -76,6 +80,9 @@ const updateHeight = (value: number) => {
|
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
const handleTouchStart = (event: TouchEvent) => {
|
|
83
|
+
const target = event.currentTarget as any
|
|
84
|
+
if (target.dataset.id == 'content' && !props.contentDraggable) return
|
|
85
|
+
|
|
79
86
|
touch.touchStart(event)
|
|
80
87
|
dragging.value = true
|
|
81
88
|
startY = -heightValue.value
|
|
@@ -86,12 +93,23 @@ const handleTouchMove = (event: TouchEvent) => {
|
|
|
86
93
|
if (target.dataset.id == 'content') {
|
|
87
94
|
if (!props.contentDraggable) return
|
|
88
95
|
}
|
|
96
|
+
|
|
97
|
+
if (!dragging.value) {
|
|
98
|
+
handleTouchStart(event)
|
|
99
|
+
}
|
|
100
|
+
|
|
89
101
|
touch.touchMove(event)
|
|
90
102
|
const moveY = touch.deltaY.value + startY
|
|
91
103
|
updateHeight(-ease(moveY))
|
|
92
104
|
}
|
|
93
105
|
|
|
106
|
+
/**
|
|
107
|
+
* 触摸结束,将面板吸附到最近的锚点。
|
|
108
|
+
* 使用 closest 工具函数找到最近的 anchors 值,emit height-change 事件。
|
|
109
|
+
*/
|
|
94
110
|
const handleTouchEnd = () => {
|
|
111
|
+
if (!dragging.value) return
|
|
112
|
+
|
|
95
113
|
dragging.value = false
|
|
96
114
|
updateHeight(closest(anchors.value, heightValue.value))
|
|
97
115
|
|
|
@@ -100,6 +118,12 @@ const handleTouchEnd = () => {
|
|
|
100
118
|
}
|
|
101
119
|
}
|
|
102
120
|
|
|
121
|
+
/**
|
|
122
|
+
* 弹性阻尼函数,限制拖拽范围。
|
|
123
|
+
* 超出边界 max 或低于边界 min 时应用阻尼系数 DAMP,产生越界回弹效果。
|
|
124
|
+
* @param y - 当前拖拽偏移量
|
|
125
|
+
* @returns 阻尼处理后的偏移量
|
|
126
|
+
*/
|
|
103
127
|
const ease = (y: number) => {
|
|
104
128
|
const absDistance = Math.abs(y)
|
|
105
129
|
const { min, max } = boundary.value
|
|
@@ -12,6 +12,13 @@
|
|
|
12
12
|
overflow: visible;
|
|
13
13
|
padding: 0;
|
|
14
14
|
background-color: $-footer-bg;
|
|
15
|
+
|
|
16
|
+
@include when(safe) {
|
|
17
|
+
box-sizing: content-box;
|
|
18
|
+
padding-bottom: constant(safe-area-inset-bottom);
|
|
19
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
@include e(content) {
|
|
16
23
|
overflow: visible;
|
|
17
24
|
padding: $-footer-padding;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view class="oxy-footer-placeholder" :style="{ height: placeholderHeight }"></view>
|
|
3
3
|
<view class="oxy-footer-wrapper">
|
|
4
|
-
<view :class="`oxy-footer ${customClass}`" :style="`background-color: ${backgroundColor};${customStyle}`">
|
|
4
|
+
<view :class="`oxy-footer ${customClass} ${safeAreaInsetBottom ? 'is-safe' : ''}`" :style="`background-color: ${backgroundColor};${customStyle}`">
|
|
5
5
|
<view class="oxy-footer__content" :style="contentStyle">
|
|
6
6
|
<slot></slot>
|
|
7
7
|
</view>
|
|
@@ -13,7 +13,9 @@ export default {
|
|
|
13
13
|
name: 'oxy-footer',
|
|
14
14
|
options: {
|
|
15
15
|
addGlobalClass: true,
|
|
16
|
+
// #ifndef MP-TOUTIAO
|
|
16
17
|
virtualHost: true,
|
|
18
|
+
// #endif
|
|
17
19
|
styleIsolation: 'shared'
|
|
18
20
|
}
|
|
19
21
|
}
|
|
@@ -67,7 +69,7 @@ onMounted(() => {
|
|
|
67
69
|
getHeight()
|
|
68
70
|
})
|
|
69
71
|
|
|
70
|
-
watch([() => props.height, () => props.customStyle, () => props.customClass, () => props.backgroundColor], () => {
|
|
72
|
+
watch([() => props.height, () => props.customStyle, () => props.customClass, () => props.backgroundColor, () => props.safeAreaInsetBottom], () => {
|
|
71
73
|
getHeight()
|
|
72
74
|
})
|
|
73
75
|
</script>
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { baseProps, makeStringProp, makeNumberProp } from '../common/props'
|
|
1
|
+
import { baseProps, makeBooleanProp, makeStringProp, makeNumberProp } from '../common/props'
|
|
2
2
|
|
|
3
3
|
export const footerProps = {
|
|
4
4
|
...baseProps,
|
|
5
5
|
/**
|
|
6
6
|
* 固定的内容高度
|
|
7
|
-
*
|
|
8
|
-
* 默认值:'id'
|
|
7
|
+
* 默认行为:0 表示由内容自适应
|
|
9
8
|
*/
|
|
10
9
|
height: makeNumberProp(0),
|
|
11
10
|
/**
|
|
12
11
|
* 背景色
|
|
13
|
-
*
|
|
14
|
-
* 默认值:''
|
|
12
|
+
* 默认行为:空字符串,使用组件默认背景色
|
|
15
13
|
*/
|
|
16
|
-
backgroundColor: makeStringProp('')
|
|
14
|
+
backgroundColor: makeStringProp(''),
|
|
15
|
+
/**
|
|
16
|
+
* 是否设置底部安全距离(iPhone X 等机型)
|
|
17
|
+
* 默认行为:true,自动补齐底部安全区
|
|
18
|
+
*/
|
|
19
|
+
safeAreaInsetBottom: makeBooleanProp(true)
|
|
17
20
|
}
|
|
@@ -10,7 +10,9 @@ export default {
|
|
|
10
10
|
name: 'oxy-form',
|
|
11
11
|
options: {
|
|
12
12
|
addGlobalClass: true,
|
|
13
|
+
// #ifndef MP-TOUTIAO
|
|
13
14
|
virtualHost: true,
|
|
15
|
+
// #endif
|
|
14
16
|
styleIsolation: 'shared'
|
|
15
17
|
}
|
|
16
18
|
}
|
|
@@ -143,7 +145,11 @@ async function validate(prop?: string | string[]): Promise<{ valid: boolean; err
|
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
|
|
146
|
-
|
|
148
|
+
/**
|
|
149
|
+
* 合并父组件 rules 与子组件 rules。
|
|
150
|
+
* 过滤掉在 children 中不存在对应子组件的父级规则,再将子组件 rules 合并到同名 prop 下。
|
|
151
|
+
* @returns 合并后的完整校验规则
|
|
152
|
+
*/
|
|
147
153
|
function getMergeRules() {
|
|
148
154
|
const mergedRules: FormRules = deepClone(props.rules)
|
|
149
155
|
const childrenProps = children.map((child) => child.prop)
|
|
@@ -167,6 +173,12 @@ function getMergeRules() {
|
|
|
167
173
|
return mergedRules
|
|
168
174
|
}
|
|
169
175
|
|
|
176
|
+
/**
|
|
177
|
+
* 根据 errorType 展示错误提示。
|
|
178
|
+
* toast 模式:显示排序后的第一条错误。
|
|
179
|
+
* message 模式:将所有错误写入 errorMessages,由各子组件自行展示。
|
|
180
|
+
* @param errors - 校验错误列表
|
|
181
|
+
*/
|
|
170
182
|
function showMessage(errors: ErrorMessage[]) {
|
|
171
183
|
const childrenProps = children.map((e) => e.prop).filter(Boolean)
|
|
172
184
|
const messages = errors.filter((error) => error.message && childrenProps.includes(error.prop))
|
|
@@ -17,7 +17,9 @@ export default {
|
|
|
17
17
|
name: 'oxy-form-item',
|
|
18
18
|
options: {
|
|
19
19
|
addGlobalClass: true,
|
|
20
|
+
// #ifndef MP-TOUTIAO
|
|
20
21
|
virtualHost: true,
|
|
22
|
+
// #endif
|
|
21
23
|
styleIsolation: 'shared'
|
|
22
24
|
}
|
|
23
25
|
}
|
|
@@ -35,15 +37,15 @@ const props = defineProps(formItemProps)
|
|
|
35
37
|
const { parent: form, index } = useParent(FORM_KEY)
|
|
36
38
|
|
|
37
39
|
const errorMessage = computed(() => {
|
|
38
|
-
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
|
|
39
|
-
return form.errorMessages[props.prop]
|
|
40
|
+
if (form.value && props.prop && form.value.errorMessages && form.value.errorMessages[props.prop]) {
|
|
41
|
+
return form.value.errorMessages[props.prop]
|
|
40
42
|
} else {
|
|
41
43
|
return ''
|
|
42
44
|
}
|
|
43
45
|
})
|
|
44
46
|
|
|
45
47
|
const border = computed(() => {
|
|
46
|
-
if (index.value > 0 && form && form.props.border) {
|
|
48
|
+
if (index.value > 0 && form.value && form.value.props.border) {
|
|
47
49
|
return true
|
|
48
50
|
} else {
|
|
49
51
|
return false
|
|
@@ -3,13 +3,20 @@ import { ref, nextTick, watch } from 'vue'
|
|
|
3
3
|
import { useToast } from '../oxy-toast'
|
|
4
4
|
import { storeToRefs } from 'pinia'
|
|
5
5
|
import { useGlobalLoading } from '../composables/useGlobalLoading'
|
|
6
|
-
import { getCurrentPath } from '../common/path'
|
|
6
|
+
import { getCurrentPageStackDepth, getCurrentPath } from '../common/path'
|
|
7
7
|
|
|
8
8
|
const { loadingOptions, currentPage } = storeToRefs(useGlobalLoading())
|
|
9
9
|
|
|
10
10
|
const { close: closeGlobalLoading } = useGlobalLoading()
|
|
11
11
|
|
|
12
12
|
const loading = useToast('globalLoading')
|
|
13
|
+
const ownerPage = getCurrentPath()
|
|
14
|
+
const ownerPageDepth = getCurrentPageStackDepth()
|
|
15
|
+
|
|
16
|
+
function isCurrentPage() {
|
|
17
|
+
if (!ownerPage) return currentPage.value === getCurrentPath()
|
|
18
|
+
return currentPage.value === ownerPage && getCurrentPageStackDepth() === ownerPageDepth
|
|
19
|
+
}
|
|
13
20
|
|
|
14
21
|
// #ifdef MP-ALIPAY
|
|
15
22
|
const hackAlipayVisible = ref(false)
|
|
@@ -23,12 +30,16 @@ watch(
|
|
|
23
30
|
() => loadingOptions.value,
|
|
24
31
|
(newVal) => {
|
|
25
32
|
if (newVal && newVal.show) {
|
|
26
|
-
if (
|
|
27
|
-
loading.
|
|
33
|
+
if (!isCurrentPage()) {
|
|
34
|
+
loading.close()
|
|
35
|
+
return
|
|
28
36
|
}
|
|
29
|
-
|
|
30
|
-
loading.
|
|
37
|
+
|
|
38
|
+
loading.loading(loadingOptions.value)
|
|
39
|
+
return
|
|
31
40
|
}
|
|
41
|
+
|
|
42
|
+
loading.close()
|
|
32
43
|
}
|
|
33
44
|
)
|
|
34
45
|
</script>
|
|
@@ -36,7 +47,9 @@ watch(
|
|
|
36
47
|
<script lang="ts">
|
|
37
48
|
export default {
|
|
38
49
|
options: {
|
|
50
|
+
// #ifndef MP-TOUTIAO
|
|
39
51
|
virtualHost: true,
|
|
52
|
+
// #endif
|
|
40
53
|
addGlobalClass: true,
|
|
41
54
|
styleIsolation: 'shared'
|
|
42
55
|
}
|
|
@@ -4,11 +4,18 @@ import { useMessage } from '../oxy-message-box'
|
|
|
4
4
|
import { deepClone, isFunction } from '../common/util'
|
|
5
5
|
import { storeToRefs } from 'pinia'
|
|
6
6
|
import { useGlobalMessage } from '../composables/useGlobalMessage'
|
|
7
|
-
import { getCurrentPath } from '../common/path'
|
|
7
|
+
import { getCurrentPageStackDepth, getCurrentPath } from '../common/path'
|
|
8
8
|
|
|
9
9
|
const { messageOptions, currentPage } = storeToRefs(useGlobalMessage())
|
|
10
10
|
|
|
11
11
|
const messageBox = useMessage('globalMessage')
|
|
12
|
+
const ownerPage = getCurrentPath()
|
|
13
|
+
const ownerPageDepth = getCurrentPageStackDepth()
|
|
14
|
+
|
|
15
|
+
function isCurrentPage() {
|
|
16
|
+
if (!ownerPage) return currentPage.value === getCurrentPath()
|
|
17
|
+
return currentPage.value === ownerPage && getCurrentPageStackDepth() === ownerPageDepth
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
// #ifdef MP-ALIPAY
|
|
14
21
|
const hackAlipayVisible = ref(false)
|
|
@@ -22,24 +29,28 @@ watch(
|
|
|
22
29
|
() => messageOptions.value,
|
|
23
30
|
(newVal) => {
|
|
24
31
|
if (newVal) {
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
})
|
|
32
|
+
if (!isCurrentPage()) {
|
|
33
|
+
messageBox.close()
|
|
34
|
+
return
|
|
39
35
|
}
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
|
|
37
|
+
const option = deepClone(newVal)
|
|
38
|
+
messageBox
|
|
39
|
+
.show(option)
|
|
40
|
+
.then((res) => {
|
|
41
|
+
if (isFunction(option.success)) {
|
|
42
|
+
option.success(res)
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
.catch((err) => {
|
|
46
|
+
if (isFunction(option.fail)) {
|
|
47
|
+
option.fail(err)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
return
|
|
42
51
|
}
|
|
52
|
+
|
|
53
|
+
messageBox.close()
|
|
43
54
|
}
|
|
44
55
|
)
|
|
45
56
|
</script>
|
|
@@ -47,7 +58,9 @@ watch(
|
|
|
47
58
|
<script lang="ts">
|
|
48
59
|
export default {
|
|
49
60
|
options: {
|
|
61
|
+
// #ifndef MP-TOUTIAO
|
|
50
62
|
virtualHost: true,
|
|
63
|
+
// #endif
|
|
51
64
|
addGlobalClass: true,
|
|
52
65
|
styleIsolation: 'shared'
|
|
53
66
|
}
|
|
@@ -3,13 +3,20 @@ import { ref, nextTick, watch } from 'vue'
|
|
|
3
3
|
import { useToast } from '../oxy-toast'
|
|
4
4
|
import { storeToRefs } from 'pinia'
|
|
5
5
|
import { useGlobalToast } from '../composables/useGlobalToast'
|
|
6
|
-
import { getCurrentPath } from '../common/path'
|
|
6
|
+
import { getCurrentPageStackDepth, getCurrentPath } from '../common/path'
|
|
7
7
|
|
|
8
8
|
const { toastOptions, currentPage } = storeToRefs(useGlobalToast())
|
|
9
9
|
|
|
10
10
|
const { close: closeGlobalToast } = useGlobalToast()
|
|
11
11
|
|
|
12
12
|
const toast = useToast('globalToast')
|
|
13
|
+
const ownerPage = getCurrentPath()
|
|
14
|
+
const ownerPageDepth = getCurrentPageStackDepth()
|
|
15
|
+
|
|
16
|
+
function isCurrentPage() {
|
|
17
|
+
if (!ownerPage) return currentPage.value === getCurrentPath()
|
|
18
|
+
return currentPage.value === ownerPage && getCurrentPageStackDepth() === ownerPageDepth
|
|
19
|
+
}
|
|
13
20
|
|
|
14
21
|
// #ifdef MP-ALIPAY
|
|
15
22
|
const hackAlipayVisible = ref(false)
|
|
@@ -23,12 +30,16 @@ watch(
|
|
|
23
30
|
() => toastOptions.value,
|
|
24
31
|
(newVal) => {
|
|
25
32
|
if (newVal && newVal.show) {
|
|
26
|
-
if (
|
|
27
|
-
toast.
|
|
33
|
+
if (!isCurrentPage()) {
|
|
34
|
+
toast.close()
|
|
35
|
+
return
|
|
28
36
|
}
|
|
29
|
-
|
|
30
|
-
toast.
|
|
37
|
+
|
|
38
|
+
toast.show(toastOptions.value)
|
|
39
|
+
return
|
|
31
40
|
}
|
|
41
|
+
|
|
42
|
+
toast.close()
|
|
32
43
|
}
|
|
33
44
|
)
|
|
34
45
|
</script>
|
|
@@ -36,7 +47,9 @@ watch(
|
|
|
36
47
|
<script lang="ts">
|
|
37
48
|
export default {
|
|
38
49
|
options: {
|
|
50
|
+
// #ifndef MP-TOUTIAO
|
|
39
51
|
virtualHost: true,
|
|
52
|
+
// #endif
|
|
40
53
|
addGlobalClass: true,
|
|
41
54
|
styleIsolation: 'shared'
|
|
42
55
|
}
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
export default {
|
|
10
10
|
name: 'oxy-grid',
|
|
11
11
|
options: {
|
|
12
|
+
// #ifndef MP-TOUTIAO
|
|
12
13
|
virtualHost: true,
|
|
14
|
+
// #endif
|
|
13
15
|
addGlobalClass: true,
|
|
14
16
|
styleIsolation: 'shared'
|
|
15
17
|
}
|
|
@@ -80,6 +82,10 @@ const handleChildrenChange = debounce(() => {
|
|
|
80
82
|
init()
|
|
81
83
|
}, 50)
|
|
82
84
|
|
|
85
|
+
/**
|
|
86
|
+
* 初始化子项样式类。
|
|
87
|
+
* border 模式下根据 column 列数标记首行(is-first)、末行(is-last)、右边界(is-right)项,非 border 模式仅标记首行。
|
|
88
|
+
*/
|
|
83
89
|
function init() {
|
|
84
90
|
if (!children) return
|
|
85
91
|
children.forEach((item, index) => {
|