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;