feat(调度任务): 实现调度任务管理功能

新增调度任务模块,支持任务的增删改查、启停及手动执行
- 后端添加 schedule_job 模型、服务、路由及调度器工具类
- 前端新增调度任务管理页面
- 修改 flow 相关接口将 id 类型从 String 改为 i64
- 添加 tokio-cron-scheduler 依赖实现定时任务调度
- 初始化时加载已启用任务并注册到调度器
This commit is contained in:
2025-09-24 00:21:30 +08:00
parent cadd336dee
commit 8c06849254
29 changed files with 1253 additions and 103 deletions

View File

@ -158,7 +158,7 @@ struct RunReq { #[serde(default)] input: serde_json::Value }
async fn run_sse(
State(db): State<Db>,
Path(id): Path<String>,
Path(id): Path<i64>,
Query(q): Query<HashMap<String, String>>,
headers: HeaderMap,
Json(req): Json<RunReq>,
@ -192,11 +192,11 @@ async fn run_sse(
// 启动后台任务运行流程,将事件通过 tx 发送
let db_clone = db.clone();
let id_clone = id.clone();
let id_clone = id;
let input = req.input.clone();
let user_info = Some((claims.uid, claims.sub));
tokio::spawn(async move {
let _ = flow_service::run_with_stream(db_clone, &id_clone, flow_service::RunReq { input }, user_info, tx).await;
let _ = flow_service::run_with_stream(db_clone, id_clone, flow_service::RunReq { input }, user_info, tx).await;
});
// 由通用组件把 Receiver 包装为 SSE 响应

View File

@ -42,7 +42,7 @@ use axum::extract::ws::{WebSocketUpgrade, WebSocket, Message, Utf8Bytes};
pub async fn run_ws(
State(db): State<Db>,
Path(id): Path<String>,
Path(id): Path<i64>,
Query(q): Query<HashMap<String, String>>,
headers: HeaderMap,
ws: WebSocketUpgrade,
@ -70,7 +70,7 @@ pub async fn run_ws(
}
let db_clone = db.clone();
let id_clone = id.clone();
let id_clone = id;
let user_info = Some((claims.uid, claims.sub));
Ok(ws.on_upgrade(move |socket| async move {
@ -78,7 +78,7 @@ pub async fn run_ws(
}))
}
pub async fn handle_ws_flow(mut socket: WebSocket, db: Db, id: String, user_info: Option<(i64, String)>) {
pub async fn handle_ws_flow(mut socket: WebSocket, db: Db, id: i64, user_info: Option<(i64, String)>) {
use tokio::time::{timeout, Duration};
use tokio::select;
use tokio::sync::mpsc;
@ -106,9 +106,9 @@ pub async fn handle_ws_flow(mut socket: WebSocket, db: Db, id: String, user_info
// 后台运行流程
let db2 = db.clone();
let id2 = id.clone();
let id2 = id;
tokio::spawn(async move {
let _ = flow_service::run_with_stream(db2, &id2, flow_service::RunReq { input: input_value }, user_info, tx).await;
let _ = flow_service::run_with_stream(db2, id2, flow_service::RunReq { input: input_value }, user_info, tx).await;
});
// 转发事件到 WebSocket