hy-app 0.5.9 → 0.5.11

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 (290) hide show
  1. package/components/hy-action-sheet/hy-action-sheet.vue +200 -200
  2. package/components/hy-action-sheet/props.ts +71 -71
  3. package/components/hy-action-sheet/typing.d.ts +64 -64
  4. package/components/hy-address-picker/hy-address-picker.vue +1 -1
  5. package/components/hy-address-picker/props.ts +100 -100
  6. package/components/hy-address-picker/typing.d.ts +16 -16
  7. package/components/hy-avatar/hy-avatar.vue +163 -163
  8. package/components/hy-avatar/props.ts +78 -78
  9. package/components/hy-avatar/typing.d.ts +4 -4
  10. package/components/hy-back-top/hy-back-top.vue +90 -90
  11. package/components/hy-back-top/props.ts +60 -60
  12. package/components/hy-back-top/typing.d.ts +4 -4
  13. package/components/hy-badge/hy-badge.vue +97 -97
  14. package/components/hy-badge/props.ts +82 -82
  15. package/components/hy-badge/typing.d.ts +9 -9
  16. package/components/hy-button/hy-button.vue +275 -275
  17. package/components/hy-button/props.ts +135 -135
  18. package/components/hy-button/typing.d.ts +30 -30
  19. package/components/hy-calendar/header.vue +60 -60
  20. package/components/hy-calendar/hy-calendar.vue +362 -362
  21. package/components/hy-calendar/month.vue +537 -537
  22. package/components/hy-calendar/props.ts +159 -159
  23. package/components/hy-calendar/typing.d.ts +6 -6
  24. package/components/hy-card/hy-card.vue +161 -161
  25. package/components/hy-card/props.ts +122 -122
  26. package/components/hy-card/typing.d.ts +12 -12
  27. package/components/hy-cell/hy-cell.vue +33 -33
  28. package/components/hy-cell/props.ts +54 -54
  29. package/components/hy-cell/typing.d.ts +4 -4
  30. package/components/hy-cell-item/hy-cell-item.vue +161 -161
  31. package/components/hy-cell-item/props.ts +66 -66
  32. package/components/hy-cell-item/typing.d.ts +7 -7
  33. package/components/hy-check-button/hy-check-button.vue +96 -96
  34. package/components/hy-check-button/props.ts +74 -74
  35. package/components/hy-check-button/typing.d.ts +44 -44
  36. package/components/hy-checkbox/hy-checkbox.vue +227 -227
  37. package/components/hy-checkbox/props.ts +96 -96
  38. package/components/hy-checkbox/typing.d.ts +8 -8
  39. package/components/hy-checkbox-group/hy-checkbox-group.vue +45 -45
  40. package/components/hy-checkbox-group/props.ts +80 -80
  41. package/components/hy-checkbox-group/typing.d.ts +6 -6
  42. package/components/hy-checkbox-item/hy-checkbox-item.vue +199 -199
  43. package/components/hy-checkbox-item/props.ts +24 -24
  44. package/components/hy-checkbox-item/typing.d.ts +7 -7
  45. package/components/hy-code-input/hy-code-input.vue +231 -231
  46. package/components/hy-code-input/props.ts +88 -88
  47. package/components/hy-code-input/typing.d.ts +8 -8
  48. package/components/hy-config-provider/hy-config-provider.vue +53 -53
  49. package/components/hy-config-provider/props.ts +28 -28
  50. package/components/hy-count-down/hy-count-down.vue +170 -170
  51. package/components/hy-count-down/index.ts +52 -52
  52. package/components/hy-count-down/props.ts +32 -32
  53. package/components/hy-count-down/typing.d.ts +14 -14
  54. package/components/hy-count-to/hy-count-to.vue +218 -218
  55. package/components/hy-count-to/props.ts +62 -62
  56. package/components/hy-count-to/typing.d.ts +4 -4
  57. package/components/hy-coupon/hy-coupon.vue +172 -172
  58. package/components/hy-coupon/index.scss +171 -171
  59. package/components/hy-coupon/props.ts +103 -103
  60. package/components/hy-coupon/typing.d.ts +14 -14
  61. package/components/hy-datetime-picker/hy-datetime-picker.vue +521 -521
  62. package/components/hy-datetime-picker/props.ts +142 -142
  63. package/components/hy-datetime-picker/typing.d.ts +20 -20
  64. package/components/hy-divider/hy-divider.vue +132 -132
  65. package/components/hy-divider/props.ts +80 -80
  66. package/components/hy-dropdown/hy-dropdown.vue +60 -60
  67. package/components/hy-dropdown/props.ts +40 -40
  68. package/components/hy-dropdown-item/hy-dropdown-item.vue +206 -206
  69. package/components/hy-dropdown-item/props.ts +21 -21
  70. package/components/hy-dropdown-item/typing.d.ts +17 -17
  71. package/components/hy-empty/hy-empty.vue +116 -116
  72. package/components/hy-empty/icon.ts +72 -72
  73. package/components/hy-empty/props.ts +60 -60
  74. package/components/hy-empty/typing.d.ts +38 -38
  75. package/components/hy-flex/hy-flex.vue +53 -53
  76. package/components/hy-flex/index.scss +8 -8
  77. package/components/hy-flex/props.ts +58 -58
  78. package/components/hy-flex/typing.d.ts +21 -21
  79. package/components/hy-float-button/hy-float-button.vue +378 -378
  80. package/components/hy-float-button/props.ts +111 -111
  81. package/components/hy-float-button/typing.d.ts +35 -35
  82. package/components/hy-folding-panel/hy-folding-panel.vue +109 -109
  83. package/components/hy-folding-panel/props.ts +42 -42
  84. package/components/hy-folding-panel/typing.d.ts +19 -19
  85. package/components/hy-folding-panel-item/hy-folding-panel-item.vue +183 -183
  86. package/components/hy-folding-panel-item/props.ts +81 -81
  87. package/components/hy-folding-panel-item/typing.d.ts +37 -37
  88. package/components/hy-form/hy-form.vue +220 -220
  89. package/components/hy-form/props.ts +37 -37
  90. package/components/hy-form/typing.d.ts +41 -41
  91. package/components/hy-form-group/hy-form-group.vue +333 -333
  92. package/components/hy-form-group/props.ts +105 -105
  93. package/components/hy-form-item/hy-form-item.vue +176 -176
  94. package/components/hy-form-item/index.scss +0 -1
  95. package/components/hy-form-item/props.ts +25 -25
  96. package/components/hy-form-item/typing.d.ts +30 -30
  97. package/components/hy-grid/hy-grid.vue +109 -109
  98. package/components/hy-grid/props.ts +60 -60
  99. package/components/hy-grid/typing.d.ts +35 -35
  100. package/components/hy-icon/hy-icon.vue +112 -112
  101. package/components/hy-icon/index.scss +0 -3
  102. package/components/hy-icon/props.ts +79 -79
  103. package/components/hy-icon/typing.d.ts +9 -9
  104. package/components/hy-image/hy-image.vue +192 -192
  105. package/components/hy-image/props.ts +107 -107
  106. package/components/hy-image/typing.d.ts +10 -10
  107. package/components/hy-input/hy-input.vue +333 -333
  108. package/components/hy-input/index.scss +5 -0
  109. package/components/hy-input/props.ts +186 -186
  110. package/components/hy-input/typing.d.ts +31 -31
  111. package/components/hy-line/hy-line.vue +55 -55
  112. package/components/hy-line/props.ts +43 -43
  113. package/components/hy-line-progress/hy-line-progress.vue +102 -102
  114. package/components/hy-line-progress/index.scss +1 -0
  115. package/components/hy-line-progress/props.ts +33 -33
  116. package/components/hy-list/hy-list.vue +226 -226
  117. package/components/hy-list/props.ts +69 -69
  118. package/components/hy-list/typing.d.ts +6 -6
  119. package/components/hy-loading/hy-loading.vue +107 -107
  120. package/components/hy-loading/props.ts +65 -65
  121. package/components/hy-menu/hy-menu.vue +159 -159
  122. package/components/hy-menu/props.ts +44 -44
  123. package/components/hy-menu/typing.d.ts +34 -34
  124. package/components/hy-modal/hy-modal.vue +173 -173
  125. package/components/hy-modal/props.ts +90 -90
  126. package/components/hy-modal/typing.d.ts +11 -11
  127. package/components/hy-navbar/hy-navbar.vue +144 -144
  128. package/components/hy-navbar/props.ts +78 -78
  129. package/components/hy-navbar/typing.d.ts +6 -6
  130. package/components/hy-notice-bar/hy-column-notice.vue +94 -94
  131. package/components/hy-notice-bar/hy-notice-bar.vue +96 -96
  132. package/components/hy-notice-bar/hy-row-notice.vue +121 -121
  133. package/components/hy-notice-bar/props.ts +85 -85
  134. package/components/hy-notice-bar/typing.d.ts +8 -8
  135. package/components/hy-notify/hy-notify.vue +174 -174
  136. package/components/hy-notify/props.ts +51 -51
  137. package/components/hy-number-step/hy-number-step.vue +367 -367
  138. package/components/hy-number-step/props.ts +112 -112
  139. package/components/hy-number-step/typing.d.ts +16 -16
  140. package/components/hy-overlay/hy-overlay.vue +60 -60
  141. package/components/hy-overlay/props.ts +33 -33
  142. package/components/hy-overlay/typing.d.ts +4 -4
  143. package/components/hy-pagination/hy-pagination.vue +135 -135
  144. package/components/hy-pagination/props.ts +55 -55
  145. package/components/hy-pagination/typing.d.ts +10 -10
  146. package/components/hy-picker/hy-picker.vue +7 -5
  147. package/components/hy-picker/props.ts +7 -2
  148. package/components/hy-picker/typing.d.ts +9 -5
  149. package/components/hy-popover/hy-popover.vue +251 -251
  150. package/components/hy-popover/props.ts +51 -51
  151. package/components/hy-popover/typing.d.ts +39 -39
  152. package/components/hy-popup/hy-popup.vue +197 -197
  153. package/components/hy-popup/props.ts +85 -85
  154. package/components/hy-popup/typing.d.ts +10 -10
  155. package/components/hy-price/hy-price.vue +79 -79
  156. package/components/hy-price/props.ts +54 -54
  157. package/components/hy-price/typing.d.ts +4 -4
  158. package/components/hy-qrcode/hy-qrcode.vue +216 -216
  159. package/components/hy-qrcode/props.ts +70 -70
  160. package/components/hy-qrcode/qrcode.js +1304 -1304
  161. package/components/hy-qrcode/typing.d.ts +8 -8
  162. package/components/hy-radio/hy-radio.vue +226 -226
  163. package/components/hy-radio/props.ts +1 -1
  164. package/components/hy-radio/typing.d.ts +8 -8
  165. package/components/hy-rate/hy-rate.vue +239 -239
  166. package/components/hy-rate/props.ts +77 -77
  167. package/components/hy-rate/typing.d.ts +6 -6
  168. package/components/hy-read-more/hy-read-more.vue +130 -130
  169. package/components/hy-read-more/props.ts +45 -45
  170. package/components/hy-read-more/typing.d.ts +6 -6
  171. package/components/hy-rolling-num/hy-rolling-num.vue +188 -188
  172. package/components/hy-rolling-num/props.ts +68 -68
  173. package/components/hy-scroll-list/hy-scroll-list.vue +123 -123
  174. package/components/hy-scroll-list/props.ts +22 -22
  175. package/components/hy-scroll-list/typing.d.ts +6 -6
  176. package/components/hy-search/hy-search.vue +221 -221
  177. package/components/hy-search/props.ts +131 -131
  178. package/components/hy-search/typing.d.ts +22 -22
  179. package/components/hy-signature/hy-signature.vue +640 -640
  180. package/components/hy-signature/props.ts +118 -118
  181. package/components/hy-signature/typing.d.ts +93 -93
  182. package/components/hy-slider/hy-slider.vue +444 -444
  183. package/components/hy-slider/props.ts +77 -77
  184. package/components/hy-slider/typing.d.ts +10 -10
  185. package/components/hy-status-bar/hy-status-bar.vue +41 -41
  186. package/components/hy-status-bar/props.ts +8 -8
  187. package/components/hy-status-bar/typing.d.ts +12 -12
  188. package/components/hy-steps/hy-steps.vue +267 -267
  189. package/components/hy-steps/props.ts +49 -49
  190. package/components/hy-steps/typing.d.ts +21 -21
  191. package/components/hy-sticky/hy-sticky.vue +226 -226
  192. package/components/hy-sticky/props.ts +24 -24
  193. package/components/hy-sticky/typing.d.ts +4 -4
  194. package/components/hy-submit-bar/hy-submit-bar.vue +189 -189
  195. package/components/hy-submit-bar/props.ts +91 -91
  196. package/components/hy-submit-bar/typing.d.ts +24 -24
  197. package/components/hy-subsection/hy-subsection.vue +207 -207
  198. package/components/hy-subsection/props.ts +52 -52
  199. package/components/hy-subsection/typing.d.ts +13 -13
  200. package/components/hy-swipe-action/hy-swipe-action.vue +323 -323
  201. package/components/hy-swipe-action/index.ts +25 -25
  202. package/components/hy-swipe-action/props.ts +47 -47
  203. package/components/hy-swipe-action/typing.d.ts +25 -25
  204. package/components/hy-swiper/hy-swiper-indicator.vue +75 -75
  205. package/components/hy-swiper/hy-swiper.vue +224 -224
  206. package/components/hy-swiper/props.ts +128 -128
  207. package/components/hy-swiper/typing.d.ts +26 -26
  208. package/components/hy-switch/hy-switch.vue +173 -173
  209. package/components/hy-switch/props.ts +61 -61
  210. package/components/hy-switch/typing.d.ts +8 -8
  211. package/components/hy-tabbar/hy-tabbar.vue +136 -136
  212. package/components/hy-tabbar/props.ts +59 -59
  213. package/components/hy-tabbar/typing.d.ts +21 -21
  214. package/components/hy-tabbar-group/hy-tabbar-group.vue +87 -87
  215. package/components/hy-tabbar-group/props.ts +78 -78
  216. package/components/hy-tabbar-group/typing.d.ts +16 -16
  217. package/components/hy-tabbar-item/hy-tabbar-item.vue +103 -103
  218. package/components/hy-tabbar-item/typing.d.ts +10 -10
  219. package/components/hy-table/hy-table.vue +358 -358
  220. package/components/hy-table/props.ts +47 -47
  221. package/components/hy-table/typing.d.ts +34 -34
  222. package/components/hy-tabs/hy-tabs.vue +335 -335
  223. package/components/hy-tabs/props.ts +77 -77
  224. package/components/hy-tabs/typing.d.ts +33 -33
  225. package/components/hy-tag/hy-tag.vue +174 -174
  226. package/components/hy-tag/props.ts +89 -89
  227. package/components/hy-tag/typing.d.ts +13 -13
  228. package/components/hy-text/hy-text.vue +237 -237
  229. package/components/hy-text/props.ts +115 -115
  230. package/components/hy-text/typing.d.ts +6 -6
  231. package/components/hy-textarea/hy-textarea.vue +197 -197
  232. package/components/hy-textarea/index.scss +5 -0
  233. package/components/hy-textarea/props.ts +116 -116
  234. package/components/hy-textarea/typing.d.ts +22 -22
  235. package/components/hy-toast/hy-toast.vue +190 -190
  236. package/components/hy-toast/typing.d.ts +38 -38
  237. package/components/hy-tooltip/hy-tooltip.vue +277 -277
  238. package/components/hy-tooltip/props.ts +78 -78
  239. package/components/hy-tooltip/typing.d.ts +4 -4
  240. package/components/hy-transition/hy-transition.vue +157 -157
  241. package/components/hy-transition/props.ts +32 -32
  242. package/components/hy-transition/typing.d.ts +16 -16
  243. package/components/hy-upload/hy-upload.vue +385 -385
  244. package/components/hy-upload/props.ts +132 -132
  245. package/components/hy-upload/typing.d.ts +65 -65
  246. package/components/hy-warn/hy-warn.vue +115 -115
  247. package/components/hy-warn/props.ts +49 -49
  248. package/components/hy-warn/typing.d.ts +6 -6
  249. package/components/hy-waterfall/hy-waterfall.vue +191 -191
  250. package/components/hy-waterfall/props.ts +21 -21
  251. package/components/hy-watermark/hy-watermark.vue +978 -978
  252. package/components/hy-watermark/props.ts +104 -104
  253. package/components/index.ts +183 -183
  254. package/global.d.ts +91 -91
  255. package/index.ts +1 -1
  256. package/libs/api/http.ts +140 -140
  257. package/libs/api/index.ts +1 -1
  258. package/libs/common/index.ts +2 -2
  259. package/libs/common/queue.ts +28 -28
  260. package/libs/composables/index.ts +6 -6
  261. package/libs/composables/usePopover.ts +241 -241
  262. package/libs/composables/useQueue.ts +53 -53
  263. package/libs/composables/useShakeService.ts +64 -64
  264. package/libs/composables/useShare.ts +42 -42
  265. package/libs/composables/useToast.ts +45 -45
  266. package/libs/composables/useTouch.ts +51 -51
  267. package/libs/config/color.ts +7 -7
  268. package/libs/config/icon.ts +430 -430
  269. package/libs/config/index.ts +2 -2
  270. package/libs/css/iconfont.css +443 -443
  271. package/libs/css/theme.scss +1 -1
  272. package/libs/global/index.ts +6 -6
  273. package/libs/global/register-properties.ts +37 -37
  274. package/libs/index.ts +7 -7
  275. package/libs/typing/index.ts +4 -4
  276. package/libs/typing/modules/common.d.ts +139 -139
  277. package/libs/typing/modules/enum.ts +67 -67
  278. package/libs/typing/modules/form.ts +5 -1
  279. package/libs/typing/modules/http.ts +17 -17
  280. package/libs/typing/modules/icon.d.ts +366 -366
  281. package/libs/typing/modules/rect.ts +10 -10
  282. package/libs/utils/base64.ts +119 -119
  283. package/libs/utils/calendar.js +1021 -1021
  284. package/libs/utils/colorGradient.ts +112 -112
  285. package/libs/utils/index.ts +5 -5
  286. package/libs/utils/inside.ts +350 -361
  287. package/libs/utils/inspect.ts +171 -171
  288. package/libs/utils/utils.ts +521 -521
  289. package/package.json +18 -18
  290. package/web-types.json +1 -1
