@xtdev/xt-miniprogram-ui 1.2.60 → 1.2.61
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/libs/package.json +1 -0
- package/libs/xt-button/README.md +60 -0
- package/libs/xt-button/index.js +116 -0
- package/libs/xt-button/index.json +7 -0
- package/libs/xt-button/index.wxml +31 -0
- package/libs/xt-button/index.wxss +70 -0
- package/libs/xt-card-cell/README.md +67 -0
- package/libs/xt-card-cell/index.js +43 -0
- package/libs/xt-card-cell/index.json +6 -0
- package/libs/xt-card-cell/index.wxml +34 -0
- package/libs/xt-card-cell/index.wxss +89 -0
- package/libs/xt-cell/README.md +41 -0
- package/libs/xt-cell/index.js +42 -0
- package/libs/xt-cell/index.json +7 -0
- package/libs/xt-cell/index.wxml +12 -0
- package/libs/xt-cell/index.wxss +50 -0
- package/libs/xt-date-picker/README.md +77 -0
- package/libs/xt-date-picker/index.js +443 -0
- package/libs/xt-date-picker/index.json +7 -0
- package/libs/xt-date-picker/index.wxml +58 -0
- package/libs/xt-date-picker/index.wxss +118 -0
- package/libs/xt-date-picker-loop/README.md +77 -0
- package/libs/xt-date-picker-loop/index.js +684 -0
- package/libs/xt-date-picker-loop/index.json +8 -0
- package/libs/xt-date-picker-loop/index.wxml +61 -0
- package/libs/xt-date-picker-loop/index.wxss +117 -0
- package/libs/xt-dialog/README.md +157 -0
- package/libs/xt-dialog/index.js +142 -0
- package/libs/xt-dialog/index.json +5 -0
- package/libs/xt-dialog/index.wxml +64 -0
- package/libs/xt-dialog/index.wxss +129 -0
- package/libs/xt-form/index.js +83 -0
- package/libs/xt-form/index.json +5 -0
- package/libs/xt-form/index.wxml +67 -0
- package/libs/xt-form/index.wxss +141 -0
- package/libs/xt-icon/README.md +39 -0
- package/libs/xt-icon/index.js +25 -0
- package/libs/xt-icon/index.json +5 -0
- package/libs/xt-icon/index.wxml +2 -0
- package/libs/xt-icon/index.wxss +159 -0
- package/libs/xt-popover/README.md +71 -0
- package/libs/xt-popover/index.js +209 -0
- package/libs/xt-popover/index.json +7 -0
- package/libs/xt-popover/index.wxml +43 -0
- package/libs/xt-popover/index.wxss +135 -0
- package/libs/xt-preview-image/README.md +46 -0
- package/libs/xt-preview-image/index.js +111 -0
- package/libs/xt-preview-image/index.json +4 -0
- package/libs/xt-preview-image/index.wxml +25 -0
- package/libs/xt-preview-image/index.wxss +82 -0
- package/libs/xt-search/README.md +55 -0
- package/libs/xt-search/index.js +88 -0
- package/libs/xt-search/index.json +7 -0
- package/libs/xt-search/index.wxml +17 -0
- package/libs/xt-search/index.wxss +82 -0
- package/libs/xt-stepper/README.md +52 -0
- package/libs/xt-stepper/index.js +158 -0
- package/libs/xt-stepper/index.json +5 -0
- package/libs/xt-stepper/index.wxml +11 -0
- package/libs/xt-stepper/index.wxss +77 -0
- package/libs/xt-steps/README.md +79 -0
- package/libs/xt-steps/index.js +37 -0
- package/libs/xt-steps/index.json +7 -0
- package/libs/xt-steps/index.wxml +34 -0
- package/libs/xt-steps/index.wxss +186 -0
- package/libs/xt-tabs/README.md +98 -0
- package/libs/xt-tabs/index.js +35 -0
- package/libs/xt-tabs/index.json +6 -0
- package/libs/xt-tabs/index.wxml +10 -0
- package/libs/xt-tabs/index.wxss +76 -0
- package/libs/xt-tag/README.md +65 -0
- package/libs/xt-tag/index.js +38 -0
- package/libs/xt-tag/index.json +7 -0
- package/libs/xt-tag/index.wxml +5 -0
- package/libs/xt-tag/index.wxss +36 -0
- package/libs/xt-toast/README.md +65 -0
- package/libs/xt-toast/index.js +85 -0
- package/libs/xt-toast/index.json +7 -0
- package/libs/xt-toast/index.wxml +6 -0
- package/libs/xt-toast/index.wxss +27 -0
- package/libs/xt-uploader/README.md +46 -0
- package/libs/xt-uploader/index.js +233 -0
- package/libs/xt-uploader/index.json +7 -0
- package/libs/xt-uploader/index.wxml +15 -0
- package/libs/xt-uploader/index.wxss +68 -0
- package/libs/xt-uploader/utils.js +69 -0
- package/package.json +1 -1
|
@@ -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
|
+

