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.
Files changed (261) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/AbortablePromise.ts +4 -0
  3. package/components/common/abstracts/variable.scss +172 -66
  4. package/components/common/base64.ts +6 -0
  5. package/components/common/clickoutside.ts +5 -0
  6. package/components/common/interceptor.ts +9 -0
  7. package/components/common/path.ts +4 -0
  8. package/components/common/props.ts +23 -0
  9. package/components/common/util.ts +18 -1
  10. package/components/composables/index.ts +2 -0
  11. package/components/composables/useCell.ts +8 -1
  12. package/components/composables/useChildren.ts +27 -1
  13. package/components/composables/useCountDown.ts +10 -1
  14. package/components/composables/useDynamicVirtualScroll.ts +9 -0
  15. package/components/composables/useGlobalLoading.ts +6 -0
  16. package/components/composables/useGlobalMessage.ts +6 -0
  17. package/components/composables/useGlobalToast.ts +6 -0
  18. package/components/composables/useLockScroll.ts +9 -0
  19. package/components/composables/useParent.ts +65 -14
  20. package/components/composables/usePopover.ts +9 -0
  21. package/components/composables/useQueue.ts +8 -0
  22. package/components/composables/useRaf.ts +10 -0
  23. package/components/composables/useSharedState.ts +284 -0
  24. package/components/composables/useTouch.ts +8 -0
  25. package/components/composables/useTranslate.ts +9 -0
  26. package/components/composables/useUpload.ts +83 -11
  27. package/components/composables/useVirtualScroll.ts +7 -0
  28. package/components/composables/useWindowResize.ts +9 -0
  29. package/components/oxy-action-sheet/index.scss +5 -5
  30. package/components/oxy-action-sheet/oxy-action-sheet.vue +11 -0
  31. package/components/oxy-backtop/index.scss +2 -2
  32. package/components/oxy-backtop/oxy-backtop.vue +2 -0
  33. package/components/oxy-badge/oxy-badge.vue +2 -0
  34. package/components/oxy-badge/types.ts +3 -0
  35. package/components/oxy-button/index.scss +13 -13
  36. package/components/oxy-button/oxy-button.vue +11 -0
  37. package/components/oxy-button/types.ts +3 -3
  38. package/components/oxy-calendar/index.scss +17 -17
  39. package/components/oxy-calendar/oxy-calendar.vue +31 -0
  40. package/components/oxy-calendar/types.ts +3 -0
  41. package/components/oxy-calendar-view/month/month.vue +2 -0
  42. package/components/oxy-calendar-view/monthPanel/month-panel.vue +3 -1
  43. package/components/oxy-calendar-view/monthPanel/types.ts +10 -7
  44. package/components/oxy-calendar-view/oxy-calendar-view.vue +2 -0
  45. package/components/oxy-calendar-view/types.ts +3 -1
  46. package/components/oxy-calendar-view/year/types.ts +33 -1
  47. package/components/oxy-calendar-view/year/year.vue +2 -0
  48. package/components/oxy-calendar-view/yearPanel/year-panel.vue +2 -0
  49. package/components/oxy-card/index.scss +1 -1
  50. package/components/oxy-card/oxy-card.vue +2 -0
  51. package/components/oxy-cell/index.scss +3 -1
  52. package/components/oxy-cell/oxy-cell.vue +6 -4
  53. package/components/oxy-cell-group/oxy-cell-group.vue +2 -0
  54. package/components/oxy-checkbox/index.scss +7 -7
  55. package/components/oxy-checkbox/oxy-checkbox.vue +22 -16
  56. package/components/oxy-checkbox/types.ts +9 -0
  57. package/components/oxy-checkbox-group/index.scss +1 -1
  58. package/components/oxy-checkbox-group/oxy-checkbox-group.vue +2 -0
  59. package/components/oxy-circle/oxy-circle.vue +2 -0
  60. package/components/oxy-col/oxy-col.vue +3 -1
  61. package/components/oxy-col-picker/index.scss +3 -3
  62. package/components/oxy-col-picker/oxy-col-picker.vue +17 -1
  63. package/components/oxy-col-picker/types.ts +3 -0
  64. package/components/oxy-collapse/index.scss +2 -2
  65. package/components/oxy-collapse/oxy-collapse.vue +9 -0
  66. package/components/oxy-collapse-item/oxy-collapse-item.vue +4 -2
  67. package/components/oxy-config-provider/oxy-config-provider.vue +18 -0
  68. package/components/oxy-config-provider/types.ts +18 -0
  69. package/components/oxy-corner/index.scss +50 -32
  70. package/components/oxy-corner/oxy-corner.vue +2 -0
  71. package/components/oxy-count-down/oxy-count-down.vue +2 -0
  72. package/components/oxy-count-to/oxy-count-to.vue +12 -1
  73. package/components/oxy-count-to/types.ts +14 -4
  74. package/components/oxy-curtain/index.scss +10 -9
  75. package/components/oxy-curtain/oxy-curtain.vue +2 -0
  76. package/components/oxy-date-strip/oxy-date-strip.vue +22 -1
  77. package/components/oxy-date-strip-item/index.scss +4 -4
  78. package/components/oxy-date-strip-item/oxy-date-strip-item.vue +2 -0
  79. package/components/oxy-datetime-picker/index.scss +3 -3
  80. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +11 -1
  81. package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +2 -0
  82. package/components/oxy-divider/oxy-divider.vue +2 -0
  83. package/components/oxy-drop-menu/index.scss +2 -2
  84. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -0
  85. package/components/oxy-drop-menu-item/index.scss +1 -1
  86. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +17 -9
  87. package/components/oxy-echarts/oxy-echarts.vue +4 -2
  88. package/components/oxy-fab/index.scss +1 -1
  89. package/components/oxy-fab/oxy-fab.vue +27 -0
  90. package/components/oxy-file-list/index.scss +9 -9
  91. package/components/oxy-file-list/oxy-file-list.vue +29 -17
  92. package/components/oxy-floating-panel/oxy-floating-panel.vue +34 -10
  93. package/components/oxy-footer/index.scss +7 -0
  94. package/components/oxy-footer/oxy-footer.vue +4 -2
  95. package/components/oxy-footer/types.ts +9 -6
  96. package/components/oxy-form/oxy-form.vue +13 -1
  97. package/components/oxy-form-item/oxy-form-item.vue +5 -3
  98. package/components/oxy-gap/oxy-gap.vue +2 -0
  99. package/components/oxy-global-loading/oxy-global-loading.vue +18 -5
  100. package/components/oxy-global-message/oxy-global-message.vue +30 -17
  101. package/components/oxy-global-toast/oxy-global-toast.vue +18 -5
  102. package/components/oxy-grid/oxy-grid.vue +6 -0
  103. package/components/oxy-grid-item/index.scss +1 -1
  104. package/components/oxy-grid-item/oxy-grid-item.vue +22 -20
  105. package/components/oxy-guidance/index.scss +9 -9
  106. package/components/oxy-guidance/oxy-guidance.vue +22 -16
  107. package/components/oxy-icon/oxy-icon.vue +2 -0
  108. package/components/oxy-icon/types.ts +3 -0
  109. package/components/oxy-image-preview/index.scss +75 -0
  110. package/components/oxy-image-preview/index.ts +56 -0
  111. package/components/oxy-image-preview/oxy-image-preview.vue +221 -0
  112. package/components/oxy-image-preview/types.ts +164 -0
  113. package/components/oxy-img/oxy-img.vue +2 -0
  114. package/components/oxy-img-cropper/index.scss +2 -2
  115. package/components/oxy-img-cropper/oxy-img-cropper.vue +6 -0
  116. package/components/oxy-img-lazy/oxy-img-lazy.vue +9 -0
  117. package/components/oxy-index-anchor/index.scss +1 -1
  118. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  119. package/components/oxy-index-bar/index.scss +1 -1
  120. package/components/oxy-index-bar/oxy-index-bar.vue +18 -0
  121. package/components/oxy-input/index.scss +2 -1
  122. package/components/oxy-input/oxy-input.vue +18 -4
  123. package/components/oxy-input/types.ts +6 -0
  124. package/components/oxy-input-number/index.scss +3 -1
  125. package/components/oxy-input-number/oxy-input-number.vue +2 -0
  126. package/components/oxy-keyboard/index.scss +3 -3
  127. package/components/oxy-keyboard/key/index.vue +2 -0
  128. package/components/oxy-keyboard/oxy-keyboard.vue +11 -2
  129. package/components/oxy-link/index.scss +8 -4
  130. package/components/oxy-link/oxy-link.vue +9 -3
  131. package/components/oxy-link/types.ts +2 -2
  132. package/components/oxy-list/oxy-list.vue +2 -0
  133. package/components/oxy-list/types.ts +7 -0
  134. package/components/oxy-loading/oxy-loading.vue +6 -0
  135. package/components/oxy-loadmore/index.scss +1 -1
  136. package/components/oxy-loadmore/oxy-loadmore.vue +2 -0
  137. package/components/oxy-long-press-menu/index.scss +1 -1
  138. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +42 -13
  139. package/components/oxy-message-box/index.scss +223 -36
  140. package/components/oxy-message-box/index.ts +49 -23
  141. package/components/oxy-message-box/oxy-message-box.vue +181 -56
  142. package/components/oxy-message-box/types.ts +60 -2
  143. package/components/oxy-navbar/index.scss +1 -1
  144. package/components/oxy-navbar/oxy-navbar.vue +9 -6
  145. package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +2 -0
  146. package/components/oxy-notice-bar/index.scss +1 -1
  147. package/components/oxy-notice-bar/oxy-notice-bar.vue +29 -0
  148. package/components/oxy-notify/index.ts +16 -12
  149. package/components/oxy-notify/oxy-notify.vue +11 -4
  150. package/components/oxy-overlay/oxy-overlay.vue +34 -2
  151. package/components/oxy-pagination/oxy-pagination.vue +2 -0
  152. package/components/oxy-password-input/oxy-password-input.vue +2 -0
  153. package/components/oxy-picker/index.scss +7 -7
  154. package/components/oxy-picker/oxy-picker.vue +11 -0
  155. package/components/oxy-picker-view/index.scss +1 -1
  156. package/components/oxy-picker-view/oxy-picker-view.vue +2 -0
  157. package/components/oxy-popover/index.scss +2 -2
  158. package/components/oxy-popover/oxy-popover.vue +4 -1
  159. package/components/oxy-popup/oxy-popup.vue +8 -0
  160. package/components/oxy-progress/index.scss +2 -2
  161. package/components/oxy-progress/oxy-progress.vue +7 -0
  162. package/components/oxy-qrcode/draw.ts +15 -1
  163. package/components/oxy-qrcode/oxy-qrcode.vue +10 -3
  164. package/components/oxy-radio/index.scss +8 -8
  165. package/components/oxy-radio/oxy-radio.vue +13 -11
  166. package/components/oxy-radio-group/index.scss +1 -1
  167. package/components/oxy-radio-group/oxy-radio-group.vue +2 -0
  168. package/components/oxy-rate/oxy-rate.vue +5 -0
  169. package/components/oxy-rate/types.ts +2 -2
  170. package/components/oxy-resize/oxy-resize.vue +12 -0
  171. package/components/oxy-rich-text/index.scss +9 -9
  172. package/components/oxy-rich-text/oxy-rich-text.vue +6 -0
  173. package/components/oxy-rich-text/types.ts +15 -0
  174. package/components/oxy-root-portal/oxy-root-portal.vue +23 -15
  175. package/components/oxy-row/oxy-row.vue +2 -0
  176. package/components/oxy-search/index.scss +3 -3
  177. package/components/oxy-search/oxy-search.vue +19 -0
  178. package/components/oxy-segmented/index.scss +4 -4
  179. package/components/oxy-segmented/oxy-segmented.vue +2 -0
  180. package/components/oxy-select/index.scss +25 -25
  181. package/components/oxy-select/oxy-select.vue +27 -0
  182. package/components/oxy-select/types.ts +3 -0
  183. package/components/oxy-select-picker/index.scss +5 -5
  184. package/components/oxy-select-picker/oxy-select-picker.vue +7 -0
  185. package/components/oxy-sidebar/oxy-sidebar.vue +2 -0
  186. package/components/oxy-sidebar-item/index.scss +3 -3
  187. package/components/oxy-sidebar-item/oxy-sidebar-item.vue +17 -31
  188. package/components/oxy-signature/oxy-signature.vue +17 -0
  189. package/components/oxy-skeleton/oxy-skeleton.vue +7 -1
  190. package/components/oxy-slide-verify/index.scss +95 -0
  191. package/components/oxy-slide-verify/oxy-slide-verify.vue +244 -0
  192. package/components/oxy-slide-verify/types.ts +98 -0
  193. package/components/oxy-slider/oxy-slider.vue +3 -0
  194. package/components/oxy-sort-button/index.scss +10 -8
  195. package/components/oxy-sort-button/oxy-sort-button.vue +6 -0
  196. package/components/oxy-splitter/index.scss +9 -0
  197. package/components/oxy-splitter/oxy-splitter.vue +23 -2
  198. package/components/oxy-splitter-panel/index.scss +7 -5
  199. package/components/oxy-splitter-panel/oxy-splitter-panel.vue +93 -89
  200. package/components/oxy-status-tip/index.scss +3 -3
  201. package/components/oxy-status-tip/oxy-status-tip.vue +2 -0
  202. package/components/oxy-step/index.scss +4 -4
  203. package/components/oxy-step/oxy-step.vue +15 -13
  204. package/components/oxy-steps/oxy-steps.vue +2 -0
  205. package/components/oxy-sticky/oxy-sticky.vue +5 -3
  206. package/components/oxy-stream-render/oxy-stream-render.vue +29 -0
  207. package/components/oxy-swipe-action/oxy-swipe-action.vue +8 -0
  208. package/components/oxy-swiper/oxy-swiper.vue +6 -0
  209. package/components/oxy-swiper-nav/index.scss +4 -4
  210. package/components/oxy-switch/index.scss +6 -3
  211. package/components/oxy-switch/oxy-switch.vue +10 -0
  212. package/components/oxy-tab/index.scss +1 -7
  213. package/components/oxy-tab/oxy-tab.vue +12 -10
  214. package/components/oxy-tabbar/oxy-tabbar.vue +5 -0
  215. package/components/oxy-tabbar-item/oxy-tabbar-item.vue +11 -9
  216. package/components/oxy-table/index.scss +1 -1
  217. package/components/oxy-table/oxy-table.vue +8 -0
  218. package/components/oxy-table/types.ts +3 -0
  219. package/components/oxy-table-col/oxy-table-col.vue +21 -19
  220. package/components/oxy-tabs/index.scss +11 -11
  221. package/components/oxy-tabs/oxy-tabs.vue +17 -0
  222. package/components/oxy-tag/index.scss +24 -5
  223. package/components/oxy-tag/oxy-tag.vue +17 -2
  224. package/components/oxy-tag/types.ts +7 -0
  225. package/components/oxy-text/oxy-text.vue +12 -1
  226. package/components/oxy-textarea/index.scss +3 -2
  227. package/components/oxy-textarea/oxy-textarea.vue +10 -4
  228. package/components/oxy-toast/index.ts +21 -20
  229. package/components/oxy-toast/oxy-toast.vue +30 -5
  230. package/components/oxy-toast/types.ts +20 -9
  231. package/components/oxy-tooltip/index.scss +1 -1
  232. package/components/oxy-tooltip/oxy-tooltip.vue +2 -0
  233. package/components/oxy-transition/index.scss +3 -1
  234. package/components/oxy-transition/oxy-transition.vue +14 -0
  235. package/components/oxy-tree/index.scss +3 -3
  236. package/components/oxy-tree/oxy-tree.vue +28 -5
  237. package/components/oxy-tree/types.ts +57 -1
  238. package/components/oxy-upload/index.scss +9 -9
  239. package/components/oxy-upload/oxy-upload.vue +5 -3
  240. package/components/oxy-verification-code/oxy-verification-code.vue +24 -0
  241. package/components/oxy-video-preview/index.scss +12 -7
  242. package/components/oxy-video-preview/index.ts +64 -0
  243. package/components/oxy-video-preview/oxy-video-preview.vue +102 -31
  244. package/components/oxy-video-preview/types.ts +54 -8
  245. package/components/oxy-virtual-scroll/index.scss +1 -1
  246. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +2 -0
  247. package/components/oxy-voice-player/index.scss +64 -64
  248. package/components/oxy-voice-player/oxy-voice-player.vue +38 -10
  249. package/components/oxy-waterfall/oxy-waterfall.vue +13 -0
  250. package/components/oxy-waterfall/types.ts +7 -0
  251. package/components/oxy-waterfall-item/oxy-waterfall-item.vue +9 -0
  252. package/components/oxy-watermark/oxy-watermark.vue +2 -0
  253. package/global.d.ts +2 -0
  254. package/index.ts +2 -0
  255. package/locale/lang/en-US.ts +51 -2
  256. package/locale/lang/zh-CN.ts +51 -2
  257. package/package.json +2 -2
  258. package/styles/all.scss +125 -0
  259. package/tags.json +1 -1
  260. package/vite-plugins/vite-plugin-host-class.ts +166 -0
  261. package/web-types.json +1 -1
