|
|
|
|
@ -44,8 +44,8 @@ const dayMap = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const CronPicker: React.FC<CronPickerProps> = ({ value, onChange, style, className, onUpdateData }) => {
|
|
|
|
|
const [mode, setMode] = useState<'visual' | 'expression'>('visual');
|
|
|
|
|
const [cron, setCron] = useState<string>(value || '0 0 0 * * ?');
|
|
|
|
|
const [mode, setMode] = useState<'visual' | 'expression'>('expression');
|
|
|
|
|
const [cron, setCron] = useState<string>(value);
|
|
|
|
|
const [error, setError] = useState<string>('');
|
|
|
|
|
|
|
|
|
|
// 图形化配置的状态
|
|
|
|
|
@ -62,7 +62,12 @@ const CronPicker: React.FC<CronPickerProps> = ({ value, onChange, style, classNa
|
|
|
|
|
|
|
|
|
|
// 初始化
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (value !== undefined && value !== cron) {
|
|
|
|
|
console.log('CronPicker value changed:', value);
|
|
|
|
|
console.log('Current cron state:', cron);
|
|
|
|
|
|
|
|
|
|
// 当 value 有值且与当前 cron 不同时,更新 cron 状态
|
|
|
|
|
if (value && value !== cron) {
|
|
|
|
|
console.log('Updating cron to:', value);
|
|
|
|
|
setCron(value);
|
|
|
|
|
// 当外部value变化时,解析并更新图形化配置的状态
|
|
|
|
|
parseCronExpression(value);
|
|
|
|
|
@ -125,14 +130,31 @@ const CronPicker: React.FC<CronPickerProps> = ({ value, onChange, style, classNa
|
|
|
|
|
if (mode === 'visual') {
|
|
|
|
|
return generateCron();
|
|
|
|
|
}
|
|
|
|
|
return cron;
|
|
|
|
|
// 如果 cron 为空,返回空字符串而不是默认值
|
|
|
|
|
return cron || '';
|
|
|
|
|
}, [mode, minuteType, minutesInterval, hourType, hourlyAt, dailyType, specificDay, selectedWeekdays, selectedMonths, monthlyType, specificMonths, cron]);
|
|
|
|
|
|
|
|
|
|
// 使用 ref 来追踪是否是初始化阶段
|
|
|
|
|
const isInitializedRef = React.useRef(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
onUpdateData({
|
|
|
|
|
customDef: { intervalSeconds: currentCron },
|
|
|
|
|
type: 'CYCLE'
|
|
|
|
|
});
|
|
|
|
|
console.log('currentCron changed:', currentCron);
|
|
|
|
|
console.log('isInitializedRef.current:', isInitializedRef.current);
|
|
|
|
|
|
|
|
|
|
// 跳过初始化时的调用
|
|
|
|
|
if (!isInitializedRef.current) {
|
|
|
|
|
isInitializedRef.current = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 只有当 currentCron 有值时才更新
|
|
|
|
|
if (currentCron) {
|
|
|
|
|
console.log('Calling onUpdateData with:', currentCron);
|
|
|
|
|
onUpdateData({
|
|
|
|
|
customDef: { intervalSeconds: currentCron },
|
|
|
|
|
type: 'CYCLE'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}, [currentCron]);
|
|
|
|
|
|
|
|
|
|
// 解析Cron表达式并更新图形化配置的状态
|
|
|
|
|
@ -309,10 +331,26 @@ const CronPicker: React.FC<CronPickerProps> = ({ value, onChange, style, classNa
|
|
|
|
|
return (
|
|
|
|
|
<div style={style} className={`${styles.container} ${className || ''}`}>
|
|
|
|
|
<Tabs onChange={handleTabChange} type="rounded" size="small" className={styles.tabs}>
|
|
|
|
|
<TabPane key="visual" title="图形化配置" />
|
|
|
|
|
<TabPane key="expression" title="Cron 表达式" />
|
|
|
|
|
<TabPane key="visual" title="图形化配置" />
|
|
|
|
|
</Tabs>
|
|
|
|
|
|
|
|
|
|
{mode === 'expression' && (
|
|
|
|
|
<div>
|
|
|
|
|
<label style={{ display: 'block', marginBottom: 6, fontSize: 14, color: '#333' }}>
|
|
|
|
|
Cron 表达式
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={currentCron}
|
|
|
|
|
onChange={handleExpressionChange}
|
|
|
|
|
placeholder="例如:0 0 12 * * ?"
|
|
|
|
|
className={`${styles.expressionInput} ${error ? styles.error : ''}`}
|
|
|
|
|
/>
|
|
|
|
|
{error && <div className={styles.errorMessage}>{error}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{mode === 'visual' && (
|
|
|
|
|
<div>
|
|
|
|
|
<Form.Item label="分钟" className={styles.formItem}>
|
|
|
|
|
@ -446,22 +484,6 @@ const CronPicker: React.FC<CronPickerProps> = ({ value, onChange, style, classNa
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{mode === 'expression' && (
|
|
|
|
|
<div>
|
|
|
|
|
<label style={{ display: 'block', marginBottom: 6, fontSize: 14, color: '#333' }}>
|
|
|
|
|
Cron 表达式
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={currentCron}
|
|
|
|
|
onChange={handleExpressionChange}
|
|
|
|
|
placeholder="0 0 12 * * ?"
|
|
|
|
|
className={`${styles.expressionInput} ${error ? styles.error : ''}`}
|
|
|
|
|
/>
|
|
|
|
|
{error && <div className={styles.errorMessage}>{error}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div className={styles.previewContainer}>
|
|
|
|
|
<Text type="secondary" style={{ fontSize: 13, display: 'block', marginBottom: 4 }}>
|
|
|
|
|
说明:{getHumanReadable()}
|
|
|
|
|
|