|
|
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
|
+

|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
<xt-date-picker show="{{true}}" />
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 指定为按日筛选
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
<xt-date-picker show="{{true}}" type="date" />
|
|
37
|
+
```
|
|
38
|
+
### 指定最小和最大可选日期
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
<xt-date-picker show="{{true}}" minDate="2023-4-1" maxDate="2024-4-1"/>
|
|
43
|
+
```
|
|
44
|
+
### 指定选择器默认选中日期
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
<xt-date-picker show="{{true}}" currentDate="2022-4-1"/>
|
|
49
|
+
```
|
|
50
|
+
### 展示切换模式按钮
|
|
51
|
+

|
|
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,443 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: Mr.Hu
|
|
3
|
+
* @Date: 2023-12-29 09:48:47
|
|
4
|
+
* @Description: 日期组件-js逻辑
|
|
5
|
+
* @LastEditors: Mr.Hu
|
|
6
|
+
*/
|
|
7
|
+
// 获取当前月份的天数
|
|
8
|
+
const getDaysInMonth = (year, month) => {
|
|
9
|
+
const daysInMonth = new Date(year, month, 0).getDate();
|
|
10
|
+
return daysInMonth;
|
|
11
|
+
}
|
|
12
|
+
// 深拷贝
|
|
13
|
+
const deepClone = (val) => {
|
|
14
|
+
if (!val) return null;
|
|
15
|
+
const isObject = (obj) => Object.prototype.toString.call(obj) === '[object object]';
|
|
16
|
+
let newResult = Array.isArray(val) ? [] : {};
|
|
17
|
+
for (const key in val) {
|
|
18
|
+
if (Object.prototype.hasOwnProperty.call(val, key)) {
|
|
19
|
+
newResult[key] = isObject(val[key]) ? deepClone(val[key]) : val[key];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return newResult;
|
|
23
|
+
}
|
|
24
|
+
// 获取默认时间
|
|
25
|
+
const getDefaultDate = () => {
|
|
26
|
+
const now = new Date();
|
|
27
|
+
return `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`;
|
|
28
|
+
}
|
|
29
|
+
Component({
|
|
30
|
+
behaviors: [],
|
|
31
|
+
properties: {
|
|
32
|
+
// 选择器显示隐藏
|
|
33
|
+
show: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
value: false,
|
|
36
|
+
},
|
|
37
|
+
// 弹窗标题
|
|
38
|
+
title: {
|
|
39
|
+
type: String,
|
|
40
|
+
value: '日期筛选'
|
|
41
|
+
},
|
|
42
|
+
// 日期选择器模式 date 年月日选择 dateRange 时间范围选择
|
|
43
|
+
type: {
|
|
44
|
+
type: String,
|
|
45
|
+
value: 'dateRange',
|
|
46
|
+
observer: function (value) {
|
|
47
|
+
this.setData({filtType: value})
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
// 最小可选日期
|
|
51
|
+
minDate: {
|
|
52
|
+
type: String,
|
|
53
|
+
value: '1990-1-1'
|
|
54
|
+
},
|
|
55
|
+
// 最大可选日期
|
|
56
|
+
maxDate: {
|
|
57
|
+
type: String,
|
|
58
|
+
value: ''
|
|
59
|
+
},
|
|
60
|
+
// 当前时间
|
|
61
|
+
currentDate: {
|
|
62
|
+
type: String,
|
|
63
|
+
value: ''
|
|
64
|
+
},
|
|
65
|
+
// 展示切换按钮
|
|
66
|
+
showChangeTab: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
value: false
|
|
69
|
+
},
|
|
70
|
+
// 确认按钮文字
|
|
71
|
+
confirmButtonText: {
|
|
72
|
+
type: String,
|
|
73
|
+
value: '确认'
|
|
74
|
+
},
|
|
75
|
+
// 取消按钮文字
|
|
76
|
+
cancelButtonText: {
|
|
77
|
+
type: String,
|
|
78
|
+
value: '重置'
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
data: {
|
|
82
|
+
show: false,
|
|
83
|
+
years: [], // 年份数组
|
|
84
|
+
months: [], // 月份数组
|
|
85
|
+
days: [], // 天份数组
|
|
86
|
+
dateArr: [9999, 1, 1], // 下拉数组下标
|
|
87
|
+
dateValue: '', // 选中的日期值
|
|
88
|
+
dateStr: '', // 选中的日期显示字符
|
|
89
|
+
startDateArr: [], // 开始日期数组下标
|
|
90
|
+
startDateValue: '', // 开始日期选中值
|
|
91
|
+
startDateStr: '', // 开始日期字符
|
|
92
|
+
endDateArr: [], // 结束日期数组下标
|
|
93
|
+
endDateValue: '', // 结束日期选中值
|
|
94
|
+
endDateStr: '', // 结束日期字符
|
|
95
|
+
defaultDate: '', // 默认日期(组件接收的|当前时间)
|
|
96
|
+
checkedType: 'start', // 当前选择的日期类型
|
|
97
|
+
filtType: 'dateRange', // 选择器模式
|
|
98
|
+
typeEnums: {
|
|
99
|
+
date: '按日筛选',
|
|
100
|
+
dateRange: '按月筛选',
|
|
101
|
+
},
|
|
102
|
+
indicatorSyle: 'font-weight: 800;height: 112rpx'
|
|
103
|
+
},
|
|
104
|
+
lifetimes: {
|
|
105
|
+
created() {
|
|
106
|
+
},
|
|
107
|
+
async attached() {
|
|
108
|
+
await this.initPickerArr();
|
|
109
|
+
this.setDefaultDate();
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
methods: {
|
|
113
|
+
// 初始化日期数组
|
|
114
|
+
initPickerArr(curSelDate, dateValue) {
|
|
115
|
+
return new Promise(resolve => {
|
|
116
|
+
let { data: { minDate, maxDate, currentDate, dateArr } } = this;
|
|
117
|
+
currentDate = currentDate || getDefaultDate();
|
|
118
|
+
const curDateArr = this.transformToArr(curSelDate ? curSelDate : currentDate); //当前日期数组
|
|
119
|
+
const selYearColum = dateValue && dateArr ? dateValue[0] !== dateArr[0] : false; // 选择的是年份列
|
|
120
|
+
const selMonthColum = dateValue && dateArr ? dateValue[1] !== dateArr[1] : false; // 选择的是月份列
|
|
121
|
+
const selDayColum = dateValue && dateArr ? dateValue[2] !== dateArr[2] : false; // 选择的是日份列
|
|
122
|
+
if (selDayColum) resolve();
|
|
123
|
+
const curYear = curDateArr[0], curMonth= curDateArr[1], curDay = curDateArr[2];
|
|
124
|
+
let minYear, maxYear, minMonth, maxMonth, minDay, maxDay = 31;
|
|
125
|
+
if (minDate && minDate.length) {
|
|
126
|
+
const minDateArr = this.transformToArr(minDate);
|
|
127
|
+
minYear = Number(minDateArr[0]);
|
|
128
|
+
minMonth = (curYear && curYear == minDateArr[0]) ? minDateArr[1] : 1;
|
|
129
|
+
minDay = (curYear && curYear == minDateArr[0] && curMonth == minDateArr[1]) ? minDateArr[2] : 1;
|
|
130
|
+
} else {
|
|
131
|
+
minYear = 1990;
|
|
132
|
+
minMonth = 1;
|
|
133
|
+
minDay = 1;
|
|
134
|
+
}
|
|
135
|
+
if (maxDate && maxDate.length) {
|
|
136
|
+
const maxDateArr = this.transformToArr(maxDate);
|
|
137
|
+
maxYear = maxDateArr[0];
|
|
138
|
+
maxMonth = (curYear && curYear == maxDateArr[0]) ? maxDateArr[1] : 12;
|
|
139
|
+
maxDay = (curYear && curYear == maxDateArr[0] && curMonth == maxDateArr[1]) ? maxDateArr[2] : 31;
|
|
140
|
+
} else {
|
|
141
|
+
maxYear = new Date().getFullYear();
|
|
142
|
+
maxMonth = 12;
|
|
143
|
+
maxDay = 31;
|
|
144
|
+
}
|
|
145
|
+
const years = [], months = [], 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 && selYearColum) {
|
|
157
|
+
this.setData({
|
|
158
|
+
months
|
|
159
|
+
})
|
|
160
|
+
} else if (curSelDate && 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
|
+
transformToArr(dateStr) {
|
|
176
|
+
if (!dateStr) return null;
|
|
177
|
+
const dateArr = dateStr.split('-');
|
|
178
|
+
if (!dateArr.length) return null;
|
|
179
|
+
return dateArr;
|
|
180
|
+
},
|
|
181
|
+
// 设置默认年月日
|
|
182
|
+
setDefaultDate() {
|
|
183
|
+
const now = new Date();
|
|
184
|
+
let { data: { dateValue, currentDate, dateStr, dateArr, defaultDate, minDate } } = this;
|
|
185
|
+
currentDate = currentDate || getDefaultDate();
|
|
186
|
+
let curDateArr = this.transformToArr(currentDate); //当前日期数组
|
|
187
|
+
const curYear = curDateArr[0];
|
|
188
|
+
const curMonth= curDateArr[1];
|
|
189
|
+
const curDay = curDateArr[2];
|
|
190
|
+
const minDateArr = this.transformToArr(minDate); // 最小可选日期数组
|
|
191
|
+
const defaultYear = minDateArr ? minDateArr[0] : 1990;
|
|
192
|
+
const defaultMonth = (minDateArr && curYear == minDateArr[0]) ? minDateArr[1] : 1;
|
|
193
|
+
const defaultDay = (minDateArr && curYear == minDateArr[0] && curMonth == minDateArr[1]) ? minDateArr[2] : 1;
|
|
194
|
+
if (curDateArr && curDateArr.length) {
|
|
195
|
+
// 如果有设置当前日期,则数组下标选中当前日期
|
|
196
|
+
dateStr = `${curYear}年${curMonth}月${curDay}日`;
|
|
197
|
+
dateArr = [curYear - defaultYear, curMonth - defaultMonth, curDateArr[2] - defaultDay];
|
|
198
|
+
dateValue = `${curYear}-${curMonth}-${curDay}`;
|
|
199
|
+
} else {
|
|
200
|
+
// 如果有设置当前日期,则数组下标默认选中当前
|
|
201
|
+
dateStr = `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日`
|
|
202
|
+
dateArr = [now.getFullYear() - 1990, now.getMonth(), now.getDate() - 1 ];
|
|
203
|
+
dateValue = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`
|
|
204
|
+
}
|
|
205
|
+
// 储存当前传入的原始值
|
|
206
|
+
defaultDate = JSON.parse(JSON.stringify(dateValue));
|
|
207
|
+
this.setData({
|
|
208
|
+
dateArr,
|
|
209
|
+
dateStr,
|
|
210
|
+
dateValue,
|
|
211
|
+
defaultDate,
|
|
212
|
+
startDateArr: dateArr,
|
|
213
|
+
startDateStr: dateStr,
|
|
214
|
+
startDateValue: dateValue
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
// 渲染天数
|
|
218
|
+
renderDayList(curMonthDays) {
|
|
219
|
+
let dayList = Array.from({ length: curMonthDays }, (v, k) => (+k + 1).toString());
|
|
220
|
+
dayList = dayList.map(day => {
|
|
221
|
+
if (day < 10) {
|
|
222
|
+
day = `0${day}`;
|
|
223
|
+
}
|
|
224
|
+
return day;
|
|
225
|
+
});
|
|
226
|
+
return dayList;
|
|
227
|
+
},
|
|
228
|
+
// 处理当前月的天数
|
|
229
|
+
handelDays(value) {
|
|
230
|
+
const { data: { days, dateArr, years, months, minDate, maxDate } } = this;
|
|
231
|
+
const minDateArr = minDate ? this.transformToArr(minDate) : [];
|
|
232
|
+
const maxDateArr = maxDate ? this.transformToArr(maxDate) : [];
|
|
233
|
+
const selYear = years[value[0]], selMonth = months[value[1]], selDay = days.length > value[2] + 1 ? value[2] + 1 : days.length;
|
|
234
|
+
const curColumnLen = days.length; // 当前日数组对应的数组长度
|
|
235
|
+
// 当前月是最小可选月份
|
|
236
|
+
const isMinMonth = selYear == minDateArr[0] && selMonth+1 <= minDateArr[1];
|
|
237
|
+
// 当前月是最大可选月份
|
|
238
|
+
const isMaxMonth = (`${selYear}-${selMonth}` == `${maxDateArr[0]}-${maxDateArr[1]}`) && (selMonth == maxDateArr[1]);
|
|
239
|
+
const curMonthDays = isMaxMonth ? maxDateArr[2] : getDaysInMonth(selYear, selMonth);
|
|
240
|
+
const oldDateArr = dateArr; // 获取老的下标选项
|
|
241
|
+
let newDaysArr = days, newDateArr = value;
|
|
242
|
+
// 如果当前所选月份的天数大于当前月所有天数
|
|
243
|
+
if (curColumnLen > curMonthDays) {
|
|
244
|
+
// 获取当前月天数
|
|
245
|
+
const dayList = this.renderDayList(curMonthDays);
|
|
246
|
+
// 数组选项重新赋值
|
|
247
|
+
newDaysArr = dayList;
|
|
248
|
+
} else if (curColumnLen < curMonthDays) {
|
|
249
|
+
const dayList = this.renderDayList(curMonthDays);
|
|
250
|
+
newDaysArr = dayList;
|
|
251
|
+
}
|
|
252
|
+
// 设置新的下标选项
|
|
253
|
+
if (isMinMonth) {
|
|
254
|
+
newDateArr = [
|
|
255
|
+
newDateArr[0],
|
|
256
|
+
(newDateArr[1] + 1 - minDateArr[1]) > 0 ? (newDateArr[1] + 1 - minDateArr[1]) : 0,
|
|
257
|
+
selDay > curMonthDays ? dayList.length : newDateArr[2]
|
|
258
|
+
];
|
|
259
|
+
} else if (isMaxMonth) {
|
|
260
|
+
// 当前所选年份是最大月
|
|
261
|
+
newDateArr = [newDateArr[0], newDateArr[1], newDateArr[2]];
|
|
262
|
+
} else if (selYear == minDateArr[0] && selYear < years[dateArr[0]]) {
|
|
263
|
+
// 当前所选年份是最小年,并且从大年份到小年份
|
|
264
|
+
newDateArr = [
|
|
265
|
+
newDateArr[0],
|
|
266
|
+
(newDateArr[1] + 1 - minDateArr[1]) > 0 ? (newDateArr[1] + 1 - minDateArr[1]) : 0,
|
|
267
|
+
newDateArr[2]
|
|
268
|
+
];
|
|
269
|
+
} else if (years[dateArr[0]] == minDateArr[0] && selYear > years[dateArr[0]]) {
|
|
270
|
+
// 上一个所选年份是最小年,并且从小年份到小年份
|
|
271
|
+
newDateArr = [
|
|
272
|
+
newDateArr[0],
|
|
273
|
+
(Number(newDateArr[1]) + Number(minDateArr[1]) - 1),
|
|
274
|
+
newDateArr[2]
|
|
275
|
+
];
|
|
276
|
+
} else if (years[dateArr[0]] == maxDateArr[0] && selYear > years[dateArr[0]]) {
|
|
277
|
+
// 如果是最大年,并且从小年份到大年份
|
|
278
|
+
newDateArr = [
|
|
279
|
+
newDateArr[0],
|
|
280
|
+
newDateArr[0] > maxDateArr[0] ? maxDateArr[0] : newDateArr[0],
|
|
281
|
+
newDateArr[2]
|
|
282
|
+
];
|
|
283
|
+
}
|
|
284
|
+
this.setData({
|
|
285
|
+
days: newDaysArr,
|
|
286
|
+
dateArr: newDateArr
|
|
287
|
+
})
|
|
288
|
+
},
|
|
289
|
+
// 滑动下拉列表
|
|
290
|
+
async bindChange(e) {
|
|
291
|
+
const value = e.detail.value;
|
|
292
|
+
const { data: { years: year, months: month, days: day } } = this;
|
|
293
|
+
// 渲染下拉列表
|
|
294
|
+
await this.initPickerArr(`${year[value[0]]}-${month[value[1]]}-${day[value[2]]}`, value);
|
|
295
|
+
// 处理每月可选天数
|
|
296
|
+
this.handelDays(value);
|
|
297
|
+
let { data: {
|
|
298
|
+
years, months, days,
|
|
299
|
+
dateValue, dateStr, dateArr,
|
|
300
|
+
filtType, checkedType,
|
|
301
|
+
startDateArr, endDateArr,
|
|
302
|
+
startDateValue, endDateValue,
|
|
303
|
+
startDateStr, endDateStr
|
|
304
|
+
} } = this;
|
|
305
|
+
if (filtType === 'date') {
|
|
306
|
+
// 如果是按月筛选
|
|
307
|
+
dateStr = `${years[dateArr[0]]}年${months[dateArr[1]]}月${days[dateArr[2]]}日`;
|
|
308
|
+
dateValue = `${years[dateArr[0]]}-${months[dateArr[1]]}-${days[dateArr[2]]}`;
|
|
309
|
+
this.setData({
|
|
310
|
+
dateStr,
|
|
311
|
+
dateValue
|
|
312
|
+
});
|
|
313
|
+
} else {
|
|
314
|
+
// 如果是按日筛选
|
|
315
|
+
if (checkedType === 'start') {
|
|
316
|
+
this.setData({
|
|
317
|
+
startDateArr: dateArr,
|
|
318
|
+
startDateStr: `${years[dateArr[0]]}年${months[dateArr[1]]}月${days[dateArr[2]]}日`,
|
|
319
|
+
startDateValue: `${years[dateArr[0]]}-${months[dateArr[1]]}-${days[dateArr[2]]}`,
|
|
320
|
+
})
|
|
321
|
+
} else {
|
|
322
|
+
this.setData({
|
|
323
|
+
endDateArr: dateArr,
|
|
324
|
+
endDateStr: `${years[dateArr[0]]}年${months[dateArr[1]]}月${days[dateArr[2]]}日`,
|
|
325
|
+
endDateValue: `${years[dateArr[0]]}-${months[dateArr[1]]}-${days[dateArr[2]]}`,
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
// 更改筛选类型
|
|
331
|
+
changeFiltType() {
|
|
332
|
+
const { data: { filtType, dateValue, dateStr, dateArr } } = this;
|
|
333
|
+
this.setData({
|
|
334
|
+
filtType: filtType === 'date' ? 'dateRange' : 'date',
|
|
335
|
+
})
|
|
336
|
+
if (filtType === 'date') {
|
|
337
|
+
this.setData({
|
|
338
|
+
startDateValue: dateValue,
|
|
339
|
+
startDateStr: dateStr,
|
|
340
|
+
startDateArr: dateArr
|
|
341
|
+
});
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
this.onReset();
|
|
345
|
+
},
|
|
346
|
+
// 切换日期类型
|
|
347
|
+
switchDateType(e) {
|
|
348
|
+
const checkedType = e.currentTarget.dataset.type;
|
|
349
|
+
this.setData({
|
|
350
|
+
checkedType,
|
|
351
|
+
});
|
|
352
|
+
this.showCheckedPicker();
|
|
353
|
+
},
|
|
354
|
+
// 反显选中的日期下拉值
|
|
355
|
+
showCheckedPicker() {
|
|
356
|
+
let { data: {
|
|
357
|
+
startDateValue, endDateValue, checkedType,
|
|
358
|
+
startDateArr, endDateArr, dateArr,
|
|
359
|
+
startDateStr, endDateStr
|
|
360
|
+
} } = this;
|
|
361
|
+
// 如果当前切换到结束时间选项
|
|
362
|
+
if (checkedType === 'end') {
|
|
363
|
+
if (!endDateValue) {
|
|
364
|
+
// 如果当前没有选结束时间
|
|
365
|
+
endDateValue = startDateValue;
|
|
366
|
+
endDateArr = startDateArr;
|
|
367
|
+
endDateStr = startDateStr;
|
|
368
|
+
} else {
|
|
369
|
+
dateArr = [endDateArr[0], endDateArr[1], endDateArr[2]]
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (checkedType === 'start') {
|
|
373
|
+
dateArr = [startDateArr[0], startDateArr[1], startDateArr[2]]
|
|
374
|
+
}
|
|
375
|
+
this.setData({
|
|
376
|
+
endDateStr,
|
|
377
|
+
endDateValue,
|
|
378
|
+
endDateArr,
|
|
379
|
+
dateArr
|
|
380
|
+
})
|
|
381
|
+
},
|
|
382
|
+
// 关闭选择器
|
|
383
|
+
onClose() {
|
|
384
|
+
this.onReset();
|
|
385
|
+
this.setData({ show: false });
|
|
386
|
+
this.triggerEvent("onClose", {});
|
|
387
|
+
},
|
|
388
|
+
// 重置时间
|
|
389
|
+
onReset() {
|
|
390
|
+
this.initPickerArr();
|
|
391
|
+
const { data: { defaultDate, filtType, minDate } } = this;
|
|
392
|
+
let resetDateValue, resetDateStr, resetDateArr;
|
|
393
|
+
let { data: { dateStr } } = this;
|
|
394
|
+
let curDateArr = this.transformToArr(defaultDate);
|
|
395
|
+
let minDateArr = this.transformToArr(minDate);
|
|
396
|
+
resetDateStr = `${curDateArr[0]}年${curDateArr[1]}月${curDateArr[2]}日`;
|
|
397
|
+
resetDateArr = [curDateArr[0] - (minDateArr && minDateArr[0] ? minDateArr[0] : 1990), curDateArr[1] - 1, curDateArr[2] - 1];
|
|
398
|
+
resetDateValue = `${curDateArr[0]}-${curDateArr[1]}-${curDateArr[2]}`;
|
|
399
|
+
this.setData({
|
|
400
|
+
dateArr: resetDateArr,
|
|
401
|
+
dateStr: resetDateStr,
|
|
402
|
+
dateValue: resetDateValue
|
|
403
|
+
});
|
|
404
|
+
if (filtType === 'dateRange') {
|
|
405
|
+
this.setData({
|
|
406
|
+
startDateValue: resetDateValue,
|
|
407
|
+
startDateArr: resetDateArr,
|
|
408
|
+
startDateStr: resetDateStr,
|
|
409
|
+
endDateArr: [],
|
|
410
|
+
endDateStr: '',
|
|
411
|
+
endDateValue: '',
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
this.triggerEvent("onReset", {});
|
|
415
|
+
},
|
|
416
|
+
// 确认选择时间
|
|
417
|
+
onConfirm() {
|
|
418
|
+
const { data: { filtType, dateValue, startDateValue, endDateValue } } = this;
|
|
419
|
+
let checkedDate;
|
|
420
|
+
if (filtType === 'date') {
|
|
421
|
+
// 如果按月筛选
|
|
422
|
+
checkedDate = dateValue;
|
|
423
|
+
} else {
|
|
424
|
+
if (!endDateValue) {
|
|
425
|
+
wx.showToast({
|
|
426
|
+
title: '请选择结束时间',
|
|
427
|
+
icon: 'none'
|
|
428
|
+
})
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
if (new Date(startDateValue) > new Date(endDateValue)) {
|
|
432
|
+
wx.showToast({
|
|
433
|
+
title: '开始时间不能大于结束时间',
|
|
434
|
+
icon: 'none'
|
|
435
|
+
})
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
checkedDate = [startDateValue, endDateValue];
|
|
439
|
+
}
|
|
440
|
+
this.triggerEvent('getDateValue', checkedDate)
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
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'}}" class="sel-sigle actived">{{dateStr}}</view>
|
|
19
|
+
<view wx:else class="sel-range">
|
|
20
|
+
<view catchtap="switchDateType" data-type="start" class="sel-start {{checkedType == 'start' ? 'actived' : ''}}">
|
|
21
|
+
{{startDateStr}}
|
|
22
|
+
</view>
|
|
23
|
+
<view>至</view>
|
|
24
|
+
<view catchtap="switchDateType" data-type="end" class="sel-end {{checkedType == 'end' ? 'actived' : ''}}">
|
|
25
|
+
{{ endDateStr || '结束时间'}}
|
|
26
|
+
</view>
|
|
27
|
+
</view>
|
|
28
|
+
</view>
|
|
29
|
+
<!-- 选择器 -->
|
|
30
|
+
<picker-view
|
|
31
|
+
class="picker-box"
|
|
32
|
+
value="{{dateArr}}"
|
|
33
|
+
indicatorStyle="{{indicatorSyle}}"
|
|
34
|
+
mask-class="picker-mask"
|
|
35
|
+
bindchange="bindChange">
|
|
36
|
+
<picker-view-column>
|
|
37
|
+
<view wx:for="{{years}}" wx:key="index" class="picker-item {{dateArr[0] === index ? 'picker-select' : ''}}">
|
|
38
|
+
{{item}}年
|
|
39
|
+
</view>
|
|
40
|
+
</picker-view-column>
|
|
41
|
+
<picker-view-column>
|
|
42
|
+
<view wx:for="{{months}}" wx:key="index" class="picker-item {{dateArr[1] === index ? 'picker-select' : ''}}">
|
|
43
|
+
{{item}}月
|
|
44
|
+
</view>
|
|
45
|
+
</picker-view-column>
|
|
46
|
+
<picker-view-column>
|
|
47
|
+
<view wx:for="{{days}}" wx:key="index" class="picker-item {{dateArr[2] === index ? 'picker-select' : ''}}">
|
|
48
|
+
{{item}}日
|
|
49
|
+
</view>
|
|
50
|
+
</picker-view-column>
|
|
51
|
+
</picker-view>
|
|
52
|
+
<!-- 按钮组 -->
|
|
53
|
+
<view class="btns-group">
|
|
54
|
+
<xt-button catchtap="onReset" class="btn-reset">{{cancelButtonText}}</xt-button>
|
|
55
|
+
<xt-button catchtap="onConfirm" type="main" class="btn-confirm">{{confirmButtonText}}</xt-button>
|
|
56
|
+
</view>
|
|
57
|
+
</view>
|
|
58
|
+
</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: 360rpx;
|
|
90
|
+
margin-top: 80rpx;
|
|
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: 34rpx;
|
|
109
|
+
font-size: 34rpx;
|
|
110
|
+
color: #000000;
|
|
111
|
+
text-align: center;
|
|
112
|
+
}
|
|
113
|
+
.picker-mask {
|
|
114
|
+
}
|
|
115
|
+
.picker-select {
|
|
116
|
+
font-size: 34rpx;
|
|
117
|
+
font-weight: 800;
|
|
118
|
+
}
|