@@ -35,20 +35,56 @@ export type TreeNode = {
35
35
 
36
36
  export const treeProps = {
37
37
  ...baseProps,
38
+ /**
39
+ * 树形数据源
40
+ */
38
41
  data: makeArrayProp<RawTreeNode>(),
42
+ /**
43
+ * 是否显示复选框
44
+ */
39
45
  showCheckbox: makeBooleanProp(false),
46
+ /**
47
+ * 子节点键名
48
+ */
40
49
  childrenKey: makeStringProp('children'),
50
+ /**
51
+ * 标签键名
52
+ */
41
53
  labelKey: makeStringProp('name'),
54
+ /**
55
+ * 节点唯一标识键名
56
+ */
42
57
  nodeKey: makeStringProp('id'),
58
+ /**
59
+ * 默认展开的节点 key 数组
60
+ */
43
61
  defaultExpandedKeys: makeArrayProp<string>(),
62
+ /**
63
+ * 是否默认展开所有节点
64
+ */
44
65
  expandAll: makeBooleanProp(false),
66
+ /**
67
+ * 是否严格模式,父子节点选中状态不关联
68
+ */
45
69
  checkStrictly: makeBooleanProp(false),
70
+ /**
71
+ * 是否显示连接线
72
+ */
46
73
  showLine: makeBooleanProp(false),
74
+ /**
75
+ * 选中的节点 key,单选为字符串,多选为数组
76
+ */
47
77
  modelValue: {
48
78
  type: [Array<string>, String],
49
79
  default: ''
50
80
  },
81
+ /**
82
+ * 空数据提示文案
83
+ */
51
84
  emptyText: makeStringProp('暂无数据'),
85
+ /**
86
+ * 容器高度,支持 `px/rpx`
87
+ */
52
88
  height: makeStringProp('600rpx'),
53
89
  /**
54
90
  * 是否显示回到顶部按钮
@@ -72,13 +108,33 @@ export const treeProps = {
72
108
  * 相邻级节点间的水平缩进,number 类型按 `rpx` 语义处理
73
109
  */
74
110
  indent: makeNumberProp(32),
111
+ /**
112
+ * 是否只能选择叶子节点
113
+ */
75
114
  selectionLeafOnly: makeBooleanProp(false),
115
+ /**
116
+ * 自定义筛选方法,接收关键字和节点数据,返回是否匹配
117
+ */
76
118
  filterMethod: {
77
119
  type: Function as PropType<(keyword: string, node: RawTreeNode) => boolean>,
78
120
  default: null
79
121
  },
122
+ /**
123
+ * 是否显示筛选输入框
124
+ */
80
125
  showFilter: makeBooleanProp(false),
81
- filterPlaceholder: makeStringProp('请输入节点名称')
126
+ /**
127
+ * 筛选输入框占位符
128
+ */
129
+ filterPlaceholder: makeStringProp('请输入节点名称'),
130
+ /**
131
+ * 展开图标名称
132
+ */
133
+ expandIcon: makeStringProp('chevron-down-circle'),
134
+ /**
135
+ * 收起图标名称
136
+ */
137
+ collapseIcon: makeStringProp('chevron-right-circle')
82
138
  }
83
139
  export type TreeExpose = {
84
140
  toggleExpand: (node: TreeNode, flag: boolean) => void
@@ -39,7 +39,7 @@
39
39
  font-size: $-upload-evoke-icon-size;
40
40
  background-color: $-upload-evoke-bg;
41
41
  color: $-upload-evoke-color;
42
- margin-bottom: 28rpx;
42
+ margin-bottom: $-upload-item-margin-bottom;
43
43
 
44
44
  @include when(disabled) {
45
45
  color: $-upload-evoke-disabled-color;
@@ -53,7 +53,7 @@
53
53
  @include e(evoke-num) {
54
54
  font-size: $-fs-content;
55
55
  line-height: $-fs-content;
56
- margin-top: 20rpx;
56
+ margin-top: $-spacing-20;
57
57
  }
58
58
 
59
59
  @include edeep(evoke-icon) {
@@ -75,7 +75,7 @@
75
75
  position: relative;
76
76
  width: $-upload-size;
77
77
  height: $-upload-size;
78
- margin: 0 24rpx 28rpx 0;
78
+ margin: 0 24rpx $-upload-item-margin-bottom 0;
79
79
  }
80
80
 
81
81
  @include e(preview-list) {
@@ -106,9 +106,9 @@
106
106
  font-size: $-upload-file-fs;
107
107
  color: $-upload-file-color;
108
108
  box-sizing: border-box;
109
- padding: 0 12rpx;
109
+ padding: 0 $-spacing-12;
110
110
  text-align: center;
111
- margin-top: 20rpx;
111
+ margin-top: $-spacing-20;
112
112
  @include lineEllipsis()
113
113
  }
114
114
 
@@ -131,7 +131,7 @@
131
131
  right: calc($-upload-close-icon-size / 2 * -1);
132
132
  top: calc($-upload-close-icon-size / 2 * -1);
133
133
  font-size: $-upload-close-icon-size;
134
- z-index: 1;
134
+ z-index: $-z-index-sticky;
135
135
  color: $-upload-close-icon-color;
136
136
  width: $-upload-close-icon-size;
137
137
  height: $-upload-close-icon-size;
@@ -159,7 +159,7 @@
159
159
  @include e(progress-txt) {
160
160
  font-size: $-upload-progress-fs;
161
161
  line-height: $-upload-progress-fs;
162
- margin-top: 20rpx;
162
+ margin-top: $-spacing-20;
163
163
  color: $-color-white;
164
164
  }
165
165
 
@@ -208,9 +208,9 @@
208
208
  font-size: $-upload-preview-name-fs;
209
209
  color: $-upload-file-color;
210
210
  box-sizing: border-box;
211
- padding: 0 12rpx;
211
+ padding: 0 $-spacing-12;
212
212
  text-align: center;
213
- margin-top: 20rpx;
213
+ margin-top: $-spacing-20;
214
214
  white-space: nowrap;
215
215
  overflow: hidden;
216
216
  text-overflow: ellipsis;
@@ -42,7 +42,7 @@
42
42
  <!-- #ifndef MP-DINGTALK -->
43
43
  <video
44
44
  :src="file.url"
45
- :title="file.name || '视频' + index"
45
+ :title="file.name || translate('videoType') + index"
46
46
  object-fit="contain"
47
47
  :controls="false"
48
48
  :poster="file.thumb"
@@ -123,7 +123,9 @@ export default {
123
123
  name: 'oxy-upload',
124
124
  options: {
125
125
  addGlobalClass: true,
126
+ // #ifndef MP-TOUTIAO
126
127
  virtualHost: true,
128
+ // #endif
127
129
  styleIsolation: 'shared'
128
130
  }
129
131
  }
@@ -596,7 +598,7 @@ function handlePreviewImage(index: number, lists: string[]) {
596
598
  imgList: lists
597
599
  })
598
600
  } else {
599
- uni.showToast({ title: '预览图片失败', icon: 'none' })
601
+ uni.showToast({ title: translate('previewImageFail'), icon: 'none' })
600
602
  }
601
603
  }
