use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; use uuid::Uuid; use validator::Validate; // --- 流程图节点/边定义 --- /// BPMN 节点类型 #[derive(Debug, Clone, Serialize, Deserialize, ToSchema, PartialEq)] pub enum NodeType { StartEvent, EndEvent, UserTask, ServiceTask, ExclusiveGateway, ParallelGateway, } /// 流程图节点定义 #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct NodeDef { pub id: String, #[serde(rename = "type")] pub node_type: NodeType, pub name: String, #[serde(skip_serializing_if = "Option::is_none")] pub assignee_id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub candidate_groups: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub service_type: Option, /// 前端渲染位置 #[serde(skip_serializing_if = "Option::is_none")] pub position: Option, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct NodePosition { pub x: f64, pub y: f64, } /// 流程图连线定义 #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct EdgeDef { pub id: String, pub source: String, pub target: String, /// 条件表达式(排他网关分支) #[serde(skip_serializing_if = "Option::is_none")] pub condition: Option, /// 前端渲染标签 #[serde(skip_serializing_if = "Option::is_none")] pub label: Option, } /// 完整流程图 #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct FlowDiagram { pub nodes: Vec, pub edges: Vec, } // --- 流程定义 DTOs --- #[derive(Debug, Serialize, ToSchema)] pub struct ProcessDefinitionResp { pub id: Uuid, pub name: String, pub key: String, pub version: i32, #[serde(skip_serializing_if = "Option::is_none")] pub category: Option, #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, pub nodes: serde_json::Value, pub edges: serde_json::Value, pub status: String, pub created_at: DateTime, pub updated_at: DateTime, pub lock_version: i32, } #[derive(Debug, Deserialize, Validate, ToSchema)] pub struct CreateProcessDefinitionReq { #[validate(length(min = 1, max = 200, message = "流程名称不能为空"))] pub name: String, #[validate(length(min = 1, max = 100, message = "流程编码不能为空"))] pub key: String, pub category: Option, pub description: Option, pub nodes: Vec, pub edges: Vec, } #[derive(Debug, Deserialize, Validate, ToSchema)] pub struct UpdateProcessDefinitionReq { #[validate(length(max = 200, message = "流程名称过长"))] pub name: Option, pub category: Option, pub description: Option, pub nodes: Option>, pub edges: Option>, pub version: i32, } // --- 流程实例 DTOs --- #[derive(Debug, Serialize, ToSchema)] pub struct ProcessInstanceResp { pub id: Uuid, pub definition_id: Uuid, pub definition_name: Option, #[serde(skip_serializing_if = "Option::is_none")] pub business_key: Option, pub status: String, pub started_by: Uuid, pub started_at: DateTime, #[serde(skip_serializing_if = "Option::is_none")] pub completed_at: Option>, pub created_at: DateTime, /// 当前活跃的 token 位置 pub active_tokens: Vec, pub version: i32, } #[derive(Debug, Deserialize, Validate, ToSchema)] pub struct StartInstanceReq { pub definition_id: Uuid, pub business_key: Option, /// 初始流程变量 pub variables: Option>, } // --- Token DTOs --- #[derive(Debug, Serialize, ToSchema)] pub struct TokenResp { pub id: Uuid, pub node_id: String, pub status: String, pub created_at: DateTime, } // --- 任务 DTOs --- #[derive(Debug, Serialize, ToSchema)] pub struct TaskResp { pub id: Uuid, pub instance_id: Uuid, pub token_id: Uuid, pub node_id: String, #[serde(skip_serializing_if = "Option::is_none")] pub node_name: Option, #[serde(skip_serializing_if = "Option::is_none")] pub assignee_id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub candidate_groups: Option, pub status: String, #[serde(skip_serializing_if = "Option::is_none")] pub outcome: Option, #[serde(skip_serializing_if = "Option::is_none")] pub form_data: Option, #[serde(skip_serializing_if = "Option::is_none")] pub due_date: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub completed_at: Option>, pub created_at: DateTime, /// 流程定义名称(用于列表展示) #[serde(skip_serializing_if = "Option::is_none")] pub definition_name: Option, #[serde(skip_serializing_if = "Option::is_none")] pub business_key: Option, pub version: i32, } #[derive(Debug, Deserialize, Validate, ToSchema)] pub struct CompleteTaskReq { #[validate(length(min = 1, max = 50, message = "审批结果不能为空"))] pub outcome: String, pub form_data: Option, } #[derive(Debug, Deserialize, Validate, ToSchema)] pub struct DelegateTaskReq { pub delegate_to: Uuid, } // --- 流程变量 DTOs --- #[derive(Debug, Serialize, ToSchema)] pub struct ProcessVariableResp { pub id: Uuid, pub name: String, pub var_type: String, #[serde(skip_serializing_if = "Option::is_none")] pub value_string: Option, #[serde(skip_serializing_if = "Option::is_none")] pub value_number: Option, #[serde(skip_serializing_if = "Option::is_none")] pub value_boolean: Option, #[serde(skip_serializing_if = "Option::is_none")] pub value_date: Option>, } #[derive(Debug, Clone, Deserialize, Validate, ToSchema)] pub struct SetVariableReq { #[validate(length(min = 1, max = 100, message = "变量名不能为空"))] pub name: String, pub var_type: Option, pub value: serde_json::Value, }