新增调度任务模块,支持任务的增删改查、启停及手动执行 - 后端添加 schedule_job 模型、服务、路由及调度器工具类 - 前端新增调度任务管理页面 - 修改 flow 相关接口将 id 类型从 String 改为 i64 - 添加 tokio-cron-scheduler 依赖实现定时任务调度 - 初始化时加载已启用任务并注册到调度器
76 lines
4.0 KiB
Rust
76 lines
4.0 KiB
Rust
use axum::{Router, routing::{get, post, put}, extract::{State, Path, Query}, Json};
|
|
use crate::{db::Db, error::AppError, response::ApiResponse, services::{schedule_job_service, flow_service}, models::schedule_job};
|
|
use crate::middlewares::jwt::AuthUser;
|
|
use sea_orm::{EntityTrait};
|
|
|
|
pub fn router() -> Router<Db> {
|
|
Router::new()
|
|
.route("/schedule_jobs", get(list).post(create))
|
|
.route("/schedule_jobs/{id}", put(update).delete(remove))
|
|
// 新增:独立启停端点
|
|
.route("/schedule_jobs/{id}/enable", post(enable))
|
|
.route("/schedule_jobs/{id}/disable", post(disable))
|
|
// 新增:手动执行端点
|
|
.route("/schedule_jobs/{id}/execute", post(execute))
|
|
}
|
|
|
|
async fn list(State(db): State<Db>, Query(p): Query<schedule_job_service::ListParams>) -> Result<Json<ApiResponse<schedule_job_service::PageResp<schedule_job_service::ScheduleJobDoc>>>, AppError> {
|
|
let res = schedule_job_service::list(&db, p).await?;
|
|
Ok(Json(ApiResponse::ok(res)))
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
struct CreateReq { name: String, cron_expr: String, enabled: bool, flow_code: String }
|
|
|
|
async fn create(State(db): State<Db>, _user: AuthUser, Json(req): Json<CreateReq>) -> Result<Json<ApiResponse<schedule_job_service::ScheduleJobDoc>>, AppError> {
|
|
let res = schedule_job_service::create(&db, schedule_job_service::CreateReq { name: req.name, cron_expr: req.cron_expr, enabled: req.enabled, flow_code: req.flow_code }).await?;
|
|
Ok(Json(ApiResponse::ok(res)))
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
struct UpdateReq { name: Option<String>, cron_expr: Option<String>, enabled: Option<bool>, flow_code: Option<String> }
|
|
|
|
async fn update(State(db): State<Db>, _user: AuthUser, Path(id): Path<String>, Json(req): Json<UpdateReq>) -> Result<Json<ApiResponse<schedule_job_service::ScheduleJobDoc>>, AppError> {
|
|
let res = schedule_job_service::update(&db, &id, schedule_job_service::UpdateReq { name: req.name, cron_expr: req.cron_expr, enabled: req.enabled, flow_code: req.flow_code }).await?;
|
|
Ok(Json(ApiResponse::ok(res)))
|
|
}
|
|
|
|
async fn remove(State(db): State<Db>, _user: AuthUser, Path(id): Path<String>) -> Result<Json<ApiResponse<serde_json::Value>>, AppError> {
|
|
schedule_job_service::remove(&db, &id).await?;
|
|
Ok(Json(ApiResponse::ok(serde_json::json!({}))))
|
|
}
|
|
|
|
// 新增:启用指定任务(不需要请求体)
|
|
async fn enable(State(db): State<Db>, _user: AuthUser, Path(id): Path<String>) -> Result<Json<ApiResponse<schedule_job_service::ScheduleJobDoc>>, AppError> {
|
|
let res = schedule_job_service::update(&db, &id, schedule_job_service::UpdateReq { name: None, cron_expr: None, enabled: Some(true), flow_code: None }).await?;
|
|
Ok(Json(ApiResponse::ok(res)))
|
|
}
|
|
|
|
// 新增:禁用指定任务(不需要请求体)
|
|
async fn disable(State(db): State<Db>, _user: AuthUser, Path(id): Path<String>) -> Result<Json<ApiResponse<schedule_job_service::ScheduleJobDoc>>, AppError> {
|
|
let res = schedule_job_service::update(&db, &id, schedule_job_service::UpdateReq { name: None, cron_expr: None, enabled: Some(false), flow_code: None }).await?;
|
|
Ok(Json(ApiResponse::ok(res)))
|
|
}
|
|
|
|
// 新增:手动执行指定任务
|
|
async fn execute(State(db): State<Db>, user: AuthUser, Path(id): Path<String>) -> Result<Json<ApiResponse<serde_json::Value>>, AppError> {
|
|
// 1) 获取任务信息
|
|
let job = schedule_job::Entity::find_by_id(id.to_string())
|
|
.one(&db)
|
|
.await?
|
|
.ok_or(AppError::NotFound)?;
|
|
|
|
// 2) 通过 flow_code 获取流程
|
|
let flow_doc = flow_service::get_by_code(&db, &job.flow_code).await
|
|
.map_err(flow_service::ae)?;
|
|
|
|
// 3) 执行流程(使用空输入,操作者为当前用户)
|
|
let result = flow_service::run(
|
|
&db,
|
|
flow_doc.id,
|
|
flow_service::RunReq { input: serde_json::json!({}) },
|
|
Some((user.uid, user.username)),
|
|
).await.map_err(flow_service::ae)?;
|
|
|
|
Ok(Json(ApiResponse::ok(serde_json::to_value(result).map_err(|e| AppError::BadRequest(e.to_string()))?)))
|
|
} |