@@ -1,521 +1,521 @@
1
- import Base64 from "./base64";
2
- import type { CSSProperties } from "vue";
3
- import { error, isNumber } from "./index";
4
- let base64: any = new Base64();
5
-
6
- /**
7
- * 加密函数
8
- * @param {any} data 对象
9
- * @return { string } 加密字符串
10
- * */
11
- function encryptData(data: Record<string, any> | string): string {
12
- return base64.encode(JSON.stringify(data));
13
- }
14
-
15
- /**
16
- * 解密函数
17
- * @param {string} encryptedVal 加密字符串
18
- * @returns { any | any[] } 解码的数据
19
- * */
20
- function decryptData(encryptedVal: string): Record<string, any> {
21
- return JSON.parse(base64.decode(encryptedVal.toString()));
22
- }
23
-
24
- /**
25
- *用于解密使用 AES 加密算法加密的数据
26
- */
27
-
28
- // const decrypt = (sessionKey: string, encryptedData: string, iv: string) => {
29
- // console.log(CryptoJS)
30
- // let key = CryptoJS.enc.Base64.parse(sessionKey)
31
- // let ivv = CryptoJS.enc.Base64.parse(iv)
32
- // let decrypt = CryptoJS.AES.decrypt(encryptedData, key, {
33
- // iv: ivv,
34
- // mode: CryptoJS.mode.CBC,
35
- // padding: CryptoJS.pad.Pkcs7
36
- // })
37
- // return JSON.parse(base64.decode(CryptoJS.enc.Base64.stringify(decrypt)))
38
- // }
39
-
40
- /**
41
- * @description 添加单位,如果有rpx,upx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾
42
- * @param {String|Number} value 需要添加单位的值
43
- * @param {String} unit 添加的单位名 比如px
44
- * @returns {String}
45
- */
46
- const addUnit = (
47
- value: string | number = "auto",
48
- unit: string = "",
49
- ): string => {
50
- if (!unit) {
51
- unit = "px";
52
- }
53
- if (unit == "rpx" && isNumber(String(value))) {
54
- value = Number(value) * 2;
55
- }
56
- value = String(value);
57
- // 用内置验证规则中的number判断是否为数值
58
- return isNumber(value) ? `${value}${unit}` : value;
59
- };
60
-
61
- /**
62
- * @description 日期的月或日补零操作
63
- * @param {String | Number} value 需要补零的值
64
- * @returns {String}
65
- */
66
- const padZero = (value: string | number): string => {
67
- return `00${value}`.slice(-2);
68
- };
69
-
70
- /**
71
- * @description 后面补零
72
- * @param {String | Number} value 需要补零的值
73
- * @param {Number} length 多少位
74
- * @returns {String}
75
- */
76
- const addZero = (value: string | number, length: number): string => {
77
- if (value === undefined || value === null) return "";
78
- let val = value.toString();
79
- if (length > val.length) {
80
- val += "0".repeat(length - val.length);
81
- } else {
82
- val = val.slice(0, length);
83
- }
84
- return val;
85
- };
86
-
87
- /**
88
- * @description 清空对象里面的值
89
- * @param val 任意类型的值
90
- * */
91
- const clearVal = (val: any) => {
92
- const type = typeof val;
93
- const isArray = val instanceof Array;
94
- switch (type) {
95
- case "string":
96
- return "";
97
- case "number":
98
- return 0;
99
- case "boolean":
100
- return false;
101
- case "undefined":
102
- return null;
103
- case "object":
104
- if (!val) return null;
105
- if (isArray) {
106
- val.map((item) => {
107
- clearVal(item);
108
- });
109
- return val;
110
- } else {
111
- Object.keys(val).map((k) => {
112
- val[k] = clearVal(val[k]);
113
- });
114
- return val;
115
- }
116
- default:
117
- return "";
118
- }
119
- };
120
-
121
- /**
122
- * 时间戳格式化
123
- * @param timestamp 时间戳或者时间格式,例:1702051200000、Sat Apr 06 2024 11:35:56 GMT+0800 (中国标准时间)
124
- * @param fmt 例:yyyy-MM-dd HH:mm:ss / yyyy-MM-dd
125
- * @return date 例:2023-12-09
126
- */
127
- const formatTime = (
128
- timestamp: number | string,
129
- fmt: string = "yyyy-MM-dd HH:mm:ss",
130
- ): string => {
131
- let date: any;
132
- if (timestamp) {
133
- date = new Date(timestamp) ? new Date(timestamp) : timestamp;
134
- let ret;
135
- const opt: any = {
136
- "y+": date.getFullYear().toString(), //年
137
- "M+": (date.getMonth() + 1).toString(), //月
138
- "d+": date.getDate().toString(), //日
139
- "H+": date.getHours().toString(), //时
140
- "m+": date.getMinutes().toString(), //分
141
- "s+": date.getSeconds().toString(), //秒
142
- //如果有其他格式字符需求可以继续添加,必须转化为字符串
143
- };
144
- for (let k in opt) {
145
- ret = new RegExp("(" + k + ")").exec(fmt);
146
- if (ret) {
147
- fmt = fmt.replace(
148
- ret[1],
149
- ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0"),
150
- );
151
- }
152
- }
153
- return fmt;
154
- }
155
- return date;
156
- };
157
-
158
- /**
159
- * @description 时间戳或年月日格式转为多久之前
160
- * @param {String|Number} timestamp 时间戳/年月日格式
161
- * @param {String|Boolean} format
162
- * 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式;
163
- * 如果为布尔值false,无论什么时间,都返回多久以前的格式
164
- * @returns {string} 转化后的内容
165
- */
166
- const formatTimeToString = (
167
- timestamp: string | number,
168
- format: string | boolean = "yyyy-mm-dd",
169
- ): string => {
170
- const now = new Date();
171
- const oneYear = new Date(now.getFullYear(), 0, 1).getTime(); // 当年一月一号时间戳
172
-
173
- if (timestamp == null) timestamp = Number(now);
174
- timestamp =
175
- typeof timestamp === "string"
176
- ? parseInt(timestamp)
177
- : new Date(timestamp).getTime();
178
- // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
179
- if (timestamp.toString().length == 10) timestamp *= 1000;
180
- let timer = now.getTime() - timestamp;
181
- timer = parseInt(String(timer / 1000));
182
- // 如果小于5分钟,则返回"刚刚",其他以此类推
183
- let tips = "";
184
- switch (true) {
185
- case timer < 300:
186
- tips = "刚刚";
187
- break;
188
- case timer >= 300 && timer < 3600:
189
- tips = `${parseInt(String(timer / 60))}分钟前`;
190
- break;
191
- case timer >= 3600 && timer < 86400:
192
- tips = `${parseInt(String(timer / 3600))}小时前`;
193
- break;
194
- case timer >= 86400 && timer < 2592000:
195
- tips = `${parseInt(String(timer / 86400))}天前`;
196
- break;
197
- default:
198
- // 如果format为false,则无论什么时间戳,都显示xx之前
199
- if (format === false) {
200
- if (timer >= 2592000 && timer < 365 * 86400) {
201
- tips = `${parseInt(String(timer / (86400 * 30)))}个月前`;
202
- } else {
203
- tips = `${parseInt(String(timer / (86400 * 365)))}年前`;
204
- }
205
- } else {
206
- if (timestamp > oneYear) {
207
- formatTime(timestamp, "MM-dd");
208
- } else {
209
- tips =
210
- format === true
211
- ? formatTime(timestamp, "yyyy-MM-dd")
212
- : formatTime(timestamp, format);
213
- }
214
- }
215
- }
216
- return tips;
217
- };
218
-
219
- /**
220
- * @description 本地图片转base64方法(兼容APP、H5、小程序)
221
- * @param {string} path 图片本地路径
222
- * @returns Promise对象
223
- */
224
- const imageToBase64 = (path: string) => {
225
- return new Promise((resolve, reject) => {
226
- // #ifdef APP-PLUS
227
- plus.io.resolveLocalFileSystemURL(path, (entry: any) => {
228
- entry.file((file: any) => {
229
- let fileReader = new plus.io.FileReader();
230
- fileReader.readAsDataURL(file);
231
- fileReader.onloadend = (evt: any) => {
232
- let base64 = evt.target.result.split(",")[1];
233
- resolve(base64);
234
- };
235
- });
236
- });
237
- // #endif
238
- // #ifdef H5
239
- uni.request({
240
- url: path,
241
- responseType: "arraybuffer",
242
- success: (res: UniApp.RequestSuccessCallbackResult) => {
243
- resolve(uni.arrayBufferToBase64(res.data as ArrayBuffer));
244
- },
245
- });
246
- // #endif
247
- // #ifdef MP-WEIXIN
248
- uni.getFileSystemManager().readFile({
249
- filePath: path,
250
- encoding: "base64",
251
- success: (res) => {
252
- resolve(res.data);
253
- },
254
- });
255
- // #endif
256
- });
257
- };
258
-
259
- /**
260
- * 函数防抖:一段实现执行多次,只执行最后一次
261
- * @param {void} fn 回调函数
262
- * @param {number} wait 节流时间
263
- * @returns {void}
264
- * @constructor
265
- */
266
- let timeout: ReturnType<typeof setTimeout> | null = null;
267
- function debounce<T extends (...args: any[]) => void>(
268
- fn: T,
269
- wait: number = 500,
270
- immediate: boolean = false,
271
- ) {
272
- // 清除定时器
273
- if (timeout !== null) clearTimeout(timeout);
274
- // 立即执行,此类情况一般用不到
275
- if (immediate) {
276
- const callNow = !timeout;
277
- timeout = setTimeout(() => {
278
- timeout = null;
279
- }, wait);
280
- if (callNow) typeof fn === "function" && fn();
281
- } else {
282
- // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
283
- timeout = setTimeout(() => {
284
- typeof fn === "function" && fn();
285
- }, wait);
286
- }
287
- }
288
-
289
- let timer: ReturnType<typeof setTimeout> | null = null;
290
- let flag: boolean | undefined;
291
- /**
292
- * 函数节流: 一段时间执行一次
293
- * @param {void} fn 回调函数
294
- * @param {number} wait 节流等待时间
295
- * @param {boolean} immediate 是否立马执行
296
- * @returns {void}
297
- * @constructor
298
- */
299
- const throttle = (
300
- fn: Function,
301
- wait: number = 500,
302
- immediate: boolean = true,
303
- ): void => {
304
- if (immediate) {
305
- if (!flag) {
306
- flag = true;
307
- // 如果是立即执行,则在wait毫秒内开始时执行
308
- typeof fn === "function" && fn();
309
- timer = setTimeout(() => {
310
- flag = false;
311
- }, wait);
312
- }
313
- } else if (!flag) {
314
- flag = true;
315
- // 如果是非立即执行,则在wait毫秒内的结束处执行
316
- timer = setTimeout(() => {
317
- flag = false;
318
- typeof fn === "function" && fn();
319
- }, wait);
320
- }
321
- };
322
-
323
- /**
324
- * 递归拷贝对象
325
- * @param {object} source 对象或数组
326
- * @returns 深拷贝的数组和对象
327
- * */
328
- const deepClone = (source: any) => {
329
- if (!source && typeof source !== "object") {
330
- throw new Error("该值不存在或者不是个对象");
331
- }
332
- const targetObj: any = source.constructor === Array ? [] : {};
333
- Object.keys(source).forEach((keys) => {
334
- if (source[keys] && typeof source[keys] === "object") {
335
- targetObj[keys] = deepClone(source[keys]);
336
- } else {
337
- targetObj[keys] = source[keys];
338
- }
339
- });
340
- return targetObj;
341
- };
342
-
343
- /**
344
- * 字节转化(b/KB/MB/GB)单位
345
- * @param {number} bytes 字节
346
- * @returns {string} 返回单位大小
347
- * */
348
- const bytesToSize = (bytes: number) => {
349
- const sizes = ["b", "KB", "MB", "GB", "TB"];
350
- if (bytes === 0) {
351
- return "0b";
352
- }
353
- const i = Math.floor(Math.log(bytes) / Math.log(1024));
354
- if (i === 0) {
355
- return `${bytes}${sizes[i]}`;
356
- }
357
- return `${(bytes / 1024 ** i).toFixed(1)}${sizes[i]}`;
358
- };
359
-
360
- /**
361
- * @description 将对象转换为 URL 查询参数字符串
362
- * @param params - 要转换的对象
363
- * @returns 转换后的查询参数字符串
364
- */
365
- const objectToUrlParams = (params: Record<string, any>): string => {
366
- return Object.entries(params)
367
- .filter(([key, value]) => value !== undefined && value !== null) // 过滤掉值为 undefined 或 null 的项
368
- .map(([key, value]) => {
369
- // 对值进行编码以确保 URL 安全
370
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
371
- })
372
- .join("&"); // 使用 & 拼接所有参数
373
- };
374
-
375
- /**
376
- * @description 地址栏参数转换对象
377
- * @param paramStr - 字符串参数
378
- * @returns 返回转换对象
379
- */
380
- const urlParamsToObject = (paramStr: string): AnyObject => {
381
- const params: AnyObject = {};
382
- // 去掉字符串两端的可能的空格
383
- paramStr = paramStr.trim();
384
- // 如果字符串以?开头,去掉它
385
- if (paramStr.startsWith("?")) {
386
- paramStr = paramStr.substring(1);
387
- }
388
- // 按&分割字符串,得到键值对数组
389
- const pairs = paramStr.split("&");
390
- for (let i = 0; i < pairs.length; i++) {
391
- const pair = pairs[i];
392
- // 按=分割键值对
393
- const [key, ...valueParts] = pair.split("=");
394
- const value = valueParts.join("=");
395
- // 将键值对存入对象
396
- params[decodeURIComponent(key)] = decodeURIComponent(value);
397
- }
398
- return params;
399
- };
400
-
401
- /**
402
- * 获取 [min,max]的随机数
403
- * Math.floor(Math.random()*10) 可均衡获取 0 到 9 的随机整数
404
- * @param min 最小值
405
- * @param max 最大值
406
- * @returns {Number} string 随机数
407
- */
408
- const random = (min: number | string, max: number | string): number => {
409
- min = Number(min);
410
- max = Number(max);
411
- return Math.floor(Math.random() * (max - min + 1) + min) || 0;
412
- };
413
-
414
- const range = (min = 0, max = 0, value = 0) => {
415
- return Math.max(min, Math.min(max, Number(value)));
416
- };
417
-
418
- export type RectResultType<T extends boolean> = T extends true
419
- ? UniApp.NodeInfo[]
420
- : UniApp.NodeInfo;
421
- /**
422
- * 查询节点信息
423
- * 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21)
424
- * 解决办法为在组件根部再套一个没有任何作用的view元素
425
- * @param selector 元素类名或id
426
- * @param all 是否获取多个相同元素数值
427
- * @param ins 在微信小程序里,因为utils文件里面获取不到instance值所以必须通过ins这个传过来【注意,(支付宝小程序无效)】
428
- * @param useFields 是否使用 fields 方法获取节点信息
429
- */
430
- const getRect = <T extends boolean>(
431
- selector: string,
432
- all?: T,
433
- ins?: any,
434
- useFields?: boolean,
435
- ): Promise<RectResultType<T>> => {
436
- return new Promise<RectResultType<T>>((resolve, reject) => {
437
- let query: UniNamespace.SelectorQuery | null = null;
438
- if (ins) {
439
- // TODO: 在微信小程序里,因为utils文件里面获取不到instance值所以必须通过ins这个传过来
440
- query = uni.createSelectorQuery().in(ins);
441
- } else {
442
- query = uni.createSelectorQuery();
443
- }
444
- const method = all ? "selectAll" : "select";
445
-
446
- const callback = (rect: UniApp.NodeInfo | UniApp.NodeInfo[]) => {
447
- if (all && Array.isArray(rect) && rect.length > 0) {
448
- resolve(rect as RectResultType<T>);
449
- } else if (!all && rect) {
450
- resolve(rect as RectResultType<T>);
451
- } else {
452
- error(`调用getRect方法,没有找到${selector}对应的元素内容`);
453
- reject(new Error("No nodes found"));
454
- }
455
- };
456
-
457
- if (useFields) {
458
- query[method](selector)
459
- .fields({ size: true, node: true }, callback)
460
- .exec();
461
- } else {
462
- query[method](selector).boundingClientRect(callback).exec();
463
- }
464
- });
465
- };
466
-
467
- /**
468
- * @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.rpx2px进行转换
469
- * @param {number|string} value 用户传递值的px值
470
- * @param {boolean} unit
471
- * @returns {number|string}
472
- */
473
- function getPx(value: string | number, unit: true): string;
474
- function getPx(value: string | number, unit?: false): number;
475
- function getPx(value: string | number, unit: boolean = false): string | number {
476
- if (isNumber(value) || typeof value === "number") {
477
- return unit ? `${value}px` : Number(value);
478
- }
479
- // 如果带有rpx,先取出其数值部分,再转为px值
480
- if (/(rpx|upx)$/.test(value)) {
481
- return unit
482
- ? `${uni.rpx2px(parseInt(value))}px`
483
- : Number(uni.rpx2px(parseInt(value)));
484
- } else if (/(px)$/.test(value)) {
485
- return unit ? value : Number(value.replace("px", ""));
486
- } else {
487
- return unit ? `${parseInt(value)}px` : Number(value);
488
- }
489
- }
490
-
491
- /**
492
- * @description 对象转换字符串,用在于style样式上
493
- * */
494
- const formatObject = (obj: CSSProperties) => {
495
- return Object.entries(obj)
496
- .map(([key, value]) => `${key.toUpperCase()}: ${value}`)
497
- .join("; ");
498
- };
499
-
500
- export {
501
- encryptData,
502
- decryptData,
503
- addUnit,
504
- padZero,
505
- addZero,
506
- clearVal,
507
- formatTime,
508
- formatTimeToString,
509
- imageToBase64,
510
- debounce,
511
- throttle,
512
- deepClone,
513
- bytesToSize,
514
- objectToUrlParams,
515
- urlParamsToObject,
516
- random,
517
- range,
518
- getRect,
519
- getPx,
520
- formatObject,
521
- };
1
+ import Base64 from "./base64";
2
+ import type { CSSProperties } from "vue";
3
+ import { error, isNumber } from "./index";
4
+ let base64: any = new Base64();
5
+
6
+ /**
7
+ * 加密函数
8
+ * @param {any} data 对象
9
+ * @return { string } 加密字符串
10
+ * */
11
+ function encryptData(data: Record<string, any> | string): string {
12
+ return base64.encode(JSON.stringify(data));
13
+ }
14
+
15
+ /**
16
+ * 解密函数
17
+ * @param {string} encryptedVal 加密字符串
18
+ * @returns { any | any[] } 解码的数据
19
+ * */
20
+ function decryptData(encryptedVal: string): Record<string, any> {
21
+ return JSON.parse(base64.decode(encryptedVal.toString()));
22
+ }
23
+
24
+ /**
25
+ *用于解密使用 AES 加密算法加密的数据
26
+ */
27
+
28
+ // const decrypt = (sessionKey: string, encryptedData: string, iv: string) => {
29
+ // console.log(CryptoJS)
30
+ // let key = CryptoJS.enc.Base64.parse(sessionKey)
31
+ // let ivv = CryptoJS.enc.Base64.parse(iv)
32
+ // let decrypt = CryptoJS.AES.decrypt(encryptedData, key, {
33
+ // iv: ivv,
34
+ // mode: CryptoJS.mode.CBC,
35
+ // padding: CryptoJS.pad.Pkcs7
36
+ // })
37
+ // return JSON.parse(base64.decode(CryptoJS.enc.Base64.stringify(decrypt)))
38
+ // }
39
+
40
+ /**
41
+ * @description 添加单位,如果有rpx,upx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾
42
+ * @param {String|Number} value 需要添加单位的值
43
+ * @param {String} unit 添加的单位名 比如px
44
+ * @returns {String}
45
+ */
46
+ const addUnit = (
47
+ value: string | number = "auto",
48
+ unit: string = "",
49
+ ): string => {
50
+ if (!unit) {
51
+ unit = "px";
52
+ }
53
+ if (unit == "rpx" && isNumber(String(value))) {
54
+ value = Number(value) * 2;
55
+ }
56
+ value = String(value);
57
+ // 用内置验证规则中的number判断是否为数值
58
+ return isNumber(value) ? `${value}${unit}` : value;
59
+ };
60
+
61
+ /**
62
+ * @description 日期的月或日补零操作
63
+ * @param {String | Number} value 需要补零的值
64
+ * @returns {String}
65
+ */
66
+ const padZero = (value: string | number): string => {
67
+ return `00${value}`.slice(-2);
68
+ };
69
+
70
+ /**
71
+ * @description 后面补零
72
+ * @param {String | Number} value 需要补零的值
73
+ * @param {Number} length 多少位
74
+ * @returns {String}
75
+ */
76
+ const addZero = (value: string | number, length: number): string => {
77
+ if (value === undefined || value === null) return "";
78
+ let val = value.toString();
79
+ if (length > val.length) {
80
+ val += "0".repeat(length - val.length);
81
+ } else {
82
+ val = val.slice(0, length);
83
+ }
84
+ return val;
85
+ };
86
+
87
+ /**
88
+ * @description 清空对象里面的值
89
+ * @param val 任意类型的值
90
+ * */
91
+ const clearVal = (val: any) => {
92
+ const type = typeof val;
93
+ const isArray = val instanceof Array;
94
+ switch (type) {
95
+ case "string":
96
+ return "";
97
+ case "number":
98
+ return 0;
99
+ case "boolean":
100
+ return false;
101
+ case "undefined":
102
+ return null;
103
+ case "object":
104
+ if (!val) return null;
105
+ if (isArray) {
106
+ val.map((item) => {
107
+ clearVal(item);
108
+ });
109
+ return val;
110
+ } else {
111
+ Object.keys(val).map((k) => {
112
+ val[k] = clearVal(val[k]);
113
+ });
114
+ return val;
115
+ }
116
+ default:
117
+ return "";
118
+ }
119
+ };
120
+
121
+ /**
122
+ * 时间戳格式化
123
+ * @param timestamp 时间戳或者时间格式,例:1702051200000、Sat Apr 06 2024 11:35:56 GMT+0800 (中国标准时间)
124
+ * @param fmt 例:yyyy-MM-dd HH:mm:ss / yyyy-MM-dd
125
+ * @return date 例:2023-12-09
126
+ */
127
+ const formatTime = (
128
+ timestamp: number | string,
129
+ fmt: string = "yyyy-MM-dd HH:mm:ss",
130
+ ): string => {
131
+ let date: any;
132
+ if (timestamp) {
133
+ date = new Date(timestamp) ? new Date(timestamp) : timestamp;
134
+ let ret;
135
+ const opt: any = {
136
+ "y+": date.getFullYear().toString(), //年
137
+ "M+": (date.getMonth() + 1).toString(), //月
138
+ "d+": date.getDate().toString(), //日
139
+ "H+": date.getHours().toString(), //时
140
+ "m+": date.getMinutes().toString(), //分
141
+ "s+": date.getSeconds().toString(), //秒
142
+ //如果有其他格式字符需求可以继续添加,必须转化为字符串
143
+ };
144
+ for (let k in opt) {
145
+ ret = new RegExp("(" + k + ")").exec(fmt);
146
+ if (ret) {
147
+ fmt = fmt.replace(
148
+ ret[1],
149
+ ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0"),
150
+ );
151
+ }
152
+ }
153
+ return fmt;
154
+ }
155
+ return date;
156
+ };
157
+
158
+ /**
159
+ * @description 时间戳或年月日格式转为多久之前
160
+ * @param {String|Number} timestamp 时间戳/年月日格式
161
+ * @param {String|Boolean} format
162
+ * 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式;
163
+ * 如果为布尔值false,无论什么时间,都返回多久以前的格式
164
+ * @returns {string} 转化后的内容
165
+ */
166
+ const formatTimeToString = (
167
+ timestamp: string | number,
168
+ format: string | boolean = "yyyy-mm-dd",
169
+ ): string => {
170
+ const now = new Date();
171
+ const oneYear = new Date(now.getFullYear(), 0, 1).getTime(); // 当年一月一号时间戳
172
+
173
+ if (timestamp == null) timestamp = Number(now);
174
+ timestamp =
175
+ typeof timestamp === "string"
176
+ ? parseInt(timestamp)
177
+ : new Date(timestamp).getTime();
178
+ // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
179
+ if (timestamp.toString().length == 10) timestamp *= 1000;
180
+ let timer = now.getTime() - timestamp;
181
+ timer = parseInt(String(timer / 1000));
182
+ // 如果小于5分钟,则返回"刚刚",其他以此类推
183
+ let tips = "";
184
+ switch (true) {
185
+ case timer < 300:
186
+ tips = "刚刚";
187
+ break;
188
+ case timer >= 300 && timer < 3600:
189
+ tips = `${parseInt(String(timer / 60))}分钟前`;
190
+ break;
191
+ case timer >= 3600 && timer < 86400:
192
+ tips = `${parseInt(String(timer / 3600))}小时前`;
193
+ break;
194
+ case timer >= 86400 && timer < 2592000:
195
+ tips = `${parseInt(String(timer / 86400))}天前`;
196
+ break;
197
+ default:
198
+ // 如果format为false,则无论什么时间戳,都显示xx之前
199
+ if (format === false) {
200
+ if (timer >= 2592000 && timer < 365 * 86400) {
201
+ tips = `${parseInt(String(timer / (86400 * 30)))}个月前`;
202
+ } else {
203
+ tips = `${parseInt(String(timer / (86400 * 365)))}年前`;
204
+ }
205
+ } else {
206
+ if (timestamp > oneYear) {
207
+ formatTime(timestamp, "MM-dd");
208
+ } else {
209
+ tips =
210
+ format === true
211
+ ? formatTime(timestamp, "yyyy-MM-dd")
212
+ : formatTime(timestamp, format);
213
+ }
214
+ }
215
+ }
216
+ return tips;
217
+ };
218
+
219
+ /**
220
+ * @description 本地图片转base64方法(兼容APP、H5、小程序)
221
+ * @param {string} path 图片本地路径
222
+ * @returns Promise对象
223
+ */
224
+ const imageToBase64 = (path: string) => {
225
+ return new Promise((resolve, reject) => {
226
+ // #ifdef APP-PLUS
227
+ plus.io.resolveLocalFileSystemURL(path, (entry: any) => {
228
+ entry.file((file: any) => {
229
+ let fileReader = new plus.io.FileReader();
230
+ fileReader.readAsDataURL(file);
231
+ fileReader.onloadend = (evt: any) => {
232
+ let base64 = evt.target.result.split(",")[1];
233
+ resolve(base64);
234
+ };
235
+ });
236
+ });
237
+ // #endif
238
+ // #ifdef H5
239
+ uni.request({
240
+ url: path,
241
+ responseType: "arraybuffer",
242
+ success: (res: UniApp.RequestSuccessCallbackResult) => {
243
+ resolve(uni.arrayBufferToBase64(res.data as ArrayBuffer));
244
+ },
245
+ });
246
+ // #endif
247
+ // #ifdef MP-WEIXIN
248
+ uni.getFileSystemManager().readFile({
249
+ filePath: path,
250
+ encoding: "base64",
251
+ success: (res) => {
252
+ resolve(res.data);
253
+ },
254
+ });
255
+ // #endif
256
+ });
257
+ };
258
+
259
+ /**
260
+ * 函数防抖:一段实现执行多次,只执行最后一次
261
+ * @param {void} fn 回调函数
262
+ * @param {number} wait 节流时间
263
+ * @returns {void}
264
+ * @constructor
265
+ */
266
+ let timeout: ReturnType<typeof setTimeout> | null = null;
267
+ function debounce<T extends (...args: any[]) => void>(
268
+ fn: T,
269
+ wait: number = 500,
270
+ immediate: boolean = false,
271
+ ) {
272
+ // 清除定时器
273
+ if (timeout !== null) clearTimeout(timeout);
274
+ // 立即执行,此类情况一般用不到
275
+ if (immediate) {
276
+ const callNow = !timeout;
277
+ timeout = setTimeout(() => {
278
+ timeout = null;
279
+ }, wait);
280
+ if (callNow) typeof fn === "function" && fn();
281
+ } else {
282
+ // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
283
+ timeout = setTimeout(() => {
284
+ typeof fn === "function" && fn();
285
+ }, wait);
286
+ }
287
+ }
288
+
289
+ let timer: ReturnType<typeof setTimeout> | null = null;
290
+ let flag: boolean | undefined;
291
+ /**
292
+ * 函数节流: 一段时间执行一次
293
+ * @param {void} fn 回调函数
294
+ * @param {number} wait 节流等待时间
295
+ * @param {boolean} immediate 是否立马执行
296
+ * @returns {void}
297
+ * @constructor
298
+ */
299
+ const throttle = (
300
+ fn: Function,
301
+ wait: number = 500,
302
+ immediate: boolean = true,
303
+ ): void => {
304
+ if (immediate) {
305
+ if (!flag) {
306
+ flag = true;
307
+ // 如果是立即执行,则在wait毫秒内开始时执行
308
+ typeof fn === "function" && fn();
309
+ timer = setTimeout(() => {
310
+ flag = false;
311
+ }, wait);
312
+ }
313
+ } else if (!flag) {
314
+ flag = true;
315
+ // 如果是非立即执行,则在wait毫秒内的结束处执行
316
+ timer = setTimeout(() => {
317
+ flag = false;
318
+ typeof fn === "function" && fn();
319
+ }, wait);
320
+ }
321
+ };
322
+
323
+ /**
324
+ * 递归拷贝对象
325
+ * @param {object} source 对象或数组
326
+ * @returns 深拷贝的数组和对象
327
+ * */
328
+ const deepClone = (source: any) => {
329
+ if (!source && typeof source !== "object") {
330
+ throw new Error("该值不存在或者不是个对象");
331
+ }
332
+ const targetObj: any = source.constructor === Array ? [] : {};
333
+ Object.keys(source).forEach((keys) => {
334
+ if (source[keys] && typeof source[keys] === "object") {
335
+ targetObj[keys] = deepClone(source[keys]);
336
+ } else {
337
+ targetObj[keys] = source[keys];
338
+ }
339
+ });
340
+ return targetObj;
341
+ };
342
+
343
+ /**
344
+ * 字节转化(b/KB/MB/GB)单位
345
+ * @param {number} bytes 字节
346
+ * @returns {string} 返回单位大小
347
+ * */
348
+ const bytesToSize = (bytes: number) => {
349
+ const sizes = ["b", "KB", "MB", "GB", "TB"];
350
+ if (bytes === 0) {
351
+ return "0b";
352
+ }
353
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
354
+ if (i === 0) {
355
+ return `${bytes}${sizes[i]}`;
356
+ }
357
+ return `${(bytes / 1024 ** i).toFixed(1)}${sizes[i]}`;
358
+ };
359
+
360
+ /**
361
+ * @description 将对象转换为 URL 查询参数字符串
362
+ * @param params - 要转换的对象
363
+ * @returns 转换后的查询参数字符串
364
+ */
365
+ const objectToUrlParams = (params: Record<string, any>): string => {
366
+ return Object.entries(params)
367
+ .filter(([key, value]) => value !== undefined && value !== null) // 过滤掉值为 undefined 或 null 的项
368
+ .map(([key, value]) => {
369
+ // 对值进行编码以确保 URL 安全
370
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
371
+ })
372
+ .join("&"); // 使用 & 拼接所有参数
373
+ };
374
+
375
+ /**
376
+ * @description 地址栏参数转换对象
377
+ * @param paramStr - 字符串参数
378
+ * @returns 返回转换对象
379
+ */
380
+ const urlParamsToObject = (paramStr: string): AnyObject => {
381
+ const params: AnyObject = {};
382
+ // 去掉字符串两端的可能的空格
383
+ paramStr = paramStr.trim();
384
+ // 如果字符串以?开头,去掉它
385
+ if (paramStr.startsWith("?")) {
386
+ paramStr = paramStr.substring(1);
387
+ }
388
+ // 按&分割字符串,得到键值对数组
389
+ const pairs = paramStr.split("&");
390
+ for (let i = 0; i < pairs.length; i++) {
391
+ const pair = pairs[i];
392
+ // 按=分割键值对
393
+ const [key, ...valueParts] = pair.split("=");
394
+ const value = valueParts.join("=");
395
+ // 将键值对存入对象
396
+ params[decodeURIComponent(key)] = decodeURIComponent(value);
397
+ }
398
+ return params;
399
+ };
400
+
401
+ /**
402
+ * 获取 [min,max]的随机数
403
+ * Math.floor(Math.random()*10) 可均衡获取 0 到 9 的随机整数
404
+ * @param min 最小值
405
+ * @param max 最大值
406
+ * @returns {Number} string 随机数
407
+ */
408
+ const random = (min: number | string, max: number | string): number => {
409
+ min = Number(min);
410
+ max = Number(max);
411
+ return Math.floor(Math.random() * (max - min + 1) + min) || 0;
412
+ };
413
+
414
+ const range = (min = 0, max = 0, value = 0) => {
415
+ return Math.max(min, Math.min(max, Number(value)));
416
+ };
417
+
418
+ export type RectResultType<T extends boolean> = T extends true
419
+ ? UniApp.NodeInfo[]
420
+ : UniApp.NodeInfo;
421
+ /**
422
+ * 查询节点信息
423
+ * 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21)
424
+ * 解决办法为在组件根部再套一个没有任何作用的view元素
425
+ * @param selector 元素类名或id
426
+ * @param all 是否获取多个相同元素数值
427
+ * @param ins 在微信小程序里,因为utils文件里面获取不到instance值所以必须通过ins这个传过来【注意,(支付宝小程序无效)】
428
+ * @param useFields 是否使用 fields 方法获取节点信息
429
+ */
430
+ const getRect = <T extends boolean>(
431
+ selector: string,
432
+ all?: T,
433
+ ins?: any,
434
+ useFields?: boolean,
435
+ ): Promise<RectResultType<T>> => {
436
+ return new Promise<RectResultType<T>>((resolve, reject) => {
437
+ let query: UniNamespace.SelectorQuery | null = null;
438
+ if (ins) {
439
+ // TODO: 在微信小程序里,因为utils文件里面获取不到instance值所以必须通过ins这个传过来
440
+ query = uni.createSelectorQuery().in(ins);
441
+ } else {
442
+ query = uni.createSelectorQuery();
443
+ }
444
+ const method = all ? "selectAll" : "select";
445
+
446
+ const callback = (rect: UniApp.NodeInfo | UniApp.NodeInfo[]) => {
447
+ if (all && Array.isArray(rect) && rect.length > 0) {
448
+ resolve(rect as RectResultType<T>);
449
+ } else if (!all && rect) {
450
+ resolve(rect as RectResultType<T>);
451
+ } else {
452
+ error(`调用getRect方法,没有找到${selector}对应的元素内容`);
453
+ reject(new Error("No nodes found"));
454
+ }
455
+ };
456
+
457
+ if (useFields) {
458
+ query[method](selector)
459
+ .fields({ size: true, node: true }, callback)
460
+ .exec();
461
+ } else {
462
+ query[method](selector).boundingClientRect(callback).exec();
463
+ }
464
+ });
465
+ };
466
+
467
+ /**
468
+ * @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.rpx2px进行转换
469
+ * @param {number|string} value 用户传递值的px值
470
+ * @param {boolean} unit
471
+ * @returns {number|string}
472
+ */
473
+ function getPx(value: string | number, unit: true): string;
474
+ function getPx(value: string | number, unit?: false): number;
475
+ function getPx(value: string | number, unit: boolean = false): string | number {
476
+ if (isNumber(value) || typeof value === "number") {
477
+ return unit ? `${value}px` : Number(value);
478
+ }
479
+ // 如果带有rpx,先取出其数值部分,再转为px值
480
+ if (/(rpx|upx)$/.test(value)) {
481
+ return unit
482
+ ? `${uni.rpx2px(parseInt(value))}px`
483
+ : Number(uni.rpx2px(parseInt(value)));
484
+ } else if (/(px)$/.test(value)) {
485
+ return unit ? value : Number(value.replace("px", ""));
486
+ } else {
487
+ return unit ? `${parseInt(value)}px` : Number(value);
488
+ }
489
+ }
490
+
491
+ /**
492
+ * @description 对象转换字符串,用在于style样式上
493
+ * */
494
+ const formatObject = (obj: CSSProperties) => {
495
+ return Object.entries(obj)
496
+ .map(([key, value]) => `${key.toUpperCase()}: ${value}`)
497
+ .join("; ");
498
+ };
499
+
500
+ export {
501
+ encryptData,
502
+ decryptData,
503
+ addUnit,
504
+ padZero,
505
+ addZero,
506
+ clearVal,
507
+ formatTime,
508
+ formatTimeToString,
509
+ imageToBase64,
510
+ debounce,
511
+ throttle,
512
+ deepClone,
513
+ bytesToSize,
514
+ objectToUrlParams,
515
+ urlParamsToObject,
516
+ random,
517
+ range,
518
+ getRect,
519
+ getPx,
520
+ formatObject,
521
+ };