@ecolovo/uniapp-components 1.0.10 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +202 -66
- package/components/aspect/aspect.vue +24 -15
- package/components/badge/badge.scss +20 -0
- package/components/badge/badge.vue +49 -40
- package/components/button/button.scss +15 -0
- package/components/button/button.vue +121 -177
- package/components/checkbox/checkbox.scss +10 -0
- package/components/checkbox/checkbox.vue +118 -146
- package/components/checkbox-group/checkbox-group.vue +79 -85
- package/components/checkbox-group2/checkbox-group2.vue +111 -107
- package/components/checkbox-group2/checkbox2.vue +104 -0
- package/components/data-list/data-list.scss +9 -0
- package/components/data-list/data-list.vue +70 -79
- package/components/date-picker/date-picker-view.vue +125 -124
- package/components/date-picker/date-picker.vue +145 -146
- package/components/dialog/dialog-content.vue +39 -47
- package/components/dialog/dialog.scss +11 -0
- package/components/dialog/dialog.vue +125 -138
- package/components/dropdown/dropdown.scss +11 -0
- package/components/dropdown/dropdown.vue +55 -97
- package/components/empty/empty.scss +14 -0
- package/components/empty/empty.vue +42 -41
- package/components/flex/flex.vue +45 -54
- package/components/form/form.vue +29 -24
- package/components/form-item/form-item.scss +11 -0
- package/components/form-item/form-item.vue +43 -40
- package/components/icon/icon.vue +70 -85
- package/components/image/image.vue +35 -38
- package/components/input/input.vue +65 -79
- package/components/input/password-input.vue +34 -42
- package/components/list-page/list-page.vue +73 -99
- package/components/load-more/load-more.scss +12 -0
- package/components/load-more/load-more.vue +29 -29
- package/components/loading/animations/loading-animation1.vue +8 -8
- package/components/loading/animations/loading-animation2.vue +8 -9
- package/components/loading/animations/loading-animation3.vue +11 -11
- package/components/loading/animations/loading-animation4.vue +8 -8
- package/components/loading/loading.vue +19 -20
- package/components/message-box/message-box.vue +59 -41
- package/components/number-dialog/number-dialog.scss +9 -0
- package/components/number-dialog/number-dialog.vue +209 -204
- package/components/number-input/number-input.scss +9 -0
- package/components/number-input/number-input.vue +233 -232
- package/components/numpad/numpad.scss +9 -0
- package/components/numpad/numpad.vue +133 -150
- package/components/page/page-body.scss +15 -0
- package/components/page/page-body.vue +137 -119
- package/components/page/page-footer.scss +13 -0
- package/components/page/page-footer.vue +31 -33
- package/components/page/page-header.scss +17 -0
- package/components/page/page-header.vue +89 -94
- package/components/page/page.scss +9 -0
- package/components/page/page.vue +105 -81
- package/components/picker/picker-popup.vue +218 -209
- package/components/picker/picker.vue +99 -104
- package/components/popover/popover-content.vue +54 -63
- package/components/popover/popover-mask.vue +63 -63
- package/components/popover/popover.scss +28 -0
- package/components/popover/popover.vue +49 -47
- package/components/popup/popup-content.vue +49 -53
- package/components/popup/popup.scss +11 -0
- package/components/popup/popup.vue +117 -132
- package/components/price/price.scss +20 -0
- package/components/price/price.vue +31 -42
- package/components/search/search.scss +12 -0
- package/components/search/search.vue +93 -117
- package/components/searching/searching.vue +33 -40
- package/components/selector/selector.vue +43 -48
- package/components/switch/switch.scss +12 -0
- package/components/switch/switch.vue +99 -96
- package/components/tab/tab.scss +19 -0
- package/components/tab/tab.vue +151 -145
- package/components/textarea/textarea.vue +104 -101
- package/composable/component-name.d.ts +2 -0
- package/composable/component-name.js +8 -0
- package/composable/component-name.ts +10 -0
- package/configs/index.d.ts +25 -10
- package/configs/index.js +14 -23
- package/configs/index.ts +82 -0
- package/easyCom.d.ts +9 -0
- package/easyCom.js +1 -2
- package/easyCom.ts +31 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.ts +1 -0
- package/init.d.ts +4 -7
- package/init.js +5 -4
- package/init.ts +34 -0
- package/package.json +14 -4
- package/styles/utils/css-var.scss +12 -15
- package/styles/utils/ellipsis.scss +0 -7
- package/styles/utils/z-index.scss +1 -1
- package/styles/var/component.scss +21 -245
- package/utils/date.d.ts +47 -0
- package/utils/date.js +23 -43
- package/utils/date.ts +153 -0
- package/utils/freezeDeep.d.ts +1 -0
- package/utils/freezeDeep.js +4 -14
- package/utils/freezeDeep.ts +9 -0
- package/utils/price.d.ts +24 -0
- package/utils/price.js +14 -8
- package/utils/price.ts +57 -0
- package/utils/round.d.ts +2 -0
- package/utils/round.js +2 -14
- package/utils/round.ts +11 -0
- package/utils/windowInfo.d.ts +24 -0
- package/utils/windowInfo.js +8 -36
- package/utils/windowInfo.ts +50 -0
- package/components/checkbox-group2/checkbox.vue +0 -109
- package/components/datetime-picker/datetime-picker-view.vue +0 -209
- package/components/datetime-picker/datetime-picker.vue +0 -235
- package/components/form/mixin.js +0 -13
- package/components/list-page/list-page.js +0 -10
- package/components/table/table.vue +0 -112
- package/components/time-picker/time-picker-view.vue +0 -127
- package/components/time-picker/time-picker.vue +0 -140
- package/components/uploader/download.js +0 -81
- package/components/uploader/file-uploader.vue +0 -52
- package/components/uploader/files.js +0 -225
- package/components/uploader/media-uploader.vue +0 -189
- package/components/uploader/mixin.js +0 -171
- package/components/uploader/uni.js +0 -38
- package/components/uploader/upload-button.vue +0 -29
- package/components/uploader/uploader copy.vue +0 -547
- package/components/uploader/uploader.vue +0 -117
- package/mixins/componentName.js +0 -32
- package/mixins/listPage.js +0 -1
- package/mixins/windowInfo.js +0 -1
- package/utils/fileSize.js +0 -39
- package/utils/floor.js +0 -20
|
@@ -1,245 +1,21 @@
|
|
|
1
|
-
@
|
|
2
|
-
@
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
$page-header: () !default;
|
|
24
|
-
$page-header-default: (
|
|
25
|
-
// 背景色
|
|
26
|
-
background: #fff,
|
|
27
|
-
// 字体大小
|
|
28
|
-
font-size: 28rpx,
|
|
29
|
-
// 标题栏下的额外内容高度,有内容时需设置次值
|
|
30
|
-
extra-height: 0px,
|
|
31
|
-
// 亮色主题下的文本颜色
|
|
32
|
-
color-light: #000,
|
|
33
|
-
// 暗色主题下的文本颜色
|
|
34
|
-
color-dark: #fff
|
|
35
|
-
);
|
|
36
|
-
$page-header: map.merge($page-header-default, $page-header);
|
|
37
|
-
|
|
38
|
-
$page-body: () !default;
|
|
39
|
-
$page-body-default: (
|
|
40
|
-
// 可视区域背景
|
|
41
|
-
background: transparent,
|
|
42
|
-
padding: 20rpx,
|
|
43
|
-
padding-top: null,
|
|
44
|
-
padding-right: null,
|
|
45
|
-
padding-bottom: null,
|
|
46
|
-
padding-left: null
|
|
47
|
-
);
|
|
48
|
-
$page-body: map.merge($page-body-default, $page-body);
|
|
49
|
-
|
|
50
|
-
$page-footer: () !default;
|
|
51
|
-
$page-footer-default: (
|
|
52
|
-
// 背景色
|
|
53
|
-
background: #fff,
|
|
54
|
-
// 高度
|
|
55
|
-
height: 100rpx,
|
|
56
|
-
// 横向两端间距
|
|
57
|
-
spacing-horizontal: 30rpx
|
|
58
|
-
);
|
|
59
|
-
$page-footer: map.merge($page-footer-default, $page-footer);
|
|
60
|
-
|
|
61
|
-
$page: () !default;
|
|
62
|
-
$page-default: (
|
|
63
|
-
// 页面背景
|
|
64
|
-
background: transparent
|
|
65
|
-
);
|
|
66
|
-
$page: map.merge($page-default, $page);
|
|
67
|
-
|
|
68
|
-
$button: () !default;
|
|
69
|
-
$button-default: (
|
|
70
|
-
// 按钮主题颜色,默认取值组件 props 中的 type
|
|
71
|
-
theme: var(--theme-from-prop),
|
|
72
|
-
// 按钮文本颜色
|
|
73
|
-
text-color: #fff,
|
|
74
|
-
// 按钮激活态遮罩颜色
|
|
75
|
-
active-mask: #ffffff,
|
|
76
|
-
// plain 按钮的边框宽度
|
|
77
|
-
border-width: 3rpx
|
|
78
|
-
);
|
|
79
|
-
$button: map.merge($button-default, $button);
|
|
80
|
-
|
|
81
|
-
$data-list: () !default;
|
|
82
|
-
$data-list-default: (
|
|
83
|
-
// 触发加载更多的区域高度
|
|
84
|
-
observer-height: 100vh
|
|
85
|
-
);
|
|
86
|
-
$data-list: map.merge($data-list-default, $data-list);
|
|
87
|
-
|
|
88
|
-
$empty: () !default;
|
|
89
|
-
$empty-default: (
|
|
90
|
-
image-size: 300rpx,
|
|
91
|
-
image-width: UTILS__LOCAL_VAR(image-size),
|
|
92
|
-
image-height: UTILS__LOCAL_VAR(image-size),
|
|
93
|
-
space: 20rpx,
|
|
94
|
-
color: #ccc,
|
|
95
|
-
font-size: UTILS__GLOBAL_VAR(font-size, normal),
|
|
96
|
-
);
|
|
97
|
-
$empty: map.merge($empty-default, $empty);
|
|
98
|
-
|
|
99
|
-
$load-more: () !default;
|
|
100
|
-
$load-more-default: (
|
|
101
|
-
height: 60rpx,
|
|
102
|
-
space: 40rpx,
|
|
103
|
-
color: #ccc,
|
|
104
|
-
font-size: UTILS__GLOBAL_VAR(font-size, normal),
|
|
105
|
-
);
|
|
106
|
-
$load-more: map.merge($load-more-default, $load-more);
|
|
107
|
-
|
|
108
|
-
$checkbox: () !default;
|
|
109
|
-
$checkbox-default: (
|
|
110
|
-
checked-color: UTILS__GLOBAL_VAR(theme, primary),
|
|
111
|
-
unchecked-color: UTILS__GLOBAL_VAR(color, foreground),
|
|
112
|
-
);
|
|
113
|
-
$checkbox: map.merge($checkbox-default, $checkbox);
|
|
114
|
-
|
|
115
|
-
$popover: () !default;
|
|
116
|
-
$popover-default: (
|
|
117
|
-
// 遮罩层颜色
|
|
118
|
-
mask-color: #00000080,
|
|
119
|
-
// 背景色
|
|
120
|
-
background: #fff,
|
|
121
|
-
// 位置,position 为 center 时有效
|
|
122
|
-
position: 50% auto auto 50%,
|
|
123
|
-
// 宽度,position 为 left 、 right 或 center 时有效
|
|
124
|
-
width: 80vw,
|
|
125
|
-
// 最小高度,position 为 top 、 bottom 或 center 时有效
|
|
126
|
-
min-height: 0px,
|
|
127
|
-
// 最大高度,position 为 top 、 bottom 或 center 时有效
|
|
128
|
-
max-height: 75vh,
|
|
129
|
-
// 内边距
|
|
130
|
-
padding: 20rpx,
|
|
131
|
-
// 边框圆角
|
|
132
|
-
radius: 20rpx,
|
|
133
|
-
// 头高度
|
|
134
|
-
header-height: 0px,
|
|
135
|
-
// 尾高度
|
|
136
|
-
footer-height: 0px
|
|
137
|
-
);
|
|
138
|
-
$popover: map.merge($popover-default, $popover);
|
|
139
|
-
|
|
140
|
-
$dialog: () !default;
|
|
141
|
-
$dialog-default: (
|
|
142
|
-
// 标题栏高度
|
|
143
|
-
header-height: 100rpx,
|
|
144
|
-
// 操作栏高度
|
|
145
|
-
footer-height: 134rpx
|
|
146
|
-
);
|
|
147
|
-
$dialog: map.merge($dialog-default, $dialog);
|
|
148
|
-
|
|
149
|
-
$popup: () !default;
|
|
150
|
-
$popup-default: (
|
|
151
|
-
// 标题栏高度
|
|
152
|
-
header-height: 100rpx,
|
|
153
|
-
// 操作栏高度
|
|
154
|
-
footer-height: 102rpx
|
|
155
|
-
);
|
|
156
|
-
$popup: map.merge($popup-default, $popup);
|
|
157
|
-
|
|
158
|
-
$form-item: () !default;
|
|
159
|
-
$form-item-default: (
|
|
160
|
-
// label 宽度
|
|
161
|
-
label-width: 6em,
|
|
162
|
-
// 高度
|
|
163
|
-
height: 80rpx
|
|
164
|
-
);
|
|
165
|
-
$form-item: map.merge($form-item-default, $form-item);
|
|
166
|
-
|
|
167
|
-
$switch: () !default;
|
|
168
|
-
$switch-default: (
|
|
169
|
-
width: 92rpx,
|
|
170
|
-
height: 48rpx,
|
|
171
|
-
active-color: UTILS__GLOBAL_VAR(theme, primary),
|
|
172
|
-
indicator-size: 42rpx,
|
|
173
|
-
);
|
|
174
|
-
$switch: map.merge($switch-default, $switch);
|
|
175
|
-
|
|
176
|
-
$number-input: () !default;
|
|
177
|
-
$number-input-default: (
|
|
178
|
-
font-size: inherit,
|
|
179
|
-
text-align: center,
|
|
180
|
-
);
|
|
181
|
-
$number-input: map.merge($number-input-default, $number-input);
|
|
182
|
-
|
|
183
|
-
$numpad: () !default;
|
|
184
|
-
$numpad-default: (
|
|
185
|
-
row-gap: 20rpx,
|
|
186
|
-
col-gap: 20rpx,
|
|
187
|
-
);
|
|
188
|
-
$numpad: map.merge($numpad-default, $numpad);
|
|
189
|
-
|
|
190
|
-
$number-dialog: () !default;
|
|
191
|
-
$number-dialog-default: (
|
|
192
|
-
// 按钮尺寸
|
|
193
|
-
button-size: 48rpx
|
|
194
|
-
);
|
|
195
|
-
$number-dialog: map.merge($number-dialog-default, $number-dialog);
|
|
196
|
-
|
|
197
|
-
$tab: () !default;
|
|
198
|
-
$tab-default: (
|
|
199
|
-
height: 88rpx,
|
|
200
|
-
tab-padding: 0 10rpx,
|
|
201
|
-
tab-gaps: 0,
|
|
202
|
-
color: UTILS__GLOBAL_VAR(color, foreground),
|
|
203
|
-
font-size: UTILS__GLOBAL_VAR(font-size, large),
|
|
204
|
-
font-weight: 600,
|
|
205
|
-
background: #ffffff,
|
|
206
|
-
border-radius: 0,
|
|
207
|
-
active-color: UTILS__LOCAL_VAR(color),
|
|
208
|
-
indicator-color: UTILS__GLOBAL_VAR(theme, primary),
|
|
209
|
-
indicator-width: null,
|
|
210
|
-
);
|
|
211
|
-
$tab: map.merge($tab-default, $tab);
|
|
212
|
-
|
|
213
|
-
$search: () !default;
|
|
214
|
-
$search-default: (
|
|
215
|
-
background: UTILS__GLOBAL_VAR(color, background),
|
|
216
|
-
border-radius: 8rpx,
|
|
217
|
-
height: 64rpx,
|
|
218
|
-
padding: 0 20rpx,
|
|
219
|
-
);
|
|
220
|
-
$search: map.merge($search-default, $search);
|
|
221
|
-
|
|
222
|
-
$price: () !default;
|
|
223
|
-
$price-default: (
|
|
224
|
-
color: inherit,
|
|
225
|
-
font-size: inherit,
|
|
226
|
-
font-weight: inherit,
|
|
227
|
-
integer-color: UTILS__LOCAL_VAR(color),
|
|
228
|
-
integer-font-size: UTILS__LOCAL_VAR(font-size),
|
|
229
|
-
integer-font-weight: UTILS__LOCAL_VAR(font-weight),
|
|
230
|
-
decimal-color: UTILS__LOCAL_VAR(color),
|
|
231
|
-
decimal-font-size: UTILS__LOCAL_VAR(font-size),
|
|
232
|
-
decimal-font-weight: UTILS__LOCAL_VAR(font-weight),
|
|
233
|
-
unit-color: UTILS__LOCAL_VAR(color),
|
|
234
|
-
unit-font-size: UTILS__LOCAL_VAR(font-size),
|
|
235
|
-
unit-font-weight: UTILS__LOCAL_VAR(font-weight),
|
|
236
|
-
);
|
|
237
|
-
$price: map.merge($price-default, $price);
|
|
238
|
-
|
|
239
|
-
// $page: () !default;
|
|
240
|
-
// $page-default: ();
|
|
241
|
-
// $page: map.merge($page-default, $page);
|
|
242
|
-
|
|
243
|
-
// $page: () !default;
|
|
244
|
-
// $page-default: ();
|
|
245
|
-
// $page: map.merge($page-default, $page);
|
|
1
|
+
// @forward '../../components/badge/badge.scss';
|
|
2
|
+
@forward '../../components/button/button.scss';
|
|
3
|
+
// @forward '../../components/checkbox/checkbox.scss';
|
|
4
|
+
// @forward '../../components/data-list/data-list.scss';
|
|
5
|
+
// @forward '../../components/dialog/dialog.scss';
|
|
6
|
+
// @forward '../../components/empty/empty.scss';
|
|
7
|
+
// @forward '../../components/form-item/form-item.scss';
|
|
8
|
+
// @forward '../../components/load-more/load-more.scss';
|
|
9
|
+
// @forward '../../components/number-dialog/number-dialog.scss';
|
|
10
|
+
// @forward '../../components/number-input/number-input.scss';
|
|
11
|
+
// @forward '../../components/numpad/numpad.scss';
|
|
12
|
+
// @forward '../../components/page/page.scss';
|
|
13
|
+
// @forward '../../components/page/page-header.scss';
|
|
14
|
+
// @forward '../../components/page/page-body.scss';
|
|
15
|
+
// @forward '../../components/page/page-footer.scss';
|
|
16
|
+
// @forward '../../components/popover/popover.scss';
|
|
17
|
+
// @forward '../../components/popup/popup.scss';
|
|
18
|
+
// @forward '../../components/price/price.scss';
|
|
19
|
+
// @forward '../../components/search/search.scss';
|
|
20
|
+
// @forward '../../components/switch/switch.scss';
|
|
21
|
+
// @forward '../../components/tab/tab.scss';
|
package/utils/date.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
type ValidDateValue = Date | number | string;
|
|
2
|
+
/**
|
|
3
|
+
* 将Date 对象、时间戳或时间格式字符串转为 Date 对象
|
|
4
|
+
* @param dateValue Date 对象、时间戳或时间格式字符串
|
|
5
|
+
* @returns Date 对象
|
|
6
|
+
*/
|
|
7
|
+
export declare function toDate(dateValue: ValidDateValue | null | undefined): Date | null;
|
|
8
|
+
type FormatFn = {
|
|
9
|
+
(date: Date | null | undefined, format?: string): string;
|
|
10
|
+
DATE: string;
|
|
11
|
+
DATE_WITH_YEAR: string;
|
|
12
|
+
TIME: string;
|
|
13
|
+
TIME_MS: string;
|
|
14
|
+
TIME_MINUTE: string;
|
|
15
|
+
DATE_TIME: string;
|
|
16
|
+
DATE_TIME_MS: string;
|
|
17
|
+
DATE_TIME_WITH_YEAR: string;
|
|
18
|
+
DATE_TIME_MS_WITH_YEAR: string;
|
|
19
|
+
DATE_MINUTE: string;
|
|
20
|
+
DATE_MINUTE_WITH_YEAR: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* 格式化日期
|
|
24
|
+
*
|
|
25
|
+
* format 参数说明:
|
|
26
|
+
* - Y: 年
|
|
27
|
+
* - M: 月
|
|
28
|
+
* - D: 日
|
|
29
|
+
* - H: 时
|
|
30
|
+
* - m: 分
|
|
31
|
+
* - s: 秒
|
|
32
|
+
* - S: 毫秒
|
|
33
|
+
* - w: 星期
|
|
34
|
+
* - W: 星期(中文)
|
|
35
|
+
* @param date 要格式化的日期对象
|
|
36
|
+
* @param format 格式化参数 默认值 YYYY-MM-DD
|
|
37
|
+
* @returns 格式化后的日期
|
|
38
|
+
*/
|
|
39
|
+
export declare const formatDate: FormatFn;
|
|
40
|
+
/**
|
|
41
|
+
* 获取两个时间的天数差
|
|
42
|
+
* @param day1 时间1
|
|
43
|
+
* @param day2 时间2
|
|
44
|
+
* @returns 天数差,负数: day1 < day2
|
|
45
|
+
*/
|
|
46
|
+
export declare function daysDiff(day1: ValidDateValue, day2: ValidDateValue): number;
|
|
47
|
+
export {};
|
package/utils/date.js
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 将Date 对象、时间戳或时间格式字符串转为 Date 对象
|
|
3
|
-
* @param
|
|
4
|
-
* @returns
|
|
3
|
+
* @param dateValue Date 对象、时间戳或时间格式字符串
|
|
4
|
+
* @returns Date 对象
|
|
5
5
|
*/
|
|
6
6
|
export function toDate(dateValue) {
|
|
7
7
|
if (dateValue instanceof Date) return new Date(dateValue);
|
|
8
8
|
if (typeof dateValue === 'number') return new Date(dateValue);
|
|
9
|
-
if (!dateValue)
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
if (typeof dateValue !== 'string') {
|
|
13
|
-
throw new Error("dateValue's type is invalid");
|
|
14
|
-
}
|
|
9
|
+
if (!dateValue) return null;
|
|
10
|
+
if (typeof dateValue !== 'string') throw new Error("dateValue's type is invalid");
|
|
15
11
|
// 兼容 iOS 日期格式
|
|
16
12
|
const result = new Date(dateValue.replace(/-/g, '/'));
|
|
17
|
-
if (isNaN(result.getTime()))
|
|
18
|
-
throw new Error('dateValue cannot be parsed to Date object');
|
|
19
|
-
}
|
|
13
|
+
if (isNaN(result.getTime())) throw new Error('dateValue cannot be parsed to Date object');
|
|
20
14
|
return result;
|
|
21
15
|
}
|
|
22
|
-
|
|
23
16
|
/**
|
|
24
17
|
* 格式化日期
|
|
25
18
|
*
|
|
@@ -33,14 +26,12 @@ export function toDate(dateValue) {
|
|
|
33
26
|
* - S: 毫秒
|
|
34
27
|
* - w: 星期
|
|
35
28
|
* - W: 星期(中文)
|
|
36
|
-
* @param
|
|
37
|
-
* @param
|
|
38
|
-
* @returns
|
|
29
|
+
* @param date 要格式化的日期对象
|
|
30
|
+
* @param format 格式化参数 默认值 YYYY-MM-DD
|
|
31
|
+
* @returns 格式化后的日期
|
|
39
32
|
*/
|
|
40
|
-
export
|
|
41
|
-
if (!date)
|
|
42
|
-
return '';
|
|
43
|
-
}
|
|
33
|
+
export const formatDate = (date, format = formatDate.DATE_WITH_YEAR) => {
|
|
34
|
+
if (!date) return '';
|
|
44
35
|
const fullYear = date.getFullYear().toString();
|
|
45
36
|
const year = fullYear.substring(fullYear.length - 2);
|
|
46
37
|
const month = (date.getMonth() + 1).toString();
|
|
@@ -74,7 +65,6 @@ export function formatDate(date, format = formatDate.DATE_WITH_YEAR) {
|
|
|
74
65
|
weekCN = '六';
|
|
75
66
|
break;
|
|
76
67
|
}
|
|
77
|
-
|
|
78
68
|
const replacement = [
|
|
79
69
|
{ reg: 'Y{3,4}', val: fullYear, pad: 0 },
|
|
80
70
|
{ reg: 'Y{1,2}', val: year, pad: 0 },
|
|
@@ -87,16 +77,14 @@ export function formatDate(date, format = formatDate.DATE_WITH_YEAR) {
|
|
|
87
77
|
{ reg: 'w', val: week, pad: 0 },
|
|
88
78
|
{ reg: 'W', val: weekCN, pad: 0 },
|
|
89
79
|
];
|
|
90
|
-
|
|
91
80
|
for (let i = 0; i < replacement.length; i++) {
|
|
92
81
|
const r = replacement[i];
|
|
93
|
-
format = format.replace(new RegExp(r.reg, 'g'),
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
format = format.replace(new RegExp(r.reg, 'g'), (m) =>
|
|
83
|
+
r.pad > 0 ? r.val.padStart(Math.min(r.pad, m.length), '0') : r.val
|
|
84
|
+
);
|
|
96
85
|
}
|
|
97
86
|
return format;
|
|
98
|
-
}
|
|
99
|
-
|
|
87
|
+
};
|
|
100
88
|
/** 月日 */
|
|
101
89
|
formatDate.DATE = 'MM-DD';
|
|
102
90
|
/** 年月日 */
|
|
@@ -119,32 +107,24 @@ formatDate.DATE_TIME_MS_WITH_YEAR = 'YYYY-MM-DD HH:mm:ss.SSS';
|
|
|
119
107
|
formatDate.DATE_MINUTE = 'MM-DD HH:mm';
|
|
120
108
|
/** 年月日 时分 */
|
|
121
109
|
formatDate.DATE_MINUTE_WITH_YEAR = 'YYYY-MM-DD HH:mm';
|
|
122
|
-
|
|
123
110
|
/** 时区差 */
|
|
124
111
|
const TIMEZONE_OFFSET = new Date().getTimezoneOffset() * 60 * 1000;
|
|
125
|
-
|
|
126
112
|
/**
|
|
127
113
|
* 获取时间的UTC相对时间戳
|
|
128
|
-
* @param
|
|
129
|
-
* @returns
|
|
114
|
+
* @param date 时间
|
|
115
|
+
* @returns 毫秒数
|
|
130
116
|
*/
|
|
131
117
|
function toDayTimestamp(date) {
|
|
132
|
-
|
|
133
|
-
if (typeof date === '
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
d = toDate(date);
|
|
137
|
-
} else if (!(date instanceof Date)) {
|
|
138
|
-
d = new Date();
|
|
139
|
-
}
|
|
140
|
-
return d.getTime() - TIMEZONE_OFFSET;
|
|
118
|
+
if (typeof date === 'number') return date - TIMEZONE_OFFSET;
|
|
119
|
+
if (typeof date === 'string') return toDate(date).getTime() - TIMEZONE_OFFSET;
|
|
120
|
+
if (date instanceof Date) return date.getTime() - TIMEZONE_OFFSET;
|
|
121
|
+
return Date.now() - TIMEZONE_OFFSET;
|
|
141
122
|
}
|
|
142
|
-
|
|
143
123
|
/**
|
|
144
124
|
* 获取两个时间的天数差
|
|
145
|
-
* @param
|
|
146
|
-
* @param
|
|
147
|
-
* @returns
|
|
125
|
+
* @param day1 时间1
|
|
126
|
+
* @param day2 时间2
|
|
127
|
+
* @returns 天数差,负数: day1 < day2
|
|
148
128
|
*/
|
|
149
129
|
export function daysDiff(day1, day2) {
|
|
150
130
|
return Math.floor(toDayTimestamp(day1) / 8.64e7) - Math.floor(toDayTimestamp(day2) / 8.64e7);
|
package/utils/date.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
type ValidDateValue = Date | number | string;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 将Date 对象、时间戳或时间格式字符串转为 Date 对象
|
|
5
|
+
* @param dateValue Date 对象、时间戳或时间格式字符串
|
|
6
|
+
* @returns Date 对象
|
|
7
|
+
*/
|
|
8
|
+
export function toDate(dateValue: ValidDateValue | null | undefined): Date | null {
|
|
9
|
+
if (dateValue instanceof Date) return new Date(dateValue);
|
|
10
|
+
if (typeof dateValue === 'number') return new Date(dateValue);
|
|
11
|
+
if (!dateValue) return null;
|
|
12
|
+
if (typeof dateValue !== 'string') throw new Error("dateValue's type is invalid");
|
|
13
|
+
|
|
14
|
+
// 兼容 iOS 日期格式
|
|
15
|
+
const result = new Date(dateValue.replace(/-/g, '/'));
|
|
16
|
+
if (isNaN(result.getTime())) throw new Error('dateValue cannot be parsed to Date object');
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type FormatFn = {
|
|
21
|
+
(date: Date | null | undefined, format?: string): string;
|
|
22
|
+
DATE: string;
|
|
23
|
+
DATE_WITH_YEAR: string;
|
|
24
|
+
TIME: string;
|
|
25
|
+
TIME_MS: string;
|
|
26
|
+
TIME_MINUTE: string;
|
|
27
|
+
DATE_TIME: string;
|
|
28
|
+
DATE_TIME_MS: string;
|
|
29
|
+
DATE_TIME_WITH_YEAR: string;
|
|
30
|
+
DATE_TIME_MS_WITH_YEAR: string;
|
|
31
|
+
DATE_MINUTE: string;
|
|
32
|
+
DATE_MINUTE_WITH_YEAR: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* 格式化日期
|
|
36
|
+
*
|
|
37
|
+
* format 参数说明:
|
|
38
|
+
* - Y: 年
|
|
39
|
+
* - M: 月
|
|
40
|
+
* - D: 日
|
|
41
|
+
* - H: 时
|
|
42
|
+
* - m: 分
|
|
43
|
+
* - s: 秒
|
|
44
|
+
* - S: 毫秒
|
|
45
|
+
* - w: 星期
|
|
46
|
+
* - W: 星期(中文)
|
|
47
|
+
* @param date 要格式化的日期对象
|
|
48
|
+
* @param format 格式化参数 默认值 YYYY-MM-DD
|
|
49
|
+
* @returns 格式化后的日期
|
|
50
|
+
*/
|
|
51
|
+
export const formatDate: FormatFn = (date, format = formatDate.DATE_WITH_YEAR) => {
|
|
52
|
+
if (!date) return '';
|
|
53
|
+
const fullYear = date.getFullYear().toString();
|
|
54
|
+
const year = fullYear.substring(fullYear.length - 2);
|
|
55
|
+
const month = (date.getMonth() + 1).toString();
|
|
56
|
+
const day = date.getDate().toString();
|
|
57
|
+
const hour = date.getHours().toString();
|
|
58
|
+
const min = date.getMinutes().toString();
|
|
59
|
+
const sec = date.getSeconds().toString();
|
|
60
|
+
const ms = date.getMilliseconds().toString();
|
|
61
|
+
const week = date.getDay().toString();
|
|
62
|
+
let weekCN = '';
|
|
63
|
+
switch (week) {
|
|
64
|
+
case '0':
|
|
65
|
+
weekCN = '日';
|
|
66
|
+
break;
|
|
67
|
+
case '1':
|
|
68
|
+
weekCN = '一';
|
|
69
|
+
break;
|
|
70
|
+
case '2':
|
|
71
|
+
weekCN = '二';
|
|
72
|
+
break;
|
|
73
|
+
case '3':
|
|
74
|
+
weekCN = '三';
|
|
75
|
+
break;
|
|
76
|
+
case '4':
|
|
77
|
+
weekCN = '四';
|
|
78
|
+
break;
|
|
79
|
+
case '5':
|
|
80
|
+
weekCN = '五';
|
|
81
|
+
break;
|
|
82
|
+
case '6':
|
|
83
|
+
weekCN = '六';
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
const replacement = [
|
|
87
|
+
{ reg: 'Y{3,4}', val: fullYear, pad: 0 },
|
|
88
|
+
{ reg: 'Y{1,2}', val: year, pad: 0 },
|
|
89
|
+
{ reg: 'M{1,2}', val: month, pad: 2 },
|
|
90
|
+
{ reg: 'D{1,2}', val: day, pad: 2 },
|
|
91
|
+
{ reg: 'H{1,2}', val: hour, pad: 2 },
|
|
92
|
+
{ reg: 'm{1,2}', val: min, pad: 2 },
|
|
93
|
+
{ reg: 's{1,2}', val: sec, pad: 2 },
|
|
94
|
+
{ reg: 'S{1,3}', val: ms, pad: 3 },
|
|
95
|
+
{ reg: 'w', val: week, pad: 0 },
|
|
96
|
+
{ reg: 'W', val: weekCN, pad: 0 },
|
|
97
|
+
];
|
|
98
|
+
for (let i = 0; i < replacement.length; i++) {
|
|
99
|
+
const r = replacement[i]!;
|
|
100
|
+
format = format.replace(new RegExp(r.reg, 'g'), (m) =>
|
|
101
|
+
r.pad > 0 ? r.val.padStart(Math.min(r.pad, m.length), '0') : r.val
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return format;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/** 月日 */
|
|
108
|
+
formatDate.DATE = 'MM-DD';
|
|
109
|
+
/** 年月日 */
|
|
110
|
+
formatDate.DATE_WITH_YEAR = 'YYYY-MM-DD';
|
|
111
|
+
/** 时分秒 */
|
|
112
|
+
formatDate.TIME = 'HH:mm:ss';
|
|
113
|
+
/** 时分秒.毫秒 */
|
|
114
|
+
formatDate.TIME_MS = 'HH:mm:ss.SSS';
|
|
115
|
+
/** 时分 */
|
|
116
|
+
formatDate.TIME_MINUTE = 'HH:mm';
|
|
117
|
+
/** 月日 时分秒 */
|
|
118
|
+
formatDate.DATE_TIME = 'MM-DD HH:mm:ss';
|
|
119
|
+
/** 月日 时分秒.毫秒 */
|
|
120
|
+
formatDate.DATE_TIME_MS = 'MM-DD HH:mm:ss.SSS';
|
|
121
|
+
/** 年月日 时分秒 */
|
|
122
|
+
formatDate.DATE_TIME_WITH_YEAR = 'YYYY-MM-DD HH:mm:ss';
|
|
123
|
+
/** 年月日 时分秒.毫秒 */
|
|
124
|
+
formatDate.DATE_TIME_MS_WITH_YEAR = 'YYYY-MM-DD HH:mm:ss.SSS';
|
|
125
|
+
/** 月日 时分 */
|
|
126
|
+
formatDate.DATE_MINUTE = 'MM-DD HH:mm';
|
|
127
|
+
/** 年月日 时分 */
|
|
128
|
+
formatDate.DATE_MINUTE_WITH_YEAR = 'YYYY-MM-DD HH:mm';
|
|
129
|
+
|
|
130
|
+
/** 时区差 */
|
|
131
|
+
const TIMEZONE_OFFSET = new Date().getTimezoneOffset() * 60 * 1000;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 获取时间的UTC相对时间戳
|
|
135
|
+
* @param date 时间
|
|
136
|
+
* @returns 毫秒数
|
|
137
|
+
*/
|
|
138
|
+
function toDayTimestamp(date: ValidDateValue): number {
|
|
139
|
+
if (typeof date === 'number') return date - TIMEZONE_OFFSET;
|
|
140
|
+
if (typeof date === 'string') return toDate(date)!.getTime() - TIMEZONE_OFFSET;
|
|
141
|
+
if (date instanceof Date) return date.getTime() - TIMEZONE_OFFSET;
|
|
142
|
+
return Date.now() - TIMEZONE_OFFSET;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 获取两个时间的天数差
|
|
147
|
+
* @param day1 时间1
|
|
148
|
+
* @param day2 时间2
|
|
149
|
+
* @returns 天数差,负数: day1 < day2
|
|
150
|
+
*/
|
|
151
|
+
export function daysDiff(day1: ValidDateValue, day2: ValidDateValue): number {
|
|
152
|
+
return Math.floor(toDayTimestamp(day1) / 8.64e7) - Math.floor(toDayTimestamp(day2) / 8.64e7);
|
|
153
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function freezeDeep<T>(obj: T): Readonly<T>;
|
package/utils/freezeDeep.js
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 深度冻结一个对象
|
|
3
|
-
*
|
|
4
|
-
* 注意:传入的对象和返回的对象是同一个引用,慎用!!
|
|
5
|
-
*
|
|
6
|
-
* @template T
|
|
7
|
-
* @param {T} obj 要被冻结的对象
|
|
8
|
-
* @returns {Readonly<T>}
|
|
9
|
-
*/
|
|
10
1
|
export function freezeDeep(obj) {
|
|
11
2
|
if (!(typeof obj === 'object' && obj)) {
|
|
12
3
|
return obj;
|
|
13
|
-
} else {
|
|
14
|
-
for (let key in obj) {
|
|
15
|
-
freezeDeep(obj[key]);
|
|
16
|
-
}
|
|
17
|
-
return Object.freeze(obj);
|
|
18
4
|
}
|
|
5
|
+
for (const key in obj) {
|
|
6
|
+
freezeDeep(obj[key]);
|
|
7
|
+
}
|
|
8
|
+
return Object.freeze(obj);
|
|
19
9
|
}
|
package/utils/price.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface FormatPriceOption {
|
|
2
|
+
/** 精度,默认为 2 */
|
|
3
|
+
precision: number;
|
|
4
|
+
/** 是否补齐小数部分 0 */
|
|
5
|
+
padDecimal: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface FormatPriceResult {
|
|
8
|
+
/** 格式化的价格字符串 */
|
|
9
|
+
price: string;
|
|
10
|
+
/** 是否负值 */
|
|
11
|
+
negative: boolean;
|
|
12
|
+
/** 整数部分价格 */
|
|
13
|
+
integer: string;
|
|
14
|
+
/** 小数部分价格 */
|
|
15
|
+
decimal: string;
|
|
16
|
+
/** 价格对应数值 */
|
|
17
|
+
number: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 格式化价格
|
|
21
|
+
* @param price 价格
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatPrice(price: number | string, option?: FormatPriceOption): FormatPriceResult;
|
|
24
|
+
export {};
|
package/utils/price.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 格式化价格
|
|
3
|
-
* @param
|
|
4
|
-
* @returns {FormattedPrice}
|
|
3
|
+
* @param price 价格
|
|
5
4
|
*/
|
|
6
|
-
export function formatPrice(price) {
|
|
7
|
-
if (isNaN(price)) {
|
|
5
|
+
export function formatPrice(price, option) {
|
|
6
|
+
if (isNaN(Number(price))) {
|
|
8
7
|
return {
|
|
9
8
|
price: '',
|
|
10
9
|
negative: false,
|
|
@@ -20,13 +19,20 @@ export function formatPrice(price) {
|
|
|
20
19
|
price = -price;
|
|
21
20
|
}
|
|
22
21
|
const integer = Math.floor(price).toString();
|
|
23
|
-
const
|
|
22
|
+
const decimalNum = Math.round(Number(price + 'e' + (option?.precision ?? 2))) % 100;
|
|
23
|
+
let decimal;
|
|
24
|
+
if (option?.padDecimal ?? true) {
|
|
25
|
+
decimal = '.' + decimalNum.toString().padStart(option?.precision ?? 2, '0');
|
|
26
|
+
} else {
|
|
27
|
+
if (decimalNum === 0) decimal = '';
|
|
28
|
+
else decimal = decimalNum.toString().slice(1);
|
|
29
|
+
}
|
|
24
30
|
const formattedPrice = `${negative ? '-' : ''}${integer}.${decimal}`;
|
|
25
31
|
return {
|
|
26
|
-
price: formattedPrice,
|
|
32
|
+
price: formattedPrice,
|
|
27
33
|
negative,
|
|
28
|
-
integer,
|
|
29
|
-
decimal,
|
|
34
|
+
integer,
|
|
35
|
+
decimal,
|
|
30
36
|
number: Number(formattedPrice),
|
|
31
37
|
};
|
|
32
38
|
}
|