微信小程序页面迁移校验之前 P5任务处理之前

This commit is contained in:
Neo
2026-03-09 01:19:21 +08:00
parent 263bf96035
commit 6e20987d2f
1112 changed files with 153824 additions and 219694 deletions

View File

@@ -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)}
/>
</>
);
};