From dcdf1e75f19ed3ef9c38d69365726af07dc51e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=80=A1?= Date: Fri, 11 Jul 2025 14:50:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Scheduled/components/TaskForm.tsx | 346 +++++++++++++++ .../Scheduled/components/TaskLogModal.tsx | 216 ++++++++++ src/pages/System/Scheduled/index.less | 197 +++++++++ src/pages/System/Scheduled/index.tsx | 405 ++++++++++++++++++ src/pages/System/Scheduled/service.ts | 88 ++++ 5 files changed, 1252 insertions(+) create mode 100644 src/pages/System/Scheduled/components/TaskForm.tsx create mode 100644 src/pages/System/Scheduled/components/TaskLogModal.tsx create mode 100644 src/pages/System/Scheduled/index.less create mode 100644 src/pages/System/Scheduled/index.tsx create mode 100644 src/pages/System/Scheduled/service.ts diff --git a/src/pages/System/Scheduled/components/TaskForm.tsx b/src/pages/System/Scheduled/components/TaskForm.tsx new file mode 100644 index 0000000..882cafd --- /dev/null +++ b/src/pages/System/Scheduled/components/TaskForm.tsx @@ -0,0 +1,346 @@ +import React, { useEffect, useState } from 'react'; +import { + Modal, + Form, + Input, + Select, + Switch, + message, + Row, + Col, + Card, + Tooltip, + Button, + Space, +} from 'antd'; +import { QuestionCircleOutlined } from '@ant-design/icons'; +import { addTask, editTask, validateCron } from '../service'; + +const { Option } = Select; +const { TextArea } = Input; + +interface TaskFormProps { + visible: boolean; + editingTask?: any; + onCancel: () => void; + onSuccess: () => void; +} + +const TaskForm: React.FC = ({ + visible, + editingTask, + onCancel, + onSuccess, +}) => { + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + const [cronValidating, setCronValidating] = useState(false); + + const isEdit = !!editingTask; + + // 常用Cron表达式示例 + const cronExamples = [ + { label: '每分钟执行', value: '0 * * * * ?' }, + { label: '每5分钟执行', value: '0 */5 * * * ?' }, + { label: '每30分钟执行', value: '0 */30 * * * ?' }, + { label: '每小时执行', value: '0 0 * * * ?' }, + { label: '每天凌晨2点执行', value: '0 0 2 * * ?' }, + { label: '每周一凌晨执行', value: '0 0 0 ? * MON' }, + { label: '每月1号凌晨执行', value: '0 0 0 1 * ?' }, + ]; + + // 请求方法选项 + const requestMethods = [ + { label: 'GET', value: 'GET' }, + { label: 'POST', value: 'POST' }, + { label: 'PUT', value: 'PUT' }, + { label: 'DELETE', value: 'DELETE' }, + ]; + + useEffect(() => { + if (visible) { + if (isEdit) { + // 编辑模式,填充表单数据 + form.setFieldsValue({ + ...editingTask, + requestParams: editingTask.requestParams ? JSON.stringify(JSON.parse(editingTask.requestParams), null, 2) : '', + requestHeaders: editingTask.requestHeaders ? JSON.stringify(JSON.parse(editingTask.requestHeaders), null, 2) : '', + }); + } else { + // 新增模式,设置默认值 + form.setFieldsValue({ + status: 1, + requestMethod: 'POST', + requestParams: '{}', + requestHeaders: '{"Content-Type": "application/json"}', + }); + } + } + }, [visible, editingTask, isEdit, form]); + + // 验证Cron表达式 + const handleCronValidate = async () => { + const cronExpression = form.getFieldValue('cronExpression'); + if (!cronExpression) { + message.warning('请先输入Cron表达式'); + return; + } + + setCronValidating(true); + try { + const { success, data } = await validateCron(cronExpression); + if (success) { + message.success('Cron表达式验证通过'); + if (data?.nextExecuteTimes) { + Modal.info({ + title: '接下来5次执行时间', + content: ( +
+ {data.nextExecuteTimes.map((time: string, index: number) => ( +
{time}
+ ))} +
+ ), + }); + } + } else { + message.error('Cron表达式格式错误'); + } + } catch (error) { + message.error('验证失败'); + } finally { + setCronValidating(false); + } + }; + + // 使用示例Cron表达式 + const useCronExample = (cronExpression: string) => { + form.setFieldsValue({ cronExpression }); + }; + + // 表单提交 + const handleSubmit = async () => { + try { + const values = await form.validateFields(); + + // 验证JSON格式 + try { + if (values.requestParams) { + JSON.parse(values.requestParams); + } + if (values.requestHeaders) { + JSON.parse(values.requestHeaders); + } + } catch (error) { + message.error('请求参数或请求头必须是有效的JSON格式'); + return; + } + + setLoading(true); + + const { success } = isEdit + ? await editTask({ ...values, taskId: editingTask.taskId }) + : await addTask(values); + + if (success) { + message.success(isEdit ? '修改成功' : '新增成功'); + onSuccess(); + } + } catch (error) { + console.error('表单提交失败:', error); + } finally { + setLoading(false); + } + }; + + return ( + +
+ + + + + + + + + form.setFieldsValue({ status: checked ? 1 : 0 })} + /> + + + + + +