@xtdev/xt-miniprogram-ui 1.2.40 → 1.2.42

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.
@@ -0,0 +1,77 @@
1
+ <!--
2
+ * @Author: Mr.Hu
3
+ * @Date: 2024-01-04 16:02:07
4
+ * @Description:
5
+ * @LastEditors: Mr.Hu
6
+ -->
7
+ # 时间选择器
8
+
9
+ ### 介绍
10
+ 用于选择单个时间点或时间范围
11
+
12
+ ### 效果图
13
+ ![效果图](https://img.tanjiu.cn/home/jejaRihM8wyBbSekBeneansB3GCTwCD8.png "时间选择器")
14
+
15
+ ### 引入
16
+ 在app.json或页面配置json中引入
17
+ ```
18
+ "usingComponents": {
19
+ "xt-date-picker": "@xtdev/xt-miniprogram-ui/xt-date-picker",
20
+ }
21
+ ```
22
+
23
+ ## 代码演示
24
+
25
+ ### 基础用法
26
+ ![效果图](https://img.tanjiu.cn/home/jejaRihM8wyBbSekBeneansB3GCTwCD8.png "基础用法")
27
+
28
+ ```
29
+ <xt-date-picker show="{{true}}" />
30
+ ```
31
+
32
+ ### 指定为按日筛选
33
+ ![效果图](https://img.tanjiu.cn/home/bX2eCnbwTyAjaxCFasTHedKfZQEdEDzD.png "指定为按日筛选")
34
+
35
+ ```
36
+ <xt-date-picker show="{{true}}" type="date" />
37
+ ```
38
+ ### 指定最小和最大可选日期
39
+ ![效果图](https://img.tanjiu.cn/home/DCHaTGQBHMy74W5n2YCZeZ6hc3fnkn3D.png "指定最小和最大可选日期")
40
+
41
+ ```
42
+ <xt-date-picker show="{{true}}" minDate="2023-4-1" maxDate="2024-4-1"/>
43
+ ```
44
+ ### 指定选择器默认选中日期
45
+ ![效果图](https://img.tanjiu.cn/home/cfwHk7JrBpGRpihQG2w6HDbw3TsQbs2p.png "指定选择器默认选中日期")
46
+
47
+ ```
48
+ <xt-date-picker show="{{true}}" currentDate="2022-4-1"/>
49
+ ```
50
+ ### 展示切换模式按钮
51
+ ![效果图](https://img.tanjiu.cn/home/sfawPWDsenpxtjWnPhXCxFcsnhQYBhHQ.png "展示切换模式按钮")
52
+
53
+ ```
54
+ <xt-date-picker show="{{true}}" showChangeTab="{{true}}"/>
55
+ ```
56
+
57
+ ## API
58
+
59
+ #### xt-date-picker props
60
+
61
+ | 参数 | 说明 | 类型 |
62
+ | ----------- | ----------- | ---------- |
63
+ | show | 是否显示时间选择器,默认false | `Boolean` |
64
+ | title | 选择器标题 | `String` |
65
+ | type | 选择模式,默认`dateRange`(可选值为`date`、`dateRange`) | `String` |
66
+ | minDate | 最小可选日期 | `String` |
67
+ | maxDate | 最大可选日期 | `String` |
68
+ | currentDate | 选择器默认选中的日期,默认为当天 | `Number` |
69
+ | showChangeTab | 是否展示切换模式按钮,默认false | `Boolean` |
70
+ | confirmButtonText | 确认按钮文字 | `String` |
71
+ | cancelButtonText | 取消按钮文字 | `String` |
72
+
73
+ ## Event
74
+
75
+ | 事件名 | 说明 | 回调参数 |
76
+ | ----------- | ----------- | ----------- |
77
+ | getDateValue | 点击确认按钮时触发 | `String` |
@@ -0,0 +1,606 @@
1
+ /*
2
+ * @Author: Mr.Hu
3
+ * @Date: 2023-12-29 09:48:47
4
+ * @Description: 日期组件-js逻辑
5
+ * @LastEditors: Mr.Hu
6
+ */
7
+ let LASTMONTH = null; // 用于储存上一次选中的月份
8
+ // 获取当前月份的天数
9
+ const getDaysInMonth = (year, month) => {
10
+ const daysInMonth = new Date(year, month, 0).getDate();
11
+ return daysInMonth;
12
+ };
13
+ // 深拷贝
14
+ const deepClone = (val) => {
15
+ if (!val) {return null;}
16
+ const isObject = (obj) =>
17
+ Object.prototype.toString.call(obj) === "[object object]";
18
+ let newResult = Array.isArray(val) ? [] : {};
19
+ for (const key in val) {
20
+ if (Object.prototype.hasOwnProperty.call(val, key)) {
21
+ newResult[key] = isObject(val[key]) ? deepClone(val[key]) : val[key];
22
+ }
23
+ }
24
+ return newResult;
25
+ };
26
+ // 获取默认时间
27
+ const getDefaultDate = () => {
28
+ const now = new Date();
29
+ return `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
30
+ };
31
+ // 查找数组中第二个出现的元素下标
32
+ const findSecondIndexOf = (arr, predicate) => {
33
+ const firstIndex = arr.findIndex(predicate);
34
+ if (firstIndex === -1) {
35
+ return -1; // 如果没有找到匹配项,返回-1
36
+ }
37
+ // 从第一个匹配项的下一个位置继续查找
38
+ return arr.slice(firstIndex + 1).findIndex(predicate);
39
+ };
40
+
41
+ Component({
42
+ behaviors: [],
43
+ properties: {
44
+ // 选择器显示隐藏
45
+ show: {
46
+ type: Boolean,
47
+ value: false,
48
+ },
49
+ // 弹窗标题
50
+ title: {
51
+ type: String,
52
+ value: "日期筛选",
53
+ },
54
+ // 日期选择器模式 date 年月日选择 dateRange 时间范围选择 yearMonth 年月
55
+ type: {
56
+ type: String,
57
+ value: "dateRange",
58
+ observer: function (value) {
59
+ this.setData({ filtType: value });
60
+ },
61
+ },
62
+ // 最小可选日期
63
+ minDate: {
64
+ type: String,
65
+ value: "1990-1-1",
66
+ },
67
+ // 最大可选日期
68
+ maxDate: {
69
+ type: String,
70
+ value: "",
71
+ },
72
+ // 当前时间
73
+ currentDate: {
74
+ type: String,
75
+ value: "",
76
+ },
77
+ // 展示切换按钮
78
+ showChangeTab: {
79
+ type: Boolean,
80
+ value: false,
81
+ },
82
+ // 确认按钮文字
83
+ confirmButtonText: {
84
+ type: String,
85
+ value: "确认",
86
+ },
87
+ // 取消按钮文字
88
+ cancelButtonText: {
89
+ type: String,
90
+ value: "重置",
91
+ },
92
+ },
93
+ data: {
94
+ years: [], // 年份数组
95
+ months: [], // 月份数组
96
+ days: [], // 天份数组
97
+ dateArr: [9999, 1, 1], // 下拉数组下标
98
+ dateValue: "", // 选中的日期值
99
+ dateStr: "", // 选中的日期显示字符
100
+ startDateArr: [], // 开始日期数组下标
101
+ startDateValue: "", // 开始日期选中值
102
+ startDateStr: "", // 开始日期字符
103
+ endDateArr: [], // 结束日期数组下标
104
+ endDateValue: "", // 结束日期选中值
105
+ endDateStr: "", // 结束日期字符
106
+ defaultDate: "", // 默认日期(组件接收的|当前时间)
107
+ checkedType: "start", // 当前选择的日期类型
108
+ clickedEnd: false, // 点击结束时间
109
+ filtType: "dateRange", // 选择器模式
110
+ typeEnums: {
111
+ date: "按日筛选",
112
+ dateRange: "按月筛选",
113
+ },
114
+ indicatorSyle: "font-size: 40rpx;font-weight: 800;height: 60px",
115
+ },
116
+ lifetimes: {
117
+ created() {},
118
+ async attached() {
119
+ await this.initPickerArr();
120
+ this.setDefaultDate();
121
+ await this.handelDays("", true);
122
+ },
123
+ },
124
+ methods: {
125
+ // 初始化日期数组
126
+ initPickerArr(curSelDate, dateValue) {
127
+ const {
128
+ minYear,
129
+ maxYear,
130
+ minMonth,
131
+ maxMonth,
132
+ minDay,
133
+ maxDay,
134
+ selYearColum,
135
+ selMonthColum,
136
+ selDayColum,
137
+ } = this.getMinAndMaxDate(curSelDate, dateValue);
138
+ return new Promise((resolve) => {
139
+ if (selDayColum) {
140
+ resolve();
141
+ return;
142
+ }
143
+ const years = [],
144
+ months = [],
145
+ days = [];
146
+
147
+ for (let i = minYear; i <= maxYear; i++) {
148
+ years.push(i);
149
+ }
150
+ for (let i = minMonth; i <= maxMonth; i++) {
151
+ months.push(i);
152
+ }
153
+ for (let i = minDay; i <= maxDay; i++) {
154
+ days.push(i);
155
+ }
156
+ if (curSelDate) {
157
+ this.setData({
158
+ months,
159
+ });
160
+ } else if (selMonthColum) {
161
+ this.setData({
162
+ days,
163
+ });
164
+ } else {
165
+ this.setData({
166
+ years,
167
+ months,
168
+ days,
169
+ });
170
+ }
171
+ resolve();
172
+ });
173
+ },
174
+ // 获取最小最大年月日, 当前所选择的列
175
+ getMinAndMaxDate(curSelDate, dateValue) {
176
+ let {
177
+ data: { minDate, maxDate, currentDate, dateArr },
178
+ } = this;
179
+ currentDate = currentDate || getDefaultDate();
180
+ let minYear,
181
+ maxYear,
182
+ minMonth,
183
+ maxMonth,
184
+ minDay,
185
+ maxDay = 31;
186
+ const selYearColum =
187
+ dateValue && dateArr ? dateValue[0] !== dateArr[0] : false; // 选择的是年份列
188
+ const selMonthColum =
189
+ dateValue && dateArr ? dateValue[1] !== dateArr[1] : false; // 选择的是月份列
190
+ const selDayColum =
191
+ dateValue && dateArr ? dateValue[2] !== dateArr[2] : false; // 选择的是日份列
192
+ const curDateArr = this.transformToArr(
193
+ curSelDate ? curSelDate : currentDate
194
+ );
195
+ // 当前日期数组
196
+ const curYear = curDateArr[0],
197
+ curMonth = curDateArr[1],
198
+ curDay = curDateArr[2];
199
+ if (minDate && minDate.length) {
200
+ const minDateArr = this.transformToArr(minDate);
201
+ minYear = Number(minDateArr[0]);
202
+ minMonth = curYear && curYear == minDateArr[0] ? minDateArr[1] : 1;
203
+ minDay =
204
+ curYear && curYear == minDateArr[0] && curMonth == minDateArr[1]
205
+ ? minDateArr[2]
206
+ : 1;
207
+ } else {
208
+ minYear = 1990;
209
+ minMonth = 1;
210
+ minDay = 1;
211
+ }
212
+ if (maxDate && maxDate.length) {
213
+ const maxDateArr = this.transformToArr(maxDate);
214
+ maxYear = maxDateArr[0];
215
+ maxMonth = curYear && curYear == maxDateArr[0] ? maxDateArr[1] : 12;
216
+ maxDay =
217
+ curYear && curYear == maxDateArr[0] && curMonth == maxDateArr[1]
218
+ ? maxDateArr[2]
219
+ : 31;
220
+ } else {
221
+ maxYear = new Date().getFullYear();
222
+ maxMonth = 12;
223
+ maxDay = getDaysInMonth(curYear, curMonth);
224
+ }
225
+ return {
226
+ minYear,
227
+ maxYear,
228
+ minMonth,
229
+ maxMonth,
230
+ minDay,
231
+ maxDay,
232
+ curYear,
233
+ curMonth,
234
+ curDay,
235
+ selYearColum,
236
+ selMonthColum,
237
+ selDayColum,
238
+ };
239
+ },
240
+ // 处理传入日期格式
241
+ transformToArr(dateStr) {
242
+ if (!dateStr) {return null;}
243
+ const dateArr = dateStr.split("-");
244
+ if (!dateArr.length) {return null;}
245
+ return dateArr;
246
+ },
247
+ // 设置默认年月日
248
+ setDefaultDate() {
249
+ const now = new Date();
250
+ let {
251
+ data: {
252
+ dateValue,
253
+ currentDate,
254
+ dateStr,
255
+ dateArr,
256
+ defaultDate,
257
+ minDate,
258
+ },
259
+ } = this;
260
+ currentDate = currentDate || getDefaultDate();
261
+ let curDateArr = this.transformToArr(currentDate); // 当前日期数组
262
+ const curYear = curDateArr[0];
263
+ const curMonth = curDateArr[1];
264
+ const curDay = curDateArr[2];
265
+ const minDateArr = this.transformToArr(minDate); // 最小可选日期数组
266
+ const defaultYear = minDateArr ? minDateArr[0] : 1990;
267
+ const defaultMonth =
268
+ minDateArr && curYear == minDateArr[0] ? minDateArr[1] : 1;
269
+ const defaultDay =
270
+ minDateArr && curYear == minDateArr[0] && curMonth == minDateArr[1]
271
+ ? minDateArr[2]
272
+ : 1;
273
+ if (curDateArr && curDateArr.length) {
274
+ // 如果有设置当前日期,则数组下标选中当前日期
275
+ dateStr = `${curYear}年${curMonth}月${curDay}日`;
276
+ dateArr = [
277
+ curYear - defaultYear,
278
+ curMonth - defaultMonth,
279
+ curDateArr[2] - defaultDay,
280
+ ];
281
+ dateValue = `${curYear}-${curMonth}-${curDay}`;
282
+ } else {
283
+ // 如果有设置当前日期,则数组下标默认选中当前
284
+ dateStr = `${now.getFullYear()}年${
285
+ now.getMonth() + 1
286
+ }月${now.getDate()}日`;
287
+ dateArr = [now.getFullYear() - 1990, now.getMonth(), now.getDate() - 1];
288
+ dateValue = `${now.getFullYear()}-${
289
+ now.getMonth() + 1
290
+ }-${now.getDate()}`;
291
+ }
292
+ // 储存当前传入的原始值
293
+ defaultDate = JSON.parse(JSON.stringify(dateValue));
294
+ this.setData({
295
+ dateArr,
296
+ dateStr,
297
+ dateValue,
298
+ defaultDate,
299
+ startDateArr: dateArr,
300
+ startDateStr: dateStr,
301
+ startDateValue: dateValue,
302
+ });
303
+ },
304
+ // 处理当前月的天数
305
+ handelDays(value, isInitDate = false) {
306
+ return new Promise((resolve) => {
307
+ let {
308
+ data: { days, dateArr, years, months, minDate, maxDate, dateValue },
309
+ } = this;
310
+ // 如果没有默认值
311
+ if (!value) {
312
+ const { minYear } = this.getMinAndMaxDate();
313
+ let {
314
+ data: { currentDate },
315
+ } = this;
316
+ currentDate = currentDate || getDefaultDate();
317
+ value = this.transformToArr(currentDate); // 当前日期数组
318
+ value = [value[0] - minYear, value[1] - 1, value[2] - 1];
319
+ }
320
+ const selYear = years[value?.[0]],
321
+ selMonth = months[value?.[1]],
322
+ selDay = days[value?.[2]];
323
+ let {
324
+ minYear,
325
+ minMonth,
326
+ maxMonth,
327
+ minDay,
328
+ maxDay,
329
+ selYearColum,
330
+ selMonthColum,
331
+ selDayColum,
332
+ } = this.getMinAndMaxDate(`${selYear}-${selMonth}-${selDay}`, value);
333
+ // 获取当前日期数组,当前选中日期值
334
+ let newDaysArr = days,
335
+ newDateArr = value;
336
+ /** 处理月数组下拉列表 **/
337
+ // 1.后面插入:如果当前选中的是月份,并且是接近最大月,并且当前月份后面没有重复月份,处理月份下拉数组
338
+ const isMonthLastColum =
339
+ selMonth >= maxMonth - 3 && (selMonthColum || selYearColum);
340
+ if (isMonthLastColum || (selMonth >= maxMonth - 3 && isInitDate)) {
341
+ for (let i = minMonth; i <= maxMonth; i++) {
342
+ months.push(i);
343
+ }
344
+ this.setData({
345
+ months,
346
+ });
347
+ }
348
+ // 2.前面插入:如果当前选中的是月份,并且是接近最小月,并且当前月份前面没有重复月份,处理月份下拉数组
349
+ const isMonthFirstColum =
350
+ selMonth <= maxMonth - 3 && newDateArr[1] < maxMonth && selMonthColum; // 当前选中的第一月
351
+ if (isMonthFirstColum || (selMonth <= maxMonth - 3 && isInitDate)) {
352
+ for (let i = maxMonth; i >= minMonth; i--) {
353
+ months.unshift(i);
354
+ }
355
+ newDateArr = [newDateArr[0], newDateArr[1] + maxMonth, newDateArr[2]];
356
+ this.setData({
357
+ months,
358
+ });
359
+ }
360
+ /** 处理天数下拉列表 **/
361
+ const firstIndex = findSecondIndexOf(newDaysArr, (el) => el == 1);
362
+ // 2.切换月份,更新天数组列表
363
+ if (selMonthColum || selYear) {
364
+ const newArray = [];
365
+ for (let j = 1; j <= 2; j++) {
366
+ for (let i = minDay; i <= maxDay; i++) {
367
+ newArray.push(i);
368
+ }
369
+ }
370
+ newDaysArr = newArray;
371
+ const beforeMonth = LASTMONTH;
372
+ const prevSelDateParams = this.getMinAndMaxDate(`${selYear}-${beforeMonth}-${selDay}`);
373
+ // 如果选中的是当月第一天,处理当前选中的下标逻辑
374
+ if (selDay == 1) {
375
+ // 获取切换之前的月数
376
+ const valueDay = maxDay - prevSelDateParams.maxDay;
377
+ newDateArr = [newDateArr[0], newDateArr[1], newDateArr[2] + valueDay];
378
+ }
379
+ // 如果选中的是当月最后一天,处理当前选中的下标逻辑
380
+ if (selDay == prevSelDateParams.maxDay) {
381
+ // 获取当前月天数
382
+ const curSelDateParams = this.getMinAndMaxDate(`${selYear}-${selMonth}-${selDay}`);
383
+ newDateArr = [newDateArr[0], newDateArr[1], curSelDateParams.maxDay - 1];
384
+ }
385
+ }
386
+ // 天数列表上拉循环选择--后面插入
387
+ // 1.如果当前选中的是天数,并且是接近最大天数,并且当前天数后面没有重复天数,处理天数下拉数组
388
+ const isDayLastColum = selDayColum && selDay >= maxDay - 3;
389
+ // 获取上一个月的天数
390
+ if (isDayLastColum || (isInitDate && selDay >= maxDay - 3)) {
391
+ // 如果当前选中的不是天数组最后三条数据,重新组装
392
+ if (newDaysArr.length > 58 && value[2] <= newDaysArr.length - 3) {
393
+ newDaysArr = newDaysArr.slice(firstIndex + 1, newDaysArr.length);
394
+ }
395
+ for (let i = minDay; i <= maxDay; i++) {
396
+ newDaysArr.push(i);
397
+ }
398
+ this.setData({
399
+ days: newDaysArr,
400
+ });
401
+ }
402
+ // 天数列表上拉循环选择--前面插入
403
+ // 1.当前选中天数列表,选中的接近最小天数,并且设置的天数小于最大天数
404
+ const isDayFirstColum =
405
+ selDay <= minDay + 3 && newDateArr[2] < maxDay && selDayColum; // 当前选中的第一日
406
+ // 2. 当前初始日期前面设置添加循环选择
407
+ if (isDayFirstColum || (isInitDate && selDay <= minDay + 3)) {
408
+ for (let i = maxDay; i >= minDay; i--) {
409
+ newDaysArr.unshift(i);
410
+ }
411
+ this.setData({
412
+ days: newDaysArr,
413
+ });
414
+ let valueDay = Number(newDateArr[2] + maxDay);
415
+ newDateArr = [newDateArr[0], newDateArr[1], valueDay];
416
+ }
417
+ LASTMONTH = selMonth;// 储存当前选中的月份,为上次选中的月份
418
+ // 天数选择下拉循环选择
419
+ // 解决回弹动画延时问题
420
+ if ((isMonthFirstColum || isDayFirstColum) && !this.data.isRset) {
421
+ setTimeout(() => {
422
+ this.setData({
423
+ days: newDaysArr,
424
+ dateArr: newDateArr,
425
+ });
426
+ resolve();
427
+ }, 1500);
428
+ } else {
429
+ this.setData({
430
+ days: newDaysArr,
431
+ dateArr: newDateArr,
432
+ isRset: false,
433
+ });
434
+ resolve();
435
+ }
436
+ });
437
+ },
438
+ // 滑动下拉列表
439
+ async bindChange(e) {
440
+ const value = e?.detail?.value;
441
+ // 处理每月可选天数
442
+ await this.handelDays(value);
443
+ let {
444
+ data: {
445
+ years,
446
+ months,
447
+ days,
448
+ dateValue,
449
+ dateStr,
450
+ dateArr,
451
+ filtType,
452
+ checkedType,
453
+ startDateArr,
454
+ endDateArr,
455
+ startDateValue,
456
+ endDateValue,
457
+ startDateStr,
458
+ endDateStr,
459
+ },
460
+ } = this;
461
+ dateStr = `${years[dateArr[0]]}年${months[dateArr[1]]}月${
462
+ days[dateArr[2]]
463
+ }日`;
464
+ dateValue = `${years[dateArr[0]]}-${months[dateArr[1]]}-${
465
+ days[dateArr[2]]
466
+ }`;
467
+ if (filtType === "yearMonth") {
468
+ dateStr = `${years[dateArr[0]]}年${months[dateArr[1]]}月`;
469
+ dateValue = `${years[dateArr[0]]}-${months[dateArr[1]]}`;
470
+ // 如果是按年月筛选
471
+ this.setData({
472
+ dateStr,
473
+ dateValue,
474
+ });
475
+ } else if (filtType === "date") {
476
+ // 如果是按年月日筛选
477
+ this.setData({
478
+ dateStr,
479
+ dateValue,
480
+ });
481
+ } else if (checkedType === "start") {
482
+ this.setData({
483
+ startDateArr: dateArr,
484
+ startDateStr: dateStr,
485
+ startDateValue: dateValue,
486
+ });
487
+ } else {
488
+ this.setData({
489
+ endDateArr: dateArr,
490
+ endDateStr: dateStr,
491
+ endDateValue: dateValue,
492
+ });
493
+ }
494
+ },
495
+ // 更改筛选类型
496
+ changeFiltType() {
497
+ const {
498
+ data: { filtType, dateValue, dateStr, dateArr },
499
+ } = this;
500
+ this.setData({
501
+ filtType: filtType === "date" ? "dateRange" : "date",
502
+ });
503
+ if (filtType === "date") {
504
+ this.setData({
505
+ startDateValue: dateValue,
506
+ startDateStr: dateStr,
507
+ startDateArr: dateArr,
508
+ });
509
+ return;
510
+ }
511
+ this.onReset();
512
+ },
513
+ // 切换日期类型
514
+ switchDateType(e) {
515
+ const checkedType = e.currentTarget.dataset.type;
516
+ const {
517
+ data: { clickedEnd },
518
+ } = this;
519
+ this.setData({
520
+ checkedType,
521
+ clickedEnd: checkedType === "end" ? true : clickedEnd,
522
+ });
523
+ this.showCheckedPicker();
524
+ },
525
+ // 反显选中的日期下拉值
526
+ showCheckedPicker() {
527
+ let {
528
+ data: {
529
+ startDateValue,
530
+ endDateValue,
531
+ checkedType,
532
+ startDateArr,
533
+ endDateArr,
534
+ dateArr,
535
+ startDateStr,
536
+ endDateStr,
537
+ },
538
+ } = this;
539
+ // 如果当前切换到结束时间选项
540
+ if (checkedType === "end") {
541
+ if (!endDateValue) {
542
+ // 如果当前没有选结束时间
543
+ endDateValue = startDateValue;
544
+ endDateArr = startDateArr;
545
+ endDateStr = startDateStr;
546
+ } else {
547
+ dateArr = [endDateArr[0], endDateArr[1], endDateArr[2]];
548
+ }
549
+ }
550
+ if (checkedType === "start") {
551
+ dateArr = [startDateArr[0], startDateArr[1], startDateArr[2]];
552
+ }
553
+ this.setData({
554
+ endDateStr,
555
+ endDateValue,
556
+ endDateArr,
557
+ dateArr,
558
+ });
559
+ },
560
+ // 重置时间
561
+ async onReset() {
562
+ this.setData({ isRset: true });
563
+ this.bindChange();
564
+ },
565
+ // 关闭选择器
566
+ async onClose() {
567
+ this.onReset();
568
+ this.setData({ show: false });
569
+ },
570
+ // 确认选择时间
571
+ onConfirm() {
572
+ const {
573
+ data: { filtType, dateValue, dateStr, startDateValue, endDateValue },
574
+ } = this;
575
+ let pickerDate;
576
+ if (filtType === "date") {
577
+ // 如果按年月日筛选
578
+ pickerDate = `${dateValue} 00:00:00`;
579
+ } else if (filtType === "yearMonth") {
580
+ // 如果按年月筛选
581
+ pickerDate = dateValue;
582
+ } else {
583
+ if (!endDateValue) {
584
+ wx.showToast({
585
+ title: "请选择结束时间",
586
+ icon: "none",
587
+ });
588
+ return;
589
+ }
590
+ if (new Date(startDateValue) > new Date(endDateValue)) {
591
+ wx.showToast({
592
+ title: "开始时间不能大于结束时间",
593
+ icon: "none",
594
+ });
595
+ return;
596
+ }
597
+ pickerDate = [`${startDateValue} 00:00:00`, `${endDateValue} 23:59:59`];
598
+ }
599
+ this.setData({ show: false });
600
+ this.triggerEvent("getDateValue", {
601
+ pickerDate,
602
+ pickerDateText: dateStr,
603
+ });
604
+ },
605
+ },
606
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "component": true,
3
+ "usingComponents": {
4
+ "xt-icon": "../xt-icon/index",
5
+ "xt-button": "../xt-button/index"
6
+ }
7
+ }
@@ -0,0 +1,57 @@
1
+ <view wx:if="{{show}}" class="container">
2
+ <view class="xt-mask"></view>
3
+ <view class="xt-popup">
4
+ <!-- 顶部标题+关闭按钮 -->
5
+ <view class="xt-popup-head">
6
+ <view class="xt-popup-head-text">{{title}}</view>
7
+ <xt-icon catchtap="onClose" icon="shibai-xiao" class="shibai-xiao" size="48"/>
8
+ </view>
9
+ <!-- 分割线 -->
10
+ <view class="head-border"></view>
11
+ <!-- 切换选择类型按钮 -->
12
+ <view wx:if="{{showChangeTab}}" class="filter-btn" catchtap="changeFiltType">
13
+ <view>{{typeEnums[filtType]}}</view>
14
+ <xt-icon icon="shaixuan" class="shaixuan" size="32"/>
15
+ </view>
16
+ <!-- 选中日期 -->
17
+ <view class="date-sel">
18
+ <view wx:if="{{filtType === 'date' || filtType === 'yearMonth'}}" class="sel-sigle actived">{{dateStr}}</view>
19
+ <view wx:else class="sel-range">
20
+ <view catchtap="switchDateType" data-type="start" class="sel-start actived">{{startDateStr}}</view>
21
+ <view>至</view>
22
+ <view catchtap="switchDateType" data-type="end" class="sel-end {{clickedEnd ? 'actived' : ''}}">
23
+ {{ clickedEnd ? endDateStr : '结束时间'}}
24
+ </view>
25
+ </view>
26
+ </view>
27
+ <!-- 选择器 -->
28
+ <picker-view
29
+ class="picker-box"
30
+ value="{{dateArr}}"
31
+ indicator-style="{{indicatorSyle}}"
32
+ immediate-change="{{true}}"
33
+ mask-class="picker-mask"
34
+ bindchange="bindChange">
35
+ <picker-view-column>
36
+ <view wx:for="{{years}}" wx:key="index" class="picker-item {{dateArr[0] === index ? 'picker-select' : ''}}">
37
+ {{item}}年
38
+ </view>
39
+ </picker-view-column>
40
+ <picker-view-column>
41
+ <view wx:for="{{months}}" wx:key="index" class="picker-item {{dateArr[1] === index ? 'picker-select' : ''}}">
42
+ {{item}}月
43
+ </view>
44
+ </picker-view-column>
45
+ <picker-view-column wx:if="{{type !== 'yearMonth'}}">
46
+ <view wx:for="{{days}}" wx:key="index" class="picker-item {{dateArr[2] === index ? 'picker-select' : ''}}">
47
+ {{item}}日
48
+ </view>
49
+ </picker-view-column>
50
+ </picker-view>
51
+ <!-- 按钮组 -->
52
+ <view class="btns-group">
53
+ <xt-button catchtap="onReset" class="btn-reset">{{cancelButtonText}}</xt-button>
54
+ <xt-button catchtap="onConfirm" type="main" class="btn-confirm">{{confirmButtonText}}</xt-button>
55
+ </view>
56
+ </view>
57
+ </view>
@@ -0,0 +1,118 @@
1
+ .btns-group {
2
+ display: flex;
3
+ }
4
+ .btn-reset, .btn-confirm {
5
+ width: 328rpx;
6
+ }
7
+ .xt-mask {
8
+ position: fixed;
9
+ top: 0;
10
+ left: 0;
11
+ width: 100%;
12
+ height: 100%;
13
+ background: rgba(0, 0, 0, 0.7);
14
+ }
15
+ .xt-popup {
16
+ position: fixed;
17
+ bottom: 0;
18
+ left: 0;
19
+ width: 100%;
20
+ height: 1204rpx;
21
+ padding: 32rpx;
22
+ border-radius: 24rpx 24rpx 0 0;
23
+ box-sizing: border-box;
24
+ background: #fff;
25
+ z-index: 999;
26
+ }
27
+ .xt-popup-head {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ padding-bottom: 32rpx;
32
+ }
33
+ .xt-popup-head .xt-popup-head-text {
34
+ line-height: 56rpx;
35
+ font-size: 40rpx;
36
+ font-weight: 800;
37
+ color: #000;
38
+ }
39
+ .xt-popup-head .shibai-xiao {
40
+ color: #B8B8B8;
41
+ }
42
+ .head-border {
43
+ width: 100%;
44
+ height: 2rpx;
45
+ background: #F5F5F5;
46
+ }
47
+ .filter-btn {
48
+ display: flex;
49
+ align-items: center;
50
+ width: 226rpx;
51
+ height: 80rpx;
52
+ margin-top: 32rpx;
53
+ padding: 16rpx 24rpx;
54
+ font-size: 34rpx;
55
+ border-radius: 60rpx;
56
+ box-sizing: border-box;
57
+ background: #E5E5E5;
58
+ }
59
+ .filter-btn .shaixuan {
60
+ margin-left: 8rpx;
61
+ }
62
+ .date-sel {
63
+ margin-top: 48rpx;
64
+ }
65
+ .sel-sigle, .sel-start, .sel-end {
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ height: 80rpx;
70
+ border-radius: 60rpx;
71
+ font-weight: 800;
72
+ color: #666666;
73
+ border: 2rpx solid #E5E5E5;
74
+ }
75
+ .date-sel .sel-range {
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: space-between;
79
+ }
80
+ .date-sel .sel-start, .date-sel .sel-end {
81
+ width: 296rpx;
82
+ }
83
+ .date-sel .actived {
84
+ color: #6722AB;
85
+ border: 2rpx solid #6722AB;
86
+ }
87
+ .picker-box {
88
+ width: 100%;
89
+ height: 600rpx;
90
+ margin-top: 32rpx;
91
+ }
92
+ .btns-group {
93
+ position: fixed;
94
+ left: 0;
95
+ bottom: 0;
96
+ padding: 32rpx;
97
+ width: 100%;
98
+ display: flex;
99
+ justify-content: space-between;
100
+ box-sizing: border-box;
101
+ padding-bottom: calc(constant(safe-area-inset-bottom) + 0rpx);
102
+ padding-bottom: calc(env(safe-area-inset-bottom) + 0rpx);
103
+ }
104
+ .picker-item {
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+ height: 120rpx;
109
+ font-size: 40rpx;
110
+ color: #000000;
111
+ text-align: center;
112
+ }
113
+ .picker-mask {
114
+ }
115
+ .picker-select {
116
+ font-size: 40rpx;
117
+ font-weight: 800;
118
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xtdev/xt-miniprogram-ui",
3
- "version": "1.2.40",
3
+ "version": "1.2.42",
4
4
  "description": "",
5
5
  "miniprogram": "libs",
6
6
  "publishConfig": {