602
604
  })
@@ -626,7 +628,7 @@ function handlePreviewVieo(index: number, lists: UploadFileItem[]) {
626
628
  imgList: []
627
629
  })
628
630
  } else {
629
- uni.showToast({ title: '预览视频失败', icon: 'none' })
631
+ uni.showToast({ title: translate('previewVideoFail'), icon: 'none' })
630
632
  }
631
633
  }
632
634
  })
@@ -14,7 +14,9 @@ export default {
14
14
  name: 'oxy-verification-code',
15
15
  options: {
16
16
  addGlobalClass: true,
17
+ // #ifndef MP-TOUTIAO
17
18
  virtualHost: true,
19
+ // #endif
18
20
  styleIsolation: 'shared'
19
21
  }
20
22
  }
@@ -73,6 +75,10 @@ function randomNum(min: number, max: number) {
73
75
  return Math.floor(Math.random() * (max - min) + min)
74
76
  }
75
77
 
78
+ /**
79
+ * 生成随机验证码字符串
80
+ * 根据 codeType 从数字/字母/混合字符集中随机选取指定长度
81
+ */
76
82
  function getcheckCode() {
77
83
  let code = ''
78
84
  const codeLength = props.codeLength
@@ -93,6 +99,10 @@ function drawTap() {
93
99
  }
94
100
  }
