import { condition, setAdvancedConfigToProps } from '../../util/util';
import {
CnDatePickerPro,
CnWeekPicker2,
CnMonthPicker2,
CnYearPicker2,
} from '@cainiaofe/cn-ui';
import { DisplayPosition } from '../position/display-position';
import React, { useEffect, useState } from 'react';
import { componentMap as formComponentMap } from '@cainiaofe/cn-ui';
import dayjs from 'dayjs';
import isPlainObject from 'lodash/isPlainObject';
import isArray from 'lodash/isArray';
import isFunction from 'lodash/isFunction';
import { makeRequest } from '@/common/util/request';
import { getJSExpressionPrototype } from '@/common/manager/common-style';
import { getDateTypeSetterSnippet } from '@/common/manager/setter-snippet';
import {
getBizExtendPrototype,
handleBizExtendComponentProps,
} from '@/common/manager/plugin';
export function requestDate(dateRequest, getRequestParams) {
const _params = getRequestParams?.();
if (isPlainObject(dateRequest)) {
return makeRequest({
buttonConfig: {
options: {
requestConfig: dateRequest,
},
},
..._params,
needSuccessToast: false,
}).then((res) => {
const { success, data } = res || {};
if (success && isPlainObject(data)) {
const { disabledDate, enabledDate } = data;
if (Array.isArray(enabledDate)) {
const list = [];
enabledDate.forEach((item) => {
const day = dayjs(item);
if (day) {
list.push(day.startOf('d').valueOf());
}
});
return {
key: 'enabledDate',
list,
};
} else if (Array.isArray(disabledDate) && disabledDate.length > 0) {
const list = [];
disabledDate.forEach((item) => {
const day = dayjs(item);
if (day) {
list.push(day.startOf('d').valueOf());
}
});
return {
key: 'disabledDate',
list,
};
}
}
});
}
}
const presetMap = {
nowTime: {
key: '此刻',
value: () => dayjs(),
},
nowTimeRanger: {
key: '此刻',
value: [dayjs(), dayjs()],
},
nowMonthRanger: {
key: '本月',
value: [dayjs().startOf('month'), dayjs().endOf('month')],
},
};
export function handlePreset(presetConfig, getRequestParams) {
if (isArray(presetConfig)) {
return presetConfig.reduce((ret, nextPresetConfig: string) => {
const matchPreset = presetMap[nextPresetConfig];
if (matchPreset) {
return {
...ret,
[matchPreset?.key]: matchPreset?.value,
};
}
return ret;
}, {});
} else if (isFunction(presetConfig)) {
const _params = getRequestParams?.();
let formValues = {};
let _state = {};
if (_params) {
const { recordDataSource, state } = _params;
if (isPlainObject(recordDataSource)) {
formValues = recordDataSource;
}
if (isPlainObject(state)) {
_state = state;
}
}
return presetConfig(dayjs, formValues, _state);
}
}
export function handleDisabledDate(
disabled,
disabledDateList,
enabledDateList,
getRequestParams,
disabledType,
) {
if (disabled) {
if (typeof disabled === 'string') {
switch (disabled) {
case 'beforeToday':
return (date, mode) => {
const currentDate = dayjs();
switch (mode) {
case 'date':
return date.valueOf() < currentDate.startOf('d').valueOf();
case 'year':
return date.year() < currentDate.year();
case 'month':
return (
date.year() * 100 + date.month() <
currentDate.year() * 100 + currentDate.month()
);
}
};
case 'afterToday':
return (date, mode) => {
const currentDate = dayjs();
switch (mode) {
case 'date':
return date.valueOf() > currentDate.valueOf();
case 'year':
return date.year() > currentDate.year();
case 'month':
return (
date.year() * 100 + date.month() >
currentDate.year() * 100 + currentDate.month()
);
}
};
}
} else if (isPlainObject(disabled)) {
if (disabledType === 'enabledDate' && Array.isArray(enabledDateList)) {
return (date, mode) => {
switch (mode) {
case 'date':
return !enabledDateList.includes(date.startOf('d').valueOf());
}
};
} else if (
disabledType === 'disabledDate' &&
disabledDateList?.length > 0
) {
return (date, mode) => {
switch (mode) {
case 'date':
return disabledDateList.includes(date.startOf('d').valueOf());
}
};
}
} else if (typeof disabled === 'function') {
const _params = getRequestParams?.();
let formValues = {};
let _state = {};
if (_params) {
const { recordDataSource, state } = _params;
if (isPlainObject(recordDataSource)) {
formValues = recordDataSource;
}
if (isPlainObject(state)) {
_state = state;
}
}
return (date, mode) => {
try {
return disabled.call(this, date, mode, formValues, _state);
} catch (e) {
console.log(e, '执行disableDate失败');
}
};
}
}
}
function handleDisabledTime(disabled) {
const currentDate = dayjs();
const currentHour = currentDate.hour();
if (typeof disabled === 'string' && disabled) {
switch (disabled) {
case 'beforeToday':
return {
disabledHours: (index) => {
return index < currentHour;
},
};
case 'afterToday':
return {
disabledHours: (index) => {
return index > currentHour;
},
};
}
}
}
export function createDisabledDateSetter() {
return {
componentName: 'MixedSetter',
props: {
setters: [
{
title: '选择禁用日期',
componentName: 'SelectSetter',
props: {
options: [
{
label: '禁用今天以前',
value: 'beforeToday',
},
{
label: '禁用今天以后',
value: 'afterToday',
},
],
},
},
{
title: '配置请求获取禁用日期',
componentName: 'ServiceChoiceSetter',
props: {
buttonText: '选择请求API',
params: {
env: 'pre',
pageSize: 999,
// serviceType: 'HSF',
},
paramSetter: {
componentName: 'MixedSetter',
props: {
setters: [
{
componentName: 'ParamSelectSetter',
props: {
dataKey: 'config',
labelKey: 'label',
valueKey: 'name',
groupName: '当前表单',
},
title: '选择参数',
},
{
componentName: 'StringSetter',
title: '字符串',
},
getJSExpressionPrototype({ type: 'formRequest' }),
],
},
},
},
},
getJSExpressionPrototype({ type: 'datepicker' }),
],
},
};
}
export function DatePickerComposite(props: any): JSX.Element {
const { type, disabledDate, getRequestParams, ...rest } = props;
const extraProps = {};
const [disabledType, setDisabledType] = useState();
const [disabledDateList, setDisabledDateList] = useState();
const [enabledDateList, setEnabledDateList] = useState();
useEffect(() => {
requestDate(disabledDate, getRequestParams)?.then((res) => {
if (res) {
const { key, list } = res;
if (key) {
setDisabledType(key);
}
if (key === 'disabledDate') {
setDisabledDateList(list);
} else if (key === 'enabledDate') {
setEnabledDateList(list);
}
}
});
}, []);
extraProps.disabledDate = handleDisabledDate(
disabledDate,
disabledDateList,
enabledDateList,
getRequestParams,
disabledType,
);
switch (type) {
case 'week':
return ;
case 'month':
return ;
case 'year':
return ;
default:
return ;
}
}
const DatePicker = {
position: [
DisplayPosition.form,
DisplayPosition.filter,
DisplayPosition.formDialog,
DisplayPosition.cnArrayTable,
DisplayPosition.cnArraySubAreaCard,
],
thumbUrl:
'https://img.alicdn.com/imgextra/i3/O1CN01wpVw5R1fGtCbNNF3X_!!6000000003980-2-tps-240-144.png',
title: '日期选择器',
componentName: 'DatePicker',
component: DatePickerComposite,
formItemBeforeHandler: (formItem, config) => {
const { urlParams, formValue, state } = config || {};
if (formItem) {
const componentProps = formItem['x-component-props'];
if (componentProps) {
componentProps.getRequestParams = () => {
return {
urlParamsDataSource: urlParams,
recordDataSource: formValue,
state,
};
};
}
handleBizExtendComponentProps(componentProps, 'CnDatePickerPro');
setAdvancedConfigToProps(componentProps);
}
},
filterItemBeforeHandler: (filterItemProps, config) => {
const { componentProps, urlParamsDataSource, recordDataSource, state } =
config || {};
if (componentProps) {
componentProps.getRequestParams = () => {
return {
urlParamsDataSource,
recordDataSource,
state,
};
};
}
},
formComponent: (props) => {
const { type, disabledDate, presetConfig, getRequestParams, ...rest } =
props;
const { showTime } = rest || {};
const extraProps = {};
let Com;
if (showTime) {
// if(disabledDate) {
// extraProps.timePanelProps = {
// disabledDate:handleDisabledDate(disabledDate),
// ...handleDisabledTime(disabledDate),
// }
// }
// if(format?.includes(' HH')){
// extraProps.timePanelProps = {
// format: format.slice(format.indexOf(' HH') + 1)
// }
// }
}
const [disabledDateList, setDisabledDateList] = useState([]);
const [enabledDateList, setEnabledDateList] = useState([]);
const [disabledType, setDisabledType] = useState();
useEffect(() => {
requestDate(disabledDate, getRequestParams)?.then((res) => {
if (res) {
const { key, list } = res;
if (key) {
setDisabledType(key);
}
if (key === 'disabledDate') {
setDisabledDateList(list);
} else if (key === 'enabledDate') {
setEnabledDateList(list);
}
}
});
}, []);
extraProps.disabledDate = handleDisabledDate(
disabledDate,
disabledDateList,
enabledDateList,
getRequestParams,
disabledType,
);
if (presetConfig?.length > 0 || isFunction(presetConfig)) {
extraProps.preset = handlePreset(presetConfig, getRequestParams);
}
switch (type) {
case 'week':
Com = formComponentMap.CnWeekPicker2;
break;
case 'month':
Com = formComponentMap.CnMonthPicker2;
break;
case 'year':
Com = formComponentMap.CnYearPicker2;
break;
default:
Com = formComponentMap.CnDatePicker2;
}
return ;
},
getDefaultProps: () => {
return {
type: 'date',
outputFormat: '',
};
},
getPrototypeList: () => {
return [
getDateTypeSetterSnippet(),
{
name: 'showTime',
title: '显示时间',
display: 'inline',
setter: 'BoolSetter',
condition(prop) {
return (
condition(prop, 'DatePicker', 'componentName') &&
prop?.parent?.getPropValue?.('type') === 'date'
);
},
},
{
name: 'outputFormat',
title: '输出格式',
display: 'inline',
condition(prop) {
return condition(prop, 'DatePicker', 'componentName');
},
setter: {
componentName: 'SelectSetter',
props: {
options: [
{
label: '时间戳',
value: '',
},
{
label: 'YYYY',
value: 'YYYY',
},
{
label: 'YYYY-MM',
value: 'YYYY-MM',
},
{
label: 'YYYY-MM-DD',
value: 'YYYY-MM-DD',
},
{
label: 'YYYY-MM-DD HH',
value: 'YYYY-MM-DD HH',
},
{
label: 'YYYY-MM-DD HH:mm',
value: 'YYYY-MM-DD HH:mm',
},
{
label: 'YYYY-MM-DD HH:mm:ss',
value: 'YYYY-MM-DD HH:mm:ss',
},
],
},
},
},
{
name: 'format',
title: '前端显示格式',
display: 'inline',
condition(prop) {
return condition(prop, 'DatePicker', 'componentName');
},
setter: {
componentName: 'SelectSetter',
props: {
options: [
{
label: 'YYYY',
value: 'YYYY',
},
{
label: 'YYYY-MM',
value: 'YYYY-MM',
},
{
label: 'YYYY-MM-DD',
value: 'YYYY-MM-DD',
},
{
label: 'YYYY-MM-DD HH',
value: 'YYYY-MM-DD HH',
},
{
label: 'YYYY-MM-DD HH:mm',
value: 'YYYY-MM-DD HH:mm',
},
{
label: 'YYYY-MM-DD HH:mm:ss',
value: 'YYYY-MM-DD HH:mm:ss',
},
],
},
},
},
{
name: 'disabledDate',
title: '禁用日期',
display: 'inline',
condition(prop) {
return condition(prop, 'DatePicker', 'componentName');
},
setter: createDisabledDateSetter(),
},
{
name: 'presetConfig',
title: '快捷操作',
display: 'inline',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
title: '选择快捷',
componentName: 'CnSelectSetter',
props: {
mode: 'muiltiple',
options: [
{
label: '此刻',
value: 'nowTime',
},
],
},
},
getJSExpressionPrototype({ type: 'datepickerPreset' }),
],
},
},
},
...getBizExtendPrototype({
componentName: 'CnDatePickerPro',
}),
];
},
};
export default DatePicker;