微信小程序页面迁移校验之前 P5任务处理之前
This commit is contained in:
@@ -10,19 +10,22 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import {
|
||||
Table, Tag, Button, Switch, Popconfirm, Space, Modal, Form,
|
||||
Input, Select, InputNumber, TimePicker, Checkbox, message,
|
||||
Input, Select, InputNumber, TimePicker, Checkbox, message, Typography,
|
||||
} from 'antd';
|
||||
import { PlusOutlined, ReloadOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import { ReloadOutlined, EditOutlined, DeleteOutlined, HistoryOutlined, PlayCircleOutlined } from '@ant-design/icons';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import dayjs from 'dayjs';
|
||||
import type { ScheduledTask, ScheduleConfig } from '../types';
|
||||
import {
|
||||
fetchSchedules,
|
||||
createSchedule,
|
||||
updateSchedule,
|
||||
deleteSchedule,
|
||||
toggleSchedule,
|
||||
runScheduleNow,
|
||||
} from '../api/schedules';
|
||||
import ScheduleHistoryDrawer from './ScheduleHistoryDrawer';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* 常量 & 工具 */
|
||||
@@ -150,6 +153,11 @@ const ScheduleTab: React.FC = () => {
|
||||
const [scheduleType, setScheduleType] = useState<string>('daily');
|
||||
const [form] = Form.useForm();
|
||||
|
||||
/* 执行历史抽屉状态 */
|
||||
const [historyOpen, setHistoryOpen] = useState(false);
|
||||
const [historyScheduleId, setHistoryScheduleId] = useState<string | null>(null);
|
||||
const [historyScheduleName, setHistoryScheduleName] = useState('');
|
||||
|
||||
/* 加载列表 */
|
||||
const load = useCallback(async () => {
|
||||
setLoading(true);
|
||||
@@ -164,25 +172,6 @@ const ScheduleTab: React.FC = () => {
|
||||
|
||||
useEffect(() => { load(); }, [load]);
|
||||
|
||||
/* 打开创建 Modal */
|
||||
const openCreate = () => {
|
||||
setEditing(null);
|
||||
form.resetFields();
|
||||
form.setFieldsValue({
|
||||
schedule_config: {
|
||||
schedule_type: 'daily',
|
||||
interval_value: 1,
|
||||
interval_unit: 'hours',
|
||||
daily_time: dayjs('04:00', 'HH:mm'),
|
||||
weekly_days: [1],
|
||||
weekly_time: dayjs('04:00', 'HH:mm'),
|
||||
cron_expression: '0 4 * * *',
|
||||
},
|
||||
});
|
||||
setScheduleType('daily');
|
||||
setModalOpen(true);
|
||||
};
|
||||
|
||||
/* 打开编辑 Modal */
|
||||
const openEdit = (record: ScheduledTask) => {
|
||||
setEditing(record);
|
||||
@@ -199,13 +188,20 @@ const ScheduleTab: React.FC = () => {
|
||||
setModalOpen(true);
|
||||
};
|
||||
|
||||
/* 提交创建/编辑 */
|
||||
/* 打开执行历史 */
|
||||
const openHistory = (record: ScheduledTask) => {
|
||||
setHistoryScheduleId(record.id);
|
||||
setHistoryScheduleName(record.name);
|
||||
setHistoryOpen(true);
|
||||
};
|
||||
|
||||
/* 提交编辑 */
|
||||
const handleSubmit = async () => {
|
||||
if (!editing) return;
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
setSubmitting(true);
|
||||
|
||||
// 将 dayjs 对象转为字符串
|
||||
const cfg = { ...values.schedule_config };
|
||||
if (cfg.daily_time && typeof cfg.daily_time !== 'string') {
|
||||
cfg.daily_time = cfg.daily_time.format('HH:mm');
|
||||
@@ -227,47 +223,16 @@ const ScheduleTab: React.FC = () => {
|
||||
end_date: null,
|
||||
};
|
||||
|
||||
if (editing) {
|
||||
await updateSchedule(editing.id, {
|
||||
name: values.name,
|
||||
schedule_config: scheduleConfig,
|
||||
});
|
||||
message.success('调度任务已更新');
|
||||
} else {
|
||||
// 创建时使用默认 task_config(简化实现)
|
||||
await createSchedule({
|
||||
name: values.name,
|
||||
task_codes: [],
|
||||
task_config: {
|
||||
tasks: [],
|
||||
flow: 'api_full',
|
||||
processing_mode: 'increment_only',
|
||||
pipeline_flow: 'FULL',
|
||||
dry_run: false,
|
||||
window_mode: 'lookback',
|
||||
window_start: null,
|
||||
window_end: null,
|
||||
window_split: null,
|
||||
window_split_days: null,
|
||||
lookback_hours: 24,
|
||||
overlap_seconds: 600,
|
||||
fetch_before_verify: false,
|
||||
skip_ods_when_fetch_before_verify: false,
|
||||
ods_use_local_json: false,
|
||||
store_id: null,
|
||||
dwd_only_tables: null,
|
||||
force_full: false,
|
||||
extra_args: {},
|
||||
},
|
||||
schedule_config: scheduleConfig,
|
||||
});
|
||||
message.success('调度任务已创建');
|
||||
}
|
||||
await updateSchedule(editing.id, {
|
||||
name: values.name,
|
||||
schedule_config: scheduleConfig,
|
||||
});
|
||||
message.success('调度任务已更新');
|
||||
|
||||
setModalOpen(false);
|
||||
load();
|
||||
} catch {
|
||||
// 表单验证失败,不做额外处理
|
||||
// 表单验证失败
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
@@ -294,8 +259,29 @@ const ScheduleTab: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
/* 手动执行一次(不更新调度间隔) */
|
||||
const handleRunNow = async (id: string) => {
|
||||
try {
|
||||
await runScheduleNow(id);
|
||||
message.success('已提交到执行队列');
|
||||
} catch {
|
||||
message.error('执行失败');
|
||||
}
|
||||
};
|
||||
|
||||
/* 表格列定义 */
|
||||
const columns: ColumnsType<ScheduledTask> = [
|
||||
{
|
||||
title: '调度 ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 120,
|
||||
render: (id: string) => (
|
||||
<Text copyable={{ text: id }} style={{ fontSize: 11 }}>
|
||||
{id.slice(0, 8)}…
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
@@ -338,9 +324,17 @@ const ScheduleTab: React.FC = () => {
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 140,
|
||||
width: 300,
|
||||
render: (_: unknown, record: ScheduledTask) => (
|
||||
<Space size="small">
|
||||
<Popconfirm title="确认立即执行一次?(不影响调度间隔)" onConfirm={() => handleRunNow(record.id)}>
|
||||
<Button type="link" icon={<PlayCircleOutlined />} size="small">
|
||||
立即执行
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Button type="link" icon={<HistoryOutlined />} size="small" onClick={() => openHistory(record)}>
|
||||
执行历史
|
||||
</Button>
|
||||
<Button type="link" icon={<EditOutlined />} size="small" onClick={() => openEdit(record)}>
|
||||
编辑
|
||||
</Button>
|
||||
@@ -356,15 +350,11 @@ const ScheduleTab: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Space>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
|
||||
新建调度
|
||||
</Button>
|
||||
<Button icon={<ReloadOutlined />} onClick={load} loading={loading}>
|
||||
刷新
|
||||
</Button>
|
||||
</Space>
|
||||
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Text type="secondary">共 {data.length} 个调度任务</Text>
|
||||
<Button icon={<ReloadOutlined />} onClick={load} loading={loading}>
|
||||
刷新
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Table<ScheduledTask>
|
||||
@@ -376,9 +366,9 @@ const ScheduleTab: React.FC = () => {
|
||||
size="middle"
|
||||
/>
|
||||
|
||||
{/* 创建/编辑 Modal */}
|
||||
{/* 编辑 Modal */}
|
||||
<Modal
|
||||
title={editing ? '编辑调度任务' : '新建调度任务'}
|
||||
title="编辑调度任务"
|
||||
open={modalOpen}
|
||||
onOk={handleSubmit}
|
||||
onCancel={() => setModalOpen(false)}
|
||||
@@ -400,6 +390,14 @@ const ScheduleTab: React.FC = () => {
|
||||
<ScheduleConfigFields scheduleType={scheduleType} />
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
{/* 执行历史抽屉 */}
|
||||
<ScheduleHistoryDrawer
|
||||
open={historyOpen}
|
||||
scheduleId={historyScheduleId}
|
||||
scheduleName={historyScheduleName}
|
||||
onClose={() => setHistoryOpen(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user