95
101
 
102
+ /**
103
+ * 获取 Canvas 上下文(兼容微信小程序 2D canvas 和传统 canvas)
104
+ * 微信小程序通过 SelectorQuery.node 获取,其他平台通过 createCanvasContext
105
+ */
96
106
  function getContext() {
97
107
  return new Promise<UniApp.CanvasContext>((resolve) => {
98
108
  if (ctx) {
@@ -122,6 +132,10 @@ function getContext() {
122
132
  })
123
133
  }
124
134
 
135
+ /**
136
+ * 主绘制方法:生成验证码并绘制到 canvas
137
+ * 包含背景填充、单个字符绘制(随机旋转/颜色/位置/大小)、干扰线绘制
138
+ */
125
139
  function drawPic() {
126
140
  if (props.securityCode) {
127
141
  identifyCode.value = props.securityCode
@@ -140,6 +154,12 @@ function drawPic() {
140
154
  })
141
155
  }
142
156
 
157
+ /**
158
+ * 绘制单个验证码字符:随机颜色、字号、位置、旋转角度
159
+ * @param context - Canvas 上下文
160
+ * @param txt - 字符
161
+ * @param i - 字符索引(用于计算 x 坐标)
162
+ */
143
163
  function drawText(context: any, txt: string, i: number) {
144
164
  let a = Math.floor(Math.random() * props.colors.length)
145
165
  context.setFillStyle(props.colors[a])
@@ -158,6 +178,10 @@ function drawText(context: any, txt: string, i: number) {
158
178
  context.translate(-x, -y)
159
179
  }
160
180
 
181
+ /**
182
+ * 绘制干扰线:随机起点、终点、颜色
183
+ * @param context - Canvas 上下文
184
+ */
161
185
  function drawLine(context: any) {
162
186
  for (let i = 0; i < props.lineLength; i++) {
163
187
  let a = Math.floor(Math.random() * props.lineColors.length)
@@ -16,19 +16,24 @@
16
16
 
17
17
  @include e(video) {
18
18
  width: 100%;
19
- height: 484rpx;
19
+ height: $-video-preview-video-height;
20
20
  transition: all $-transition-duration-slow ease;
21
21
  }
22
22
 
23
- @include edeep(close) {
23
+ @include e(close) {
24
24
  position: absolute;
25
- box-sizing: border-box;
26
- top: 0;
27
- right: 0;
28
- padding: 24rpx;
29
- text-align: center;
25
+ z-index: $-video-preview-close-z-index;
26
+ top: $-video-preview-close-margin;
27
+ right: $-video-preview-close-margin;
28
+ display: flex;
29
+ justify-content: center;
30
+ align-items: center;
30
31
  cursor: pointer;
32
+ }
33
+
34
+ @include edeep(close-icon) {
31
35
  font-size: $-video-preview-close-font-size;
36
+ line-height: $-video-preview-close-font-size;
32
37
  color: $-video-preview-close-color;
33
38
  }
34
39
  }
@@ -0,0 +1,64 @@
1
+ import { inject, provide, ref } from 'vue'
2
+ import type { PreviewVideo, VideoPreview, VideoPreviewOptions } from './types'
3
+ import { deepMerge } from '../common/util'
4
+
5
+ /**
6
+ * useVideoPreview 注入 key
7
+ */
8
+ const videoPreviewDefaultOptionKey = '__VIDEO_PREVIEW_OPTION__'
9
+
10
+ /**
11
+ * 默认配置
12
+ */
13
+ export const defaultOptions: VideoPreviewOptions = {
14
+ url: '',
15
+ poster: '',
16
+ title: '',
17
+ show: false,
18
+ zIndex: 1000
19
+ }
20
+
21
+ const None = Symbol('None')
22
+
23
+ /**
24
+ * 视频预览 Hook
25
+ * @param selector 实例标识,支持同一页面多个视频预览实例
26
+ */
27
+ export function useVideoPreview(selector: string = ''): VideoPreview {
28
+ const videoPreviewOptionKey = getVideoPreviewOptionKey(selector)
29
+ const videoPreviewOption = inject(videoPreviewOptionKey, ref<VideoPreviewOptions | typeof None>(None))
30
+
31
+ if (videoPreviewOption.value === None) {
32
+ videoPreviewOption.value = defaultOptions
33
+ provide(videoPreviewOptionKey, videoPreviewOption)
34
+ }
35
+
36
+ /**
37
+ * 打开视频预览
38
+ * @param options 预览配置
39
+ */
40
+ const open = (options: VideoPreviewOptions | PreviewVideo) => {
41
+ const mergedOptions = deepMerge(defaultOptions, options) as VideoPreviewOptions
42
+ videoPreviewOption.value = deepMerge(mergedOptions, { show: true }) as VideoPreviewOptions
43
+ }
44
+
45
+ /**
46
+ * 关闭视频预览
47
+ */
48
+ const close = () => {
49
+ videoPreviewOption.value = { show: false } as VideoPreviewOptions
50
+ }
51
+
52
+ return {
53
+ previewVideo: open,
54
+ closeVideoPreview: close
55
+ }
56
+ }
57
+
58
+ /**
59
+ * 获取视频预览选项 key
60
+ * @param selector 实例标识
61
+ */
62
+ export const getVideoPreviewOptionKey = (selector: string) => {
63
+ return selector ? `${videoPreviewDefaultOptionKey}${selector}` : videoPreviewDefaultOptionKey
64
+ }
@@ -1,20 +1,31 @@
1
1
  <template>
2
- <view :class="`oxy-video-preview ${customClass}`" :style="customStyle" v-if="showPopup" @click="close">
2
+ <oxy-overlay
3
+ :show="state.show"
4
+ :z-index="options.zIndex"
5
+ :lock-scroll="true"
6
+ :custom-class="`oxy-video-preview ${props.customClass}`"
7
+ :custom-style="props.customStyle"
8
+ @click="close"
9
+ @enter="handleEnter"
10
+ @after-leave="handleAfterLeave"
11
+ >
3
12
  <view class="oxy-video-preview__video" @click.stop="">
4
13
  <video
5
14
  class="oxy-video-preview__video"
6
- v-if="previdewVideo.url"
15
+ v-if="state.visible && previewVideo.url"
7
16
  :controls="true"
8
- :poster="previdewVideo.poster"
9
- :title="previdewVideo.title"
17
+ :poster="previewVideo.poster"
18
+ :title="previewVideo.title"
10
19
  play-btn-position="center"
11
20
  :enableNative="true"
12
- :src="previdewVideo.url"
21
+ :src="previewVideo.url"
13
22
  :enable-progress-gesture="false"
14
23
  ></video>
15
24
  </view>
16
- <oxy-icon name="close" :custom-class="`oxy-video-preview__close`" @click="close" />
17
- </view>
25
+ <view class="oxy-video-preview__close" @click.stop="close">
26
+ <oxy-icon name="close" custom-class="oxy-video-preview__close-icon" />
27
+ </view>
28
+ </oxy-overlay>
18
29
  </template>
19
30
 
20
31
  <script lang="ts">
@@ -22,7 +33,9 @@ export default {
22
33
  name: 'oxy-video-preview',
23
34
  options: {
24
35
  addGlobalClass: true,
36
+ // #ifndef MP-TOUTIAO
25
37
  virtualHost: true,
38
+ // #endif
26
39
  styleIsolation: 'shared'
27
40
  }
28
41
  }
@@ -30,43 +43,101 @@ export default {
30
43
 
31
44
  <script lang="ts" setup>
32
45
  import OxyIcon from '../oxy-icon/oxy-icon.vue'
33
- import { nextTick, reactive, ref } from 'vue'
34
- import { videoPreviewProps, type PreviewVideo, type VideoPreviewExpose } from './types'
35
- import { useLockScroll } from '../composables/useLockScroll'
36
- defineProps(videoPreviewProps)
46
+ import OxyOverlay from '../oxy-overlay/oxy-overlay.vue'
47
+ import { computed, inject, reactive, ref, watch } from 'vue'
48
+ import { defaultOptions, getVideoPreviewOptionKey } from './index'
49
+ import { videoPreviewProps, type PreviewVideo, type VideoPreviewExpose, type VideoPreviewOptions } from './types'
50
+ import { isDef, isFunction } from '../common/util'
37
51
 
38
- const showPopup = ref<boolean>(false)
39
- const previdewVideo = reactive<PreviewVideo>({ url: '', poster: '', title: '' })
52
+ const props = defineProps(videoPreviewProps)
40
53
 
41
- function open(video: PreviewVideo) {
42
- showPopup.value = true
43
- previdewVideo.url = video.url
44
- previdewVideo.poster = video.poster
45
- previdewVideo.title = video.title
54
+ const emit = defineEmits<{
55
+ open: []
56
+ close: []
57
+ }>()
58
+
59
+ const state = reactive({
60
+ show: false,
61
+ visible: false
62
+ })
63
+
64
+ const previewVideo = reactive<PreviewVideo>({
65
+ url: '',
66
+ poster: '',
67
+ title: ''
68
+ })
69
+
70
+ // 获取函数式调用注入的选项
71
+ const videoPreviewOptionKey = getVideoPreviewOptionKey(props.selector)
72
+ const videoPreviewOption = inject(videoPreviewOptionKey, ref<VideoPreviewOptions>(defaultOptions))
73
+
74
+ const options = computed(() => ({
75
+ zIndex: isDef(videoPreviewOption.value.zIndex) ? videoPreviewOption.value.zIndex! : props.zIndex,
76
+ onOpen: videoPreviewOption.value.onOpen || props.onOpen || null,
77
+ onClose: videoPreviewOption.value.onClose || props.onClose || null
78
+ }))
79
+
80
+ watch(
81
+ () => videoPreviewOption.value,
82
+ (newVal: VideoPreviewOptions) => {
83
+ reset(newVal)
84
+ },
85
+ { deep: true, immediate: true }
86
+ )
87
+
88
+ watch(
89
+ () => state.show,
90
+ (newVal, oldVal) => {
91
+ if (newVal && !oldVal) {
92
+ emit('open')
93
+ if (isFunction(options.value.onOpen)) {
94
+ options.value.onOpen()
95
+ }
96
+ } else if (!newVal && oldVal) {
97
+ emit('close')
98
+ if (isFunction(options.value.onClose)) {
99
+ options.value.onClose()
100
+ }
101
+ }
102
+ }
103
+ )
104
+
105
+ function reset(option: VideoPreviewOptions) {
106
+ state.show = isDef(option.show) ? option.show! : false
107
+ if (state.show) {
108
+ previewVideo.url = option.url
109
+ previewVideo.poster = option.poster
110
+ previewVideo.title = option.title
111
+ }
46
112
  }
47
113
 
48
- function close() {
49
- showPopup.value = false
50
- nextTick(() => {
51
- handleClosed()
52
- })
114
+ function handleEnter() {
115
+ state.visible = true
53
116
  }
54
117
 
55
- function handleClosed() {
56
- previdewVideo.url = ''
57
- previdewVideo.poster = ''
58
- previdewVideo.title = ''
118
+ function handleAfterLeave() {
119
+ state.visible = false
120
+ previewVideo.url = ''
121
+ previewVideo.poster = ''
122
+ previewVideo.title = ''
59
123
  }
60
124
 
61
- // #ifdef H5
62
- useLockScroll(() => showPopup.value)
63
- // #endif
125
+ function open(video: PreviewVideo) {
126
+ previewVideo.url = video.url
127
+ previewVideo.poster = video.poster
128
+ previewVideo.title = video.title
129
+ state.show = true
130
+ }
131
+
132
+ function close() {
133
+ state.show = false
134
+ }
64
135
 
65
136
  defineExpose<VideoPreviewExpose>({
66
137
  open,
67
138
  close
68
139
  })
69
140
  </script>
70
- <style lang="scss" scoped>
141
+ <style lang="scss">
71
142
  @import './index.scss';
72
143
  </style>
@@ -1,23 +1,69 @@
1
1
  import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
2
- import { baseProps } from '../common/props'
2
+ import { baseProps, makeNumberProp, makeStringProp } from '../common/props'
3
3
 
4
4
  export const videoPreviewProps = {
5
- ...baseProps
5
+ ...baseProps,
6
+
7
+ /**
8
+ * 区分视频预览实例标识
9
+ * 类型:string
10
+ * 默认值:''
11
+ */
12
+ selector: makeStringProp(''),
13
+ /**
14
+ * 预览层级
15
+ * 类型:number
16
+ * 默认值:1000
17
+ */
18
+ zIndex: makeNumberProp(1000),
19
+ /**
20
+ * 打开回调(优先级低于 useVideoPreview 传入的 onOpen)
21
+ * 类型:function
22
+ * 默认值:-
23
+ */
24
+ onOpen: Function as PropType<() => void>,
25
+ /**
26
+ * 关闭回调(优先级低于 useVideoPreview 传入的 onClose)
27
+ * 类型:function
28
+ * 默认值:-
29
+ */
30
+ onClose: Function as PropType<() => void>
6
31
  }
7
32
 
8
33
  export type PreviewVideo = {
9
- url: string // 视频资源地址
10
- poster?: string // 视频封面
11
- title?: string // 视频标题
34
+ /** 视频资源地址 */
35
+ url: string
36
+ /** 视频封面地址,默认不展示封面 */
37
+ poster?: string
38
+ /** 视频标题,默认空字符串 */
39
+ title?: string
40
+ }
41
+
42
+ export interface VideoPreviewOptions extends PreviewVideo {
43
+ /** 是否显示预览层,默认 false */
44
+ show?: boolean
45
+ /** 预览层级,默认 1000 */
46
+ zIndex?: number
47
+ /** 打开时回调 */
48
+ onOpen?: () => void
49
+ /** 关闭时回调 */
50
+ onClose?: () => void
51
+ }
52
+
53
+ export type VideoPreview = {
54
+ /** 打开视频预览 */
55
+ previewVideo: (options: VideoPreviewOptions | PreviewVideo) => void
56
+ /** 关闭视频预览 */
57
+ closeVideoPreview: () => void
12
58
  }
13
59
 
14
60
  export type VideoPreviewProps = ExtractPropTypes<typeof videoPreviewProps>
15
61
 
16
62
  export type VideoPreviewExpose = {
17
- // 打开弹框
63
+ /** 打开预览 */
18
64
  open: (video: PreviewVideo) => void
19
- // 关闭弹框
65
+ /** 关闭预览 */
20
66
  close: () => void
21
67
  }
22
68
 
23
- export type VideoPreviewInstance = ComponentPublicInstance<VideoPreviewExpose, VideoPreviewProps>
69
+ export type VideoPreviewInstance = ComponentPublicInstance<VideoPreviewProps, VideoPreviewExpose>
@@ -30,6 +30,6 @@
30
30
  align-items: center;
31
31
  justify-content: center;
32
32
  cursor: pointer;
33
- z-index: 100;
33
+ z-index: $-virtual-scroll-back-top-z-index;
34
34
  }
35
35
  }
@@ -51,7 +51,9 @@ export default {
51
51
  name: 'oxy-virtual-scroll',
52
52
  options: {
53
53
  addGlobalClass: true,
54
+ // #ifndef MP-TOUTIAO
54
55
  virtualHost: true,
56
+ // #endif
55
57
  styleIsolation: 'shared'
56
58
  }
57
59
  }