vxe-pc-ui 3.14.4 → 3.14.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +134 -134
  3. package/es/tree/src/tree.js +40 -5
  4. package/es/tree-select/src/tree-select.js +2 -0
  5. package/es/ui/index.js +1 -1
  6. package/es/ui/src/log.js +1 -1
  7. package/lib/index.umd.js +8406 -8476
  8. package/lib/index.umd.min.js +1 -1
  9. package/lib/tree/src/tree.js +40 -5
  10. package/lib/tree/src/tree.min.js +1 -1
  11. package/lib/tree-select/src/tree-select.js +2 -0
  12. package/lib/tree-select/src/tree-select.min.js +1 -1
  13. package/lib/ui/index.js +1 -1
  14. package/lib/ui/index.min.js +1 -1
  15. package/lib/ui/src/log.js +1 -1
  16. package/lib/ui/src/log.min.js +1 -1
  17. package/package.json +89 -89
  18. package/packages/alert/index.ts +16 -16
  19. package/packages/alert/src/alert.ts +106 -106
  20. package/packages/anchor/index.ts +16 -16
  21. package/packages/anchor/src/anchor-link.ts +158 -158
  22. package/packages/anchor/src/anchor.ts +267 -267
  23. package/packages/anchor/src/util.ts +23 -23
  24. package/packages/anchor-link/index.ts +16 -16
  25. package/packages/avatar/index.ts +16 -16
  26. package/packages/avatar/src/avatar.ts +141 -141
  27. package/packages/backtop/index.ts +16 -16
  28. package/packages/backtop/src/backtop.ts +330 -330
  29. package/packages/badge/index.ts +16 -16
  30. package/packages/badge/src/badge.ts +87 -87
  31. package/packages/breadcrumb/index.ts +16 -16
  32. package/packages/breadcrumb/src/breadcrumb-item.ts +118 -118
  33. package/packages/breadcrumb/src/breadcrumb.ts +89 -89
  34. package/packages/breadcrumb-item/index.ts +16 -16
  35. package/packages/button/index.ts +16 -16
  36. package/packages/button/src/button-group.ts +113 -113
  37. package/packages/button/src/button.ts +956 -956
  38. package/packages/button-group/index.ts +16 -16
  39. package/packages/calendar/index.ts +16 -16
  40. package/packages/calendar/src/calendar.ts +1527 -1527
  41. package/packages/card/index.ts +16 -16
  42. package/packages/card/src/card.ts +162 -162
  43. package/packages/carousel/index.ts +16 -16
  44. package/packages/carousel/src/carousel-item.ts +117 -117
  45. package/packages/carousel/src/carousel.ts +460 -460
  46. package/packages/carousel/src/util.ts +21 -21
  47. package/packages/carousel-item/index.ts +16 -16
  48. package/packages/cascader/index.ts +16 -16
  49. package/packages/cascader/src/cascader.ts +943 -943
  50. package/packages/checkbox/index.ts +16 -16
  51. package/packages/checkbox/src/button.ts +185 -185
  52. package/packages/checkbox/src/checkbox.ts +189 -189
  53. package/packages/checkbox/src/group.ts +259 -259
  54. package/packages/checkbox-button/index.ts +16 -16
  55. package/packages/checkbox-group/index.ts +16 -16
  56. package/packages/col/index.ts +16 -16
  57. package/packages/collapse/index.ts +16 -16
  58. package/packages/collapse/src/collapse-pane.ts +136 -136
  59. package/packages/collapse/src/collapse.ts +259 -259
  60. package/packages/collapse/src/util.ts +21 -21
  61. package/packages/collapse-pane/index.ts +16 -16
  62. package/packages/color-picker/index.ts +16 -16
  63. package/packages/color-picker/src/color-picker.ts +1286 -1286
  64. package/packages/color-picker/src/util.ts +198 -198
  65. package/packages/components.ts +307 -307
  66. package/packages/context-menu/index.ts +54 -54
  67. package/packages/context-menu/src/context-menu.ts +727 -727
  68. package/packages/countdown/index.ts +16 -16
  69. package/packages/countdown/src/countdown.ts +276 -276
  70. package/packages/date-panel/index.ts +16 -16
  71. package/packages/date-panel/src/date-panel.ts +2024 -2024
  72. package/packages/date-panel/src/util.ts +244 -244
  73. package/packages/date-picker/index.ts +17 -17
  74. package/packages/date-picker/src/date-picker.ts +1249 -1249
  75. package/packages/date-range-picker/index.ts +16 -16
  76. package/packages/date-range-picker/src/date-range-picker.ts +1480 -1480
  77. package/packages/drawer/index.ts +87 -87
  78. package/packages/drawer/src/drawer.ts +767 -767
  79. package/packages/dynamics/index.ts +127 -127
  80. package/packages/empty/index.ts +16 -16
  81. package/packages/empty/src/empty.ts +80 -80
  82. package/packages/form/index.ts +16 -16
  83. package/packages/form/render/index.ts +617 -617
  84. package/packages/form/src/form-config-item.ts +84 -84
  85. package/packages/form/src/form-group.ts +125 -125
  86. package/packages/form/src/form-item.ts +217 -217
  87. package/packages/form/src/form.ts +1032 -1032
  88. package/packages/form/src/itemInfo.ts +80 -80
  89. package/packages/form/src/render.ts +398 -398
  90. package/packages/form/src/util.ts +92 -92
  91. package/packages/form-gather/index.ts +18 -18
  92. package/packages/form-group/index.ts +16 -16
  93. package/packages/form-item/index.ts +16 -16
  94. package/packages/icon/index.ts +16 -16
  95. package/packages/icon/src/icon.ts +75 -75
  96. package/packages/icon-picker/index.ts +16 -16
  97. package/packages/icon-picker/src/icon-picker.ts +753 -753
  98. package/packages/image/index.ts +16 -16
  99. package/packages/image/src/group.ts +162 -162
  100. package/packages/image/src/image.ts +303 -303
  101. package/packages/image/src/preview.ts +737 -737
  102. package/packages/image/src/util.ts +62 -62
  103. package/packages/image-group/index.ts +16 -16
  104. package/packages/image-preview/index.ts +19 -19
  105. package/packages/index.ts +8 -8
  106. package/packages/input/index.ts +16 -16
  107. package/packages/input/src/input.ts +3187 -3187
  108. package/packages/language/ar-EG.ts +840 -840
  109. package/packages/language/de-DE.ts +840 -840
  110. package/packages/language/en-US.ts +840 -840
  111. package/packages/language/es-ES.ts +840 -840
  112. package/packages/language/fr-FR.ts +840 -840
  113. package/packages/language/hu-HU.ts +840 -840
  114. package/packages/language/hy-AM.ts +840 -840
  115. package/packages/language/id-ID.ts +840 -840
  116. package/packages/language/it-IT.ts +840 -840
  117. package/packages/language/ja-JP.ts +840 -840
  118. package/packages/language/ko-KR.ts +840 -840
  119. package/packages/language/ms-MY.ts +840 -840
  120. package/packages/language/nb-NO.ts +840 -840
  121. package/packages/language/pt-BR.ts +840 -840
  122. package/packages/language/ru-RU.ts +840 -840
  123. package/packages/language/th-TH.ts +840 -840
  124. package/packages/language/ug-CN.ts +840 -840
  125. package/packages/language/uk-UA.ts +840 -840
  126. package/packages/language/uz-UZ.ts +840 -840
  127. package/packages/language/vi-VN.ts +840 -840
  128. package/packages/language/zh-CHT.ts +840 -840
  129. package/packages/language/zh-CN.ts +840 -840
  130. package/packages/language/zh-HK.ts +3 -3
  131. package/packages/language/zh-MO.ts +3 -3
  132. package/packages/language/zh-TC.ts +3 -3
  133. package/packages/language/zh-TW.ts +3 -3
  134. package/packages/layout-aside/index.ts +16 -16
  135. package/packages/layout-aside/src/layout-aside.ts +115 -115
  136. package/packages/layout-body/index.ts +16 -16
  137. package/packages/layout-body/src/layout-body.ts +137 -137
  138. package/packages/layout-container/index.ts +16 -16
  139. package/packages/layout-container/src/layout-container.ts +65 -65
  140. package/packages/layout-footer/index.ts +16 -16
  141. package/packages/layout-footer/src/layout-footer.ts +53 -53
  142. package/packages/layout-header/index.ts +16 -16
  143. package/packages/layout-header/src/layout-header.ts +49 -49
  144. package/packages/link/index.ts +16 -16
  145. package/packages/link/src/link.ts +153 -153
  146. package/packages/list/index.ts +16 -16
  147. package/packages/list/src/list.ts +492 -492
  148. package/packages/loading/index.ts +34 -34
  149. package/packages/loading/src/loading.ts +162 -162
  150. package/packages/mention/index.ts +16 -16
  151. package/packages/mention/src/mention.ts +54 -54
  152. package/packages/menu/index.ts +16 -16
  153. package/packages/menu/src/menu.ts +632 -632
  154. package/packages/modal/index.ts +150 -150
  155. package/packages/modal/src/modal.ts +1668 -1668
  156. package/packages/notice-bar/index.ts +16 -16
  157. package/packages/notice-bar/src/notice-bar.ts +182 -182
  158. package/packages/number-input/index.ts +16 -16
  159. package/packages/number-input/src/number-input.ts +1255 -1255
  160. package/packages/number-input/src/util.ts +12 -12
  161. package/packages/optgroup/index.ts +16 -16
  162. package/packages/option/index.ts +16 -16
  163. package/packages/pager/index.ts +16 -16
  164. package/packages/pager/src/pager.ts +913 -913
  165. package/packages/password-input/index.ts +16 -16
  166. package/packages/password-input/src/password-input.ts +466 -466
  167. package/packages/print/index.ts +18 -18
  168. package/packages/print/src/page-break.ts +78 -78
  169. package/packages/print/src/print.ts +266 -266
  170. package/packages/print/src/util.ts +284 -284
  171. package/packages/print-page-break/index.ts +14 -14
  172. package/packages/pulldown/index.ts +16 -16
  173. package/packages/pulldown/src/pulldown.ts +533 -533
  174. package/packages/radio/index.ts +16 -16
  175. package/packages/radio/src/button.ts +221 -221
  176. package/packages/radio/src/group.ts +252 -252
  177. package/packages/radio/src/radio.ts +228 -228
  178. package/packages/radio-button/index.ts +16 -16
  179. package/packages/radio-group/index.ts +16 -16
  180. package/packages/rate/index.ts +16 -16
  181. package/packages/rate/src/rate.ts +199 -199
  182. package/packages/result/index.ts +16 -16
  183. package/packages/result/src/result.ts +93 -93
  184. package/packages/row/index.ts +16 -16
  185. package/packages/row/src/col.ts +130 -130
  186. package/packages/row/src/row.ts +106 -106
  187. package/packages/segmented/index.ts +16 -16
  188. package/packages/segmented/src/segmented.ts +281 -281
  189. package/packages/select/index.ts +16 -16
  190. package/packages/select/src/optgroup.ts +107 -107
  191. package/packages/select/src/option-info.ts +20 -20
  192. package/packages/select/src/option.ts +103 -103
  193. package/packages/select/src/select.ts +2001 -2001
  194. package/packages/select/src/util.ts +47 -47
  195. package/packages/slider/index.ts +16 -16
  196. package/packages/slider/src/slider.ts +332 -332
  197. package/packages/split/index.ts +16 -16
  198. package/packages/split-pane/index.ts +17 -17
  199. package/packages/splitter/index.ts +16 -16
  200. package/packages/splitter/src/splitter-panel.ts +171 -171
  201. package/packages/splitter/src/splitter.ts +1032 -1032
  202. package/packages/splitter/src/util.ts +21 -21
  203. package/packages/splitter-panel/index.ts +16 -16
  204. package/packages/steps/index.ts +16 -16
  205. package/packages/steps/src/steps.ts +57 -57
  206. package/packages/switch/index.ts +16 -16
  207. package/packages/switch/src/switch.ts +279 -279
  208. package/packages/tab-pane/index.ts +16 -16
  209. package/packages/table-select/index.ts +16 -16
  210. package/packages/table-select/src/table-select.ts +904 -904
  211. package/packages/tabs/index.ts +16 -16
  212. package/packages/tabs/src/tab-pane.ts +137 -137
  213. package/packages/tabs/src/tabs.ts +1014 -1014
  214. package/packages/tabs/src/util.ts +21 -21
  215. package/packages/tag/index.ts +16 -16
  216. package/packages/tag/src/tag.ts +195 -195
  217. package/packages/text/index.ts +16 -16
  218. package/packages/text/src/text.ts +267 -267
  219. package/packages/text-ellipsis/index.ts +16 -16
  220. package/packages/text-ellipsis/src/text-ellipsis.ts +291 -291
  221. package/packages/textarea/index.ts +16 -16
  222. package/packages/textarea/src/textarea.ts +436 -436
  223. package/packages/timeline/index.ts +16 -16
  224. package/packages/timeline/src/timeline-item.ts +41 -41
  225. package/packages/timeline/src/timeline.ts +54 -54
  226. package/packages/timeline-item/index.ts +16 -16
  227. package/packages/tip/index.ts +19 -19
  228. package/packages/tip/src/tip.ts +112 -112
  229. package/packages/tooltip/index.ts +16 -16
  230. package/packages/tooltip/src/tooltip.ts +669 -669
  231. package/packages/tour/index.ts +16 -16
  232. package/packages/tour/src/tour.ts +54 -54
  233. package/packages/tree/index.ts +16 -16
  234. package/packages/tree/src/store.ts +15 -15
  235. package/packages/tree/src/tree.ts +3122 -3080
  236. package/packages/tree/src/util.ts +44 -44
  237. package/packages/tree-select/index.ts +16 -16
  238. package/packages/tree-select/src/tree-select.ts +1118 -1116
  239. package/packages/ui/index.ts +697 -697
  240. package/packages/ui/src/anime.ts +52 -52
  241. package/packages/ui/src/comp.ts +3 -3
  242. package/packages/ui/src/dom.ts +279 -279
  243. package/packages/ui/src/log.ts +6 -6
  244. package/packages/ui/src/utils.ts +49 -49
  245. package/packages/ui/src/vn.ts +60 -60
  246. package/packages/upload/index.ts +20 -20
  247. package/packages/upload/src/upload.ts +2129 -2129
  248. package/packages/upload/src/util.ts +109 -109
  249. package/packages/vxe-u-i/index.ts +4 -4
  250. package/packages/watermark/index.ts +31 -31
  251. package/packages/watermark/src/util.ts +176 -176
  252. package/packages/watermark/src/watermark.ts +166 -166
  253. package/styles/all.scss +90 -90
  254. package/styles/base.scss +16 -16
  255. package/styles/components/alert.scss +101 -101
  256. package/styles/components/anchor.scss +44 -44
  257. package/styles/components/avatar.scss +115 -115
  258. package/styles/components/backtop.scss +82 -82
  259. package/styles/components/badge.scss +45 -45
  260. package/styles/components/breadcrumb.scss +29 -29
  261. package/styles/components/button-group.scss +30 -30
  262. package/styles/components/button.scss +415 -415
  263. package/styles/components/calendar.scss +471 -471
  264. package/styles/components/card.scss +121 -121
  265. package/styles/components/carousel.scss +184 -184
  266. package/styles/components/cascader.scss +140 -140
  267. package/styles/components/checkbox-button.scss +57 -57
  268. package/styles/components/checkbox.scss +81 -81
  269. package/styles/components/collapse.scss +56 -56
  270. package/styles/components/color-picker.scss +409 -409
  271. package/styles/components/context-menu.scss +102 -102
  272. package/styles/components/countdown.scss +35 -35
  273. package/styles/components/date-panel.scss +505 -505
  274. package/styles/components/date-picker.scss +247 -247
  275. package/styles/components/date-range-picker.scss +252 -252
  276. package/styles/components/drawer.scss +298 -298
  277. package/styles/components/empty.scss +79 -79
  278. package/styles/components/form.scss +668 -668
  279. package/styles/components/icon-picker.scss +211 -211
  280. package/styles/components/icon.scss +1048 -1048
  281. package/styles/components/image-group.scss +2 -2
  282. package/styles/components/image-preview.scss +215 -215
  283. package/styles/components/image.scss +16 -16
  284. package/styles/components/input.scss +846 -846
  285. package/styles/components/layout-aside.scss +22 -22
  286. package/styles/components/layout-body.scss +14 -14
  287. package/styles/components/layout-container.scss +13 -13
  288. package/styles/components/layout-footer.scss +14 -14
  289. package/styles/components/layout-header.scss +11 -11
  290. package/styles/components/link.scss +115 -115
  291. package/styles/components/list.scss +40 -40
  292. package/styles/components/loading.scss +137 -137
  293. package/styles/components/menu.scss +150 -150
  294. package/styles/components/modal.scss +480 -480
  295. package/styles/components/notice-bar.scss +91 -91
  296. package/styles/components/number-input.scss +283 -283
  297. package/styles/components/old-icon.scss +4 -4
  298. package/styles/components/pager.scss +282 -282
  299. package/styles/components/password-input.scss +374 -374
  300. package/styles/components/print.scss +3 -3
  301. package/styles/components/pulldown.scss +75 -75
  302. package/styles/components/radio-button.scss +57 -57
  303. package/styles/components/radio.scss +79 -79
  304. package/styles/components/rate.scss +76 -76
  305. package/styles/components/result.scss +91 -91
  306. package/styles/components/row.scss +69 -69
  307. package/styles/components/segmented.scss +215 -215
  308. package/styles/components/select.scss +244 -244
  309. package/styles/components/slider.scss +139 -139
  310. package/styles/components/split.scss +1 -1
  311. package/styles/components/splitter.scss +318 -318
  312. package/styles/components/switch.scss +128 -128
  313. package/styles/components/table-select.scss +105 -105
  314. package/styles/components/tabs.scss +745 -745
  315. package/styles/components/tag.scss +184 -184
  316. package/styles/components/text-ellipsis.scss +130 -130
  317. package/styles/components/text.scss +123 -123
  318. package/styles/components/textarea.scss +106 -106
  319. package/styles/components/tip.scss +97 -97
  320. package/styles/components/tooltip.scss +141 -141
  321. package/styles/components/tree-select.scss +166 -166
  322. package/styles/components/tree.scss +294 -294
  323. package/styles/components/upload.scss +497 -497
  324. package/styles/components/watermark.scss +26 -26
  325. package/styles/helpers/baseMixin.scss +95 -95
  326. package/styles/helpers/baseVar.scss +3 -3
  327. package/styles/helpers/placement.scss +38 -38
  328. package/styles/theme/base.scss +214 -214
  329. package/styles/theme/dark.scss +119 -119
  330. package/styles/theme/light.scss +118 -118
  331. package/styles/variable.scss +111 -111
  332. package/types/all.d.ts +328 -328
  333. package/types/components/alert.d.ts +80 -80
  334. package/types/components/anchor-link.d.ts +84 -84
  335. package/types/components/anchor.d.ts +84 -84
  336. package/types/components/avatar.d.ts +81 -81
  337. package/types/components/backtop.d.ts +115 -115
  338. package/types/components/badge.d.ts +69 -69
  339. package/types/components/breadcrumb-item.d.ts +73 -73
  340. package/types/components/breadcrumb.d.ts +80 -80
  341. package/types/components/button-group.d.ts +113 -113
  342. package/types/components/button.d.ts +314 -314
  343. package/types/components/calendar.d.ts +254 -254
  344. package/types/components/card.d.ts +86 -86
  345. package/types/components/carousel-item.d.ts +68 -68
  346. package/types/components/carousel.d.ts +126 -126
  347. package/types/components/cascader.d.ts +250 -250
  348. package/types/components/checkbox-button.d.ts +93 -93
  349. package/types/components/checkbox-group.d.ts +135 -135
  350. package/types/components/checkbox.d.ts +115 -115
  351. package/types/components/col.d.ts +73 -73
  352. package/types/components/colgroup.d.ts +131 -131
  353. package/types/components/collapse-pane.d.ts +82 -82
  354. package/types/components/collapse.d.ts +115 -115
  355. package/types/components/color-picker.d.ts +164 -164
  356. package/types/components/column.d.ts +852 -852
  357. package/types/components/context-menu.d.ts +301 -301
  358. package/types/components/countdown.d.ts +99 -99
  359. package/types/components/date-panel.d.ts +269 -269
  360. package/types/components/date-picker.d.ts +322 -322
  361. package/types/components/date-range-picker.d.ts +336 -336
  362. package/types/components/drawer.d.ts +295 -295
  363. package/types/components/empty.d.ts +71 -71
  364. package/types/components/flow-design.d.ts +78 -78
  365. package/types/components/flow-view.d.ts +78 -78
  366. package/types/components/form-design.d.ts +364 -364
  367. package/types/components/form-gather.d.ts +72 -72
  368. package/types/components/form-group.d.ts +63 -63
  369. package/types/components/form-item.d.ts +405 -405
  370. package/types/components/form-view.d.ts +175 -175
  371. package/types/components/form.d.ts +463 -463
  372. package/types/components/gantt-module/gantt-view.d.ts +171 -171
  373. package/types/components/gantt-module/index.d.ts +1 -1
  374. package/types/components/gantt-plugins/extend-gantt-chart.d.ts +132 -132
  375. package/types/components/gantt-plugins/index.d.ts +1 -1
  376. package/types/components/gantt.d.ts +1201 -1192
  377. package/types/components/grid.d.ts +1038 -1038
  378. package/types/components/icon-picker.d.ts +185 -185
  379. package/types/components/icon.d.ts +80 -80
  380. package/types/components/image-group.d.ts +120 -120
  381. package/types/components/image-preview.d.ts +159 -159
  382. package/types/components/image.d.ts +166 -166
  383. package/types/components/input.d.ts +425 -425
  384. package/types/components/layout-aside.d.ts +73 -73
  385. package/types/components/layout-body.d.ts +84 -84
  386. package/types/components/layout-container.d.ts +66 -66
  387. package/types/components/layout-footer.d.ts +66 -66
  388. package/types/components/layout-header.d.ts +64 -64
  389. package/types/components/link.d.ts +104 -104
  390. package/types/components/list-design.d.ts +177 -177
  391. package/types/components/list-view.d.ts +190 -190
  392. package/types/components/list.d.ts +196 -196
  393. package/types/components/loading.d.ts +96 -96
  394. package/types/components/mention.d.ts +70 -70
  395. package/types/components/menu.d.ts +203 -203
  396. package/types/components/modal.d.ts +540 -540
  397. package/types/components/notice-bar.d.ts +95 -95
  398. package/types/components/number-input.d.ts +300 -300
  399. package/types/components/optgroup.d.ts +81 -81
  400. package/types/components/option.d.ts +95 -95
  401. package/types/components/pager.d.ts +322 -322
  402. package/types/components/password-input.d.ts +129 -129
  403. package/types/components/print-page-break.d.ts +62 -62
  404. package/types/components/print.d.ts +199 -199
  405. package/types/components/pulldown.d.ts +226 -226
  406. package/types/components/radio-button.d.ts +104 -104
  407. package/types/components/radio-group.d.ts +136 -136
  408. package/types/components/radio.d.ts +121 -121
  409. package/types/components/rate.d.ts +75 -75
  410. package/types/components/result.d.ts +77 -77
  411. package/types/components/row.d.ts +72 -72
  412. package/types/components/segmented.d.ts +117 -117
  413. package/types/components/select.d.ts +519 -519
  414. package/types/components/slider.d.ts +117 -117
  415. package/types/components/split-pane.d.ts +135 -135
  416. package/types/components/split.d.ts +318 -318
  417. package/types/components/splitter-panel.d.ts +98 -98
  418. package/types/components/splitter.d.ts +283 -283
  419. package/types/components/steps.d.ts +61 -61
  420. package/types/components/switch.d.ts +124 -124
  421. package/types/components/tab-pane.d.ts +107 -107
  422. package/types/components/table-module/custom.d.ts +115 -115
  423. package/types/components/table-module/edit.d.ts +245 -245
  424. package/types/components/table-module/export.d.ts +96 -96
  425. package/types/components/table-module/filter.d.ts +140 -140
  426. package/types/components/table-module/index.d.ts +7 -7
  427. package/types/components/table-module/keyboard.d.ts +26 -26
  428. package/types/components/table-module/menu.d.ts +26 -26
  429. package/types/components/table-module/validator.d.ts +53 -53
  430. package/types/components/table-plugins/extend-cell-area.d.ts +768 -768
  431. package/types/components/table-plugins/extend-pivot-table.d.ts +68 -68
  432. package/types/components/table-plugins/filters-combination.d.ts +15 -15
  433. package/types/components/table-plugins/filters-complex-input.d.ts +9 -9
  434. package/types/components/table-plugins/index.d.ts +4 -4
  435. package/types/components/table-select.d.ts +216 -216
  436. package/types/components/table.d.ts +7496 -7496
  437. package/types/components/tabs.d.ts +324 -324
  438. package/types/components/tag.d.ts +107 -107
  439. package/types/components/text-ellipsis.d.ts +105 -105
  440. package/types/components/text.d.ts +115 -115
  441. package/types/components/textarea.d.ts +237 -237
  442. package/types/components/timeline-item.d.ts +68 -68
  443. package/types/components/timeline.d.ts +70 -70
  444. package/types/components/tip.d.ts +76 -76
  445. package/types/components/toolbar.d.ts +329 -329
  446. package/types/components/tooltip.d.ts +169 -169
  447. package/types/components/tour.d.ts +70 -70
  448. package/types/components/tree-select.d.ts +299 -299
  449. package/types/components/tree.d.ts +836 -826
  450. package/types/components/upload.d.ts +432 -432
  451. package/types/components/watermark.d.ts +113 -113
  452. package/types/index.d.ts +4 -4
  453. package/types/ui/commands.d.ts +57 -57
  454. package/types/ui/formats.d.ts +62 -62
  455. package/types/ui/global-config.d.ts +254 -254
  456. package/types/ui/global-icon.d.ts +292 -292
  457. package/types/ui/hooks.d.ts +11 -11
  458. package/types/ui/index.d.ts +95 -95
  459. package/types/ui/interceptor.d.ts +54 -54
  460. package/types/ui/menus.d.ts +77 -77
  461. package/types/ui/renderer.d.ts +1042 -1042
  462. package/types/ui/validators.d.ts +38 -38
  463. /package/es/icon/{iconfont.1778169069480.ttf → iconfont.1778317204332.ttf} +0 -0
  464. /package/es/icon/{iconfont.1778169069480.woff → iconfont.1778317204332.woff} +0 -0
  465. /package/es/icon/{iconfont.1778169069480.woff2 → iconfont.1778317204332.woff2} +0 -0
  466. /package/es/{iconfont.1778169069480.ttf → iconfont.1778317204332.ttf} +0 -0
  467. /package/es/{iconfont.1778169069480.woff → iconfont.1778317204332.woff} +0 -0
  468. /package/es/{iconfont.1778169069480.woff2 → iconfont.1778317204332.woff2} +0 -0
  469. /package/lib/icon/style/{iconfont.1778169069480.ttf → iconfont.1778317204332.ttf} +0 -0
  470. /package/lib/icon/style/{iconfont.1778169069480.woff → iconfont.1778317204332.woff} +0 -0
  471. /package/lib/icon/style/{iconfont.1778169069480.woff2 → iconfont.1778317204332.woff2} +0 -0
  472. /package/lib/{iconfont.1778169069480.ttf → iconfont.1778317204332.ttf} +0 -0
  473. /package/lib/{iconfont.1778169069480.woff → iconfont.1778317204332.woff} +0 -0
  474. /package/lib/{iconfont.1778169069480.woff2 → iconfont.1778317204332.woff2} +0 -0
