From 016cff7646d0f0bb9e782710a21f570a9cc57afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=BC=BA?= <1049229070@qq.com> Date: Mon, 9 Dec 2024 11:19:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E6=97=A5=E6=9C=9F=E8=8C=83=E5=9B=B4minDate=EF=BD=9Ema?= =?UTF-8?q?xDate=E6=8C=89=E5=B9=B4=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zh-CN/components/form/input-date-range.md | 24 +++++ .../components/form/input-datetime-range.md | 1 + .../amis-ui/src/components/CalendarMobile.tsx | 93 +++++++++++++++---- .../src/components/DateRangePicker.tsx | 5 +- .../src/renderers/Form/InputDateRange.tsx | 4 + 5 files changed, 106 insertions(+), 21 deletions(-) diff --git a/docs/zh-CN/components/form/input-date-range.md b/docs/zh-CN/components/form/input-date-range.md index 9a3b424f3d5..16269980d53 100755 --- a/docs/zh-CN/components/form/input-date-range.md +++ b/docs/zh-CN/components/form/input-date-range.md @@ -230,6 +230,29 @@ order: 15 } ``` +## 按年加载 + +在移动端,`input-date-range`以及`input-datetime-range`默认是加载今年明年和前年的月份数据,如果要选择其他年份,只能需要通过设置 `minDate` 和 `maxDate` 间距, 由于年份间距乘以每年 12 月,数据量大,`PopUp` 无法打开,导致卡顿, 内部`ref=this.mobileBody onScroll`滚动不流畅。 可以配置`dateRangeMobileLazyYear`为 true,只会加载当前年份,其他年份不加载,实现按年份加载。`InputDatetimeRange`也可以通过该配置进行按年加载。 + +```schema: scope="body" +{ + "type": "form", + "debug": true, + "api": "/api/mock2/form/saveForm", + "body": [ + { + "type": "input-date-range", + "name": "select", + "label": "日期范围", + "value":"1701446340,1702483199", + "minDate": "-662716800", + "maxDate": "4794307200", + "dateRangeMobileLazyYear": true, + } + ] +} +``` + ## 数据处理函数 > `3.5.0`及以上版本 @@ -352,6 +375,7 @@ function transform(value, config, props, data) { | extraName | `string` | | 是否存成两个字段 | `3.3.0` | | transform | `string` | | 日期数据处理函数,用来处理选择日期之后的的值,返回值为 `Moment`对象 | `3.5.0` | | popOverContainerSelector | `string` | | 弹层挂载位置选择器,会通过`querySelector`获取 | `6.4.0` | +| dateRangeMobileLazyYear | `boolean` | `false` | 是否开启移动端日期选择器按年加载 | ## 事件表 diff --git a/docs/zh-CN/components/form/input-datetime-range.md b/docs/zh-CN/components/form/input-datetime-range.md index d2fffc5f788..3c605500a04 100755 --- a/docs/zh-CN/components/form/input-datetime-range.md +++ b/docs/zh-CN/components/form/input-datetime-range.md @@ -139,6 +139,7 @@ order: 16 | animation | `boolean` | `true` | 是否启用游标动画 | `2.2.0` | | extraName | `string` | | 是否存成两个字段 | `3.3.0` | | popOverContainerSelector | `string` | | 弹层挂载位置选择器,会通过`querySelector`获取 | `6.4.0` | +| dateRangeMobileLazyYear | `boolean` | `false` | [是否开启移动端日期选择器按年加载](./input-date-range#按年加载) | ## 事件表 diff --git a/packages/amis-ui/src/components/CalendarMobile.tsx b/packages/amis-ui/src/components/CalendarMobile.tsx index df5547878a4..32a69c58408 100644 --- a/packages/amis-ui/src/components/CalendarMobile.tsx +++ b/packages/amis-ui/src/components/CalendarMobile.tsx @@ -54,6 +54,7 @@ export interface CalendarMobileProps extends ThemeProps, LocaleProps { defaultDate?: moment.Moment; isEndDate?: boolean; popOverContainer?: any; + dateRangeMobileLazyYear?: boolean; } export interface CalendarMobileState { @@ -222,9 +223,11 @@ export class CalendarMobile extends React.Component< } scollToDate(date: moment.Moment) { - const {showViewMode} = this.props; + const {showViewMode, dateRangeMobileLazyYear = false} = this.props; const {minDate} = this.state; - const index = date.diff(minDate, showViewMode); + const index = dateRangeMobileLazyYear + ? date.month() + : date.diff(minDate, showViewMode); const currentEl = this.mobileBody.current.children[index]; if (!currentEl) { return; @@ -570,20 +573,7 @@ export class CalendarMobile extends React.Component< @autobind renderMobileCalendarBody() { - const { - classnames: cx, - dateFormat, - timeFormat, - inputFormat, - displayForamt, - locale, - viewMode = 'days', - close, - defaultDate, - showViewMode, - isEndDate - } = this.props; - const __ = this.props.translate; + const {classnames: cx, defaultDate, showViewMode} = this.props; const {minDate, maxDate} = this.state; if (!minDate || !maxDate) { @@ -611,6 +601,62 @@ export class CalendarMobile extends React.Component< ref={this.mobileBody} onScroll={this.onMobileBodyScroll} > + {this.renderCalendarNodes(calendarDates)} + + ); + } + + @autobind + renderMobileLazyCalendarBody() { + const {classnames: cx, defaultDate, showViewMode} = this.props; + + const {minDate, maxDate, currentDate} = this.state; + if (!minDate || !maxDate) { + return; + } + let calendarDates: moment.Moment[] = []; + const currentYear = moment(currentDate).format('YYYY'); + for ( + let minDateClone = minDate.clone(); + minDateClone.isSameOrBefore(maxDate); + minDateClone.add(1, showViewMode) + ) { + let date = minDateClone.clone(); + if (defaultDate) { + date = moment(defaultDate).set({ + year: date.get('year'), + month: date.get('month') + }); + } + if (date.year() === +currentYear) { + calendarDates.push(date); + } + } + + return ( +
+ {this.renderCalendarNodes(calendarDates)} +
+ ); + } + + @autobind + renderCalendarNodes(calendarDates: moment.Moment[]) { + const { + classnames: cx, + dateFormat, + inputFormat, + displayForamt, + locale, + viewMode = 'days', + close, + showViewMode, + isEndDate + } = this.props; + const __ = this.props.translate; + + return ( + <> {calendarDates.map((calendarDate: moment.Moment, index: number) => { const rdtOldNone = showViewMode === 'months' && @@ -666,7 +712,7 @@ export class CalendarMobile extends React.Component< ); })} - + ); } @@ -752,7 +798,8 @@ export class CalendarMobile extends React.Component< isDatePicker, locale, popOverContainer, - timeConstraints + timeConstraints, + dateRangeMobileLazyYear = false } = this.props; const __ = this.props.translate; @@ -784,7 +831,11 @@ export class CalendarMobile extends React.Component< ‹ )} - {dateNow} + + {dateRangeMobileLazyYear + ? moment(currentDate).format('YYYY') + : dateNow} + {(currentDate && currentDate.isSameOrAfter(maxDate, showViewMode)) || isScrollToBottom ? null : ( @@ -840,7 +891,9 @@ export class CalendarMobile extends React.Component< >
{header} - {this.renderMobileCalendarBody()} + {dateRangeMobileLazyYear + ? this.renderMobileLazyCalendarBody() + : this.renderMobileCalendarBody()} {footer}
{showToast ? ( diff --git a/packages/amis-ui/src/components/DateRangePicker.tsx b/packages/amis-ui/src/components/DateRangePicker.tsx index 14e4f9cfd9e..c364b13df5f 100644 --- a/packages/amis-ui/src/components/DateRangePicker.tsx +++ b/packages/amis-ui/src/components/DateRangePicker.tsx @@ -89,6 +89,7 @@ export interface DateRangePickerProps extends ThemeProps, LocaleProps { animation?: boolean; /** 日期处理函数,通常用于自定义处理绑定日期的值 */ transform?: string; + dateRangeMobileLazyYear?: boolean; testIdBuilder?: TestIdBuilder; } @@ -2015,7 +2016,8 @@ export class DateRangePicker extends React.Component< label, animation, testIdBuilder, - locale + locale, + dateRangeMobileLazyYear = false } = this.props; const useCalendarMobile = mobileUI && ['days', 'months', 'quarters'].indexOf(viewMode) > -1; @@ -2052,6 +2054,7 @@ export class DateRangePicker extends React.Component< showViewMode={ viewMode === 'quarters' || viewMode === 'months' ? 'years' : 'months' } + dateRangeMobileLazyYear={dateRangeMobileLazyYear} /> ); diff --git a/packages/amis/src/renderers/Form/InputDateRange.tsx b/packages/amis/src/renderers/Form/InputDateRange.tsx index d9c4bc7d77c..f7f26df64ce 100644 --- a/packages/amis/src/renderers/Form/InputDateRange.tsx +++ b/packages/amis/src/renderers/Form/InputDateRange.tsx @@ -128,6 +128,10 @@ export interface DateRangeControlSchema extends FormBaseControlSchema { * 弹窗容器选择器 */ popOverContainerSelector?: string; + /** + * 移动端input-date-range和input-datetime-range,是否按年加载 + */ + dateRangeMobileLazyYear?: boolean; } export interface DateRangeProps