公司网站建设审批流程,免费网站托管,微信小程序平台官网登录入口,广告流量平台前言 
最近在写的一个分布式调度系统#xff0c;后端同学需要让我传入cron表达式#xff0c;给调度接口传参。我去了学习了解了cron表达式的用法#xff0c;发现有3个通用的表达式刚好符合我们的需求#xff1a; 
需求 
每天 xx 的时间#xff1a; 
0 11 20 * * ? 上面是…前言 
最近在写的一个分布式调度系统后端同学需要让我传入cron表达式给调度接口传参。我去了学习了解了cron表达式的用法发现有3个通用的表达式刚好符合我们的需求 
需求 
每天 xx 的时间 
0 11 20 * * ? 上面是每天20:11的cron表达式 每周的 xxx 星期 的 xxx 时间 
0 14 20 * * WED,THU 上面是 每周星期三星期四20:14的cron表达式 每周的 xxx号 的 xxx时间 
0 15 20 3,7 * ? 上面是 每月的37号20:15的cron表达式 这三个表达式刚好符合我们的需求并且每个符号表达的意思也很直观。那么话不多说直接开写 
环境 react 我的版本“react”: “18.2.0”用的函数组件react hooks  moment npm install moment  semi-design组件库 npm install semi-design  typescript  
实现 
数据 
utils下创建cron.ts对组件所用到的数据进行统一的管理 
export const dayOfTheWeekData  [{ key: MON, label: 星期一 },{ key: TUE, label: 星期二 },{ key: WED, label: 星期三 },{ key: THU, label: 星期四 },{ key: FRI, label: 星期五 },{ key: SAT, label: 星期六 },{ key: SUN, label: 星期天 }
];export const dayOfTheWeekOption  [{ key: 1, label: 星期一 },{ key: 2, label: 星期二 },{ key: 3, label: 星期三 },{ key: 4, label: 星期四 },{ key: 5, label: 星期五 },{ key: 6, label: 星期六 },{ key: 7, label: 星期天 }
];export const monthOption  [{ key: 1, label: 一月 },{ key: 2, label: 二月 },{ key: 3, label: 三月 },{ key: 4, label: 四月 },{ key: 5, label: 五月 },{ key: 6, label: 六月 },{ key: 7, label: 七月 },{ key: 8, label: 八月 },{ key: 9, label: 九月 },{ key: 10, label: 十月 },{ key: 11, label: 十一月 },{ key: 12, label: 十二月 }
];//获取dayOfTheMonthOption的每月对象
function getDayOfTheMonthOption() {const days  [];for (let i  1; i  32; i  1) {days.push({ key: i.toString(), label: i.toString().concat(号) });}return days;
}export const dayOfTheMonthOption  getDayOfTheMonthOption(); 
组件 
到了组件的具体实现个人感觉我写的注释挺全的就单挑几个核心重点讲下 
时间转换函数handleTimeChange //时间选择函数const handleTimeChange  (time: moment.Moment | null)  {setSelectTime(time);if (!time) return;const currentCron  expression ? expression.split( ) : [];const [seconds, , , dayOfMonth, month1, dayOfWeek]  currentCron;const minutes  moment(time).minutes().toString(); //获取分钟const hours  moment(time).hours().toString(); //获取小时let result  null;if (!Number.isNaN(Number(hours))  !Number.isNaN(Number(minutes))) {const minutesAndHour  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space);if (defaultTimeType  everyDay) result  minutesAndHour.concat(* * ?);if (defaultTimeType ! everyDay)result  minutesAndHour.concat(dayOfMonth).concat(space).concat(month1).concat(space).concat(dayOfWeek);}if (result) onChange?.(result);setExpression(result);};使用moment函数将time转成数字类型 minutes  moment(time).minutes().toString(); //获取分钟hours  moment(time).hours().toString(); //获取小时 获取时间cron字符串minutesAndHour 
const minutesAndHour  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space);拼接得到完整的cron表达式 defaultTimeType  ‘everyDay’  result  minutesAndHour.concat(‘* * ?’); defaultTimeType ! ‘everyDay’ 
result  minutesAndHour.concat(dayOfMonth).concat(space).concat(month1).concat(space).concat(dayOfWeek);日期转换函数handleSelectChange 
setSelectedValue(data);
const selectValues  data.join(,);
const currentCron  expression ? expression.split( ) : [];
const [seconds, minutes, hours, dayOfMonth, month1, dayOfWeek]  currentCron;
let result  ;
if (defaultTimeType  everyWeek) {result  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space).concat(dayOfMonth).concat(space).concat(month1).concat(space).concat(selectValues);
}
if (defaultTimeType  everyMonth) {result  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space).concat(data.length ? selectValues : *).concat(space).concat(month1).concat(space).concat(dayOfWeek);
}
if (selectTime) onChange?.(result);
setExpression(result);defaultTimeType  ‘everyWeek’ 
result  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space).concat(dayOfMonth).concat(space).concat(month1).concat(space).concat(selectValues);defaultTimeType  ‘everyMonth’ 
result  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space).concat(data.length ? selectValues : *).concat(space).concat(month1).concat(space).concat(dayOfWeek);组件全部代码CronInput 
import { ConfigProvider, TimePicker } from douyinfe/semi-ui;
import { Fragment, useState } from react;
import { Select } from douyinfe/semi-ui;
import moment from moment;
//引入数据
import { dayOfTheMonthOption, dayOfTheWeekData } from /utils/cron;const { Option }  Select;
const format  HH:mm;
const defaultCron  0 * * * * ?;
const space   ; //空格
//类型选择
const timeTypes  [{ key: everyDay, label: 每天 },{ key: everyWeek, label: 每周 },{ key: everyMonth, label: 每月 }
];interface Props {onChange?: (cron?: string)  void;
}
const CronInput: React.FCProps  ({ onChange })  {const [defaultTimeType, setDefaultTimeType]  useState(timeTypes[0].key); //选择类型const [selectedValue, setSelectedValue]  useState[]([]); //日期多选数组const [selectTime, setSelectTime]  useStateany(null); //时间const [expression, setExpression]  useStatestring | null(defaultCron); //bzd//类型选择函数const handleTimeTypeChange  (selectValue: string)  {setDefaultTimeType(selectValue);setSelectTime(null);setSelectedValue([]);setExpression(defaultCron);};//时间选择函数const handleTimeChange  (time: moment.Moment | null)  {setSelectTime(time);if (!time) return;const currentCron  expression ? expression.split( ) : [];const [seconds, , , dayOfMonth, month1, dayOfWeek]  currentCron;const minutes  moment(time).minutes().toString(); //获取分钟const hours  moment(time).hours().toString(); //获取小时let result  null;if (!Number.isNaN(Number(hours))  !Number.isNaN(Number(minutes))) {const minutesAndHour  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space);if (defaultTimeType  everyDay) result  minutesAndHour.concat(* * ?);if (defaultTimeType ! everyDay)result  minutesAndHour.concat(dayOfMonth).concat(space).concat(month1).concat(space).concat(dayOfWeek);}if (result) onChange?.(result);setExpression(result);};const handleSelectChange  (data: [])  {setSelectedValue(data);const selectValues  data.join(,);const currentCron  expression ? expression.split( ) : [];const [seconds, minutes, hours, dayOfMonth, month1, dayOfWeek]  currentCron;let result  ;if (defaultTimeType  everyWeek) {result  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space).concat(dayOfMonth).concat(space).concat(month1).concat(space).concat(selectValues);}if (defaultTimeType  everyMonth) {result  seconds.concat(space).concat(minutes).concat(space).concat(hours).concat(space).concat(data.length ? selectValues : *).concat(space).concat(month1).concat(space).concat(dayOfWeek);}if (selectTime) onChange?.(result);setExpression(result);};const RenderSelect  ({placeholder,data  []}: {placeholder: string;data: { key: string; label: string }[];})  {return (FragmentSelectmultipleplaceholder{placeholder}onChange{(val: any)  handleSelectChange(val)}style{{ marginRight: 16px, width: auto }}value{selectedValue}{data.map((item: { key: string; label: string })  (Option key{item.key} value{item.key}{item.label}/Option))}/SelectConfigProviderTimePickervalue{selectTime  moment(selectTime, format).toDate()}format{format}placeholder请选择时间onChange{(val: any)  handleTimeChange(val)}//ConfigProvider/Fragment);};return (div className{cron}Select// rolecron-typestyle{{ marginRight: 16px, width: auto }}placeholder请选择类型onChange{(val: any)  handleTimeTypeChange(val)}value{defaultTimeType}{timeTypes.map((item)  (Option key{item.key} value{item.key}{ }{item.label}/Option))}/Select{defaultTimeType  everyDay  (ConfigProviderTimePickervalue{selectTime  moment(selectTime, format).toDate()}format{format}placeholder请选择时间onChange{(val: any)  handleTimeChange(val)}//ConfigProvider)}{defaultTimeType  everyWeek  (RenderSelect data{dayOfTheWeekData} placeholder请选择星期 /)}{defaultTimeType  everyMonth  (RenderSelect data{dayOfTheMonthOption} placeholder请选择日期 /)}/div/);
};export default CronInput; 
使用与效果 
使用 
使用方法很简单接收onChange传来的cron表达式即可 
const App: FCIProps  (props)  {const { datas  [] }  props;let [value, setValue]  useStatestring();return (divCronInput onChange{(cron)  setValue(cron)} /div{value}/div/div);
};效果 
每天 每周 每月