@@ -1,2129 +1,2129 @@
1
- import { PropType, CreateElement, VNode } from 'vue'
2
- import { defineVxeComponent } from '../../ui/src/comp'
3
- import XEUtils from 'xe-utils'
4
- import { VxeUI, getConfig, getI18n, getIcon, globalMixins, createEvent, globalEvents, renderEmptyElement } from '../../ui'
5
- import { getSlotVNs } from '../../ui/src/vn'
6
- import { errLog, warnLog } from '../../ui/src/log'
7
- import { initTpImg, getTpImg, getEventTargetNode, toCssUnit } from '../../ui/src/dom'
8
- import { readLocalFile } from './util'
9
- import VxeButtonComponent from '../../button/src/button'
10
-
11
- import type { VxeUploadDefines, VxeUploadConstructor, VxeUploadPropTypes, UploadReactData, UploadInternalData, VxeUploadEmits, VxeComponentSizeType, VxeFormDefines, VxeFormConstructor, VxeFormPrivateMethods, ValueOf, VxeComponentEventParams } from '../../../types'
12
- import type { VxeTableConstructor, VxeTablePrivateMethods } from '../../../types/components/table'
13
-
14
- function getUniqueKey () {
15
- return XEUtils.uniqueId()
16
- }
17
-
18
- function handleTransferFiles (items: DataTransferItemList) {
19
- const files: File[] = []
20
- XEUtils.arrayEach(items, item => {
21
- const file = item.getAsFile()
22
- if (file) {
23
- files.push(file)
24
- }
25
- })
26
- return files
27
- }
28
-
29
- function showDropTip ($xeUpload: VxeUploadConstructor, evnt: DragEvent, dragEl: HTMLElement, dragPos: string) {
30
- const { xID } = $xeUpload
31
-
32
- const reactData = $xeUpload.reactData
33
-
34
- const { showMorePopup } = reactData
35
- const el = $xeUpload.$refs.refElem as HTMLDivElement
36
- const popupEl = document.getElementById(`refPopupElem${xID}`) as HTMLDivElement
37
- const wrapperEl = showMorePopup ? popupEl : el
38
- if (!wrapperEl) {
39
- return
40
- }
41
- const wrapperRect = wrapperEl.getBoundingClientRect()
42
- const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
43
- const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
44
- const currDLineEl = showMorePopup ? mdLineEl : ddLineEl
45
- if (currDLineEl) {
46
- const dragRect = dragEl.getBoundingClientRect()
47
- currDLineEl.style.display = 'block'
48
- currDLineEl.style.top = `${Math.max(1, dragRect.y - wrapperRect.y)}px`
49
- currDLineEl.style.left = `${Math.max(1, dragRect.x - wrapperRect.x)}px`
50
- currDLineEl.style.height = `${dragRect.height}px`
51
- currDLineEl.style.width = `${dragRect.width - 1}px`
52
- currDLineEl.setAttribute('drag-pos', dragPos)
53
- }
54
- }
55
-
56
- function hideDropTip ($xeUpload: VxeUploadConstructor) {
57
- const { xID } = $xeUpload
58
-
59
- const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
60
- const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
61
- if (ddLineEl) {
62
- ddLineEl.style.display = ''
63
- }
64
- if (mdLineEl) {
65
- mdLineEl.style.display = ''
66
- }
67
- }
68
-
69
- function createReactData (): UploadReactData {
70
- return {
71
- isDragUploadStatus: false,
72
- showMorePopup: false,
73
- isActivated: false,
74
- fileList: [],
75
- fileCacheMaps: {},
76
- isDragMove: false,
77
- dragIndex: -1,
78
- dragTipText: ''
79
- }
80
- }
81
-
82
- function createInternalData (): UploadInternalData {
83
- return {
84
- moreId: XEUtils.uniqueId('upload'),
85
- imagePreviewTypes: ['jpg', 'jpeg', 'png', 'gif'],
86
- prevDragIndex: -1
87
- // prevDragPos: ''
88
- }
89
- }
90
-
91
- export default /* define-vxe-component start */ defineVxeComponent({
92
- name: 'VxeUpload',
93
- model: {
94
- prop: 'value',
95
- event: 'modelValue'
96
- },
97
- mixins: [
98
- globalMixins.sizeMixin
99
- ],
100
- props: {
101
- value: [Array, String, Object] as PropType<VxeUploadPropTypes.ModelValue>,
102
- showList: {
103
- type: Boolean as PropType<VxeUploadPropTypes.ShowList>,
104
- default: () => getConfig().upload.showList
105
- },
106
- moreConfig: Object as PropType<VxeUploadPropTypes.MoreConfig>,
107
- readonly: {
108
- type: Boolean as PropType<VxeUploadPropTypes.Readonly>,
109
- default: null
110
- },
111
- disabled: {
112
- type: Boolean as PropType<VxeUploadPropTypes.Disabled>,
113
- default: null
114
- },
115
- autoSubmit: {
116
- type: Boolean as PropType<VxeUploadPropTypes.AutoSubmit>,
117
- default: () => getConfig().upload.autoSubmit
118
- },
119
- mode: {
120
- type: String as PropType<VxeUploadPropTypes.Mode>,
121
- default: () => getConfig().upload.mode
122
- },
123
- imageTypes: {
124
- type: Array as PropType<VxeUploadPropTypes.ImageTypes>,
125
- default: () => XEUtils.clone(getConfig().upload.imageTypes, true)
126
- },
127
- imageConfig: {
128
- type: Object as PropType<VxeUploadPropTypes.ImageConfig>,
129
- default: () => XEUtils.clone(getConfig().upload.imageConfig, true)
130
- },
131
- /**
132
- * 已废弃,被 image-config 替换
133
- * @deprecated
134
- */
135
- imageStyle: {
136
- type: Object as PropType<VxeUploadPropTypes.ImageStyle>,
137
- default: () => XEUtils.clone(getConfig().upload.imageStyle, true)
138
- },
139
- fileTypes: {
140
- type: Array as PropType<VxeUploadPropTypes.FileTypes>,
141
- default: () => XEUtils.clone(getConfig().upload.fileTypes, true)
142
- },
143
- dragSort: Boolean as PropType<VxeUploadPropTypes.DragSort>,
144
- dragToUpload: {
145
- type: Boolean as PropType<VxeUploadPropTypes.DragToUpload>,
146
- default: () => XEUtils.clone(getConfig().upload.dragToUpload, true)
147
- },
148
- dragPlaceholder: {
149
- type: String as PropType<VxeUploadPropTypes.DragPlaceholder>,
150
- default: () => getConfig().upload.dragPlaceholder
151
- },
152
- pasteToUpload: {
153
- type: Boolean as PropType<VxeUploadPropTypes.PasteToUpload>,
154
- default: () => XEUtils.clone(getConfig().upload.pasteToUpload, true)
155
- },
156
- keyField: String as PropType<VxeUploadPropTypes.KeyField>,
157
- singleMode: Boolean as PropType<VxeUploadPropTypes.SingleMode>,
158
- urlMode: Boolean as PropType<VxeUploadPropTypes.UrlMode>,
159
- urlArgs: {
160
- type: Boolean as PropType<VxeUploadPropTypes.UrlArgs>,
161
- default: () => getConfig().upload.urlArgs
162
- },
163
- multiple: Boolean as PropType<VxeUploadPropTypes.Multiple>,
164
- limitSize: {
165
- type: [String, Number] as PropType<VxeUploadPropTypes.LimitSize>,
166
- default: () => getConfig().upload.limitSize
167
- },
168
- showLimitSize: {
169
- type: Boolean as PropType<VxeUploadPropTypes.ShowLimitSize>,
170
- default: () => getConfig().upload.showLimitSize
171
- },
172
- limitSizeText: {
173
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitSizeText>,
174
- default: () => getConfig().upload.limitSizeText
175
- },
176
- limitCount: {
177
- type: [String, Number] as PropType<VxeUploadPropTypes.LimitCount>,
178
- default: () => getConfig().upload.limitCount
179
- },
180
- showLimitCount: {
181
- type: Boolean as PropType<VxeUploadPropTypes.ShowLimitCount>,
182
- default: () => getConfig().upload.showLimitCount
183
- },
184
- limitCountText: {
185
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitCountText>,
186
- default: () => getConfig().upload.limitCountText
187
- },
188
- nameField: {
189
- type: String as PropType<VxeUploadPropTypes.NameField>,
190
- default: () => getConfig().upload.nameField
191
- },
192
- typeField: {
193
- type: String as PropType<VxeUploadPropTypes.TypeField>,
194
- default: () => getConfig().upload.typeField
195
- },
196
- urlField: {
197
- type: String as PropType<VxeUploadPropTypes.UrlField>,
198
- default: () => getConfig().upload.urlField
199
- },
200
- sizeField: {
201
- type: String as PropType<VxeUploadPropTypes.SizeField>,
202
- default: () => getConfig().upload.sizeField
203
- },
204
- showErrorStatus: {
205
- type: Boolean as PropType<VxeUploadPropTypes.ShowErrorStatus>,
206
- default: () => getConfig().upload.showErrorStatus
207
- },
208
- showProgress: {
209
- type: Boolean as PropType<VxeUploadPropTypes.ShowProgress>,
210
- default: () => getConfig().upload.showProgress
211
- },
212
- progressText: {
213
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.ProgressText>,
214
- default: () => getConfig().upload.progressText
215
- },
216
- previewImageConfig: Object as PropType<VxeUploadPropTypes.PreviewImageConfig>,
217
- showSubmitButton: Boolean as PropType<VxeUploadPropTypes.ShowSubmitButton>,
218
- autoHiddenButton: {
219
- type: Boolean as PropType<VxeUploadPropTypes.AutoHiddenButton>,
220
- default: () => getConfig().upload.autoHiddenButton
221
- },
222
- showUploadButton: {
223
- type: Boolean as PropType<VxeUploadPropTypes.ShowUploadButton>,
224
- default: () => getConfig().upload.showUploadButton
225
- },
226
- buttonText: {
227
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.ButtonText>,
228
- default: () => getConfig().upload.buttonText
229
- },
230
- buttonIcon: {
231
- type: String as PropType<VxeUploadPropTypes.ButtonIcon>,
232
- default: () => getConfig().upload.buttonIcon
233
- },
234
- showButtonText: {
235
- type: Boolean as PropType<VxeUploadPropTypes.ShowButtonText>,
236
- default: () => getConfig().upload.showButtonText
237
- },
238
- showButtonIcon: {
239
- type: Boolean as PropType<VxeUploadPropTypes.ShowButtonIcon>,
240
- default: () => getConfig().upload.showButtonIcon
241
- },
242
- showRemoveButton: {
243
- type: Boolean as PropType<VxeUploadPropTypes.ShowRemoveButton>,
244
- default: () => getConfig().upload.showRemoveButton
245
- },
246
- showDownloadButton: {
247
- type: Boolean as PropType<VxeUploadPropTypes.ShowDownloadButton>,
248
- default: () => getConfig().upload.showDownloadButton
249
- },
250
- showPreview: {
251
- type: Boolean as PropType<VxeUploadPropTypes.ShowPreview>,
252
- default: () => getConfig().upload.showPreview
253
- },
254
- showTip: {
255
- type: Boolean as PropType<VxeUploadPropTypes.ShowTip>,
256
- default: () => getConfig().upload.showTip
257
- },
258
- maxSimultaneousUploads: {
259
- type: Number as PropType<VxeUploadPropTypes.MaxSimultaneousUploads>,
260
- default: () => getConfig().upload.maxSimultaneousUploads
261
- },
262
- tipText: [String, Number, Function] as PropType<VxeUploadPropTypes.TipText>,
263
- hintText: String as PropType<VxeUploadPropTypes.HintText>,
264
- previewMethod: Function as PropType<VxeUploadPropTypes.PreviewMethod>,
265
- beforeSelectMethod: Function as PropType<VxeUploadPropTypes.BeforeSelectMethod>,
266
- uploadMethod: Function as PropType<VxeUploadPropTypes.UploadMethod>,
267
- beforeRemoveMethod: Function as PropType<VxeUploadPropTypes.BeforeRemoveMethod>,
268
- removeMethod: Function as PropType<VxeUploadPropTypes.RemoveMethod>,
269
- beforeDownloadMethod: Function as PropType<VxeUploadPropTypes.BeforeDownloadMethod>,
270
- downloadMethod: Function as PropType<VxeUploadPropTypes.DownloadMethod>,
271
- getUrlMethod: Function as PropType<VxeUploadPropTypes.GetUrlMethod>,
272
- getThumbnailUrlMethod: Function as PropType<VxeUploadPropTypes.GetThumbnailUrlMethod>,
273
- size: {
274
- type: String as PropType<VxeUploadPropTypes.Size>,
275
- default: () => getConfig().upload.size || getConfig().size
276
- }
277
- },
278
- inject: {
279
- $xeForm: {
280
- default: null
281
- },
282
- formItemInfo: {
283
- from: 'xeFormItemInfo',
284
- default: null
285
- },
286
- $xeTable: {
287
- default: null
288
- }
289
- },
290
- data () {
291
- const xID = XEUtils.uniqueId()
292
- const reactData = createReactData()
293
- const internalData = createInternalData()
294
- return {
295
- xID,
296
- reactData,
297
- internalData
298
- }
299
- },
300
- computed: {
301
- ...({} as {
302
- computeSize(): VxeComponentSizeType
303
- $xeForm(): (VxeFormConstructor & VxeFormPrivateMethods) | null
304
- formItemInfo(): VxeFormDefines.ProvideItemInfo | null,
305
- $xeTable(): (VxeTableConstructor & VxeTablePrivateMethods) | null
306
- }),
307
- computeFormReadonly () {
308
- const $xeUpload = this
309
- const props = $xeUpload
310
- const $xeForm = $xeUpload.$xeForm
311
-
312
- const { readonly } = props
313
- if (readonly === null) {
314
- if ($xeForm) {
315
- return $xeForm.readonly
316
- }
317
- return false
318
- }
319
- return readonly
320
- },
321
- computeIsDisabled () {
322
- const $xeUpload = this
323
- const props = $xeUpload
324
- const $xeForm = $xeUpload.$xeForm
325
-
326
- const { disabled } = props
327
- if (disabled === null) {
328
- if ($xeForm) {
329
- return $xeForm.disabled
330
- }
331
- return false
332
- }
333
- return disabled
334
- },
335
- computeKeyField () {
336
- const $xeUpload = this
337
- const props = $xeUpload
338
-
339
- return props.keyField || '_X_KEY'
340
- },
341
- computeIsImage () {
342
- const $xeUpload = this
343
- const props = $xeUpload
344
-
345
- return props.mode === 'image'
346
- },
347
- computeNameProp () {
348
- const $xeUpload = this
349
- const props = $xeUpload
350
-
351
- return props.nameField || 'name'
352
- },
353
- computeTypeProp () {
354
- const $xeUpload = this
355
- const props = $xeUpload
356
-
357
- return props.typeField || 'type'
358
- },
359
- computeUrlProp () {
360
- const $xeUpload = this
361
- const props = $xeUpload
362
-
363
- return props.urlField || 'url'
364
- },
365
- computeSizeProp () {
366
- const $xeUpload = this
367
- const props = $xeUpload
368
-
369
- return props.sizeField || 'size'
370
- },
371
- computeLimitMaxSize () {
372
- const $xeUpload = this
373
- const props = $xeUpload
374
-
375
- return XEUtils.toNumber(props.limitSize) * 1024 * 1024
376
- },
377
- computeLimitMaxCount () {
378
- const $xeUpload = this
379
- const props = $xeUpload
380
-
381
- return props.multiple ? XEUtils.toNumber(props.limitCount) : 1
382
- },
383
- computePreviewImageOpts () {
384
- const $xeUpload = this
385
- const props = $xeUpload
386
-
387
- const { showDownloadButton } = props
388
- return Object.assign({
389
- showDownloadButton
390
- }, getConfig().upload.previewImageConfig, props.previewImageConfig)
391
- },
392
- computeOverCount () {
393
- const $xeUpload = this
394
- const props = $xeUpload
395
- const reactData = $xeUpload.reactData as UploadReactData
396
-
397
- const { multiple } = props
398
- const { fileList } = reactData
399
- const limitMaxCount = $xeUpload.computeLimitMaxCount as number
400
- if (multiple) {
401
- if (limitMaxCount) {
402
- return fileList.length >= limitMaxCount
403
- }
404
- return true
405
- }
406
- return fileList.length >= 1
407
- },
408
- computeLimitSizeUnit () {
409
- const $xeUpload = this
410
- const props = $xeUpload
411
-
412
- const limitSize = XEUtils.toNumber(props.limitSize)
413
- if (limitSize) {
414
- if (limitSize > 1048576) {
415
- return `${limitSize / 1048576}T`
416
- }
417
- if (limitSize > 1024) {
418
- return `${limitSize / 1024}G`
419
- }
420
- return `${limitSize}M`
421
- }
422
- return ''
423
- },
424
- computedShowTipText () {
425
- const $xeUpload = this
426
- const props = $xeUpload
427
-
428
- const { showTip, tipText } = props
429
- if (XEUtils.isBoolean(showTip)) {
430
- return showTip
431
- }
432
- const defShowTip = getConfig().upload.showTip
433
- if (XEUtils.isBoolean(defShowTip)) {
434
- return defShowTip
435
- }
436
- if (tipText) {
437
- return true
438
- }
439
- return false
440
- },
441
- computedDefTipText () {
442
- const $xeUpload = this
443
- const props = $xeUpload
444
-
445
- const { limitSize, fileTypes, multiple, limitCount } = props
446
- const tipText = props.tipText || props.hintText
447
- const isImage = $xeUpload.computeIsImage
448
- const limitSizeUnit = $xeUpload.computeLimitSizeUnit
449
- if (XEUtils.isString(tipText)) {
450
- return tipText
451
- }
452
- if (XEUtils.isFunction(tipText)) {
453
- return `${tipText({})}`
454
- }
455
- const defTips: string[] = []
456
- if (isImage) {
457
- if (multiple && limitCount) {
458
- defTips.push(getI18n('vxe.upload.imgCountHint', [limitCount]))
459
- }
460
- if (limitSize && limitSizeUnit) {
461
- defTips.push(getI18n('vxe.upload.imgSizeHint', [limitSizeUnit]))
462
- }
463
- } else {
464
- if (fileTypes && fileTypes.length) {
465
- defTips.push(getI18n('vxe.upload.fileTypeHint', [fileTypes.join('/')]))
466
- }
467
- if (limitSize && limitSizeUnit) {
468
- defTips.push(getI18n('vxe.upload.fileSizeHint', [limitSizeUnit]))
469
- }
470
- if (multiple && limitCount) {
471
- defTips.push(getI18n('vxe.upload.fileCountHint', [limitCount]))
472
- }
473
- }
474
- return defTips.join(getI18n('vxe.base.comma'))
475
- },
476
- computeImageOpts () {
477
- const $xeUpload = this
478
- const props = $xeUpload
479
-
480
- return Object.assign({}, props.imageConfig || props.imageStyle)
481
- },
482
- computeImgStyle () {
483
- const $xeUpload = this
484
-
485
- const imageOpts = $xeUpload.computeImageOpts
486
- const { width, height } = imageOpts
487
- const stys: Record<string, string> = {}
488
- if (width) {
489
- stys.width = toCssUnit(width)
490
- }
491
- if (height) {
492
- stys.height = toCssUnit(height)
493
- }
494
- return stys
495
- },
496
- computeMoreOpts () {
497
- const $xeUpload = this
498
- const props = $xeUpload
499
-
500
- return Object.assign({ showMoreButton: true }, props.moreConfig)
501
- }
502
- },
503
- watch: {
504
- value () {
505
- const $xeUpload = this
506
- $xeUpload.updateFileList()
507
- }
508
- },
509
- methods: {
510
- //
511
- // Method
512
- //
513
- dispatchEvent (type: ValueOf<VxeUploadEmits>, params: Record<string, any>, evnt: Event | null) {
514
- const $xeUpload = this
515
- $xeUpload.$emit(type, createEvent(evnt, { $upload: $xeUpload }, params))
516
- },
517
- emitModel (value: any) {
518
- const $xeUpload = this
519
-
520
- const { _events } = $xeUpload as any
521
- if (_events && _events.modelValue) {
522
- $xeUpload.$emit('modelValue', value)
523
- } else {
524
- $xeUpload.$emit('model-value', value)
525
- }
526
- },
527
- choose () {
528
- const $xeUpload = this
529
- return $xeUpload.handleChoose(null)
530
- },
531
- getPendingFiles () {
532
- const $xeUpload = this
533
- const reactData = $xeUpload.reactData
534
-
535
- const { fileList, fileCacheMaps } = reactData
536
- const pendingFiles: File[] = []
537
- fileList.forEach(item => {
538
- const fileKey = $xeUpload.getFieldKey(item)
539
- const cacheItem = fileCacheMaps[fileKey]
540
- if (cacheItem && cacheItem.status === 'pending') {
541
- pendingFiles.push(cacheItem.file)
542
- }
543
- })
544
- return pendingFiles
545
- },
546
- submit (isFull?: boolean) {
547
- const $xeUpload = this
548
- const props = $xeUpload
549
- const reactData = $xeUpload.reactData
550
-
551
- const { maxSimultaneousUploads } = props
552
- const msNum = XEUtils.toNumber(maxSimultaneousUploads || 1) || 1
553
- const { fileList, fileCacheMaps } = reactData
554
- const allPendingList = fileList.filter(item => {
555
- const fileKey = $xeUpload.getFieldKey(item)
556
- const cacheItem = fileCacheMaps[fileKey]
557
- return cacheItem && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))
558
- })
559
-
560
- const handleSubmit = (item: VxeUploadDefines.FileObjItem): Promise<void> => {
561
- const fileKey = $xeUpload.getFieldKey(item)
562
- const cacheItem = fileCacheMaps[fileKey]
563
- if (cacheItem) {
564
- const file = cacheItem.file
565
- if (file && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))) {
566
- cacheItem.loading = true
567
- cacheItem.percent = 0
568
- return $xeUpload.handleUploadResult(item, file).then(handleNextSubmit)
569
- }
570
- }
571
- return handleNextSubmit()
572
- }
573
-
574
- const handleNextSubmit = (): Promise<void> => {
575
- if (allPendingList.length) {
576
- const item = allPendingList[0]
577
- allPendingList.splice(0, 1)
578
- return handleSubmit(item).then(handleNextSubmit)
579
- }
580
- return Promise.resolve()
581
- }
582
-
583
- return Promise.all(allPendingList.splice(0, msNum).map(handleSubmit)).then(() => {
584
- // 完成
585
- })
586
- },
587
- getMoreVisible () {
588
- const $xeUpload = this
589
- const reactData = $xeUpload.reactData
590
-
591
- return reactData.showMorePopup
592
- },
593
- openMore () {
594
- const $xeUpload = this
595
-
596
- $xeUpload.handleMoreEvent({ $event: new Event('click') })
597
- return $xeUpload.$nextTick()
598
- },
599
- openMoreByEvent (evnt: Event) {
600
- const $xeUpload = this
601
-
602
- $xeUpload.handleMoreEvent({ $event: evnt })
603
- return $xeUpload.$nextTick()
604
- },
605
- closeMore () {
606
- const $xeUpload = this
607
- const internalData = $xeUpload.internalData
608
-
609
- if (VxeUI.modal) {
610
- VxeUI.modal.close(internalData.moreId)
611
- }
612
- return $xeUpload.$nextTick()
613
- },
614
- getFieldKey (item: VxeUploadDefines.FileObjItem) {
615
- const $xeUpload = this
616
-
617
- const keyField = $xeUpload.computeKeyField
618
- return item[keyField]
619
- },
620
- updateFileList () {
621
- const $xeUpload = this
622
- const props = $xeUpload
623
- const reactData = $xeUpload.reactData
624
-
625
- const { value, multiple } = props
626
- const formReadonly = $xeUpload.computeFormReadonly
627
- const keyField = $xeUpload.computeKeyField
628
- const nameProp = $xeUpload.computeNameProp
629
- const typeProp = $xeUpload.computeTypeProp
630
- const urlProp = $xeUpload.computeUrlProp
631
- const sizeProp = $xeUpload.computeSizeProp
632
- const fileList = value
633
- ? (value ? (XEUtils.isArray(value) ? value : [value]) : []).map(item => {
634
- if (!item || XEUtils.isString(item)) {
635
- const url = `${item || ''}`
636
- const urlObj = XEUtils.parseUrl(item)
637
- const name = (urlObj ? urlObj.searchQuery[nameProp] : '') || $xeUpload.parseFileName(url)
638
- return {
639
- [nameProp]: name,
640
- [typeProp]: (urlObj ? urlObj.searchQuery[typeProp] : '') || $xeUpload.parseFileType(name),
641
- [urlProp]: url,
642
- [sizeProp]: XEUtils.toNumber(urlObj ? urlObj.searchQuery[sizeProp] : 0) || 0,
643
- [keyField]: getUniqueKey()
644
- }
645
- }
646
- const name = item[nameProp] || ''
647
- item[nameProp] = name
648
- item[typeProp] = item[typeProp] || $xeUpload.parseFileType(name)
649
- item[urlProp] = item[urlProp] || ''
650
- item[sizeProp] = item[sizeProp] || 0
651
- item[keyField] = item[keyField] || getUniqueKey()
652
- return item
653
- })
654
- : []
655
- reactData.fileList = (formReadonly || multiple) ? fileList : (fileList.slice(0, 1))
656
- },
657
- parseFileName (url: string) {
658
- return decodeURIComponent(`${url || ''}`).split('/').pop() || ''
659
- },
660
- parseFileType (name: string) {
661
- const index = name.lastIndexOf('.')
662
- if (index > 0) {
663
- return name.substring(index + 1).toLowerCase()
664
- }
665
- return ''
666
- },
667
- handleChange (value: VxeUploadDefines.FileObjItem[]) {
668
- const $xeUpload = this
669
- const props = $xeUpload
670
-
671
- const { singleMode, urlMode, urlArgs } = props
672
- const urlProp = $xeUpload.computeUrlProp
673
- const nameProp = $xeUpload.computeNameProp
674
- let restList = value ? value.slice(0) : []
675
- if (urlMode) {
676
- restList = restList.map(item => {
677
- const url = item[urlProp]
678
- if (url && urlArgs) {
679
- const urlObj = XEUtils.parseUrl(url)
680
- if (!urlObj.searchQuery[nameProp]) {
681
- if (url.indexOf('blob:') === -1) {
682
- return `${url}${url.indexOf('?') === -1 ? '?' : '&'}${encodeURIComponent(item[nameProp] || '')}`
683
- }
684
- }
685
- }
686
- return url
687
- })
688
- }
689
- $xeUpload.emitModel(singleMode ? (restList[0] || null) : restList)
690
- },
691
- getThumbnailFileUrl (item: VxeUploadDefines.FileObjItem) {
692
- const $xeUpload = this
693
- const props = $xeUpload
694
-
695
- const getThumbnailUrlFn = props.getThumbnailUrlMethod || getConfig().upload.getThumbnailUrlMethod
696
- if (getThumbnailUrlFn) {
697
- return getThumbnailUrlFn({
698
- $upload: $xeUpload,
699
- option: item
700
- })
701
- }
702
- return $xeUpload.getFileUrl(item)
703
- },
704
- getFileUrl (item: VxeUploadDefines.FileObjItem) {
705
- const $xeUpload = this
706
- const props = $xeUpload
707
-
708
- const getUrlFn = props.getUrlMethod || getConfig().upload.getUrlMethod
709
- const urlProp = $xeUpload.computeUrlProp
710
- return getUrlFn
711
- ? getUrlFn({
712
- $upload: $xeUpload,
713
- option: item
714
- })
715
- : item[urlProp]
716
- },
717
- handleDefaultFilePreview (item: VxeUploadDefines.FileObjItem) {
718
- const $xeUpload = this
719
- const props = $xeUpload
720
- const internalData = $xeUpload.internalData
721
-
722
- const { imageTypes } = props
723
- const typeProp = $xeUpload.computeTypeProp
724
- const previewImageOpts = $xeUpload.computePreviewImageOpts
725
- const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
726
- const { imagePreviewTypes } = internalData
727
- // 如果是预览图片
728
- if (imagePreviewTypes.concat(imageTypes || []).some(type => `${type}`.toLowerCase() === `${item[typeProp]}`.toLowerCase())) {
729
- if (VxeUI.previewImage) {
730
- VxeUI.previewImage({
731
- ...previewImageOpts,
732
- urlList: [$xeUpload.getFileUrl(item)],
733
- beforeDownloadMethod: beforeDownloadFn
734
- ? () => {
735
- return beforeDownloadFn({
736
- $upload: $xeUpload,
737
- option: item
738
- })
739
- }
740
- : undefined
741
- })
742
- }
743
- }
744
- },
745
- handlePreviewFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
746
- const $xeUpload = this
747
- const props = $xeUpload
748
-
749
- const previewFn = props.previewMethod || getConfig().upload.previewMethod
750
- if (props.showPreview) {
751
- if (previewFn) {
752
- previewFn({
753
- $upload: $xeUpload,
754
- option: item
755
- })
756
- } else {
757
- $xeUpload.handleDefaultFilePreview(item)
758
- }
759
- }
760
- },
761
- handlePreviewImageEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
762
- const $xeUpload = this
763
- const props = $xeUpload
764
- const reactData = $xeUpload.reactData
765
-
766
- const { fileList } = reactData
767
- const previewImageOpts = $xeUpload.computePreviewImageOpts
768
- const previewFn = props.previewMethod || getConfig().upload.previewMethod
769
- const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
770
- if (props.showPreview) {
771
- if (previewFn) {
772
- previewFn({
773
- $upload: $xeUpload,
774
- option: item
775
- })
776
- } else if (VxeUI.previewImage) {
777
- VxeUI.previewImage({
778
- ...previewImageOpts,
779
- urlList: fileList.map(item => $xeUpload.getFileUrl(item)),
780
- activeIndex: index,
781
- beforeDownloadMethod: beforeDownloadFn
782
- ? ({ index }) => {
783
- return beforeDownloadFn({
784
- $upload: $xeUpload,
785
- option: fileList[index]
786
- })
787
- }
788
- : undefined
789
- })
790
- }
791
- }
792
- },
793
- handleUploadResult (item: VxeUploadDefines.FileObjItem, file: File) {
794
- const $xeUpload = this
795
- const props = $xeUpload
796
- const reactData = $xeUpload.reactData
797
-
798
- const { showErrorStatus } = props
799
- const fileKey = $xeUpload.getFieldKey(item)
800
- const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
801
- if (uploadFn) {
802
- return Promise.resolve(
803
- uploadFn({
804
- $upload: $xeUpload,
805
- file,
806
- option: item,
807
- updateProgress (percentNum) {
808
- const { fileCacheMaps } = reactData
809
- const cacheItem = fileCacheMaps[$xeUpload.getFieldKey(item)]
810
- if (cacheItem) {
811
- cacheItem.percent = Math.max(0, Math.min(99, XEUtils.toNumber(percentNum)))
812
- }
813
- }
814
- })
815
- ).then(res => {
816
- const { fileCacheMaps } = reactData
817
- const cacheItem = fileCacheMaps[fileKey]
818
- if (cacheItem) {
819
- cacheItem.percent = 100
820
- cacheItem.status = 'success'
821
- }
822
- // 处理动态字段双向绑定问题
823
- // Object.assign(item, res)
824
- XEUtils.each(res, (val, key) => {
825
- $xeUpload.$set(item, key, val)
826
- })
827
- $xeUpload.dispatchEvent('upload-success', { option: item, data: res }, null)
828
- }).catch((res) => {
829
- const { fileCacheMaps } = reactData
830
- const cacheItem = fileCacheMaps[fileKey]
831
- if (cacheItem) {
832
- cacheItem.status = 'error'
833
- }
834
- if (showErrorStatus) {
835
- // 处理动态字段双向绑定问题
836
- // Object.assign(item, res)
837
- XEUtils.each(res, (val, key) => {
838
- $xeUpload.$set(item, key, val)
839
- })
840
- } else {
841
- reactData.fileList = reactData.fileList.filter(obj => $xeUpload.getFieldKey(obj) !== fileKey)
842
- delete fileCacheMaps[fileKey]
843
- }
844
- $xeUpload.dispatchEvent('upload-error', { option: item, data: res }, null)
845
- }).finally(() => {
846
- const { fileCacheMaps } = reactData
847
- const cacheItem = fileCacheMaps[fileKey]
848
- if (cacheItem) {
849
- cacheItem.loading = false
850
- }
851
- })
852
- } else {
853
- const { fileCacheMaps } = reactData
854
- const cacheItem = fileCacheMaps[fileKey]
855
- if (cacheItem) {
856
- cacheItem.loading = false
857
- }
858
- }
859
- return Promise.resolve()
860
- },
861
- handleReUpload (item: VxeUploadDefines.FileObjItem) {
862
- const $xeUpload = this
863
- const props = $xeUpload
864
- const reactData = $xeUpload.reactData
865
-
866
- const { uploadMethod, urlMode } = props
867
- const { fileCacheMaps } = reactData
868
- const fileKey = $xeUpload.getFieldKey(item)
869
- const cacheItem = fileCacheMaps[fileKey]
870
- const uploadFn = uploadMethod || getConfig().upload.uploadMethod
871
- if (uploadFn && cacheItem) {
872
- const file = cacheItem.file
873
- cacheItem.loading = true
874
- cacheItem.status = 'pending'
875
- cacheItem.percent = 0
876
- $xeUpload.handleUploadResult(item, file).then(() => {
877
- if (urlMode) {
878
- $xeUpload.handleChange(reactData.fileList)
879
- }
880
- })
881
- }
882
- },
883
- handleUploadFile (files: File[], evnt: Event | null) {
884
- const $xeUpload = this
885
- const props = $xeUpload
886
- const reactData = $xeUpload.reactData
887
- const $xeForm = $xeUpload.$xeForm
888
- const formItemInfo = $xeUpload.formItemInfo
889
-
890
- const { multiple, urlMode, showLimitSize, limitSizeText, showLimitCount, limitCountText, autoSubmit } = props
891
- const { fileList } = reactData
892
- const beforeSelectFn = props.beforeSelectMethod || getConfig().upload.beforeSelectMethod
893
- const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
894
- const keyField = $xeUpload.computeKeyField
895
- const nameProp = $xeUpload.computeNameProp
896
- const typeProp = $xeUpload.computeTypeProp
897
- const urlProp = $xeUpload.computeUrlProp
898
- const sizeProp = $xeUpload.computeSizeProp
899
- const limitMaxSize = $xeUpload.computeLimitMaxSize
900
- const limitMaxCount = $xeUpload.computeLimitMaxCount
901
- const limitSizeUnit = $xeUpload.computeLimitSizeUnit
902
- let selectFiles = files
903
-
904
- if (multiple && limitMaxCount) {
905
- // 校验文件数量
906
- if (showLimitCount && fileList.length >= limitMaxCount) {
907
- if (VxeUI.modal) {
908
- VxeUI.modal.notification({
909
- title: getI18n('vxe.modal.errTitle'),
910
- status: 'error',
911
- content: limitCountText ? `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}` : getI18n('vxe.upload.overCountErr', [limitMaxCount])
912
- })
913
- }
914
- return
915
- }
916
- const overNum = selectFiles.length - (limitMaxCount - fileList.length)
917
- if (showLimitCount && overNum > 0) {
918
- const overExtraList = selectFiles.slice(limitMaxCount - fileList.length)
919
- if (limitCountText) {
920
- VxeUI.modal.notification({
921
- title: getI18n('vxe.modal.errTitle'),
922
- status: 'error',
923
- content: `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}`
924
- })
925
- } else if (VxeUI.modal) {
926
- VxeUI.modal.notification({
927
- title: getI18n('vxe.modal.errTitle'),
928
- status: 'error',
929
- slots: {
930
- default (params, h) {
931
- return h('div', {
932
- class: 'vxe-upload--file-message-over-error'
933
- }, [
934
- h('div', {}, getI18n('vxe.upload.overCountExtraErr', [limitMaxCount, overNum])),
935
- h('div', {
936
- class: 'vxe-upload--file-message-over-extra'
937
- }, overExtraList.map((file, index) => {
938
- return h('div', {
939
- key: index,
940
- class: 'vxe-upload--file-message-over-extra-item'
941
- }, file.name)
942
- }))
943
- ])
944
- }
945
- }
946
- })
947
- }
948
- }
949
- selectFiles = selectFiles.slice(0, limitMaxCount - fileList.length)
950
- }
951
-
952
- // 校验文件大小
953
- if (showLimitSize && limitMaxSize) {
954
- for (let i = 0; i < files.length; i++) {
955
- const file = files[0]
956
- if (file.size > limitMaxSize) {
957
- if (VxeUI.modal) {
958
- VxeUI.modal.notification({
959
- title: getI18n('vxe.modal.errTitle'),
960
- status: 'error',
961
- content: limitSizeText ? `${XEUtils.isFunction(limitSizeText) ? limitSizeText({ maxSize: limitMaxSize }) : limitSizeText}` : getI18n('vxe.upload.overSizeErr', [limitSizeUnit])
962
- })
963
- }
964
- return
965
- }
966
- }
967
- }
968
-
969
- const cacheMaps = Object.assign({}, reactData.fileCacheMaps)
970
- const newFileList = multiple ? fileList : []
971
- const uploadPromiseRests: any[] = []
972
- selectFiles.forEach(file => {
973
- const { name } = file
974
- const fileKey = getUniqueKey()
975
- const fileObj: VxeUploadDefines.FileObjItem = {
976
- [nameProp]: name,
977
- [typeProp]: $xeUpload.parseFileType(name),
978
- [sizeProp]: file.size,
979
- [urlProp]: URL.createObjectURL(file),
980
- [keyField]: fileKey
981
- }
982
- if (uploadFn) {
983
- cacheMaps[fileKey] = {
984
- file: file,
985
- loading: !!autoSubmit,
986
- status: 'pending',
987
- percent: 0
988
- }
989
- }
990
- const item = fileObj
991
- if (!beforeSelectFn || beforeSelectFn({ $upload: $xeUpload, file })) {
992
- if (uploadFn && autoSubmit) {
993
- uploadPromiseRests.push(
994
- $xeUpload.handleUploadResult(item, file)
995
- )
996
- }
997
- newFileList.push(item)
998
- }
999
- })
1000
- reactData.fileList = newFileList
1001
- reactData.fileCacheMaps = cacheMaps
1002
- newFileList.forEach(item => {
1003
- $xeUpload.dispatchEvent('add', { option: item }, evnt)
1004
- })
1005
- Promise.all(urlMode ? uploadPromiseRests : []).then(() => {
1006
- const restFileList = reactData.fileList
1007
- $xeUpload.handleChange(restFileList)
1008
- // 自动更新校验状态
1009
- if ($xeForm && formItemInfo) {
1010
- $xeForm.triggerItemEvent(evnt as any, formItemInfo.itemConfig.field, restFileList)
1011
- }
1012
- })
1013
- },
1014
- handleChoose (evnt: MouseEvent | null) {
1015
- const $xeUpload = this
1016
- const props = $xeUpload
1017
-
1018
- const { multiple, imageTypes, fileTypes } = props
1019
- const isDisabled = $xeUpload.computeIsDisabled
1020
- const isImage = $xeUpload.computeIsImage
1021
- if (isDisabled) {
1022
- return Promise.resolve({
1023
- status: false,
1024
- files: [],
1025
- file: null
1026
- })
1027
- }
1028
- return readLocalFile({
1029
- multiple,
1030
- types: isImage ? imageTypes : fileTypes
1031
- }).then((params) => {
1032
- $xeUpload.handleUploadFile(params.files, evnt)
1033
- return params
1034
- })
1035
- },
1036
- clickEvent (evnt: MouseEvent) {
1037
- const $xeUpload = this
1038
-
1039
- $xeUpload.handleChoose(evnt).catch(() => {
1040
- // 错误文件类型
1041
- })
1042
- },
1043
- handleRemoveEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1044
- const $xeUpload = this
1045
- const reactData = $xeUpload.reactData
1046
- const $xeForm = $xeUpload.$xeForm
1047
- const formItemInfo = $xeUpload.formItemInfo
1048
-
1049
- const { fileList } = reactData
1050
- fileList.splice(index, 1)
1051
- $xeUpload.handleChange(fileList)
1052
- // 自动更新校验状态
1053
- if ($xeForm && formItemInfo) {
1054
- $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, fileList)
1055
- }
1056
- $xeUpload.dispatchEvent('remove', { option: item }, evnt)
1057
- },
1058
- removeFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1059
- const $xeUpload = this
1060
- const props = $xeUpload
1061
-
1062
- const beforeRemoveFn = props.beforeRemoveMethod || getConfig().upload.beforeRemoveMethod
1063
- const removeFn = props.removeMethod || getConfig().upload.removeMethod
1064
- Promise.resolve(
1065
- beforeRemoveFn
1066
- ? beforeRemoveFn({
1067
- $upload: $xeUpload,
1068
- option: item
1069
- })
1070
- : true
1071
- ).then(status => {
1072
- if (status) {
1073
- if (removeFn) {
1074
- Promise.resolve(
1075
- removeFn({
1076
- $upload: $xeUpload,
1077
- option: item
1078
- })
1079
- ).then(() => {
1080
- $xeUpload.handleRemoveEvent(evnt, item, index)
1081
- }).catch(e => e)
1082
- } else {
1083
- $xeUpload.handleRemoveEvent(evnt, item, index)
1084
- }
1085
- } else {
1086
- $xeUpload.dispatchEvent('remove-fail', { option: item }, evnt)
1087
- }
1088
- })
1089
- },
1090
- handleDownloadEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1091
- const $xeUpload = this
1092
-
1093
- $xeUpload.dispatchEvent('download', { option: item }, evnt)
1094
- },
1095
- downloadFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1096
- const $xeUpload = this
1097
- const props = $xeUpload
1098
-
1099
- const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
1100
- const downloadFn = props.downloadMethod || getConfig().upload.downloadMethod
1101
- Promise.resolve(
1102
- beforeDownloadFn
1103
- ? beforeDownloadFn({
1104
- $upload: $xeUpload,
1105
- option: item
1106
- })
1107
- : true
1108
- ).then(status => {
1109
- if (status) {
1110
- if (downloadFn) {
1111
- Promise.resolve(
1112
- downloadFn({
1113
- $upload: $xeUpload,
1114
- option: item
1115
- })
1116
- ).then(() => {
1117
- $xeUpload.handleDownloadEvent(evnt, item)
1118
- }).catch(e => e)
1119
- } else {
1120
- $xeUpload.handleDownloadEvent(evnt, item)
1121
- }
1122
- } else {
1123
- $xeUpload.dispatchEvent('download-fail', { option: item }, evnt)
1124
- }
1125
- })
1126
- },
1127
- handleUploadDragleaveEvent (evnt: DragEvent) {
1128
- const $xeUpload = this
1129
- const reactData = $xeUpload.reactData
1130
-
1131
- const targetElem = evnt.currentTarget as HTMLDivElement
1132
- const { clientX, clientY } = evnt
1133
- if (targetElem) {
1134
- const { x: targetX, y: targetY, height: targetHeight, width: targetWidth } = targetElem.getBoundingClientRect()
1135
- if (clientX < targetX || clientX > targetX + targetWidth || clientY < targetY || clientY > targetY + targetHeight) {
1136
- reactData.isDragUploadStatus = false
1137
- }
1138
- }
1139
- },
1140
- handleUploadDragoverEvent (evnt: DragEvent) {
1141
- const $xeUpload = this
1142
- const reactData = $xeUpload.reactData
1143
-
1144
- const dataTransfer = evnt.dataTransfer
1145
- if (dataTransfer) {
1146
- const { items } = dataTransfer
1147
- if (items && items.length) {
1148
- evnt.preventDefault()
1149
- reactData.isDragUploadStatus = true
1150
- }
1151
- }
1152
- },
1153
- uploadTransferFileEvent (evnt: Event, files: File[]) {
1154
- const $xeUpload = this
1155
- const props = $xeUpload
1156
- const internalData = $xeUpload.internalData
1157
-
1158
- const { imageTypes, fileTypes } = props
1159
- const { imagePreviewTypes } = internalData
1160
- const isImage = $xeUpload.computeIsImage
1161
- if (isImage) {
1162
- const pasteImgTypes = imagePreviewTypes.concat(imageTypes && imageTypes.length ? imageTypes : [])
1163
- files = files.filter(file => {
1164
- const fileType = `${file.type.split('/')[1] || ''}`.toLowerCase()
1165
- if (pasteImgTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1166
- return true
1167
- }
1168
- return false
1169
- })
1170
- } else {
1171
- if (fileTypes && fileTypes.length) {
1172
- const errTypes: string[] = []
1173
- files.forEach(file => {
1174
- const fileType = $xeUpload.parseFileType(file.name)
1175
- if (!fileTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1176
- errTypes.push(fileType)
1177
- }
1178
- })
1179
- if (errTypes.length) {
1180
- if (VxeUI.modal) {
1181
- VxeUI.modal.message({
1182
- content: getI18n('vxe.error.notType', [errTypes.join(', ')]),
1183
- status: 'error'
1184
- })
1185
- }
1186
- return
1187
- }
1188
- }
1189
- }
1190
- // 如果全部不满足条件
1191
- if (!files.length) {
1192
- if (VxeUI.modal) {
1193
- VxeUI.modal.notification({
1194
- title: getI18n('vxe.modal.errTitle'),
1195
- status: 'error',
1196
- content: getI18n('vxe.upload.uploadTypeErr')
1197
- })
1198
- }
1199
- return
1200
- }
1201
- $xeUpload.handleUploadFile(files, evnt)
1202
- },
1203
- handleUploadDropEvent (evnt: DragEvent) {
1204
- const $xeUpload = this
1205
- const reactData = $xeUpload.reactData
1206
-
1207
- const dataTransfer = evnt.dataTransfer
1208
- if (dataTransfer) {
1209
- const { items } = dataTransfer
1210
- if (items && items.length) {
1211
- evnt.preventDefault()
1212
- const files = handleTransferFiles(items)
1213
- if (files.length) {
1214
- $xeUpload.uploadTransferFileEvent(evnt, files)
1215
- }
1216
- }
1217
- }
1218
- reactData.isDragUploadStatus = false
1219
- },
1220
- handleMoreEvent (evntParams: VxeComponentEventParams) {
1221
- const $xeUpload = this
1222
- const props = $xeUpload
1223
- const slots = $xeUpload.$scopedSlots
1224
- const reactData = $xeUpload.reactData
1225
- const internalData = $xeUpload.internalData
1226
-
1227
- const { xID } = $xeUpload
1228
-
1229
- const formReadonly = $xeUpload.computeFormReadonly
1230
- const isImage = $xeUpload.computeIsImage
1231
-
1232
- const evnt = evntParams.$event
1233
- if (VxeUI.modal) {
1234
- VxeUI.modal.open({
1235
- id: internalData.moreId,
1236
- title: formReadonly ? getI18n('vxe.upload.morePopup.readTitle') : getI18n(`vxe.upload.morePopup.${isImage ? 'imageTitle' : 'fileTitle'}`),
1237
- width: 660,
1238
- height: 500,
1239
- escClosable: true,
1240
- showMaximize: true,
1241
- resize: true,
1242
- maskClosable: true,
1243
- slots: {
1244
- default (params, h) {
1245
- const { showErrorStatus, dragToUpload, dragSort, dragPlaceholder } = props
1246
- const { isActivated, isDragMove, isDragUploadStatus, dragIndex } = reactData
1247
- const { fileList } = reactData
1248
- const isDisabled = $xeUpload.computeIsDisabled
1249
- const moreContSlot = slots.moreContent || slots['more-content']
1250
-
1251
- const ons: Record<string, any> = {}
1252
- if (dragToUpload && dragIndex === -1) {
1253
- ons.dragover = $xeUpload.handleUploadDragoverEvent
1254
- ons.dragleave = $xeUpload.handleUploadDragleaveEvent
1255
- ons.drop = $xeUpload.handleUploadDropEvent
1256
- }
1257
-
1258
- return h('div', {
1259
- attrs: {
1260
- id: `refPopupElem${xID}`
1261
- },
1262
- class: ['vxe-upload--more-popup', {
1263
- 'is--readonly': formReadonly,
1264
- 'is--disabled': isDisabled,
1265
- 'is--active': isActivated,
1266
- 'show--error': showErrorStatus,
1267
- 'is--drag': isDragUploadStatus
1268
- }],
1269
- on: ons
1270
- }, moreContSlot
1271
- ? getSlotVNs(moreContSlot({ options: fileList }))
1272
- : [
1273
- isImage
1274
- ? (
1275
- dragSort
1276
- ? h('transition-group', {
1277
- props: {
1278
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1279
- tag: 'div'
1280
- },
1281
- class: 'vxe-upload--image-more-list'
1282
- }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1283
- : h('div', {
1284
- class: 'vxe-upload--image-more-list'
1285
- }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1286
- )
1287
- : h('div', {
1288
- class: 'vxe-upload--file-more-list'
1289
- }, [
1290
- $xeUpload.renderFileAction(h, true),
1291
- (
1292
- dragSort
1293
- ? h('transition-group', {
1294
- props: {
1295
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1296
- tag: 'div'
1297
- },
1298
- class: 'vxe-upload--file-list'
1299
- }, $xeUpload.renderFileItemList(h, fileList, true))
1300
- : h('div', {
1301
- class: 'vxe-upload--file-list'
1302
- }, $xeUpload.renderFileItemList(h, fileList, true))
1303
- )
1304
- ]),
1305
- dragSort
1306
- ? h('div', {
1307
- attrs: {
1308
- id: `refModalDragLineElem${xID}`
1309
- },
1310
- class: 'vxe-upload--drag-line'
1311
- })
1312
- : renderEmptyElement($xeUpload),
1313
- isDragUploadStatus
1314
- ? h('div', {
1315
- class: 'vxe-upload--drag-placeholder'
1316
- }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
1317
- : renderEmptyElement($xeUpload)
1318
- ])
1319
- }
1320
- },
1321
- events: {
1322
- show () {
1323
- reactData.showMorePopup = true
1324
- },
1325
- hide ({ $event }) {
1326
- reactData.showMorePopup = false
1327
- if ($event) {
1328
- $xeUpload.dispatchEvent('more-visible', { visible: false }, $event)
1329
- }
1330
- }
1331
- }
1332
- })
1333
- if (evnt) {
1334
- $xeUpload.dispatchEvent('more-visible', { visible: true }, evnt)
1335
- }
1336
- }
1337
- },
1338
- // 拖拽
1339
- handleDragSortDragstartEvent (evnt: DragEvent) {
1340
- const $xeUpload = this
1341
- const reactData = $xeUpload.reactData
1342
-
1343
- evnt.stopPropagation()
1344
- if (evnt.dataTransfer) {
1345
- evnt.dataTransfer.setDragImage(getTpImg(), 0, 0)
1346
- }
1347
- const dragEl = evnt.currentTarget as HTMLElement
1348
- const parentEl = dragEl.parentElement as HTMLDivElement
1349
- const dragIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1350
- reactData.isDragMove = true
1351
- reactData.dragIndex = dragIndex
1352
- setTimeout(() => {
1353
- reactData.isDragMove = false
1354
- }, 500)
1355
- },
1356
- handleDragSortDragoverEvent (evnt: DragEvent) {
1357
- const $xeUpload = this
1358
- const reactData = $xeUpload.reactData
1359
- const internalData = $xeUpload.internalData
1360
-
1361
- evnt.stopPropagation()
1362
- evnt.preventDefault()
1363
- const { dragIndex } = reactData
1364
- if (dragIndex === -1) {
1365
- return
1366
- }
1367
- const isImage = $xeUpload.computeIsImage
1368
- const dragEl = evnt.currentTarget as HTMLElement
1369
- const parentEl = dragEl.parentElement as HTMLDivElement
1370
- const currIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1371
- let dragPos: 'top' | 'bottom' | 'left' | 'right' | '' = ''
1372
- if (isImage) {
1373
- const offsetX = evnt.clientX - dragEl.getBoundingClientRect().x
1374
- dragPos = offsetX < dragEl.clientWidth / 2 ? 'left' : 'right'
1375
- } else {
1376
- const offsetY = evnt.clientY - dragEl.getBoundingClientRect().y
1377
- dragPos = offsetY < dragEl.clientHeight / 2 ? 'top' : 'bottom'
1378
- }
1379
- if (dragIndex === currIndex) {
1380
- showDropTip($xeUpload, evnt, dragEl, dragPos)
1381
- return
1382
- }
1383
- showDropTip($xeUpload, evnt, dragEl, dragPos)
1384
- internalData.prevDragIndex = currIndex
1385
- internalData.prevDragPos = dragPos
1386
- },
1387
- handleDragSortDragendEvent (evnt: DragEvent) {
1388
- const $xeUpload = this
1389
- const reactData = $xeUpload.reactData
1390
- const internalData = $xeUpload.internalData
1391
-
1392
- const { fileList, dragIndex } = reactData
1393
- const { prevDragIndex, prevDragPos } = internalData
1394
- const oldIndex = dragIndex
1395
- const targetIndex = prevDragIndex
1396
- const dragOffsetIndex = prevDragPos === 'bottom' || prevDragPos === 'right' ? 1 : 0
1397
- const oldItem = fileList[oldIndex]
1398
- const newItem = fileList[targetIndex]
1399
- if (oldItem && newItem) {
1400
- fileList.splice(oldIndex, 1)
1401
- const ptfIndex = XEUtils.findIndexOf(fileList, item => newItem === item)
1402
- const nIndex = ptfIndex + dragOffsetIndex
1403
- fileList.splice(nIndex, 0, oldItem)
1404
- $xeUpload.dispatchEvent('sort-dragend', {
1405
- oldItem: oldItem,
1406
- newItem: newItem,
1407
- dragPos: prevDragPos as any,
1408
- offsetIndex: dragOffsetIndex,
1409
- _index: {
1410
- newIndex: nIndex,
1411
- oldIndex: oldIndex
1412
- }
1413
- }, evnt)
1414
- }
1415
- hideDropTip($xeUpload)
1416
- reactData.dragIndex = -1
1417
- },
1418
- handleItemMousedownEvent (evnt: MouseEvent) {
1419
- const $xeUpload = this
1420
- const $xeTable = $xeUpload.$xeTable
1421
- const reactData = $xeUpload.reactData
1422
-
1423
- if ($xeTable) {
1424
- evnt.stopPropagation()
1425
- }
1426
- reactData.isActivated = true
1427
- },
1428
- handleGlobalPasteEvent (evnt: ClipboardEvent) {
1429
- const $xeUpload = this
1430
- const props = $xeUpload
1431
- const reactData = $xeUpload.reactData
1432
-
1433
- const { pasteToUpload } = props
1434
- const { isActivated } = reactData
1435
- if (!isActivated || !pasteToUpload) {
1436
- return
1437
- }
1438
- const clipboardData: DataTransfer = evnt.clipboardData || (evnt as any).originalEvent.clipboardData
1439
- if (!clipboardData) {
1440
- return
1441
- }
1442
- const { items } = clipboardData
1443
- if (!items) {
1444
- return
1445
- }
1446
- const files = handleTransferFiles(items)
1447
- if (files.length) {
1448
- evnt.preventDefault()
1449
- $xeUpload.uploadTransferFileEvent(evnt, files)
1450
- }
1451
- },
1452
- handleGlobalClickEvent (evnt: MouseEvent) {
1453
- const $xeUpload = this
1454
- const reactData = $xeUpload.reactData
1455
-
1456
- const el = $xeUpload.$refs.refElem as HTMLDivElement
1457
- const popupEl = $xeUpload.$refs.refPopupElem as HTMLDivElement
1458
- let isActivated = getEventTargetNode(evnt, el).flag
1459
- if (!isActivated && popupEl) {
1460
- const parentEl = popupEl.parentElement || popupEl
1461
- const modalEl = parentEl ? parentEl.parentElement : parentEl
1462
- isActivated = getEventTargetNode(evnt, modalEl).flag
1463
- }
1464
- reactData.isActivated = isActivated
1465
- },
1466
- handleGlobalBlurEvent () {
1467
- const $xeUpload = this
1468
- const reactData = $xeUpload.reactData
1469
-
1470
- reactData.isActivated = false
1471
- },
1472
-
1473
- //
1474
- // Render
1475
- //
1476
- renderFileItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1477
- const $xeUpload = this
1478
- const props = $xeUpload
1479
- const slots = $xeUpload.$scopedSlots
1480
- const reactData = $xeUpload.reactData
1481
-
1482
- const { showRemoveButton, showDownloadButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1483
- const { fileList, fileCacheMaps } = reactData
1484
- const isDisabled = $xeUpload.computeIsDisabled
1485
- const formReadonly = $xeUpload.computeFormReadonly
1486
- const nameProp = $xeUpload.computeNameProp
1487
- const typeProp = $xeUpload.computeTypeProp
1488
- const optionSlot = slots.option
1489
- const actionSlot = slots.action
1490
- const cornerSlot = slots.corner
1491
- const nameSlot = slots.name
1492
-
1493
- const ons: Record<string, any> = {}
1494
- if (dragSort && currList.length > 1) {
1495
- ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1496
- ons.dragover = $xeUpload.handleDragSortDragoverEvent
1497
- ons.dragend = $xeUpload.handleDragSortDragendEvent
1498
- }
1499
-
1500
- return currList.map((item, index) => {
1501
- const fileKey = $xeUpload.getFieldKey(item)
1502
- const cacheItem = fileCacheMaps[fileKey]
1503
- let isLoading = false
1504
- let isError = false
1505
- let isPending = false
1506
- const fileName = `${item[nameProp] || ''}`
1507
- if (cacheItem) {
1508
- isLoading = cacheItem.loading
1509
- isError = cacheItem.status === 'error'
1510
- isPending = cacheItem.status === 'pending'
1511
- }
1512
- return h('div', {
1513
- key: dragSort ? fileKey : index,
1514
- class: ['vxe-upload--file-item', {
1515
- 'is--preview': showPreview,
1516
- 'is--loading': isLoading,
1517
- 'is--pending': isPending,
1518
- 'is--error': isError
1519
- }],
1520
- attrs: {
1521
- fileid: fileKey,
1522
- draggable: dragSort ? true : null
1523
- },
1524
- on: ons
1525
- }, optionSlot
1526
- ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1527
- : [
1528
- h('div', {
1529
- class: 'vxe-upload--file-item-icon'
1530
- }, [
1531
- h('i', {
1532
- class: getIcon()[`UPLOAD_FILE_TYPE_${`${item[typeProp]}`.toLocaleUpperCase() as 'DEFAULT'}`] || getIcon().UPLOAD_FILE_TYPE_DEFAULT
1533
- })
1534
- ]),
1535
- h('div', {
1536
- class: 'vxe-upload--file-item-name',
1537
- attrs: {
1538
- title: fileName
1539
- },
1540
- on: {
1541
- click (evnt: MouseEvent) {
1542
- if (!isLoading && !isError) {
1543
- $xeUpload.handlePreviewFileEvent(evnt, item)
1544
- }
1545
- }
1546
- }
1547
- }, nameSlot ? getSlotVNs(nameSlot({ option: item, isMoreView, options: fileList })) : fileName),
1548
- isLoading
1549
- ? h('div', {
1550
- class: 'vxe-upload--file-item-loading-icon'
1551
- }, [
1552
- h('i', {
1553
- class: getIcon().UPLOAD_LOADING
1554
- })
1555
- ])
1556
- : renderEmptyElement($xeUpload),
1557
- showProgress && isLoading && cacheItem
1558
- ? h('div', {
1559
- class: 'vxe-upload--file-item-loading-text'
1560
- }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1561
- : renderEmptyElement($xeUpload),
1562
- !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1563
- ? h('div', {
1564
- class: 'vxe-upload--file-item-rebtn'
1565
- }, [
1566
- h(VxeButtonComponent, {
1567
- props: {
1568
- icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1569
- mode: 'text',
1570
- status: 'primary',
1571
- content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1572
- },
1573
- on: {
1574
- click () {
1575
- $xeUpload.handleReUpload(item)
1576
- }
1577
- }
1578
- })
1579
- ])
1580
- : renderEmptyElement($xeUpload),
1581
- h('div', {
1582
- class: 'vxe-upload--file-item-btn-wrapper'
1583
- }, actionSlot
1584
- ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1585
- : [
1586
- cornerSlot
1587
- ? h('div', {
1588
- class: 'vxe-upload--file-item-action'
1589
- }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1590
- : renderEmptyElement($xeUpload),
1591
- showDownloadButton && !isLoading
1592
- ? h('div', {
1593
- class: 'vxe-upload--file-item-download-btn',
1594
- on: {
1595
- click (evnt: MouseEvent) {
1596
- $xeUpload.downloadFileEvent(evnt, item)
1597
- }
1598
- }
1599
- }, [
1600
- h('i', {
1601
- class: getIcon().UPLOAD_FILE_DOWNLOAD
1602
- })
1603
- ])
1604
- : renderEmptyElement($xeUpload),
1605
- showRemoveButton && !formReadonly && !isDisabled && !isLoading
1606
- ? h('div', {
1607
- class: 'vxe-upload--file-item-remove-btn',
1608
- on: {
1609
- click (evnt: MouseEvent) {
1610
- $xeUpload.removeFileEvent(evnt, item, index)
1611
- }
1612
- }
1613
- }, [
1614
- h('i', {
1615
- class: getIcon().UPLOAD_FILE_REMOVE
1616
- })
1617
- ])
1618
- : renderEmptyElement($xeUpload)
1619
- ])
1620
- ])
1621
- })
1622
- },
1623
- renderFileAction (h: CreateElement, isMoreView: boolean) {
1624
- const $xeUpload = this
1625
- const props = $xeUpload
1626
- const slots = $xeUpload.$scopedSlots
1627
- const reactData = $xeUpload.reactData
1628
-
1629
- const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1630
- const { fileList } = reactData
1631
- const isDisabled = $xeUpload.computeIsDisabled
1632
- const formReadonly = $xeUpload.computeFormReadonly
1633
- const showTipText = $xeUpload.computedShowTipText
1634
- const defTipText = $xeUpload.computedDefTipText
1635
- const overCount = $xeUpload.computeOverCount
1636
- const defaultSlot = slots.default
1637
- const tipSlot = slots.tip || slots.hint
1638
-
1639
- if (formReadonly || !showUploadButton) {
1640
- return renderEmptyElement($xeUpload)
1641
- }
1642
- return h('div', {
1643
- class: 'vxe-upload--file-action'
1644
- }, [
1645
- autoHiddenButton && overCount
1646
- ? renderEmptyElement($xeUpload)
1647
- : h('div', {
1648
- class: 'vxe-upload--file-action-btn',
1649
- on: {
1650
- click: $xeUpload.clickEvent
1651
- }
1652
- }, defaultSlot
1653
- ? getSlotVNs(defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload }))
1654
- : [
1655
- h(VxeButtonComponent, {
1656
- class: 'vxe-upload--file-action-button',
1657
- props: {
1658
- content: (isMoreView || showButtonText) ? (buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.fileBtnText')) : '',
1659
- icon: showButtonIcon ? (buttonIcon || getIcon().UPLOAD_FILE_ADD) : '',
1660
- disabled: isDisabled
1661
- }
1662
- })
1663
- ]),
1664
- showTipText && (defTipText || tipSlot)
1665
- ? h('div', {
1666
- class: 'vxe-upload--file-action-tip'
1667
- }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1668
- : renderEmptyElement($xeUpload)
1669
- ])
1670
- },
1671
- rendeFileMode (h: CreateElement) {
1672
- const $xeUpload = this
1673
- const props = $xeUpload
1674
- const slots = $xeUpload.$scopedSlots
1675
- const reactData = $xeUpload.reactData
1676
-
1677
- const { showList, moreConfig, dragSort } = props
1678
- const { fileList, isDragMove } = reactData
1679
- const moreOpts = $xeUpload.computeMoreOpts
1680
- const { maxCount, showMoreButton, layout, moreButtonText } = moreOpts
1681
- const isHorizontal = layout === 'horizontal'
1682
- const moreBtnSlot = slots.moreButton || slots['more-button']
1683
-
1684
- let currList = fileList
1685
- let overMaxNum = 0
1686
- let isMoreMax = false
1687
- let isMiniMore = false
1688
- if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1689
- isMoreMax = true
1690
- isMiniMore = maxCount === 0
1691
- overMaxNum = fileList.length - maxCount
1692
- currList = fileList.slice(0, maxCount)
1693
- }
1694
-
1695
- return h('div', {
1696
- key: 'all',
1697
- class: 'vxe-upload--file-wrapper'
1698
- }, showList
1699
- ? [
1700
- showMoreButton && moreConfig && isHorizontal
1701
- ? renderEmptyElement($xeUpload)
1702
- : $xeUpload.renderFileAction(h, true),
1703
- h('div', {
1704
- class: ['vxe-upload--file-list-wrapper', {
1705
- 'is--horizontal': isHorizontal
1706
- }]
1707
- }, [
1708
- currList.length
1709
- ? (
1710
- dragSort
1711
- ? h('transition-group', {
1712
- attrs: {
1713
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1714
- tag: 'div'
1715
- },
1716
- class: 'vxe-upload--file-list'
1717
- }, $xeUpload.renderFileItemList(h, currList, false))
1718
- : h('div', {
1719
- class: 'vxe-upload--file-list'
1720
- }, $xeUpload.renderFileItemList(h, currList, false))
1721
- )
1722
- : renderEmptyElement($xeUpload),
1723
- showMoreButton && overMaxNum
1724
- ? h('div', {
1725
- class: 'vxe-upload--file-over-more'
1726
- }, moreBtnSlot
1727
- ? getSlotVNs(moreBtnSlot({ options: fileList }))
1728
- : [
1729
- h(VxeButtonComponent, {
1730
- props: {
1731
- mode: 'text',
1732
- content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreFileBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
1733
- status: 'primary'
1734
- },
1735
- on: {
1736
- click: $xeUpload.handleMoreEvent
1737
- }
1738
- })
1739
- ])
1740
- : renderEmptyElement($xeUpload),
1741
- showMoreButton && moreConfig && isHorizontal
1742
- ? $xeUpload.renderFileAction(h, false)
1743
- : renderEmptyElement($xeUpload)
1744
- ])
1745
- ]
1746
- : [
1747
- $xeUpload.renderFileAction(h, false)
1748
- ])
1749
- },
1750
- renderImageItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1751
- const $xeUpload = this
1752
- const props = $xeUpload
1753
- const slots = $xeUpload.$scopedSlots
1754
- const reactData = $xeUpload.reactData
1755
-
1756
- const { showRemoveButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1757
- const { fileList, fileCacheMaps } = reactData
1758
- const isDisabled = $xeUpload.computeIsDisabled
1759
- const formReadonly = $xeUpload.computeFormReadonly
1760
- const imageOpts = $xeUpload.computeImageOpts
1761
- const imgStyle = $xeUpload.computeImgStyle
1762
- const optionSlot = slots.option
1763
- const actionSlot = slots.action
1764
- const cornerSlot = slots.corner
1765
-
1766
- const ons: Record<string, any> = {}
1767
- if (dragSort && currList.length > 1) {
1768
- ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1769
- ons.dragover = $xeUpload.handleDragSortDragoverEvent
1770
- ons.dragend = $xeUpload.handleDragSortDragendEvent
1771
- }
1772
-
1773
- return currList.map((item, index) => {
1774
- const fileKey = $xeUpload.getFieldKey(item)
1775
- const cacheItem = fileCacheMaps[fileKey]
1776
- let isLoading = false
1777
- let isError = false
1778
- let isPending = false
1779
- if (cacheItem) {
1780
- isLoading = cacheItem.loading
1781
- isError = cacheItem.status === 'error'
1782
- isPending = cacheItem.status === 'pending'
1783
- }
1784
- return h('div', {
1785
- key: dragSort ? fileKey : index,
1786
- class: ['vxe-upload--image-item', {
1787
- 'is--preview': showPreview,
1788
- 'is--circle': imageOpts.circle,
1789
- 'is--loading': isLoading,
1790
- 'is--pending': isPending,
1791
- 'is--error': isError
1792
- }],
1793
- attrs: {
1794
- fileid: fileKey,
1795
- draggable: dragSort ? true : null
1796
- },
1797
- on: ons
1798
- }, optionSlot
1799
- ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1800
- : [
1801
- h('div', {
1802
- class: 'vxe-upload--image-item-box',
1803
- style: isMoreView ? {} : imgStyle,
1804
- on: {
1805
- click (evnt: MouseEvent) {
1806
- if (!isLoading && !isError) {
1807
- $xeUpload.handlePreviewImageEvent(evnt, item, index)
1808
- }
1809
- }
1810
- }
1811
- }, [
1812
- isLoading && cacheItem
1813
- ? h('div', {
1814
- class: 'vxe-upload--image-item-loading'
1815
- }, [
1816
- h('div', {
1817
- class: 'vxe-upload--image-item-loading-icon'
1818
- }, [
1819
- h('i', {
1820
- class: getIcon().UPLOAD_LOADING
1821
- })
1822
- ]),
1823
- showProgress
1824
- ? h('div', {
1825
- class: 'vxe-upload--image-item-loading-text'
1826
- }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1827
- : renderEmptyElement($xeUpload)
1828
- ])
1829
- : renderEmptyElement($xeUpload),
1830
- h('div', {
1831
- class: 'vxe-upload--image-item-img-wrapper',
1832
- attrs: {
1833
- title: getI18n('vxe.upload.viewItemTitle')
1834
- }
1835
- }, [
1836
- h('img', {
1837
- class: 'vxe-upload--image-item-img',
1838
- attrs: {
1839
- src: $xeUpload.getThumbnailFileUrl(item)
1840
- }
1841
- })
1842
- ]),
1843
- !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1844
- ? h('div', {
1845
- class: 'vxe-upload--image-item-rebtn'
1846
- }, [
1847
- h(VxeButtonComponent, {
1848
- props: {
1849
- icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1850
- mode: 'text',
1851
- status: 'primary',
1852
- content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1853
- },
1854
- on: {
1855
- click () {
1856
- $xeUpload.handleReUpload(item)
1857
- }
1858
- }
1859
- })
1860
- ])
1861
- : renderEmptyElement($xeUpload),
1862
- h('div', {
1863
- class: 'vxe-upload--image-item-btn-wrapper',
1864
- on: {
1865
- click (evnt: MouseEvent) {
1866
- evnt.stopPropagation()
1867
- }
1868
- }
1869
- }, actionSlot
1870
- ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1871
- : [
1872
- cornerSlot
1873
- ? h('div', {
1874
- class: 'vxe-upload--file-item-action'
1875
- }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1876
- : renderEmptyElement($xeUpload),
1877
- showRemoveButton && !formReadonly && !isDisabled && !isLoading
1878
- ? h('div', {
1879
- class: 'vxe-upload--image-item-remove-btn',
1880
- on: {
1881
- click (evnt: MouseEvent) {
1882
- evnt.stopPropagation()
1883
- $xeUpload.removeFileEvent(evnt, item, index)
1884
- }
1885
- }
1886
- }, [
1887
- h('i', {
1888
- class: getIcon().UPLOAD_IMAGE_REMOVE
1889
- })
1890
- ])
1891
- : renderEmptyElement($xeUpload)
1892
- ])
1893
- ])
1894
- ])
1895
- })
1896
- },
1897
- renderImageAction (h: CreateElement, isMoreView: boolean) {
1898
- const $xeUpload = this
1899
- const props = $xeUpload
1900
- const slots = $xeUpload.$scopedSlots
1901
- const reactData = $xeUpload.reactData
1902
-
1903
- const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1904
- const { fileList } = reactData
1905
- const formReadonly = $xeUpload.computeFormReadonly
1906
- const showTipText = $xeUpload.computedShowTipText
1907
- const defTipText = $xeUpload.computedDefTipText
1908
- const overCount = $xeUpload.computeOverCount
1909
- const imgStyle = $xeUpload.computeImgStyle
1910
- const defaultSlot = slots.default
1911
- const tipSlot = slots.tip || slots.hint
1912
-
1913
- if (formReadonly || !showUploadButton || (autoHiddenButton && overCount)) {
1914
- return renderEmptyElement($xeUpload)
1915
- }
1916
- return h('div', {
1917
- key: 'action',
1918
- class: 'vxe-upload--image-action'
1919
- }, [
1920
- h('div', {
1921
- class: 'vxe-upload--image-action-btn',
1922
- on: {
1923
- click: $xeUpload.clickEvent
1924
- }
1925
- }, defaultSlot
1926
- ? defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload })
1927
- : [
1928
- h('div', {
1929
- class: 'vxe-upload--image-action-box',
1930
- style: isMoreView ? {} : imgStyle
1931
- }, [
1932
- showButtonIcon
1933
- ? h('div', {
1934
- class: 'vxe-upload--image-action-icon'
1935
- }, [
1936
- h('i', {
1937
- class: buttonIcon || getIcon().UPLOAD_IMAGE_ADD
1938
- })
1939
- ])
1940
- : renderEmptyElement($xeUpload),
1941
- isMoreView || showButtonText
1942
- ? h('div', {
1943
- class: 'vxe-upload--image-action-content'
1944
- }, buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.imgBtnText'))
1945
- : renderEmptyElement($xeUpload),
1946
- showTipText && (defTipText || tipSlot)
1947
- ? h('div', {
1948
- class: 'vxe-upload--image-action-hint'
1949
- }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1950
- : renderEmptyElement($xeUpload)
1951
- ])
1952
- ])
1953
- ])
1954
- },
1955
- renderImageMode (h: CreateElement) {
1956
- const $xeUpload = this
1957
- const props = $xeUpload
1958
- const slots = $xeUpload.$scopedSlots
1959
- const reactData = $xeUpload.reactData
1960
-
1961
- const { showList, dragSort } = props
1962
- const { fileList, isDragMove } = reactData
1963
- const moreOpts = $xeUpload.computeMoreOpts
1964
- const moreBtnSlot = slots.moreButton || slots['more-button']
1965
-
1966
- const { maxCount, showMoreButton, moreButtonText } = moreOpts
1967
- let currList = fileList
1968
- let overMaxNum = 0
1969
- let isMoreMax = false
1970
- let isMiniMore = false
1971
- if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1972
- isMoreMax = true
1973
- isMiniMore = maxCount === 0
1974
- overMaxNum = fileList.length - maxCount
1975
- currList = fileList.slice(0, maxCount)
1976
- }
1977
-
1978
- return h('div', {
1979
- key: 'image',
1980
- class: 'vxe-upload--image-wrapper'
1981
- }, showList
1982
- ? [
1983
- dragSort
1984
- ? h('transition-group', {
1985
- attrs: {
1986
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1987
- tag: 'div'
1988
- },
1989
- class: 'vxe-upload--image-list'
1990
- }, $xeUpload.renderImageItemList(h, currList, false).concat([
1991
- showMoreButton && overMaxNum
1992
- ? h('div', {
1993
- key: 'om',
1994
- class: 'vxe-upload--image-over-more'
1995
- }, moreBtnSlot
1996
- ? getSlotVNs(moreBtnSlot({ options: fileList }))
1997
- : [
1998
- h(VxeButtonComponent, {
1999
- props: {
2000
- mode: 'text',
2001
- content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2002
- status: 'primary'
2003
- },
2004
- on: {
2005
- click: $xeUpload.handleMoreEvent
2006
- }
2007
- })
2008
- ])
2009
- : renderEmptyElement($xeUpload),
2010
- $xeUpload.renderImageAction(h, false)
2011
- ]))
2012
- : h('div', {
2013
- class: 'vxe-upload--image-list'
2014
- }, $xeUpload.renderImageItemList(h, currList, false).concat([
2015
- showMoreButton && overMaxNum
2016
- ? h('div', {
2017
- class: 'vxe-upload--image-over-more'
2018
- }, moreBtnSlot
2019
- ? getSlotVNs(moreBtnSlot({ options: fileList }))
2020
- : [
2021
- h(VxeButtonComponent, {
2022
- props: {
2023
- mode: 'text',
2024
- content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2025
- status: 'primary'
2026
- },
2027
- on: {
2028
- click: $xeUpload.handleMoreEvent
2029
- }
2030
- })
2031
- ])
2032
- : renderEmptyElement($xeUpload),
2033
- $xeUpload.renderImageAction(h, false)
2034
- ]))
2035
- ]
2036
- : [
2037
- h('div', {
2038
- class: 'vxe-upload--image-list'
2039
- }, [
2040
- $xeUpload.renderImageAction(h, false)
2041
- ])
2042
- ])
2043
- },
2044
- renderVN (h: CreateElement): VNode {
2045
- const $xeUpload = this
2046
- const props = $xeUpload
2047
- const reactData = $xeUpload.reactData
2048
-
2049
- const { showErrorStatus, dragToUpload, pasteToUpload, dragSort, dragPlaceholder } = props
2050
- const { isDragUploadStatus, showMorePopup, isActivated, dragIndex } = reactData
2051
- const vSize = $xeUpload.computeSize
2052
- const isDisabled = $xeUpload.computeIsDisabled
2053
- const formReadonly = $xeUpload.computeFormReadonly
2054
- const isImage = $xeUpload.computeIsImage
2055
-
2056
- const ons: Record<string, any> = {}
2057
- if (dragToUpload && dragIndex === -1) {
2058
- ons.dragover = $xeUpload.handleUploadDragoverEvent
2059
- ons.dragleave = $xeUpload.handleUploadDragleaveEvent
2060
- ons.drop = $xeUpload.handleUploadDropEvent
2061
- }
2062
-
2063
- return h('div', {
2064
- ref: 'refElem',
2065
- class: ['vxe-upload', {
2066
- [`size--${vSize}`]: vSize,
2067
- 'is--active': isActivated,
2068
- 'is--readonly': formReadonly,
2069
- 'is--disabled': isDisabled,
2070
- 'is--paste': pasteToUpload,
2071
- 'show--error': showErrorStatus,
2072
- 'is--drag': isDragUploadStatus
2073
- }],
2074
- on: ons
2075
- }, [
2076
- isImage ? $xeUpload.renderImageMode(h) : $xeUpload.rendeFileMode(h),
2077
- dragSort
2078
- ? h('div', {
2079
- ref: 'refDragLineElem',
2080
- class: 'vxe-upload--drag-line'
2081
- })
2082
- : renderEmptyElement($xeUpload),
2083
- isDragUploadStatus && !showMorePopup
2084
- ? h('div', {
2085
- class: 'vxe-upload--drag-placeholder'
2086
- }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
2087
- : renderEmptyElement($xeUpload)
2088
- ])
2089
- }
2090
- },
2091
- created () {
2092
- const $xeUpload = this
2093
-
2094
- $xeUpload.updateFileList()
2095
- },
2096
- mounted () {
2097
- const $xeUpload = this
2098
- const props = $xeUpload
2099
-
2100
- if (props.multiple && props.singleMode) {
2101
- errLog('vxe.error.errConflicts', ['[upload] multiple', 'single-mode'])
2102
- }
2103
- if (props.imageStyle) {
2104
- warnLog('vxe.error.delProp', ['[upload] image-style', 'image-config'])
2105
- }
2106
-
2107
- if (props.dragSort) {
2108
- initTpImg()
2109
- }
2110
- globalEvents.on($xeUpload, 'paste', $xeUpload.handleGlobalPasteEvent)
2111
- globalEvents.on($xeUpload, 'click', $xeUpload.handleGlobalClickEvent)
2112
- globalEvents.on($xeUpload, 'blur', $xeUpload.handleGlobalBlurEvent)
2113
- },
2114
- beforeDestroy () {
2115
- const $xeUpload = this
2116
- const reactData = $xeUpload.reactData
2117
- const internalData = $xeUpload.internalData
2118
-
2119
- reactData.isDragUploadStatus = false
2120
- globalEvents.off($xeUpload, 'paste')
2121
- globalEvents.off($xeUpload, 'click')
2122
- globalEvents.off($xeUpload, 'blur')
2123
- XEUtils.assign(reactData, createReactData())
2124
- XEUtils.assign(internalData, createInternalData())
2125
- },
2126
- render (this: any, h) {
2127
- return this.renderVN(h)
2128
- }
2129
- }) /* define-vxe-component end */
1
+ import { PropType, CreateElement, VNode } from 'vue'
2
+ import { defineVxeComponent } from '../../ui/src/comp'
3
+ import XEUtils from 'xe-utils'
4
+ import { VxeUI, getConfig, getI18n, getIcon, globalMixins, createEvent, globalEvents, renderEmptyElement } from '../../ui'
5
+ import { getSlotVNs } from '../../ui/src/vn'
6
+ import { errLog, warnLog } from '../../ui/src/log'
7
+ import { initTpImg, getTpImg, getEventTargetNode, toCssUnit } from '../../ui/src/dom'
8
+ import { readLocalFile } from './util'
9
+ import VxeButtonComponent from '../../button/src/button'
10
+
11
+ import type { VxeUploadDefines, VxeUploadConstructor, VxeUploadPropTypes, UploadReactData, UploadInternalData, VxeUploadEmits, VxeComponentSizeType, VxeFormDefines, VxeFormConstructor, VxeFormPrivateMethods, ValueOf, VxeComponentEventParams } from '../../../types'
12
+ import type { VxeTableConstructor, VxeTablePrivateMethods } from '../../../types/components/table'
13
+
14
+ function getUniqueKey () {
15
+ return XEUtils.uniqueId()
16
+ }
17
+
18
+ function handleTransferFiles (items: DataTransferItemList) {
19
+ const files: File[] = []
20
+ XEUtils.arrayEach(items, item => {
21
+ const file = item.getAsFile()
22
+ if (file) {
23
+ files.push(file)
24
+ }
25
+ })
26
+ return files
27
+ }
28
+
29
+ function showDropTip ($xeUpload: VxeUploadConstructor, evnt: DragEvent, dragEl: HTMLElement, dragPos: string) {
30
+ const { xID } = $xeUpload
31
+
32
+ const reactData = $xeUpload.reactData
33
+
34
+ const { showMorePopup } = reactData
35
+ const el = $xeUpload.$refs.refElem as HTMLDivElement
36
+ const popupEl = document.getElementById(`refPopupElem${xID}`) as HTMLDivElement
37
+ const wrapperEl = showMorePopup ? popupEl : el
38
+ if (!wrapperEl) {
39
+ return
40
+ }
41
+ const wrapperRect = wrapperEl.getBoundingClientRect()
42
+ const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
43
+ const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
44
+ const currDLineEl = showMorePopup ? mdLineEl : ddLineEl
45
+ if (currDLineEl) {
46
+ const dragRect = dragEl.getBoundingClientRect()
47
+ currDLineEl.style.display = 'block'
48
+ currDLineEl.style.top = `${Math.max(1, dragRect.y - wrapperRect.y)}px`
49
+ currDLineEl.style.left = `${Math.max(1, dragRect.x - wrapperRect.x)}px`
50
+ currDLineEl.style.height = `${dragRect.height}px`
51
+ currDLineEl.style.width = `${dragRect.width - 1}px`
52
+ currDLineEl.setAttribute('drag-pos', dragPos)
53
+ }
54
+ }
55
+
56
+ function hideDropTip ($xeUpload: VxeUploadConstructor) {
57
+ const { xID } = $xeUpload
58
+
59
+ const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
60
+ const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
61
+ if (ddLineEl) {
62
+ ddLineEl.style.display = ''
63
+ }
64
+ if (mdLineEl) {
65
+ mdLineEl.style.display = ''
66
+ }
67
+ }
68
+
69
+ function createReactData (): UploadReactData {
70
+ return {
71
+ isDragUploadStatus: false,
72
+ showMorePopup: false,
73
+ isActivated: false,
74
+ fileList: [],
75
+ fileCacheMaps: {},
76
+ isDragMove: false,
77
+ dragIndex: -1,
78
+ dragTipText: ''
79
+ }
80
+ }
81
+
82
+ function createInternalData (): UploadInternalData {
83
+ return {
84
+ moreId: XEUtils.uniqueId('upload'),
85
+ imagePreviewTypes: ['jpg', 'jpeg', 'png', 'gif'],
86
+ prevDragIndex: -1
87
+ // prevDragPos: ''
88
+ }
89
+ }
90
+
91
+ export default /* define-vxe-component start */ defineVxeComponent({
92
+ name: 'VxeUpload',
93
+ model: {
94
+ prop: 'value',
95
+ event: 'modelValue'
96
+ },
97
+ mixins: [
98
+ globalMixins.sizeMixin
99
+ ],
100
+ props: {
101
+ value: [Array, String, Object] as PropType<VxeUploadPropTypes.ModelValue>,
102
+ showList: {
103
+ type: Boolean as PropType<VxeUploadPropTypes.ShowList>,
104
+ default: () => getConfig().upload.showList
105
+ },
106
+ moreConfig: Object as PropType<VxeUploadPropTypes.MoreConfig>,
107
+ readonly: {
108
+ type: Boolean as PropType<VxeUploadPropTypes.Readonly>,
109
+ default: null
110
+ },
111
+ disabled: {
112
+ type: Boolean as PropType<VxeUploadPropTypes.Disabled>,
113
+ default: null
114
+ },
115
+ autoSubmit: {
116
+ type: Boolean as PropType<VxeUploadPropTypes.AutoSubmit>,
117
+ default: () => getConfig().upload.autoSubmit
118
+ },
119
+ mode: {
120
+ type: String as PropType<VxeUploadPropTypes.Mode>,
121
+ default: () => getConfig().upload.mode
122
+ },
123
+ imageTypes: {
124
+ type: Array as PropType<VxeUploadPropTypes.ImageTypes>,
125
+ default: () => XEUtils.clone(getConfig().upload.imageTypes, true)
126
+ },
127
+ imageConfig: {
128
+ type: Object as PropType<VxeUploadPropTypes.ImageConfig>,
129
+ default: () => XEUtils.clone(getConfig().upload.imageConfig, true)
130
+ },
131
+ /**
132
+ * 已废弃,被 image-config 替换
133
+ * @deprecated
134
+ */
135
+ imageStyle: {
136
+ type: Object as PropType<VxeUploadPropTypes.ImageStyle>,
137
+ default: () => XEUtils.clone(getConfig().upload.imageStyle, true)
138
+ },
139
+ fileTypes: {
140
+ type: Array as PropType<VxeUploadPropTypes.FileTypes>,
141
+ default: () => XEUtils.clone(getConfig().upload.fileTypes, true)
142
+ },
143
+ dragSort: Boolean as PropType<VxeUploadPropTypes.DragSort>,
144
+ dragToUpload: {
145
+ type: Boolean as PropType<VxeUploadPropTypes.DragToUpload>,
146
+ default: () => XEUtils.clone(getConfig().upload.dragToUpload, true)
147
+ },
148
+ dragPlaceholder: {
149
+ type: String as PropType<VxeUploadPropTypes.DragPlaceholder>,
150
+ default: () => getConfig().upload.dragPlaceholder
151
+ },
152
+ pasteToUpload: {
153
+ type: Boolean as PropType<VxeUploadPropTypes.PasteToUpload>,
154
+ default: () => XEUtils.clone(getConfig().upload.pasteToUpload, true)
155
+ },
156
+ keyField: String as PropType<VxeUploadPropTypes.KeyField>,
157
+ singleMode: Boolean as PropType<VxeUploadPropTypes.SingleMode>,
158
+ urlMode: Boolean as PropType<VxeUploadPropTypes.UrlMode>,
159
+ urlArgs: {
160
+ type: Boolean as PropType<VxeUploadPropTypes.UrlArgs>,
161
+ default: () => getConfig().upload.urlArgs
162
+ },
163
+ multiple: Boolean as PropType<VxeUploadPropTypes.Multiple>,
164
+ limitSize: {
165
+ type: [String, Number] as PropType<VxeUploadPropTypes.LimitSize>,
166
+ default: () => getConfig().upload.limitSize
167
+ },
168
+ showLimitSize: {
169
+ type: Boolean as PropType<VxeUploadPropTypes.ShowLimitSize>,
170
+ default: () => getConfig().upload.showLimitSize
171
+ },
172
+ limitSizeText: {
173
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitSizeText>,
174
+ default: () => getConfig().upload.limitSizeText
175
+ },
176
+ limitCount: {
177
+ type: [String, Number] as PropType<VxeUploadPropTypes.LimitCount>,
178
+ default: () => getConfig().upload.limitCount
179
+ },
180
+ showLimitCount: {
181
+ type: Boolean as PropType<VxeUploadPropTypes.ShowLimitCount>,
182
+ default: () => getConfig().upload.showLimitCount
183
+ },
184
+ limitCountText: {
185
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitCountText>,
186
+ default: () => getConfig().upload.limitCountText
187
+ },
188
+ nameField: {
189
+ type: String as PropType<VxeUploadPropTypes.NameField>,
190
+ default: () => getConfig().upload.nameField
191
+ },
192
+ typeField: {
193
+ type: String as PropType<VxeUploadPropTypes.TypeField>,
194
+ default: () => getConfig().upload.typeField
195
+ },
196
+ urlField: {
197
+ type: String as PropType<VxeUploadPropTypes.UrlField>,
198
+ default: () => getConfig().upload.urlField
199
+ },
200
+ sizeField: {
201
+ type: String as PropType<VxeUploadPropTypes.SizeField>,
202
+ default: () => getConfig().upload.sizeField
203
+ },
204
+ showErrorStatus: {
205
+ type: Boolean as PropType<VxeUploadPropTypes.ShowErrorStatus>,
206
+ default: () => getConfig().upload.showErrorStatus
207
+ },
208
+ showProgress: {
209
+ type: Boolean as PropType<VxeUploadPropTypes.ShowProgress>,
210
+ default: () => getConfig().upload.showProgress
211
+ },
212
+ progressText: {
213
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.ProgressText>,
214
+ default: () => getConfig().upload.progressText
215
+ },
216
+ previewImageConfig: Object as PropType<VxeUploadPropTypes.PreviewImageConfig>,
217
+ showSubmitButton: Boolean as PropType<VxeUploadPropTypes.ShowSubmitButton>,
218
+ autoHiddenButton: {
219
+ type: Boolean as PropType<VxeUploadPropTypes.AutoHiddenButton>,
220
+ default: () => getConfig().upload.autoHiddenButton
221
+ },
222
+ showUploadButton: {
223
+ type: Boolean as PropType<VxeUploadPropTypes.ShowUploadButton>,
224
+ default: () => getConfig().upload.showUploadButton
225
+ },
226
+ buttonText: {
227
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.ButtonText>,
228
+ default: () => getConfig().upload.buttonText
229
+ },
230
+ buttonIcon: {
231
+ type: String as PropType<VxeUploadPropTypes.ButtonIcon>,
232
+ default: () => getConfig().upload.buttonIcon
233
+ },
234
+ showButtonText: {
235
+ type: Boolean as PropType<VxeUploadPropTypes.ShowButtonText>,
236
+ default: () => getConfig().upload.showButtonText
237
+ },
238
+ showButtonIcon: {
239
+ type: Boolean as PropType<VxeUploadPropTypes.ShowButtonIcon>,
240
+ default: () => getConfig().upload.showButtonIcon
241
+ },
242
+ showRemoveButton: {
243
+ type: Boolean as PropType<VxeUploadPropTypes.ShowRemoveButton>,
244
+ default: () => getConfig().upload.showRemoveButton
245
+ },
246
+ showDownloadButton: {
247
+ type: Boolean as PropType<VxeUploadPropTypes.ShowDownloadButton>,
248
+ default: () => getConfig().upload.showDownloadButton
249
+ },
250
+ showPreview: {
251
+ type: Boolean as PropType<VxeUploadPropTypes.ShowPreview>,
252
+ default: () => getConfig().upload.showPreview
253
+ },
254
+ showTip: {
255
+ type: Boolean as PropType<VxeUploadPropTypes.ShowTip>,
256
+ default: () => getConfig().upload.showTip
257
+ },
258
+ maxSimultaneousUploads: {
259
+ type: Number as PropType<VxeUploadPropTypes.MaxSimultaneousUploads>,
260
+ default: () => getConfig().upload.maxSimultaneousUploads
261
+ },
262
+ tipText: [String, Number, Function] as PropType<VxeUploadPropTypes.TipText>,
263
+ hintText: String as PropType<VxeUploadPropTypes.HintText>,
264
+ previewMethod: Function as PropType<VxeUploadPropTypes.PreviewMethod>,
265
+ beforeSelectMethod: Function as PropType<VxeUploadPropTypes.BeforeSelectMethod>,
266
+ uploadMethod: Function as PropType<VxeUploadPropTypes.UploadMethod>,
267
+ beforeRemoveMethod: Function as PropType<VxeUploadPropTypes.BeforeRemoveMethod>,
268
+ removeMethod: Function as PropType<VxeUploadPropTypes.RemoveMethod>,
269
+ beforeDownloadMethod: Function as PropType<VxeUploadPropTypes.BeforeDownloadMethod>,
270
+ downloadMethod: Function as PropType<VxeUploadPropTypes.DownloadMethod>,
271
+ getUrlMethod: Function as PropType<VxeUploadPropTypes.GetUrlMethod>,
272
+ getThumbnailUrlMethod: Function as PropType<VxeUploadPropTypes.GetThumbnailUrlMethod>,
273
+ size: {
274
+ type: String as PropType<VxeUploadPropTypes.Size>,
275
+ default: () => getConfig().upload.size || getConfig().size
276
+ }
277
+ },
278
+ inject: {
279
+ $xeForm: {
280
+ default: null
281
+ },
282
+ formItemInfo: {
283
+ from: 'xeFormItemInfo',
284
+ default: null
285
+ },
286
+ $xeTable: {
287
+ default: null
288
+ }
289
+ },
290
+ data () {
291
+ const xID = XEUtils.uniqueId()
292
+ const reactData = createReactData()
293
+ const internalData = createInternalData()
294
+ return {
295
+ xID,
296
+ reactData,
297
+ internalData
298
+ }
299
+ },
300
+ computed: {
301
+ ...({} as {
302
+ computeSize(): VxeComponentSizeType
303
+ $xeForm(): (VxeFormConstructor & VxeFormPrivateMethods) | null
304
+ formItemInfo(): VxeFormDefines.ProvideItemInfo | null,
305
+ $xeTable(): (VxeTableConstructor & VxeTablePrivateMethods) | null
306
+ }),
307
+ computeFormReadonly () {
308
+ const $xeUpload = this
309
+ const props = $xeUpload
310
+ const $xeForm = $xeUpload.$xeForm
311
+
312
+ const { readonly } = props
313
+ if (readonly === null) {
314
+ if ($xeForm) {
315
+ return $xeForm.readonly
316
+ }
317
+ return false
318
+ }
319
+ return readonly
320
+ },
321
+ computeIsDisabled () {
322
+ const $xeUpload = this
323
+ const props = $xeUpload
324
+ const $xeForm = $xeUpload.$xeForm
325
+
326
+ const { disabled } = props
327
+ if (disabled === null) {
328
+ if ($xeForm) {
329
+ return $xeForm.disabled
330
+ }
331
+ return false
332
+ }
333
+ return disabled
334
+ },
335
+ computeKeyField () {
336
+ const $xeUpload = this
337
+ const props = $xeUpload
338
+
339
+ return props.keyField || '_X_KEY'
340
+ },
341
+ computeIsImage () {
342
+ const $xeUpload = this
343
+ const props = $xeUpload
344
+
345
+ return props.mode === 'image'
346
+ },
347
+ computeNameProp () {
348
+ const $xeUpload = this
349
+ const props = $xeUpload
350
+
351
+ return props.nameField || 'name'
352
+ },
353
+ computeTypeProp () {
354
+ const $xeUpload = this
355
+ const props = $xeUpload
356
+
357
+ return props.typeField || 'type'
358
+ },
359
+ computeUrlProp () {
360
+ const $xeUpload = this
361
+ const props = $xeUpload
362
+
363
+ return props.urlField || 'url'
364
+ },
365
+ computeSizeProp () {
366
+ const $xeUpload = this
367
+ const props = $xeUpload
368
+
369
+ return props.sizeField || 'size'
370
+ },
371
+ computeLimitMaxSize () {
372
+ const $xeUpload = this
373
+ const props = $xeUpload
374
+
375
+ return XEUtils.toNumber(props.limitSize) * 1024 * 1024
376
+ },
377
+ computeLimitMaxCount () {
378
+ const $xeUpload = this
379
+ const props = $xeUpload
380
+
381
+ return props.multiple ? XEUtils.toNumber(props.limitCount) : 1
382
+ },
383
+ computePreviewImageOpts () {
384
+ const $xeUpload = this
385
+ const props = $xeUpload
386
+
387
+ const { showDownloadButton } = props
388
+ return Object.assign({
389
+ showDownloadButton
390
+ }, getConfig().upload.previewImageConfig, props.previewImageConfig)
391
+ },
392
+ computeOverCount () {
393
+ const $xeUpload = this
394
+ const props = $xeUpload
395
+ const reactData = $xeUpload.reactData as UploadReactData
396
+
397
+ const { multiple } = props
398
+ const { fileList } = reactData
399
+ const limitMaxCount = $xeUpload.computeLimitMaxCount as number
400
+ if (multiple) {
401
+ if (limitMaxCount) {
402
+ return fileList.length >= limitMaxCount
403
+ }
404
+ return true
405
+ }
406
+ return fileList.length >= 1
407
+ },
408
+ computeLimitSizeUnit () {
409
+ const $xeUpload = this
410
+ const props = $xeUpload
411
+
412
+ const limitSize = XEUtils.toNumber(props.limitSize)
413
+ if (limitSize) {
414
+ if (limitSize > 1048576) {
415
+ return `${limitSize / 1048576}T`
416
+ }
417
+ if (limitSize > 1024) {
418
+ return `${limitSize / 1024}G`
419
+ }
420
+ return `${limitSize}M`
421
+ }
422
+ return ''
423
+ },
424
+ computedShowTipText () {
425
+ const $xeUpload = this
426
+ const props = $xeUpload
427
+
428
+ const { showTip, tipText } = props
429
+ if (XEUtils.isBoolean(showTip)) {
430
+ return showTip
431
+ }
432
+ const defShowTip = getConfig().upload.showTip
433
+ if (XEUtils.isBoolean(defShowTip)) {
434
+ return defShowTip
435
+ }
436
+ if (tipText) {
437
+ return true
438
+ }
439
+ return false
440
+ },
441
+ computedDefTipText () {
442
+ const $xeUpload = this
443
+ const props = $xeUpload
444
+
445
+ const { limitSize, fileTypes, multiple, limitCount } = props
446
+ const tipText = props.tipText || props.hintText
447
+ const isImage = $xeUpload.computeIsImage
448
+ const limitSizeUnit = $xeUpload.computeLimitSizeUnit
449
+ if (XEUtils.isString(tipText)) {
450
+ return tipText
451
+ }
452
+ if (XEUtils.isFunction(tipText)) {
453
+ return `${tipText({})}`
454
+ }
455
+ const defTips: string[] = []
456
+ if (isImage) {
457
+ if (multiple && limitCount) {
458
+ defTips.push(getI18n('vxe.upload.imgCountHint', [limitCount]))
459
+ }
460
+ if (limitSize && limitSizeUnit) {
461
+ defTips.push(getI18n('vxe.upload.imgSizeHint', [limitSizeUnit]))
462
+ }
463
+ } else {
464
+ if (fileTypes && fileTypes.length) {
465
+ defTips.push(getI18n('vxe.upload.fileTypeHint', [fileTypes.join('/')]))
466
+ }
467
+ if (limitSize && limitSizeUnit) {
468
+ defTips.push(getI18n('vxe.upload.fileSizeHint', [limitSizeUnit]))
469
+ }
470
+ if (multiple && limitCount) {
471
+ defTips.push(getI18n('vxe.upload.fileCountHint', [limitCount]))
472
+ }
473
+ }
474
+ return defTips.join(getI18n('vxe.base.comma'))
475
+ },
476
+ computeImageOpts () {
477
+ const $xeUpload = this
478
+ const props = $xeUpload
479
+
480
+ return Object.assign({}, props.imageConfig || props.imageStyle)
481
+ },
482
+ computeImgStyle () {
483
+ const $xeUpload = this
484
+
485
+ const imageOpts = $xeUpload.computeImageOpts
486
+ const { width, height } = imageOpts
487
+ const stys: Record<string, string> = {}
488
+ if (width) {
489
+ stys.width = toCssUnit(width)
490
+ }
491
+ if (height) {
492
+ stys.height = toCssUnit(height)
493
+ }
494
+ return stys
495
+ },
496
+ computeMoreOpts () {
497
+ const $xeUpload = this
498
+ const props = $xeUpload
499
+
500
+ return Object.assign({ showMoreButton: true }, props.moreConfig)
501
+ }
502
+ },
503
+ watch: {
504
+ value () {
505
+ const $xeUpload = this
506
+ $xeUpload.updateFileList()
507
+ }
508
+ },
509
+ methods: {
510
+ //
511
+ // Method
512
+ //
513
+ dispatchEvent (type: ValueOf<VxeUploadEmits>, params: Record<string, any>, evnt: Event | null) {
514
+ const $xeUpload = this
515
+ $xeUpload.$emit(type, createEvent(evnt, { $upload: $xeUpload }, params))
516
+ },
517
+ emitModel (value: any) {
518
+ const $xeUpload = this
519
+
520
+ const { _events } = $xeUpload as any
521
+ if (_events && _events.modelValue) {
522
+ $xeUpload.$emit('modelValue', value)
523
+ } else {
524
+ $xeUpload.$emit('model-value', value)
525
+ }
526
+ },
527
+ choose () {
528
+ const $xeUpload = this
529
+ return $xeUpload.handleChoose(null)
530
+ },
531
+ getPendingFiles () {
532
+ const $xeUpload = this
533
+ const reactData = $xeUpload.reactData
534
+
535
+ const { fileList, fileCacheMaps } = reactData
536
+ const pendingFiles: File[] = []
537
+ fileList.forEach(item => {
538
+ const fileKey = $xeUpload.getFieldKey(item)
539
+ const cacheItem = fileCacheMaps[fileKey]
540
+ if (cacheItem && cacheItem.status === 'pending') {
541
+ pendingFiles.push(cacheItem.file)
542
+ }
543
+ })
544
+ return pendingFiles
545
+ },
546
+ submit (isFull?: boolean) {
547
+ const $xeUpload = this
548
+ const props = $xeUpload
549
+ const reactData = $xeUpload.reactData
550
+
551
+ const { maxSimultaneousUploads } = props
552
+ const msNum = XEUtils.toNumber(maxSimultaneousUploads || 1) || 1
553
+ const { fileList, fileCacheMaps } = reactData
554
+ const allPendingList = fileList.filter(item => {
555
+ const fileKey = $xeUpload.getFieldKey(item)
556
+ const cacheItem = fileCacheMaps[fileKey]
557
+ return cacheItem && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))
558
+ })
559
+
560
+ const handleSubmit = (item: VxeUploadDefines.FileObjItem): Promise<void> => {
561
+ const fileKey = $xeUpload.getFieldKey(item)
562
+ const cacheItem = fileCacheMaps[fileKey]
563
+ if (cacheItem) {
564
+ const file = cacheItem.file
565
+ if (file && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))) {
566
+ cacheItem.loading = true
567
+ cacheItem.percent = 0
568
+ return $xeUpload.handleUploadResult(item, file).then(handleNextSubmit)
569
+ }
570
+ }
571
+ return handleNextSubmit()
572
+ }
573
+
574
+ const handleNextSubmit = (): Promise<void> => {
575
+ if (allPendingList.length) {
576
+ const item = allPendingList[0]
577
+ allPendingList.splice(0, 1)
578
+ return handleSubmit(item).then(handleNextSubmit)
579
+ }
580
+ return Promise.resolve()
581
+ }
582
+
583
+ return Promise.all(allPendingList.splice(0, msNum).map(handleSubmit)).then(() => {
584
+ // 完成
585
+ })
586
+ },
587
+ getMoreVisible () {
588
+ const $xeUpload = this
589
+ const reactData = $xeUpload.reactData
590
+
591
+ return reactData.showMorePopup
592
+ },
593
+ openMore () {
594
+ const $xeUpload = this
595
+
596
+ $xeUpload.handleMoreEvent({ $event: new Event('click') })
597
+ return $xeUpload.$nextTick()
598
+ },
599
+ openMoreByEvent (evnt: Event) {
600
+ const $xeUpload = this
601
+
602
+ $xeUpload.handleMoreEvent({ $event: evnt })
603
+ return $xeUpload.$nextTick()
604
+ },
605
+ closeMore () {
606
+ const $xeUpload = this
607
+ const internalData = $xeUpload.internalData
608
+
609
+ if (VxeUI.modal) {
610
+ VxeUI.modal.close(internalData.moreId)
611
+ }
612
+ return $xeUpload.$nextTick()
613
+ },
614
+ getFieldKey (item: VxeUploadDefines.FileObjItem) {
615
+ const $xeUpload = this
616
+
617
+ const keyField = $xeUpload.computeKeyField
618
+ return item[keyField]
619
+ },
620
+ updateFileList () {
621
+ const $xeUpload = this
622
+ const props = $xeUpload
623
+ const reactData = $xeUpload.reactData
624
+
625
+ const { value, multiple } = props
626
+ const formReadonly = $xeUpload.computeFormReadonly
627
+ const keyField = $xeUpload.computeKeyField
628
+ const nameProp = $xeUpload.computeNameProp
629
+ const typeProp = $xeUpload.computeTypeProp
630
+ const urlProp = $xeUpload.computeUrlProp
631
+ const sizeProp = $xeUpload.computeSizeProp
632
+ const fileList = value
633
+ ? (value ? (XEUtils.isArray(value) ? value : [value]) : []).map(item => {
634
+ if (!item || XEUtils.isString(item)) {
635
+ const url = `${item || ''}`
636
+ const urlObj = XEUtils.parseUrl(item)
637
+ const name = (urlObj ? urlObj.searchQuery[nameProp] : '') || $xeUpload.parseFileName(url)
638
+ return {
639
+ [nameProp]: name,
640
+ [typeProp]: (urlObj ? urlObj.searchQuery[typeProp] : '') || $xeUpload.parseFileType(name),
641
+ [urlProp]: url,
642
+ [sizeProp]: XEUtils.toNumber(urlObj ? urlObj.searchQuery[sizeProp] : 0) || 0,
643
+ [keyField]: getUniqueKey()
644
+ }
645
+ }
646
+ const name = item[nameProp] || ''
647
+ item[nameProp] = name
648
+ item[typeProp] = item[typeProp] || $xeUpload.parseFileType(name)
649
+ item[urlProp] = item[urlProp] || ''
650
+ item[sizeProp] = item[sizeProp] || 0
651
+ item[keyField] = item[keyField] || getUniqueKey()
652
+ return item
653
+ })
654
+ : []
655
+ reactData.fileList = (formReadonly || multiple) ? fileList : (fileList.slice(0, 1))
656
+ },
657
+ parseFileName (url: string) {
658
+ return decodeURIComponent(`${url || ''}`).split('/').pop() || ''
659
+ },
660
+ parseFileType (name: string) {
661
+ const index = name.lastIndexOf('.')
662
+ if (index > 0) {
663
+ return name.substring(index + 1).toLowerCase()
664
+ }
665
+ return ''
666
+ },
667
+ handleChange (value: VxeUploadDefines.FileObjItem[]) {
668
+ const $xeUpload = this
669
+ const props = $xeUpload
670
+
671
+ const { singleMode, urlMode, urlArgs } = props
672
+ const urlProp = $xeUpload.computeUrlProp
673
+ const nameProp = $xeUpload.computeNameProp
674
+ let restList = value ? value.slice(0) : []
675
+ if (urlMode) {
676
+ restList = restList.map(item => {
677
+ const url = item[urlProp]
678
+ if (url && urlArgs) {
679
+ const urlObj = XEUtils.parseUrl(url)
680
+ if (!urlObj.searchQuery[nameProp]) {
681
+ if (url.indexOf('blob:') === -1) {
682
+ return `${url}${url.indexOf('?') === -1 ? '?' : '&'}${encodeURIComponent(item[nameProp] || '')}`
683
+ }
684
+ }
685
+ }
686
+ return url
687
+ })
688
+ }
689
+ $xeUpload.emitModel(singleMode ? (restList[0] || null) : restList)
690
+ },
691
+ getThumbnailFileUrl (item: VxeUploadDefines.FileObjItem) {
692
+ const $xeUpload = this
693
+ const props = $xeUpload
694
+
695
+ const getThumbnailUrlFn = props.getThumbnailUrlMethod || getConfig().upload.getThumbnailUrlMethod
696
+ if (getThumbnailUrlFn) {
697
+ return getThumbnailUrlFn({
698
+ $upload: $xeUpload,
699
+ option: item
700
+ })
701
+ }
702
+ return $xeUpload.getFileUrl(item)
703
+ },
704
+ getFileUrl (item: VxeUploadDefines.FileObjItem) {
705
+ const $xeUpload = this
706
+ const props = $xeUpload
707
+
708
+ const getUrlFn = props.getUrlMethod || getConfig().upload.getUrlMethod
709
+ const urlProp = $xeUpload.computeUrlProp
710
+ return getUrlFn
711
+ ? getUrlFn({
712
+ $upload: $xeUpload,
713
+ option: item
714
+ })
715
+ : item[urlProp]
716
+ },
717
+ handleDefaultFilePreview (item: VxeUploadDefines.FileObjItem) {
718
+ const $xeUpload = this
719
+ const props = $xeUpload
720
+ const internalData = $xeUpload.internalData
721
+
722
+ const { imageTypes } = props
723
+ const typeProp = $xeUpload.computeTypeProp
724
+ const previewImageOpts = $xeUpload.computePreviewImageOpts
725
+ const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
726
+ const { imagePreviewTypes } = internalData
727
+ // 如果是预览图片
728
+ if (imagePreviewTypes.concat(imageTypes || []).some(type => `${type}`.toLowerCase() === `${item[typeProp]}`.toLowerCase())) {
729
+ if (VxeUI.previewImage) {
730
+ VxeUI.previewImage({
731
+ ...previewImageOpts,
732
+ urlList: [$xeUpload.getFileUrl(item)],
733
+ beforeDownloadMethod: beforeDownloadFn
734
+ ? () => {
735
+ return beforeDownloadFn({
736
+ $upload: $xeUpload,
737
+ option: item
738
+ })
739
+ }
740
+ : undefined
741
+ })
742
+ }
743
+ }
744
+ },
745
+ handlePreviewFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
746
+ const $xeUpload = this
747
+ const props = $xeUpload
748
+
749
+ const previewFn = props.previewMethod || getConfig().upload.previewMethod
750
+ if (props.showPreview) {
751
+ if (previewFn) {
752
+ previewFn({
753
+ $upload: $xeUpload,
754
+ option: item
755
+ })
756
+ } else {
757
+ $xeUpload.handleDefaultFilePreview(item)
758
+ }
759
+ }
760
+ },
761
+ handlePreviewImageEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
762
+ const $xeUpload = this
763
+ const props = $xeUpload
764
+ const reactData = $xeUpload.reactData
765
+
766
+ const { fileList } = reactData
767
+ const previewImageOpts = $xeUpload.computePreviewImageOpts
768
+ const previewFn = props.previewMethod || getConfig().upload.previewMethod
769
+ const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
770
+ if (props.showPreview) {
771
+ if (previewFn) {
772
+ previewFn({
773
+ $upload: $xeUpload,
774
+ option: item
775
+ })
776
+ } else if (VxeUI.previewImage) {
777
+ VxeUI.previewImage({
778
+ ...previewImageOpts,
779
+ urlList: fileList.map(item => $xeUpload.getFileUrl(item)),
780
+ activeIndex: index,
781
+ beforeDownloadMethod: beforeDownloadFn
782
+ ? ({ index }) => {
783
+ return beforeDownloadFn({
784
+ $upload: $xeUpload,
785
+ option: fileList[index]
786
+ })
787
+ }
788
+ : undefined
789
+ })
790
+ }
791
+ }
792
+ },
793
+ handleUploadResult (item: VxeUploadDefines.FileObjItem, file: File) {
794
+ const $xeUpload = this
795
+ const props = $xeUpload
796
+ const reactData = $xeUpload.reactData
797
+
798
+ const { showErrorStatus } = props
799
+ const fileKey = $xeUpload.getFieldKey(item)
800
+ const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
801
+ if (uploadFn) {
802
+ return Promise.resolve(
803
+ uploadFn({
804
+ $upload: $xeUpload,
805
+ file,
806
+ option: item,
807
+ updateProgress (percentNum) {
808
+ const { fileCacheMaps } = reactData
809
+ const cacheItem = fileCacheMaps[$xeUpload.getFieldKey(item)]
810
+ if (cacheItem) {
811
+ cacheItem.percent = Math.max(0, Math.min(99, XEUtils.toNumber(percentNum)))
812
+ }
813
+ }
814
+ })
815
+ ).then(res => {
816
+ const { fileCacheMaps } = reactData
817
+ const cacheItem = fileCacheMaps[fileKey]
818
+ if (cacheItem) {
819
+ cacheItem.percent = 100
820
+ cacheItem.status = 'success'
821
+ }
822
+ // 处理动态字段双向绑定问题
823
+ // Object.assign(item, res)
824
+ XEUtils.each(res, (val, key) => {
825
+ $xeUpload.$set(item, key, val)
826
+ })
827
+ $xeUpload.dispatchEvent('upload-success', { option: item, data: res }, null)
828
+ }).catch((res) => {
829
+ const { fileCacheMaps } = reactData
830
+ const cacheItem = fileCacheMaps[fileKey]
831
+ if (cacheItem) {
832
+ cacheItem.status = 'error'
833
+ }
834
+ if (showErrorStatus) {
835
+ // 处理动态字段双向绑定问题
836
+ // Object.assign(item, res)
837
+ XEUtils.each(res, (val, key) => {
838
+ $xeUpload.$set(item, key, val)
839
+ })
840
+ } else {
841
+ reactData.fileList = reactData.fileList.filter(obj => $xeUpload.getFieldKey(obj) !== fileKey)
842
+ delete fileCacheMaps[fileKey]
843
+ }
844
+ $xeUpload.dispatchEvent('upload-error', { option: item, data: res }, null)
845
+ }).finally(() => {
846
+ const { fileCacheMaps } = reactData
847
+ const cacheItem = fileCacheMaps[fileKey]
848
+ if (cacheItem) {
849
+ cacheItem.loading = false
850
+ }
851
+ })
852
+ } else {
853
+ const { fileCacheMaps } = reactData
854
+ const cacheItem = fileCacheMaps[fileKey]
855
+ if (cacheItem) {
856
+ cacheItem.loading = false
857
+ }
858
+ }
859
+ return Promise.resolve()
860
+ },
861
+ handleReUpload (item: VxeUploadDefines.FileObjItem) {
862
+ const $xeUpload = this
863
+ const props = $xeUpload
864
+ const reactData = $xeUpload.reactData
865
+
866
+ const { uploadMethod, urlMode } = props
867
+ const { fileCacheMaps } = reactData
868
+ const fileKey = $xeUpload.getFieldKey(item)
869
+ const cacheItem = fileCacheMaps[fileKey]
870
+ const uploadFn = uploadMethod || getConfig().upload.uploadMethod
871
+ if (uploadFn && cacheItem) {
872
+ const file = cacheItem.file
873
+ cacheItem.loading = true
874
+ cacheItem.status = 'pending'
875
+ cacheItem.percent = 0
876
+ $xeUpload.handleUploadResult(item, file).then(() => {
877
+ if (urlMode) {
878
+ $xeUpload.handleChange(reactData.fileList)
879
+ }
880
+ })
881
+ }
882
+ },
883
+ handleUploadFile (files: File[], evnt: Event | null) {
884
+ const $xeUpload = this
885
+ const props = $xeUpload
886
+ const reactData = $xeUpload.reactData
887
+ const $xeForm = $xeUpload.$xeForm
888
+ const formItemInfo = $xeUpload.formItemInfo
889
+
890
+ const { multiple, urlMode, showLimitSize, limitSizeText, showLimitCount, limitCountText, autoSubmit } = props
891
+ const { fileList } = reactData
892
+ const beforeSelectFn = props.beforeSelectMethod || getConfig().upload.beforeSelectMethod
893
+ const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
894
+ const keyField = $xeUpload.computeKeyField
895
+ const nameProp = $xeUpload.computeNameProp
896
+ const typeProp = $xeUpload.computeTypeProp
897
+ const urlProp = $xeUpload.computeUrlProp
898
+ const sizeProp = $xeUpload.computeSizeProp
899
+ const limitMaxSize = $xeUpload.computeLimitMaxSize
900
+ const limitMaxCount = $xeUpload.computeLimitMaxCount
901
+ const limitSizeUnit = $xeUpload.computeLimitSizeUnit
902
+ let selectFiles = files
903
+
904
+ if (multiple && limitMaxCount) {
905
+ // 校验文件数量
906
+ if (showLimitCount && fileList.length >= limitMaxCount) {
907
+ if (VxeUI.modal) {
908
+ VxeUI.modal.notification({
909
+ title: getI18n('vxe.modal.errTitle'),
910
+ status: 'error',
911
+ content: limitCountText ? `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}` : getI18n('vxe.upload.overCountErr', [limitMaxCount])
912
+ })
913
+ }
914
+ return
915
+ }
916
+ const overNum = selectFiles.length - (limitMaxCount - fileList.length)
917
+ if (showLimitCount && overNum > 0) {
918
+ const overExtraList = selectFiles.slice(limitMaxCount - fileList.length)
919
+ if (limitCountText) {
920
+ VxeUI.modal.notification({
921
+ title: getI18n('vxe.modal.errTitle'),
922
+ status: 'error',
923
+ content: `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}`
924
+ })
925
+ } else if (VxeUI.modal) {
926
+ VxeUI.modal.notification({
927
+ title: getI18n('vxe.modal.errTitle'),
928
+ status: 'error',
929
+ slots: {
930
+ default (params, h) {
931
+ return h('div', {
932
+ class: 'vxe-upload--file-message-over-error'
933
+ }, [
934
+ h('div', {}, getI18n('vxe.upload.overCountExtraErr', [limitMaxCount, overNum])),
935
+ h('div', {
936
+ class: 'vxe-upload--file-message-over-extra'
937
+ }, overExtraList.map((file, index) => {
938
+ return h('div', {
939
+ key: index,
940
+ class: 'vxe-upload--file-message-over-extra-item'
941
+ }, file.name)
942
+ }))
943
+ ])
944
+ }
945
+ }
946
+ })
947
+ }
948
+ }
949
+ selectFiles = selectFiles.slice(0, limitMaxCount - fileList.length)
950
+ }
951
+
952
+ // 校验文件大小
953
+ if (showLimitSize && limitMaxSize) {
954
+ for (let i = 0; i < files.length; i++) {
955
+ const file = files[0]
956
+ if (file.size > limitMaxSize) {
957
+ if (VxeUI.modal) {
958
+ VxeUI.modal.notification({
959
+ title: getI18n('vxe.modal.errTitle'),
960
+ status: 'error',
961
+ content: limitSizeText ? `${XEUtils.isFunction(limitSizeText) ? limitSizeText({ maxSize: limitMaxSize }) : limitSizeText}` : getI18n('vxe.upload.overSizeErr', [limitSizeUnit])
962
+ })
963
+ }
964
+ return
965
+ }
966
+ }
967
+ }
968
+
969
+ const cacheMaps = Object.assign({}, reactData.fileCacheMaps)
970
+ const newFileList = multiple ? fileList : []
971
+ const uploadPromiseRests: any[] = []
972
+ selectFiles.forEach(file => {
973
+ const { name } = file
974
+ const fileKey = getUniqueKey()
975
+ const fileObj: VxeUploadDefines.FileObjItem = {
976
+ [nameProp]: name,
977
+ [typeProp]: $xeUpload.parseFileType(name),
978
+ [sizeProp]: file.size,
979
+ [urlProp]: URL.createObjectURL(file),
980
+ [keyField]: fileKey
981
+ }
982
+ if (uploadFn) {
983
+ cacheMaps[fileKey] = {
984
+ file: file,
985
+ loading: !!autoSubmit,
986
+ status: 'pending',
987
+ percent: 0
988
+ }
989
+ }
990
+ const item = fileObj
991
+ if (!beforeSelectFn || beforeSelectFn({ $upload: $xeUpload, file })) {
992
+ if (uploadFn && autoSubmit) {
993
+ uploadPromiseRests.push(
994
+ $xeUpload.handleUploadResult(item, file)
995
+ )
996
+ }
997
+ newFileList.push(item)
998
+ }
999
+ })
1000
+ reactData.fileList = newFileList
1001
+ reactData.fileCacheMaps = cacheMaps
1002
+ newFileList.forEach(item => {
1003
+ $xeUpload.dispatchEvent('add', { option: item }, evnt)
1004
+ })
1005
+ Promise.all(urlMode ? uploadPromiseRests : []).then(() => {
1006
+ const restFileList = reactData.fileList
1007
+ $xeUpload.handleChange(restFileList)
1008
+ // 自动更新校验状态
1009
+ if ($xeForm && formItemInfo) {
1010
+ $xeForm.triggerItemEvent(evnt as any, formItemInfo.itemConfig.field, restFileList)
1011
+ }
1012
+ })
1013
+ },
1014
+ handleChoose (evnt: MouseEvent | null) {
1015
+ const $xeUpload = this
1016
+ const props = $xeUpload
1017
+
1018
+ const { multiple, imageTypes, fileTypes } = props
1019
+ const isDisabled = $xeUpload.computeIsDisabled
1020
+ const isImage = $xeUpload.computeIsImage
1021
+ if (isDisabled) {
1022
+ return Promise.resolve({
1023
+ status: false,
1024
+ files: [],
1025
+ file: null
1026
+ })
1027
+ }
1028
+ return readLocalFile({
1029
+ multiple,
1030
+ types: isImage ? imageTypes : fileTypes
1031
+ }).then((params) => {
1032
+ $xeUpload.handleUploadFile(params.files, evnt)
1033
+ return params
1034
+ })
1035
+ },
1036
+ clickEvent (evnt: MouseEvent) {
1037
+ const $xeUpload = this
1038
+
1039
+ $xeUpload.handleChoose(evnt).catch(() => {
1040
+ // 错误文件类型
1041
+ })
1042
+ },
1043
+ handleRemoveEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1044
+ const $xeUpload = this
1045
+ const reactData = $xeUpload.reactData
1046
+ const $xeForm = $xeUpload.$xeForm
1047
+ const formItemInfo = $xeUpload.formItemInfo
1048
+
1049
+ const { fileList } = reactData
1050
+ fileList.splice(index, 1)
1051
+ $xeUpload.handleChange(fileList)
1052
+ // 自动更新校验状态
1053
+ if ($xeForm && formItemInfo) {
1054
+ $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, fileList)
1055
+ }
1056
+ $xeUpload.dispatchEvent('remove', { option: item }, evnt)
1057
+ },
1058
+ removeFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1059
+ const $xeUpload = this
1060
+ const props = $xeUpload
1061
+
1062
+ const beforeRemoveFn = props.beforeRemoveMethod || getConfig().upload.beforeRemoveMethod
1063
+ const removeFn = props.removeMethod || getConfig().upload.removeMethod
1064
+ Promise.resolve(
1065
+ beforeRemoveFn
1066
+ ? beforeRemoveFn({
1067
+ $upload: $xeUpload,
1068
+ option: item
1069
+ })
1070
+ : true
1071
+ ).then(status => {
1072
+ if (status) {
1073
+ if (removeFn) {
1074
+ Promise.resolve(
1075
+ removeFn({
1076
+ $upload: $xeUpload,
1077
+ option: item
1078
+ })
1079
+ ).then(() => {
1080
+ $xeUpload.handleRemoveEvent(evnt, item, index)
1081
+ }).catch(e => e)
1082
+ } else {
1083
+ $xeUpload.handleRemoveEvent(evnt, item, index)
1084
+ }
1085
+ } else {
1086
+ $xeUpload.dispatchEvent('remove-fail', { option: item }, evnt)
1087
+ }
1088
+ })
1089
+ },
1090
+ handleDownloadEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1091
+ const $xeUpload = this
1092
+
1093
+ $xeUpload.dispatchEvent('download', { option: item }, evnt)
1094
+ },
1095
+ downloadFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1096
+ const $xeUpload = this
1097
+ const props = $xeUpload
1098
+
1099
+ const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
1100
+ const downloadFn = props.downloadMethod || getConfig().upload.downloadMethod
1101
+ Promise.resolve(
1102
+ beforeDownloadFn
1103
+ ? beforeDownloadFn({
1104
+ $upload: $xeUpload,
1105
+ option: item
1106
+ })
1107
+ : true
1108
+ ).then(status => {
1109
+ if (status) {
1110
+ if (downloadFn) {
1111
+ Promise.resolve(
1112
+ downloadFn({
1113
+ $upload: $xeUpload,
1114
+ option: item
1115
+ })
1116
+ ).then(() => {
1117
+ $xeUpload.handleDownloadEvent(evnt, item)
1118
+ }).catch(e => e)
1119
+ } else {
1120
+ $xeUpload.handleDownloadEvent(evnt, item)
1121
+ }
1122
+ } else {
1123
+ $xeUpload.dispatchEvent('download-fail', { option: item }, evnt)
1124
+ }
1125
+ })
1126
+ },
1127
+ handleUploadDragleaveEvent (evnt: DragEvent) {
1128
+ const $xeUpload = this
1129
+ const reactData = $xeUpload.reactData
1130
+
1131
+ const targetElem = evnt.currentTarget as HTMLDivElement
1132
+ const { clientX, clientY } = evnt
1133
+ if (targetElem) {
1134
+ const { x: targetX, y: targetY, height: targetHeight, width: targetWidth } = targetElem.getBoundingClientRect()
1135
+ if (clientX < targetX || clientX > targetX + targetWidth || clientY < targetY || clientY > targetY + targetHeight) {
1136
+ reactData.isDragUploadStatus = false
1137
+ }
1138
+ }
1139
+ },
1140
+ handleUploadDragoverEvent (evnt: DragEvent) {
1141
+ const $xeUpload = this
1142
+ const reactData = $xeUpload.reactData
1143
+
1144
+ const dataTransfer = evnt.dataTransfer
1145
+ if (dataTransfer) {
1146
+ const { items } = dataTransfer
1147
+ if (items && items.length) {
1148
+ evnt.preventDefault()
1149
+ reactData.isDragUploadStatus = true
1150
+ }
1151
+ }
1152
+ },
1153
+ uploadTransferFileEvent (evnt: Event, files: File[]) {
1154
+ const $xeUpload = this
1155
+ const props = $xeUpload
1156
+ const internalData = $xeUpload.internalData
1157
+
1158
+ const { imageTypes, fileTypes } = props
1159
+ const { imagePreviewTypes } = internalData
1160
+ const isImage = $xeUpload.computeIsImage
1161
+ if (isImage) {
1162
+ const pasteImgTypes = imagePreviewTypes.concat(imageTypes && imageTypes.length ? imageTypes : [])
1163
+ files = files.filter(file => {
1164
+ const fileType = `${file.type.split('/')[1] || ''}`.toLowerCase()
1165
+ if (pasteImgTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1166
+ return true
1167
+ }
1168
+ return false
1169
+ })
1170
+ } else {
1171
+ if (fileTypes && fileTypes.length) {
1172
+ const errTypes: string[] = []
1173
+ files.forEach(file => {
1174
+ const fileType = $xeUpload.parseFileType(file.name)
1175
+ if (!fileTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1176
+ errTypes.push(fileType)
1177
+ }
1178
+ })
1179
+ if (errTypes.length) {
1180
+ if (VxeUI.modal) {
1181
+ VxeUI.modal.message({
1182
+ content: getI18n('vxe.error.notType', [errTypes.join(', ')]),
1183
+ status: 'error'
1184
+ })
1185
+ }
1186
+ return
1187
+ }
1188
+ }
1189
+ }
1190
+ // 如果全部不满足条件
1191
+ if (!files.length) {
1192
+ if (VxeUI.modal) {
1193
+ VxeUI.modal.notification({
1194
+ title: getI18n('vxe.modal.errTitle'),
1195
+ status: 'error',
1196
+ content: getI18n('vxe.upload.uploadTypeErr')
1197
+ })
1198
+ }
1199
+ return
1200
+ }
1201
+ $xeUpload.handleUploadFile(files, evnt)
1202
+ },
1203
+ handleUploadDropEvent (evnt: DragEvent) {
1204
+ const $xeUpload = this
1205
+ const reactData = $xeUpload.reactData
1206
+
1207
+ const dataTransfer = evnt.dataTransfer
1208
+ if (dataTransfer) {
1209
+ const { items } = dataTransfer
1210
+ if (items && items.length) {
1211
+ evnt.preventDefault()
1212
+ const files = handleTransferFiles(items)
1213
+ if (files.length) {
1214
+ $xeUpload.uploadTransferFileEvent(evnt, files)
1215
+ }
1216
+ }
1217
+ }
1218
+ reactData.isDragUploadStatus = false
1219
+ },
1220
+ handleMoreEvent (evntParams: VxeComponentEventParams) {
1221
+ const $xeUpload = this
1222
+ const props = $xeUpload
1223
+ const slots = $xeUpload.$scopedSlots
1224
+ const reactData = $xeUpload.reactData
1225
+ const internalData = $xeUpload.internalData
1226
+
1227
+ const { xID } = $xeUpload
1228
+
1229
+ const formReadonly = $xeUpload.computeFormReadonly
1230
+ const isImage = $xeUpload.computeIsImage
1231
+
1232
+ const evnt = evntParams.$event
1233
+ if (VxeUI.modal) {
1234
+ VxeUI.modal.open({
1235
+ id: internalData.moreId,
1236
+ title: formReadonly ? getI18n('vxe.upload.morePopup.readTitle') : getI18n(`vxe.upload.morePopup.${isImage ? 'imageTitle' : 'fileTitle'}`),
1237
+ width: 660,
1238
+ height: 500,
1239
+ escClosable: true,
1240
+ showMaximize: true,
1241
+ resize: true,
1242
+ maskClosable: true,
1243
+ slots: {
1244
+ default (params, h) {
1245
+ const { showErrorStatus, dragToUpload, dragSort, dragPlaceholder } = props
1246
+ const { isActivated, isDragMove, isDragUploadStatus, dragIndex } = reactData
1247
+ const { fileList } = reactData
1248
+ const isDisabled = $xeUpload.computeIsDisabled
1249
+ const moreContSlot = slots.moreContent || slots['more-content']
1250
+
1251
+ const ons: Record<string, any> = {}
1252
+ if (dragToUpload && dragIndex === -1) {
1253
+ ons.dragover = $xeUpload.handleUploadDragoverEvent
1254
+ ons.dragleave = $xeUpload.handleUploadDragleaveEvent
1255
+ ons.drop = $xeUpload.handleUploadDropEvent
1256
+ }
1257
+
1258
+ return h('div', {
1259
+ attrs: {
1260
+ id: `refPopupElem${xID}`
1261
+ },
1262
+ class: ['vxe-upload--more-popup', {
1263
+ 'is--readonly': formReadonly,
1264
+ 'is--disabled': isDisabled,
1265
+ 'is--active': isActivated,
1266
+ 'show--error': showErrorStatus,
1267
+ 'is--drag': isDragUploadStatus
1268
+ }],
1269
+ on: ons
1270
+ }, moreContSlot
1271
+ ? getSlotVNs(moreContSlot({ options: fileList }))
1272
+ : [
1273
+ isImage
1274
+ ? (
1275
+ dragSort
1276
+ ? h('transition-group', {
1277
+ props: {
1278
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1279
+ tag: 'div'
1280
+ },
1281
+ class: 'vxe-upload--image-more-list'
1282
+ }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1283
+ : h('div', {
1284
+ class: 'vxe-upload--image-more-list'
1285
+ }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1286
+ )
1287
+ : h('div', {
1288
+ class: 'vxe-upload--file-more-list'
1289
+ }, [
1290
+ $xeUpload.renderFileAction(h, true),
1291
+ (
1292
+ dragSort
1293
+ ? h('transition-group', {
1294
+ props: {
1295
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1296
+ tag: 'div'
1297
+ },
1298
+ class: 'vxe-upload--file-list'
1299
+ }, $xeUpload.renderFileItemList(h, fileList, true))
1300
+ : h('div', {
1301
+ class: 'vxe-upload--file-list'
1302
+ }, $xeUpload.renderFileItemList(h, fileList, true))
1303
+ )
1304
+ ]),
1305
+ dragSort
1306
+ ? h('div', {
1307
+ attrs: {
1308
+ id: `refModalDragLineElem${xID}`
1309
+ },
1310
+ class: 'vxe-upload--drag-line'
1311
+ })
1312
+ : renderEmptyElement($xeUpload),
1313
+ isDragUploadStatus
1314
+ ? h('div', {
1315
+ class: 'vxe-upload--drag-placeholder'
1316
+ }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
1317
+ : renderEmptyElement($xeUpload)
1318
+ ])
1319
+ }
1320
+ },
1321
+ events: {
1322
+ show () {
1323
+ reactData.showMorePopup = true
1324
+ },
1325
+ hide ({ $event }) {
1326
+ reactData.showMorePopup = false
1327
+ if ($event) {
1328
+ $xeUpload.dispatchEvent('more-visible', { visible: false }, $event)
1329
+ }
1330
+ }
1331
+ }
1332
+ })
1333
+ if (evnt) {
1334
+ $xeUpload.dispatchEvent('more-visible', { visible: true }, evnt)
1335
+ }
1336
+ }
1337
+ },
1338
+ // 拖拽
1339
+ handleDragSortDragstartEvent (evnt: DragEvent) {
1340
+ const $xeUpload = this
1341
+ const reactData = $xeUpload.reactData
1342
+
1343
+ evnt.stopPropagation()
1344
+ if (evnt.dataTransfer) {
1345
+ evnt.dataTransfer.setDragImage(getTpImg(), 0, 0)
1346
+ }
1347
+ const dragEl = evnt.currentTarget as HTMLElement
1348
+ const parentEl = dragEl.parentElement as HTMLDivElement
1349
+ const dragIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1350
+ reactData.isDragMove = true
1351
+ reactData.dragIndex = dragIndex
1352
+ setTimeout(() => {
1353
+ reactData.isDragMove = false
1354
+ }, 500)
1355
+ },
1356
+ handleDragSortDragoverEvent (evnt: DragEvent) {
1357
+ const $xeUpload = this
1358
+ const reactData = $xeUpload.reactData
1359
+ const internalData = $xeUpload.internalData
1360
+
1361
+ evnt.stopPropagation()
1362
+ evnt.preventDefault()
1363
+ const { dragIndex } = reactData
1364
+ if (dragIndex === -1) {
1365
+ return
1366
+ }
1367
+ const isImage = $xeUpload.computeIsImage
1368
+ const dragEl = evnt.currentTarget as HTMLElement
1369
+ const parentEl = dragEl.parentElement as HTMLDivElement
1370
+ const currIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1371
+ let dragPos: 'top' | 'bottom' | 'left' | 'right' | '' = ''
1372
+ if (isImage) {
1373
+ const offsetX = evnt.clientX - dragEl.getBoundingClientRect().x
1374
+ dragPos = offsetX < dragEl.clientWidth / 2 ? 'left' : 'right'
1375
+ } else {
1376
+ const offsetY = evnt.clientY - dragEl.getBoundingClientRect().y
1377
+ dragPos = offsetY < dragEl.clientHeight / 2 ? 'top' : 'bottom'
1378
+ }
1379
+ if (dragIndex === currIndex) {
1380
+ showDropTip($xeUpload, evnt, dragEl, dragPos)
1381
+ return
1382
+ }
1383
+ showDropTip($xeUpload, evnt, dragEl, dragPos)
1384
+ internalData.prevDragIndex = currIndex
1385
+ internalData.prevDragPos = dragPos
1386
+ },
1387
+ handleDragSortDragendEvent (evnt: DragEvent) {
1388
+ const $xeUpload = this
1389
+ const reactData = $xeUpload.reactData
1390
+ const internalData = $xeUpload.internalData
1391
+
1392
+ const { fileList, dragIndex } = reactData
1393
+ const { prevDragIndex, prevDragPos } = internalData
1394
+ const oldIndex = dragIndex
1395
+ const targetIndex = prevDragIndex
1396
+ const dragOffsetIndex = prevDragPos === 'bottom' || prevDragPos === 'right' ? 1 : 0
1397
+ const oldItem = fileList[oldIndex]
1398
+ const newItem = fileList[targetIndex]
1399
+ if (oldItem && newItem) {
1400
+ fileList.splice(oldIndex, 1)
1401
+ const ptfIndex = XEUtils.findIndexOf(fileList, item => newItem === item)
1402
+ const nIndex = ptfIndex + dragOffsetIndex
1403
+ fileList.splice(nIndex, 0, oldItem)
1404
+ $xeUpload.dispatchEvent('sort-dragend', {
1405
+ oldItem: oldItem,
1406
+ newItem: newItem,
1407
+ dragPos: prevDragPos as any,
1408
+ offsetIndex: dragOffsetIndex,
1409
+ _index: {
1410
+ newIndex: nIndex,
1411
+ oldIndex: oldIndex
1412
+ }
1413
+ }, evnt)
1414
+ }
1415
+ hideDropTip($xeUpload)
1416
+ reactData.dragIndex = -1
1417
+ },
1418
+ handleItemMousedownEvent (evnt: MouseEvent) {
1419
+ const $xeUpload = this
1420
+ const $xeTable = $xeUpload.$xeTable
1421
+ const reactData = $xeUpload.reactData
1422
+
1423
+ if ($xeTable) {
1424
+ evnt.stopPropagation()
1425
+ }
1426
+ reactData.isActivated = true
1427
+ },
1428
+ handleGlobalPasteEvent (evnt: ClipboardEvent) {
1429
+ const $xeUpload = this
1430
+ const props = $xeUpload
1431
+ const reactData = $xeUpload.reactData
1432
+
1433
+ const { pasteToUpload } = props
1434
+ const { isActivated } = reactData
1435
+ if (!isActivated || !pasteToUpload) {
1436
+ return
1437
+ }
1438
+ const clipboardData: DataTransfer = evnt.clipboardData || (evnt as any).originalEvent.clipboardData
1439
+ if (!clipboardData) {
1440
+ return
1441
+ }
1442
+ const { items } = clipboardData
1443
+ if (!items) {
1444
+ return
1445
+ }
1446
+ const files = handleTransferFiles(items)
1447
+ if (files.length) {
1448
+ evnt.preventDefault()
1449
+ $xeUpload.uploadTransferFileEvent(evnt, files)
1450
+ }
1451
+ },
1452
+ handleGlobalClickEvent (evnt: MouseEvent) {
1453
+ const $xeUpload = this
1454
+ const reactData = $xeUpload.reactData
1455
+
1456
+ const el = $xeUpload.$refs.refElem as HTMLDivElement
1457
+ const popupEl = $xeUpload.$refs.refPopupElem as HTMLDivElement
1458
+ let isActivated = getEventTargetNode(evnt, el).flag
1459
+ if (!isActivated && popupEl) {
1460
+ const parentEl = popupEl.parentElement || popupEl
1461
+ const modalEl = parentEl ? parentEl.parentElement : parentEl
1462
+ isActivated = getEventTargetNode(evnt, modalEl).flag
1463
+ }
1464
+ reactData.isActivated = isActivated
1465
+ },
1466
+ handleGlobalBlurEvent () {
1467
+ const $xeUpload = this
1468
+ const reactData = $xeUpload.reactData
1469
+
1470
+ reactData.isActivated = false
1471
+ },
1472
+
1473
+ //
1474
+ // Render
1475
+ //
1476
+ renderFileItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1477
+ const $xeUpload = this
1478
+ const props = $xeUpload
1479
+ const slots = $xeUpload.$scopedSlots
1480
+ const reactData = $xeUpload.reactData
1481
+
1482
+ const { showRemoveButton, showDownloadButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1483
+ const { fileList, fileCacheMaps } = reactData
1484
+ const isDisabled = $xeUpload.computeIsDisabled
1485
+ const formReadonly = $xeUpload.computeFormReadonly
1486
+ const nameProp = $xeUpload.computeNameProp
1487
+ const typeProp = $xeUpload.computeTypeProp
1488
+ const optionSlot = slots.option
1489
+ const actionSlot = slots.action
1490
+ const cornerSlot = slots.corner
1491
+ const nameSlot = slots.name
1492
+
1493
+ const ons: Record<string, any> = {}
1494
+ if (dragSort && currList.length > 1) {
1495
+ ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1496
+ ons.dragover = $xeUpload.handleDragSortDragoverEvent
1497
+ ons.dragend = $xeUpload.handleDragSortDragendEvent
1498
+ }
1499
+
1500
+ return currList.map((item, index) => {
1501
+ const fileKey = $xeUpload.getFieldKey(item)
1502
+ const cacheItem = fileCacheMaps[fileKey]
1503
+ let isLoading = false
1504
+ let isError = false
1505
+ let isPending = false
1506
+ const fileName = `${item[nameProp] || ''}`
1507
+ if (cacheItem) {
1508
+ isLoading = cacheItem.loading
1509
+ isError = cacheItem.status === 'error'
1510
+ isPending = cacheItem.status === 'pending'
1511
+ }
1512
+ return h('div', {
1513
+ key: dragSort ? fileKey : index,
1514
+ class: ['vxe-upload--file-item', {
1515
+ 'is--preview': showPreview,
1516
+ 'is--loading': isLoading,
1517
+ 'is--pending': isPending,
1518
+ 'is--error': isError
1519
+ }],
1520
+ attrs: {
1521
+ fileid: fileKey,
1522
+ draggable: dragSort ? true : null
1523
+ },
1524
+ on: ons
1525
+ }, optionSlot
1526
+ ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1527
+ : [
1528
+ h('div', {
1529
+ class: 'vxe-upload--file-item-icon'
1530
+ }, [
1531
+ h('i', {
1532
+ class: getIcon()[`UPLOAD_FILE_TYPE_${`${item[typeProp]}`.toLocaleUpperCase() as 'DEFAULT'}`] || getIcon().UPLOAD_FILE_TYPE_DEFAULT
1533
+ })
1534
+ ]),
1535
+ h('div', {
1536
+ class: 'vxe-upload--file-item-name',
1537
+ attrs: {
1538
+ title: fileName
1539
+ },
1540
+ on: {
1541
+ click (evnt: MouseEvent) {
1542
+ if (!isLoading && !isError) {
1543
+ $xeUpload.handlePreviewFileEvent(evnt, item)
1544
+ }
1545
+ }
1546
+ }
1547
+ }, nameSlot ? getSlotVNs(nameSlot({ option: item, isMoreView, options: fileList })) : fileName),
1548
+ isLoading
1549
+ ? h('div', {
1550
+ class: 'vxe-upload--file-item-loading-icon'
1551
+ }, [
1552
+ h('i', {
1553
+ class: getIcon().UPLOAD_LOADING
1554
+ })
1555
+ ])
1556
+ : renderEmptyElement($xeUpload),
1557
+ showProgress && isLoading && cacheItem
1558
+ ? h('div', {
1559
+ class: 'vxe-upload--file-item-loading-text'
1560
+ }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1561
+ : renderEmptyElement($xeUpload),
1562
+ !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1563
+ ? h('div', {
1564
+ class: 'vxe-upload--file-item-rebtn'
1565
+ }, [
1566
+ h(VxeButtonComponent, {
1567
+ props: {
1568
+ icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1569
+ mode: 'text',
1570
+ status: 'primary',
1571
+ content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1572
+ },
1573
+ on: {
1574
+ click () {
1575
+ $xeUpload.handleReUpload(item)
1576
+ }
1577
+ }
1578
+ })
1579
+ ])
1580
+ : renderEmptyElement($xeUpload),
1581
+ h('div', {
1582
+ class: 'vxe-upload--file-item-btn-wrapper'
1583
+ }, actionSlot
1584
+ ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1585
+ : [
1586
+ cornerSlot
1587
+ ? h('div', {
1588
+ class: 'vxe-upload--file-item-action'
1589
+ }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1590
+ : renderEmptyElement($xeUpload),
1591
+ showDownloadButton && !isLoading
1592
+ ? h('div', {
1593
+ class: 'vxe-upload--file-item-download-btn',
1594
+ on: {
1595
+ click (evnt: MouseEvent) {
1596
+ $xeUpload.downloadFileEvent(evnt, item)
1597
+ }
1598
+ }
1599
+ }, [
1600
+ h('i', {
1601
+ class: getIcon().UPLOAD_FILE_DOWNLOAD
1602
+ })
1603
+ ])
1604
+ : renderEmptyElement($xeUpload),
1605
+ showRemoveButton && !formReadonly && !isDisabled && !isLoading
1606
+ ? h('div', {
1607
+ class: 'vxe-upload--file-item-remove-btn',
1608
+ on: {
1609
+ click (evnt: MouseEvent) {
1610
+ $xeUpload.removeFileEvent(evnt, item, index)
1611
+ }
1612
+ }
1613
+ }, [
1614
+ h('i', {
1615
+ class: getIcon().UPLOAD_FILE_REMOVE
1616
+ })
1617
+ ])
1618
+ : renderEmptyElement($xeUpload)
1619
+ ])
1620
+ ])
1621
+ })
1622
+ },
1623
+ renderFileAction (h: CreateElement, isMoreView: boolean) {
1624
+ const $xeUpload = this
1625
+ const props = $xeUpload
1626
+ const slots = $xeUpload.$scopedSlots
1627
+ const reactData = $xeUpload.reactData
1628
+
1629
+ const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1630
+ const { fileList } = reactData
1631
+ const isDisabled = $xeUpload.computeIsDisabled
1632
+ const formReadonly = $xeUpload.computeFormReadonly
1633
+ const showTipText = $xeUpload.computedShowTipText
1634
+ const defTipText = $xeUpload.computedDefTipText
1635
+ const overCount = $xeUpload.computeOverCount
1636
+ const defaultSlot = slots.default
1637
+ const tipSlot = slots.tip || slots.hint
1638
+
1639
+ if (formReadonly || !showUploadButton) {
1640
+ return renderEmptyElement($xeUpload)
1641
+ }
1642
+ return h('div', {
1643
+ class: 'vxe-upload--file-action'
1644
+ }, [
1645
+ autoHiddenButton && overCount
1646
+ ? renderEmptyElement($xeUpload)
1647
+ : h('div', {
1648
+ class: 'vxe-upload--file-action-btn',
1649
+ on: {
1650
+ click: $xeUpload.clickEvent
1651
+ }
1652
+ }, defaultSlot
1653
+ ? getSlotVNs(defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload }))
1654
+ : [
1655
+ h(VxeButtonComponent, {
1656
+ class: 'vxe-upload--file-action-button',
1657
+ props: {
1658
+ content: (isMoreView || showButtonText) ? (buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.fileBtnText')) : '',
1659
+ icon: showButtonIcon ? (buttonIcon || getIcon().UPLOAD_FILE_ADD) : '',
1660
+ disabled: isDisabled
1661
+ }
1662
+ })
1663
+ ]),
1664
+ showTipText && (defTipText || tipSlot)
1665
+ ? h('div', {
1666
+ class: 'vxe-upload--file-action-tip'
1667
+ }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1668
+ : renderEmptyElement($xeUpload)
1669
+ ])
1670
+ },
1671
+ rendeFileMode (h: CreateElement) {
1672
+ const $xeUpload = this
1673
+ const props = $xeUpload
1674
+ const slots = $xeUpload.$scopedSlots
1675
+ const reactData = $xeUpload.reactData
1676
+
1677
+ const { showList, moreConfig, dragSort } = props
1678
+ const { fileList, isDragMove } = reactData
1679
+ const moreOpts = $xeUpload.computeMoreOpts
1680
+ const { maxCount, showMoreButton, layout, moreButtonText } = moreOpts
1681
+ const isHorizontal = layout === 'horizontal'
1682
+ const moreBtnSlot = slots.moreButton || slots['more-button']
1683
+
1684
+ let currList = fileList
1685
+ let overMaxNum = 0
1686
+ let isMoreMax = false
1687
+ let isMiniMore = false
1688
+ if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1689
+ isMoreMax = true
1690
+ isMiniMore = maxCount === 0
1691
+ overMaxNum = fileList.length - maxCount
1692
+ currList = fileList.slice(0, maxCount)
1693
+ }
1694
+
1695
+ return h('div', {
1696
+ key: 'all',
1697
+ class: 'vxe-upload--file-wrapper'
1698
+ }, showList
1699
+ ? [
1700
+ showMoreButton && moreConfig && isHorizontal
1701
+ ? renderEmptyElement($xeUpload)
1702
+ : $xeUpload.renderFileAction(h, true),
1703
+ h('div', {
1704
+ class: ['vxe-upload--file-list-wrapper', {
1705
+ 'is--horizontal': isHorizontal
1706
+ }]
1707
+ }, [
1708
+ currList.length
1709
+ ? (
1710
+ dragSort
1711
+ ? h('transition-group', {
1712
+ attrs: {
1713
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1714
+ tag: 'div'
1715
+ },
1716
+ class: 'vxe-upload--file-list'
1717
+ }, $xeUpload.renderFileItemList(h, currList, false))
1718
+ : h('div', {
1719
+ class: 'vxe-upload--file-list'
1720
+ }, $xeUpload.renderFileItemList(h, currList, false))
1721
+ )
1722
+ : renderEmptyElement($xeUpload),
1723
+ showMoreButton && overMaxNum
1724
+ ? h('div', {
1725
+ class: 'vxe-upload--file-over-more'
1726
+ }, moreBtnSlot
1727
+ ? getSlotVNs(moreBtnSlot({ options: fileList }))
1728
+ : [
1729
+ h(VxeButtonComponent, {
1730
+ props: {
1731
+ mode: 'text',
1732
+ content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreFileBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
1733
+ status: 'primary'
1734
+ },
1735
+ on: {
1736
+ click: $xeUpload.handleMoreEvent
1737
+ }
1738
+ })
1739
+ ])
1740
+ : renderEmptyElement($xeUpload),
1741
+ showMoreButton && moreConfig && isHorizontal
1742
+ ? $xeUpload.renderFileAction(h, false)
1743
+ : renderEmptyElement($xeUpload)
1744
+ ])
1745
+ ]
1746
+ : [
1747
+ $xeUpload.renderFileAction(h, false)
1748
+ ])
1749
+ },
1750
+ renderImageItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1751
+ const $xeUpload = this
1752
+ const props = $xeUpload
1753
+ const slots = $xeUpload.$scopedSlots
1754
+ const reactData = $xeUpload.reactData
1755
+
1756
+ const { showRemoveButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1757
+ const { fileList, fileCacheMaps } = reactData
1758
+ const isDisabled = $xeUpload.computeIsDisabled
1759
+ const formReadonly = $xeUpload.computeFormReadonly
1760
+ const imageOpts = $xeUpload.computeImageOpts
1761
+ const imgStyle = $xeUpload.computeImgStyle
1762
+ const optionSlot = slots.option
1763
+ const actionSlot = slots.action
1764
+ const cornerSlot = slots.corner
1765
+
1766
+ const ons: Record<string, any> = {}
1767
+ if (dragSort && currList.length > 1) {
1768
+ ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1769
+ ons.dragover = $xeUpload.handleDragSortDragoverEvent
1770
+ ons.dragend = $xeUpload.handleDragSortDragendEvent
1771
+ }
1772
+
1773
+ return currList.map((item, index) => {
1774
+ const fileKey = $xeUpload.getFieldKey(item)
1775
+ const cacheItem = fileCacheMaps[fileKey]
1776
+ let isLoading = false
1777
+ let isError = false
1778
+ let isPending = false
1779
+ if (cacheItem) {
1780
+ isLoading = cacheItem.loading
1781
+ isError = cacheItem.status === 'error'
1782
+ isPending = cacheItem.status === 'pending'
1783
+ }
1784
+ return h('div', {
1785
+ key: dragSort ? fileKey : index,
1786
+ class: ['vxe-upload--image-item', {
1787
+ 'is--preview': showPreview,
1788
+ 'is--circle': imageOpts.circle,
1789
+ 'is--loading': isLoading,
1790
+ 'is--pending': isPending,
1791
+ 'is--error': isError
1792
+ }],
1793
+ attrs: {
1794
+ fileid: fileKey,
1795
+ draggable: dragSort ? true : null
1796
+ },
1797
+ on: ons
1798
+ }, optionSlot
1799
+ ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1800
+ : [
1801
+ h('div', {
1802
+ class: 'vxe-upload--image-item-box',
1803
+ style: isMoreView ? {} : imgStyle,
1804
+ on: {
1805
+ click (evnt: MouseEvent) {
1806
+ if (!isLoading && !isError) {
1807
+ $xeUpload.handlePreviewImageEvent(evnt, item, index)
1808
+ }
1809
+ }
1810
+ }
1811
+ }, [
1812
+ isLoading && cacheItem
1813
+ ? h('div', {
1814
+ class: 'vxe-upload--image-item-loading'
1815
+ }, [
1816
+ h('div', {
1817
+ class: 'vxe-upload--image-item-loading-icon'
1818
+ }, [
1819
+ h('i', {
1820
+ class: getIcon().UPLOAD_LOADING
1821
+ })
1822
+ ]),
1823
+ showProgress
1824
+ ? h('div', {
1825
+ class: 'vxe-upload--image-item-loading-text'
1826
+ }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1827
+ : renderEmptyElement($xeUpload)
1828
+ ])
1829
+ : renderEmptyElement($xeUpload),
1830
+ h('div', {
1831
+ class: 'vxe-upload--image-item-img-wrapper',
1832
+ attrs: {
1833
+ title: getI18n('vxe.upload.viewItemTitle')
1834
+ }
1835
+ }, [
1836
+ h('img', {
1837
+ class: 'vxe-upload--image-item-img',
1838
+ attrs: {
1839
+ src: $xeUpload.getThumbnailFileUrl(item)
1840
+ }
1841
+ })
1842
+ ]),
1843
+ !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1844
+ ? h('div', {
1845
+ class: 'vxe-upload--image-item-rebtn'
1846
+ }, [
1847
+ h(VxeButtonComponent, {
1848
+ props: {
1849
+ icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1850
+ mode: 'text',
1851
+ status: 'primary',
1852
+ content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1853
+ },
1854
+ on: {
1855
+ click () {
1856
+ $xeUpload.handleReUpload(item)
1857
+ }
1858
+ }
1859
+ })
1860
+ ])
1861
+ : renderEmptyElement($xeUpload),
1862
+ h('div', {
1863
+ class: 'vxe-upload--image-item-btn-wrapper',
1864
+ on: {
1865
+ click (evnt: MouseEvent) {
1866
+ evnt.stopPropagation()
1867
+ }
1868
+ }
1869
+ }, actionSlot
1870
+ ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1871
+ : [
1872
+ cornerSlot
1873
+ ? h('div', {
1874
+ class: 'vxe-upload--file-item-action'
1875
+ }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1876
+ : renderEmptyElement($xeUpload),
1877
+ showRemoveButton && !formReadonly && !isDisabled && !isLoading
1878
+ ? h('div', {
1879
+ class: 'vxe-upload--image-item-remove-btn',
1880
+ on: {
1881
+ click (evnt: MouseEvent) {
1882
+ evnt.stopPropagation()
1883
+ $xeUpload.removeFileEvent(evnt, item, index)
1884
+ }
1885
+ }
1886
+ }, [
1887
+ h('i', {
1888
+ class: getIcon().UPLOAD_IMAGE_REMOVE
1889
+ })
1890
+ ])
1891
+ : renderEmptyElement($xeUpload)
1892
+ ])
1893
+ ])
1894
+ ])
1895
+ })
1896
+ },
1897
+ renderImageAction (h: CreateElement, isMoreView: boolean) {
1898
+ const $xeUpload = this
1899
+ const props = $xeUpload
1900
+ const slots = $xeUpload.$scopedSlots
1901
+ const reactData = $xeUpload.reactData
1902
+
1903
+ const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1904
+ const { fileList } = reactData
1905
+ const formReadonly = $xeUpload.computeFormReadonly
1906
+ const showTipText = $xeUpload.computedShowTipText
1907
+ const defTipText = $xeUpload.computedDefTipText
1908
+ const overCount = $xeUpload.computeOverCount
1909
+ const imgStyle = $xeUpload.computeImgStyle
1910
+ const defaultSlot = slots.default
1911
+ const tipSlot = slots.tip || slots.hint
1912
+
1913
+ if (formReadonly || !showUploadButton || (autoHiddenButton && overCount)) {
1914
+ return renderEmptyElement($xeUpload)
1915
+ }
1916
+ return h('div', {
1917
+ key: 'action',
1918
+ class: 'vxe-upload--image-action'
1919
+ }, [
1920
+ h('div', {
1921
+ class: 'vxe-upload--image-action-btn',
1922
+ on: {
1923
+ click: $xeUpload.clickEvent
1924
+ }
1925
+ }, defaultSlot
1926
+ ? defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload })
1927
+ : [
1928
+ h('div', {
1929
+ class: 'vxe-upload--image-action-box',
1930
+ style: isMoreView ? {} : imgStyle
1931
+ }, [
1932
+ showButtonIcon
1933
+ ? h('div', {
1934
+ class: 'vxe-upload--image-action-icon'
1935
+ }, [
1936
+ h('i', {
1937
+ class: buttonIcon || getIcon().UPLOAD_IMAGE_ADD
1938
+ })
1939
+ ])
1940
+ : renderEmptyElement($xeUpload),
1941
+ isMoreView || showButtonText
1942
+ ? h('div', {
1943
+ class: 'vxe-upload--image-action-content'
1944
+ }, buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.imgBtnText'))
1945
+ : renderEmptyElement($xeUpload),
1946
+ showTipText && (defTipText || tipSlot)
1947
+ ? h('div', {
1948
+ class: 'vxe-upload--image-action-hint'
1949
+ }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1950
+ : renderEmptyElement($xeUpload)
1951
+ ])
1952
+ ])
1953
+ ])
1954
+ },
1955
+ renderImageMode (h: CreateElement) {
1956
+ const $xeUpload = this
1957
+ const props = $xeUpload
1958
+ const slots = $xeUpload.$scopedSlots
1959
+ const reactData = $xeUpload.reactData
1960
+
1961
+ const { showList, dragSort } = props
1962
+ const { fileList, isDragMove } = reactData
1963
+ const moreOpts = $xeUpload.computeMoreOpts
1964
+ const moreBtnSlot = slots.moreButton || slots['more-button']
1965
+
1966
+ const { maxCount, showMoreButton, moreButtonText } = moreOpts
1967
+ let currList = fileList
1968
+ let overMaxNum = 0
1969
+ let isMoreMax = false
1970
+ let isMiniMore = false
1971
+ if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1972
+ isMoreMax = true
1973
+ isMiniMore = maxCount === 0
1974
+ overMaxNum = fileList.length - maxCount
1975
+ currList = fileList.slice(0, maxCount)
1976
+ }
1977
+
1978
+ return h('div', {
1979
+ key: 'image',
1980
+ class: 'vxe-upload--image-wrapper'
1981
+ }, showList
1982
+ ? [
1983
+ dragSort
1984
+ ? h('transition-group', {
1985
+ attrs: {
1986
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1987
+ tag: 'div'
1988
+ },
1989
+ class: 'vxe-upload--image-list'
1990
+ }, $xeUpload.renderImageItemList(h, currList, false).concat([
1991
+ showMoreButton && overMaxNum
1992
+ ? h('div', {
1993
+ key: 'om',
1994
+ class: 'vxe-upload--image-over-more'
1995
+ }, moreBtnSlot
1996
+ ? getSlotVNs(moreBtnSlot({ options: fileList }))
1997
+ : [
1998
+ h(VxeButtonComponent, {
1999
+ props: {
2000
+ mode: 'text',
2001
+ content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2002
+ status: 'primary'
2003
+ },
2004
+ on: {
2005
+ click: $xeUpload.handleMoreEvent
2006
+ }
2007
+ })
2008
+ ])
2009
+ : renderEmptyElement($xeUpload),
2010
+ $xeUpload.renderImageAction(h, false)
2011
+ ]))
2012
+ : h('div', {
2013
+ class: 'vxe-upload--image-list'
2014
+ }, $xeUpload.renderImageItemList(h, currList, false).concat([
2015
+ showMoreButton && overMaxNum
2016
+ ? h('div', {
2017
+ class: 'vxe-upload--image-over-more'
2018
+ }, moreBtnSlot
2019
+ ? getSlotVNs(moreBtnSlot({ options: fileList }))
2020
+ : [
2021
+ h(VxeButtonComponent, {
2022
+ props: {
2023
+ mode: 'text',
2024
+ content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2025
+ status: 'primary'
2026
+ },
2027
+ on: {
2028
+ click: $xeUpload.handleMoreEvent
2029
+ }
2030
+ })
2031
+ ])
2032
+ : renderEmptyElement($xeUpload),
2033
+ $xeUpload.renderImageAction(h, false)
2034
+ ]))
2035
+ ]
2036
+ : [
2037
+ h('div', {
2038
+ class: 'vxe-upload--image-list'
2039
+ }, [
2040
+ $xeUpload.renderImageAction(h, false)
2041
+ ])
2042
+ ])
2043
+ },
2044
+ renderVN (h: CreateElement): VNode {
2045
+ const $xeUpload = this
2046
+ const props = $xeUpload
2047
+ const reactData = $xeUpload.reactData
2048
+
2049
+ const { showErrorStatus, dragToUpload, pasteToUpload, dragSort, dragPlaceholder } = props
2050
+ const { isDragUploadStatus, showMorePopup, isActivated, dragIndex } = reactData
2051
+ const vSize = $xeUpload.computeSize
2052
+ const isDisabled = $xeUpload.computeIsDisabled
2053
+ const formReadonly = $xeUpload.computeFormReadonly
2054
+ const isImage = $xeUpload.computeIsImage
2055
+
2056
+ const ons: Record<string, any> = {}
2057
+ if (dragToUpload && dragIndex === -1) {
2058
+ ons.dragover = $xeUpload.handleUploadDragoverEvent
2059
+ ons.dragleave = $xeUpload.handleUploadDragleaveEvent
2060
+ ons.drop = $xeUpload.handleUploadDropEvent
2061
+ }
2062
+
2063
+ return h('div', {
2064
+ ref: 'refElem',
2065
+ class: ['vxe-upload', {
2066
+ [`size--${vSize}`]: vSize,
2067
+ 'is--active': isActivated,
2068
+ 'is--readonly': formReadonly,
2069
+ 'is--disabled': isDisabled,
2070
+ 'is--paste': pasteToUpload,
2071
+ 'show--error': showErrorStatus,
2072
+ 'is--drag': isDragUploadStatus
2073
+ }],
2074
+ on: ons
2075
+ }, [
2076
+ isImage ? $xeUpload.renderImageMode(h) : $xeUpload.rendeFileMode(h),
2077
+ dragSort
2078
+ ? h('div', {
2079
+ ref: 'refDragLineElem',
2080
+ class: 'vxe-upload--drag-line'
2081
+ })
2082
+ : renderEmptyElement($xeUpload),
2083
+ isDragUploadStatus && !showMorePopup
2084
+ ? h('div', {
2085
+ class: 'vxe-upload--drag-placeholder'
2086
+ }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
2087
+ : renderEmptyElement($xeUpload)
2088
+ ])
2089
+ }
2090
+ },
2091
+ created () {
2092
+ const $xeUpload = this
2093
+
2094
+ $xeUpload.updateFileList()
2095
+ },
2096
+ mounted () {
2097
+ const $xeUpload = this
2098
+ const props = $xeUpload
2099
+
2100
+ if (props.multiple && props.singleMode) {
2101
+ errLog('vxe.error.errConflicts', ['[upload] multiple', 'single-mode'])
2102
+ }
2103
+ if (props.imageStyle) {
2104
+ warnLog('vxe.error.delProp', ['[upload] image-style', 'image-config'])
2105
+ }
2106
+
2107
+ if (props.dragSort) {
2108
+ initTpImg()
2109
+ }
2110
+ globalEvents.on($xeUpload, 'paste', $xeUpload.handleGlobalPasteEvent)
2111
+ globalEvents.on($xeUpload, 'click', $xeUpload.handleGlobalClickEvent)
2112
+ globalEvents.on($xeUpload, 'blur', $xeUpload.handleGlobalBlurEvent)
2113
+ },
2114
+ beforeDestroy () {
2115
+ const $xeUpload = this
2116
+ const reactData = $xeUpload.reactData
2117
+ const internalData = $xeUpload.internalData
2118
+
2119
+ reactData.isDragUploadStatus = false
2120
+ globalEvents.off($xeUpload, 'paste')
2121
+ globalEvents.off($xeUpload, 'click')
2122
+ globalEvents.off($xeUpload, 'blur')
2123
+ XEUtils.assign(reactData, createReactData())
2124
+ XEUtils.assign(internalData, createInternalData())
2125
+ },
2126
+ render (this: any, h) {
2127
+ return this.renderVN(h)
2128
+ }
2129
+ }) /* define-vxe-component end */