组件
index.js
import React from 'react';
import { Radio } from 'antd';
import 'moment/locale/zh-cn';
import moment from 'moment';
import dayjs from 'dayjs';
export { default as DatePageChange } from './DatePageChange';
export { default as DateInfoChange } from './DateInfoChange';
const GRadio = Radio.Group;
const BRadio = Radio.Button;
export default ({ dateType, handleCustomClick = () => {} }) => {
const onChangeGRadio = value => {
let date = null;
switch (value) {
case 'daily':
date = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
break;
case 'weekly':
date = [
moment()
?.week(moment()?.week())
.startOf('week')
.format('YYYY-MM-DD'),
moment()
?.week(moment()?.week())
.endOf('week')
.format('YYYY-MM-DD'),
];
break;
case 'monthly':
date = [
moment()
?.month(moment()?.month())
.startOf('month')
.format('YYYY-MM-DD'),
moment()
?.month(moment()?.month())
.endOf('month')
.format('YYYY-MM-DD'),
];
break;
case 'year':
date = [`${dayjs().format('YYYY')}-01-01`, `${dayjs().format('YYYY')}-12-31`];
break;
case 'custom':
date = [
moment().format('YYYY-MM-DD'),
moment()
?.endOf('month')
?.format('YYYY-MM-DD'),
];
break;
default:
date = [
moment().format('YYYY-MM-DD'),
moment()
?.endOf('month')
?.format('YYYY-MM-DD'),
];
break;
}
handleCustomClick({
start_date: date && date?.[0] ? date?.[0] : null,
end_date: date && date?.[1] ? date?.[1] : null,
dateType: value,
});
};
return (
<div style={{ display: 'flex' }}>
<GRadio value={dateType} onChange={e => onChangeGRadio(e?.target?.value)}>
<BRadio value="daily" style={{ width: '60px', textAlign: 'center' }}>
日
</BRadio>
<BRadio value="weekly" style={{ width: '60px', textAlign: 'center' }}>
周
</BRadio>
<BRadio value="monthly" style={{ width: '60px', textAlign: 'center' }}>
月
</BRadio>
<BRadio value="year" style={{ width: '60px', textAlign: 'center' }}>
年
</BRadio>
<BRadio value="custom" style={{ minWidth: '60px', textAlign: 'center' }}>
自定义
</BRadio>
</GRadio>
</div>
);
};
//DateInfoChange.jsx
import React, { useState, useEffect, useMemo } from 'react';
import { Button, Form, DatePicker, Radio, Checkbox } from 'antd';
import locale from 'antd/es/date-picker/locale/zh_CN';
import 'moment/locale/zh-cn';
import moment from 'moment';
export { default as DatePageChange } from './DatePageChange';
const { RangePicker } = DatePicker;
export default ({ dateType, handleCustomDateClick = () => {} }) => {
const dataPicker = useMemo(() => {
const onValueChange = value => {
let params = {};
switch (dateType) {
case 'daily':
params = {
start_date: value ? value.format('YYYY-MM-DD') : null,
end_date: value ? value.format('YYYY-MM-DD') : null,
};
break;
case 'weekly':
params = {
start_date: value
? value
?.week(value?.week())
.startOf('week')
.format('YYYY-MM-DD')
: null,
end_date: value
? value
?.week(value?.week())
.endOf('week')
.format('YYYY-MM-DD')
: null,
};
break;
case 'monthly':
params = {
start_date: value
? value
?.month(value?.month())
.startOf('month')
.format('YYYY-MM-DD')
: null,
end_date: value
? value
?.month(value?.month())
.endOf('month')
.format('YYYY-MM-DD')
: null,
};
break;
case 'year':
params = {
start_date: value ? moment(`${value}-01-01`)?.format('YYYY-MM-DD') : null,
end_date: value
? moment(`${value}-01-01`)
?.endOf('month')
?.format('YYYY-MM-DD')
: null,
};
break;
case 'custom':
params = {
start_date: value && value[0] ? value[0].format('YYYY-MM-DD') : null,
end_date: value && value[1] ? value[1].format('YYYY-MM-DD') : null,
};
break;
default:
break;
}
handleCustomDateClick(params);
};
switch (dateType) {
case 'daily':
return (
<DatePicker
allowClear={false}
disabledDate={current => {
return current && current >= moment();
}}
locale={locale}
style={{ width: '100%' }}
onChange={onValueChange}
/>
);
case 'weekly':
return (
<DatePicker
allowClear={false}
disabledDate={current => {
return current > moment().endOf('day');
}}
locale={locale}
style={{ width: '100%' }}
onChange={onValueChange}
picker="week"
/>
);
case 'monthly':
return (
<DatePicker
allowClear={false}
disabledDate={current => {
return current > moment().endOf('day');
}}
locale={locale}
style={{ width: '100%' }}
onChange={onValueChange}
picker="month"
/>
);
case 'year':
return (
<DatePicker
allowClear={false}
disabledDate={current => {
return current > moment().endOf('day');
}}
locale={locale}
style={{ width: '100%' }}
onChange={onValueChange}
picker="year"
/>
);
case 'custom':
return (
<RangePicker
allowClear={false}
disabledDate={current => {
return current && current.valueOf() > moment().subtract(0, 'days');
}}
locale={locale}
style={{ width: '100%' }}
onChange={onValueChange}
/>
);
default:
break;
}
}, [dateType, handleCustomDateClick]);
return dataPicker;
};
//DatePageChange.jsx
import React, { useMemo } from 'react';
import { Button } from 'antd';
import moment from 'moment';
export default ({ dateType, currentDateInfo = {}, handleDatePageClick = () => {} }) => {
const changeDate = useMemo(() => {
let preName = '';
let nextName = '';
switch (dateType) {
case 'daily':
preName = '前一天';
nextName = '后一天';
break;
case 'weekly':
preName = '上一周';
nextName = '下一周';
break;
case 'monthly':
preName = '上一月';
nextName = '下一月';
break;
case 'year':
preName = '上一年';
nextName = '下一年';
break;
case 'custom':
preName = '前一天';
nextName = '后一天';
break;
default:
break;
}
const onChangeDatePage = flag => {
let start_date = currentDateInfo?.start_date;
let end_date = currentDateInfo?.end_date;
switch (dateType) {
case 'daily':
if (flag) {
start_date = moment(start_date)
.subtract(1, 'days')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.subtract(1, 'days')
.format('YYYY-MM-DD');
} else {
const current = moment(start_date).format('YYYY-MM-DD');
const disable_start = moment()
.endOf('days')
.format('YYYY-MM-DD');
if (moment(current).isSameOrAfter(disable_start)) return;
start_date = moment(start_date)
.add(1, 'days')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.add(1, 'days')
.format('YYYY-MM-DD');
}
break;
case 'weekly':
if (flag) {
start_date = moment(start_date)
.subtract(1, 'weeks')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.subtract(1, 'weeks')
.format('YYYY-MM-DD');
} else {
const current = moment(start_date).format('YYYY-MM-DD');
const disable_start = moment()
.endOf('weeks')
.format('YYYY-MM-DD');
if (moment(current).isSameOrAfter(disable_start)) return;
start_date = moment(start_date)
.add(1, 'weeks')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.add(1, 'weeks')
.format('YYYY-MM-DD');
}
break;
case 'monthly':
if (flag) {
start_date = moment(start_date)
.subtract(1, 'months')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.subtract(1, 'months')
.format('YYYY-MM-DD');
} else {
const current = moment(start_date).format('YYYY-MM');
const disable_start = moment()
.endOf('month')
.format('YYYY-MM');
if (moment(current).isSameOrAfter(disable_start)) return;
start_date = moment(start_date)
.add(1, 'months')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.add(1, 'months')
.format('YYYY-MM-DD');
}
break;
case 'year':
if (flag) {
start_date = moment(start_date)
.subtract(1, 'years')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.subtract(1, 'years')
.format('YYYY-MM-DD');
} else {
const current = moment(start_date).year();
const disable_start = moment()
.endOf('year')
.format('YYYY');
if (current === Number(disable_start)) return;
start_date = moment(start_date)
.add(1, 'years')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.add(1, 'years')
.format('YYYY-MM-DD');
}
break;
case 'custom':
if (flag) {
start_date = moment(start_date)
.subtract(1, 'days')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.subtract(1, 'days')
.format('YYYY-MM-DD');
} else {
start_date = moment(start_date)
.add(1, 'days')
.format('YYYY-MM-DD');
end_date = moment(end_date)
.add(1, 'days')
.format('YYYY-MM-DD');
}
break;
default:
break;
}
handleDatePageClick(start_date, end_date);
};
return (
<div style={{ display: 'flex' }}>
<Button onClick={() => onChangeDatePage(true)}>{preName} </Button>
<Button onClick={() => onChangeDatePage(false)}>{nextName} </Button>
</div>
);
}, [dateType, currentDateInfo, handleDatePageClick]);
return changeDate;
};
使用组件
import React, { useState, useEffect, useMemo } from 'react';
import '@ant-design/compatible/assets/index.css';
import { Button, Form, Checkbox } from 'antd';
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import moment from 'moment';
import { getCombineClassName, getShowCount } from '@/utils/utils';
import ProductNameSelect from '@/components/ProductNameSelect';
import HardwareModelSelect from '@/components/HardwareModelSelect';
import WarehouseNameSelect from '@/components/WarehouseNameSelect';
import CustomDateSelect, { DateInfoChange, DatePageChange } from '@/components/CustomDateSelect';
const FormItem = Form.Item;
const Filter = ({ listParams, dispatch, currentModel, dateType, isExpand, staticFilter }) => {
const [form] = Form.useForm();
const { resetFields, setFieldsValue } = form;
const [clientWidth, setClientWidth] = useState(document.body.clientWidth);
useEffect(() => {
window.addEventListener('resize', () => {
setClientWidth(document.body.clientWidth);
});
}, []);
useEffect(() => {
const end_date = listParams?.end_date ? moment(listParams?.end_date) : null;
const start_date = listParams?.end_date ? moment(listParams?.end_date) : null;
const datas = [start_date, end_date];
setFieldsValue({
...listParams,
dates: datas,
dates_daily: listParams?.start_date ? moment(listParams?.start_date) : null,
start_dt_week: listParams?.start_date ? moment(listParams?.start_date) : null,
end_dt_week: listParams?.start_date ? moment(listParams?.start_date) : null,
start_dt_month: listParams?.start_date ? moment(listParams?.start_date) : null,
end_dt_month: listParams?.start_date ? moment(listParams?.start_date) : null,
start_dt_year: listParams?.start_date ? moment(listParams?.start_date) : null,
});
}, [setFieldsValue, listParams]);
const handleSearch = () => {
dispatch({ type: `${currentModel}/getList` });
};
const handleFormReset = () => {
dispatch({ type: `${currentModel}/resetParams` }).then(res => {
resetFields();
setFieldsValue({
dates_daily: moment(),
});
});
};
const onValuesChange = (changedValues, allValues) => {
const {
dates,
dates_daily,
start_dt_week,
end_dt_week,
start_dt_month,
end_dt_month,
start_dt_year,
change_date,
...others
} = allValues;
const params = {
page: 1,
...others,
};
dispatch({
type: `${currentModel}/updateStateProps`,
payload: {
name: 'listParams',
value: { ...params },
},
});
if (['name'].includes(Object.keys(changedValues)[0])) {
// input输入项通过回车来触发搜索
return;
}
dispatch({ type: `${currentModel}/getList` });
};
const onChangeCheckbox = value => {
dispatch({
type: `${currentModel}/overrideStateProps`,
payload: {
staticFilter: value,
},
});
};
const commonCustomDateProps = {
dateType,
currentDateInfo: {
start_date: listParams?.start_date || null,
end_date: listParams?.end_date || null,
},
handleCustomClick({ start_date, end_date, dateType }) {
dispatch({
type: `${currentModel}/updateStateProps`,
payload: {
name: 'listParams',
value: {
start_date: start_date || null,
end_date: end_date || null,
},
},
});
dispatch({
type: `${currentModel}/overrideStateProps`,
payload: {
dateType,
},
});
dispatch({ type: `${currentModel}/getList` });
},
handleDatePageClick(start_date, end_date) {
dispatch({
type: `${currentModel}/updateStateProps`,
payload: {
name: 'listParams',
value: {
start_date: start_date || null,
end_date: end_date || null,
},
},
});
setFieldsValue({
dates: [moment(start_date), moment(end_date)],
});
dispatch({ type: `${currentModel}/getList` });
},
handleCustomDateClick({ start_date, end_date }) {
dispatch({
type: `${currentModel}/updateStateProps`,
payload: {
name: 'listParams',
value: {
start_date: start_date || null,
end_date: end_date || null,
},
},
});
},
};
const datePickerItemLable = useMemo(() => {
let lable = '';
switch (dateType) {
case 'daily':
lable = '选择日';
break;
case 'weekly':
lable = '选择周';
break;
case 'monthly':
lable = '选择月';
break;
case 'year':
lable = '选择年';
break;
case 'custom':
lable = '';
break;
default:
break;
}
return lable;
}, [dateType]);
return (
<Form
onFinish={handleSearch}
className="filterListForm"
form={form}
initialValues={{
name: '', // 客户名称
}}
onValuesChange={onValuesChange}
>
<FormItem
style={{ minWidth: 350 }}
className={getCombineClassName({
sourceClassName: '',
isExpand,
sort: 1,
clientWidth,
})}
>
<CustomDateSelect {...commonCustomDateProps} />
</FormItem>
<FormItem
name=""
label={datePickerItemLable}
className={getCombineClassName({
sourceClassName: 'three-word-padding',
isExpand,
sort: 2,
clientWidth,
})}
>
<DateInfoChange {...commonCustomDateProps} />
</FormItem>
<FormItem
name="change_date"
label=""
className={getCombineClassName({
sourceClassName: 'three-word-padding',
isExpand,
sort: 3,
clientWidth,
})}
>
<DatePageChange {...commonCustomDateProps} />
</FormItem>
<FormItem
name="operator_id"
label="仓库"
className={getCombineClassName({
sourceClassName: 'three-word-padding',
isExpand,
sort: 4,
clientWidth,
})}
>
<WarehouseNameSelect placeholder="请选择仓库" />
</FormItem>
<FormItem
name="product_name"
label="产品名称"
className={getCombineClassName({
sourceClassName: 'four-word-padding',
isExpand,
sort: 5,
clientWidth,
})}
>
<ProductNameSelect type="product" allowClear={false} hasAll="全部" />
</FormItem>
<FormItem
name="product_id"
label="硬件型号"
className={getCombineClassName({
sourceClassName: 'four-word-padding',
isExpand,
sort: 6,
clientWidth,
})}
>
<HardwareModelSelect type="product" hasAll />
</FormItem>
{/* 年后再处理 分组统计条件 */}
{false && (
<FormItem
style={{ minWidth: 600 }}
className={getCombineClassName({
sourceClassName: 'six-word-padding',
isExpand,
sort: 7,
clientWidth,
})}
label=""
>
<Checkbox.Group style={{ width: '100%' }} onChange={onChangeCheckbox} defaultValue={staticFilter}>
<span style={{ marginRight: 10 }}>分组统计条件</span>
<Checkbox value="wear_name">仓库名称</Checkbox>
<Checkbox value="name">产品名称</Checkbox>
<Checkbox value="hardware_model">硬件型号</Checkbox>
</Checkbox.Group>
</FormItem>
)}
<FormItem>
<Button type="primary" htmlType="submit">
搜索
</Button>
<Button type="default" style={{ marginLeft: 8 }} onClick={handleFormReset}>
重置
</Button>
{getShowCount(clientWidth) < 12 ? (
<Button
type="link"
onClick={() => {
dispatch({
type: `${currentModel}/overrideStateProps`,
payload: {
isExpand: !isExpand,
},
});
}}
icon={isExpand ? <DownOutlined /> : <UpOutlined />}
style={{ marginLeft: 8 }}
>
{!isExpand ? '折叠' : '展开'}
</Button>
) : null}
</FormItem>
</Form>
);
};
export default Filter;