From 943ac9e648de31abcc97113033ea8b1164fef0e8 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 2 Sep 2025 14:40:15 +0800 Subject: [PATCH] =?UTF-8?q?feat(flowEditor):=20=E5=A2=9E=E5=8A=A0=E5=91=A8?= =?UTF-8?q?=E6=9C=9F=E6=80=A7=E8=8A=82=E7=82=B9=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 CronPicker 组件用于编辑周期表达式 - 在 CycleEditor 中集成 CronPicker,支持周期参数配置- 优化 NodeContent 组件,支持显示周期性节点的执行周期 - 新增 isJSON 函数用于判断是否为 JSON 字符串 --- src/components/CronPicker/index.tsx | 67 +++++++++++++++++-- .../flowEditor/components/nodeContent.tsx | 25 ++++--- .../nodeEditors/components/CycleEditor.tsx | 24 ++++++- .../nodeEditors/components/WaitEditor.tsx | 1 - src/utils/common.ts | 11 +++ 5 files changed, 113 insertions(+), 15 deletions(-) diff --git a/src/components/CronPicker/index.tsx b/src/components/CronPicker/index.tsx index 75fed34..91eca42 100644 --- a/src/components/CronPicker/index.tsx +++ b/src/components/CronPicker/index.tsx @@ -20,6 +20,7 @@ interface CronPickerProps { onChange?: (value: string) => void; style?: React.CSSProperties; className?: string; + onUpdateData: (data) => void; } const PRESETS = [ @@ -42,7 +43,7 @@ const dayMap = { 'SUN': '周日' }; -const CronPicker: React.FC = ({ value, onChange, style, className }) => { +const CronPicker: React.FC = ({ value, onChange, style, className, onUpdateData }) => { const [mode, setMode] = useState<'visual' | 'expression'>('visual'); const [cron, setCron] = useState(value || '0 0 0 * * ?'); const [error, setError] = useState(''); @@ -56,6 +57,8 @@ const CronPicker: React.FC = ({ value, onChange, style, classNa const [specificDay, setSpecificDay] = useState(1); const [selectedWeekdays, setSelectedWeekdays] = useState(['MON']); const [selectedMonths, setSelectedMonths] = useState(['1']); + const [monthlyType, setMonthlyType] = useState<'every' | 'specific'>('every'); + const [specificMonths, setSpecificMonths] = useState(['1']); // 初始化 useEffect(() => { @@ -108,7 +111,11 @@ const CronPicker: React.FC = ({ value, onChange, style, classNa dow = selectedWeekdays.length > 0 ? selectedWeekdays.join(',') : '*'; } - const mon = selectedMonths.length < 12 ? selectedMonths.join(',') : '*'; + const mon = monthlyType === 'every' + ? '*' + : specificMonths.length > 0 + ? specificMonths.join(',') + : '*'; const newCron = `${sec} ${min} ${hour} ${dom} ${mon} ${dow}`; return newCron; // validateAndSet(newCron); @@ -119,7 +126,14 @@ const CronPicker: React.FC = ({ value, onChange, style, classNa return generateCron(); } return cron; - }, [mode, minuteType, minutesInterval, hourType, hourlyAt, dailyType, specificDay, selectedWeekdays, selectedMonths, cron]); + }, [mode, minuteType, minutesInterval, hourType, hourlyAt, dailyType, specificDay, selectedWeekdays, selectedMonths, monthlyType, specificMonths, cron]); + + useEffect(() => { + onUpdateData({ + customDef: { intervalSeconds: currentCron }, + type: 'CYCLE' + }); + }, [currentCron]); // 解析Cron表达式并更新图形化配置的状态 const parseCronExpression = (cronExpression: string) => { @@ -189,11 +203,18 @@ const CronPicker: React.FC = ({ value, onChange, style, classNa } // 解析月份部分 - if (month !== '*' && month.includes(',')) { + if (month === '*') { + setMonthlyType('every'); + } + else if (month.includes(',')) { + setMonthlyType('specific'); setSelectedMonths(month.split(',')); + setSpecificMonths(month.split(',')); } else if (month !== '*') { + setMonthlyType('specific'); setSelectedMonths([month]); + setSpecificMonths([month]); } } }; @@ -225,7 +246,6 @@ const CronPicker: React.FC = ({ value, onChange, style, classNa const getNextTime = (): string => { try { - console.log('currentCron:', currentCron); const interval = CronExpressionParser.parse(currentCron); const next = interval.next(); return next?.toDate ? next.toDate().toLocaleString() : '无法计算'; @@ -379,6 +399,43 @@ const CronPicker: React.FC = ({ value, onChange, style, classNa )} + + setMonthlyType(value as 'every' | 'specific')} + style={{ display: 'flex' }} + > + + 每月 + 指定月份 + + + + + {monthlyType === 'specific' && ( + +
+ {Array.from({ length: 12 }, (_, i) => i + 1).map(month => ( + + ))} +
+
+ )} + {PRESETS.map(p => (