diff --git a/middleware/flow/src/dto/flow_transition_dto.rs b/middleware/flow/src/dto/flow_transition_dto.rs index 6ecbf35bc..c5cd09400 100644 --- a/middleware/flow/src/dto/flow_transition_dto.rs +++ b/middleware/flow/src/dto/flow_transition_dto.rs @@ -1,4 +1,5 @@ use bios_basic::dto::BasicQueryCondInfo; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use strum::Display; use tardis::{basic::field::TrimString, db::sea_orm, serde_json::Value, web::poem_openapi, TardisFuns}; @@ -384,6 +385,9 @@ pub enum FlowTransitionFrontActionInfoRelevanceRelation { impl FlowTransitionFrontActionInfoRelevanceRelation { pub fn check_conform(&self, left_value: String, right_value: String) -> bool { + if left_value.is_empty() { + return false; + } match self { FlowTransitionFrontActionInfoRelevanceRelation::Eq => left_value == right_value, FlowTransitionFrontActionInfoRelevanceRelation::Ne => left_value != right_value, @@ -393,8 +397,22 @@ impl FlowTransitionFrontActionInfoRelevanceRelation { FlowTransitionFrontActionInfoRelevanceRelation::Le => left_value <= right_value, FlowTransitionFrontActionInfoRelevanceRelation::Like => left_value.contains(&right_value), FlowTransitionFrontActionInfoRelevanceRelation::NotLike => !left_value.contains(&right_value), - FlowTransitionFrontActionInfoRelevanceRelation::In => TardisFuns::json.str_to_obj::>(&right_value).unwrap_or_default().contains(&left_value), - FlowTransitionFrontActionInfoRelevanceRelation::NotIn => !TardisFuns::json.str_to_obj::>(&right_value).unwrap_or_default().contains(&left_value), + FlowTransitionFrontActionInfoRelevanceRelation::In => { + TardisFuns::json + .str_to_obj::>(&right_value) + .unwrap() + .into_iter() + .map(|item| item.as_str().unwrap_or(item.to_string().as_str()).to_string()) + .collect_vec() + .contains(&left_value) + }, + FlowTransitionFrontActionInfoRelevanceRelation::NotIn => !TardisFuns::json + .str_to_obj::>(&right_value) + .unwrap() + .into_iter() + .map(|item| item.as_str().unwrap_or(item.to_string().as_str()).to_string()) + .collect_vec() + .contains(&left_value), FlowTransitionFrontActionInfoRelevanceRelation::Between => { let time_interval = TardisFuns::json.str_to_obj::>(&right_value).unwrap_or_default(); if time_interval.len() != 2 { diff --git a/middleware/flow/src/flow_initializer.rs b/middleware/flow/src/flow_initializer.rs index 5d39a2450..899457f52 100644 --- a/middleware/flow/src/flow_initializer.rs +++ b/middleware/flow/src/flow_initializer.rs @@ -37,8 +37,8 @@ use crate::{ }, }, flow_config::{BasicInfo, FlowBasicInfoManager, FlowConfig}, - flow_constants, - serv::flow_model_serv::FlowModelServ, + flow_constants::{self, DOMAIN_CODE}, + serv::{flow_inst_serv::FlowInstServ, flow_model_serv::FlowModelServ}, }; pub async fn init(web_server: &TardisWebServer) -> TardisResult<()> { @@ -79,6 +79,7 @@ pub async fn init_db(mut funs: TardisFunsInst) -> TardisResult<()> { if check_initialized(&funs, &ctx).await? { init_basic_info(&funs).await?; self::modify_post_actions(&funs, &ctx).await?; + self::check_data(&funs, &ctx).await?; } else { let db_kind = TardisFuns::reldb().backend(); let compatible_type = TardisFuns::reldb().compatible_type(); @@ -126,6 +127,7 @@ async fn init_basic_info<'a>(funs: &TardisFunsInst) -> TardisResult<()> { Ok(()) } +// @TODO temporary pub async fn modify_post_actions(funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { #[derive(sea_orm::FromQueryResult)] pub struct FlowTransactionPostAction { @@ -229,6 +231,48 @@ pub async fn truncate_data<'a>(funs: &TardisFunsInst) -> TardisResult<()> { Ok(()) } +// @TODO temporary +async fn check_data(funs: &TardisFunsInst, global_ctx: &TardisContext) -> TardisResult<()> { + //1.add missed model + let proj_insts = FlowInstServ::paginate(None, Some("PROJ".to_string()), Some(false), None, 1, 99999, funs, global_ctx).await?; + for proj_inst in proj_insts.records { + let ctx = TardisContext { + own_paths: proj_inst.own_paths.clone(), + owner: proj_inst.create_ctx.owner.clone(), + ..global_ctx.clone() + }; + FlowModelServ::get_models(vec!["MS", "REQ", "ITER", "TASK", "CTS", "TP", "ISSUE", "TS"], None, funs, &ctx).await?; + } + TardisFuns::reldb_by_module_or_default(DOMAIN_CODE) + .conn() + .execute_one( + r#"update + flow_inst + set + rel_flow_model_id = flow_res.model_id + from + ( + select + flow_inst.id, + flow_model2.id as model_id + from + flow_inst + left join flow_model as flow_model1 on flow_inst.rel_flow_model_id = flow_model1.id + inner join flow_model as flow_model2 on flow_inst.own_paths = flow_model2.own_paths + and flow_model1.tag = flow_model2.tag + WHERE + flow_inst.own_paths <> flow_model1.own_paths + and flow_model1.tag not in ('TICKET', 'PROJ') + ) as flow_res + where + flow_inst.id = flow_res.id"#, + vec![], + ) + .await?; + + Ok(()) +} + pub async fn init_flow_model(funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { let ticket_init_model = FlowModelServ::paginate_items( &FlowModelFilterReq { diff --git a/middleware/flow/src/serv/flow_inst_serv.rs b/middleware/flow/src/serv/flow_inst_serv.rs index 431271d68..4aa08e49a 100644 --- a/middleware/flow/src/serv/flow_inst_serv.rs +++ b/middleware/flow/src/serv/flow_inst_serv.rs @@ -30,7 +30,7 @@ use tardis::{ }; use crate::{ - domain::{flow_inst, flow_transition}, + domain::{flow_inst, flow_model, flow_transition}, dto::{ flow_external_dto::FlowExternalParams, flow_inst_dto::{ @@ -73,7 +73,7 @@ impl FlowInstServ { ctx, ) .await?; - let id = TardisFuns::field.nanoid(); + let inst_id = TardisFuns::field.nanoid(); let current_state_id = if let Some(current_state_name) = ¤t_state_name { if current_state_name.is_empty() { flow_model.init_state_id.clone() @@ -84,7 +84,7 @@ impl FlowInstServ { flow_model.init_state_id.clone() }; let flow_inst: flow_inst::ActiveModel = flow_inst::ActiveModel { - id: Set(id.clone()), + id: Set(inst_id.clone()), rel_flow_model_id: Set(flow_model_id.to_string()), rel_business_obj_id: Set(start_req.rel_business_obj_id.to_string()), @@ -98,13 +98,14 @@ impl FlowInstServ { }; funs.db().insert_one(flow_inst, ctx).await?; + Self::do_front_change(&inst_id, ctx, funs).await?; Self::do_request_webhook( None, flow_model.transitions().iter().filter(|model_transition| model_transition.to_flow_state_id == flow_model.init_state_id).collect_vec().pop(), ) .await?; - Ok(id) + Ok(inst_id) } pub async fn batch_bind(batch_bind_req: &FlowInstBatchBindReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult> { @@ -444,6 +445,10 @@ impl FlowInstServ { .left_join( RBUM_ITEM_TABLE.clone(), Expr::col((RBUM_ITEM_TABLE.clone(), ID_FIELD.clone())).equals((flow_inst::Entity, flow_inst::Column::RelFlowModelId)), + ) + .left_join( + flow_model::Entity, + Expr::col((flow_model::Entity, flow_model::Column::Id)).equals((flow_inst::Entity, flow_inst::Column::RelFlowModelId)), ); if with_sub.unwrap_or(false) { query.and_where(Expr::col((flow_inst::Entity, flow_inst::Column::OwnPaths)).like(format!("{}%", ctx.own_paths))); @@ -454,8 +459,7 @@ impl FlowInstServ { query.and_where(Expr::col((flow_inst::Entity, flow_inst::Column::RelFlowModelId)).eq(flow_model_id)); } if let Some(tag) = &tag { - let flow_model_id = Self::get_model_id_by_own_paths_and_rel_template_id(tag, None, funs, ctx).await?; - query.and_where(Expr::col((flow_inst::Entity, flow_inst::Column::RelFlowModelId)).eq(flow_model_id)); + query.and_where(Expr::col((flow_model::Entity, flow_model::Column::Tag)).eq(tag)); } if let Some(finish) = finish { if finish { @@ -1290,7 +1294,7 @@ impl FlowInstServ { FlowTransitionFrontActionRightValue::ChangeContent => { if let Some(left_value) = current_vars.get(&condition.left_value) { Ok(condition.relevance_relation.check_conform( - left_value.as_str().unwrap_or_default().to_string(), + left_value.as_str().unwrap_or(left_value.to_string().as_str()).to_string(), condition .change_content .clone() @@ -1308,14 +1312,20 @@ impl FlowInstServ { current_vars.get(&condition.left_value), current_vars.get(&condition.select_field.clone().unwrap_or_default()), ) { - Ok(condition.relevance_relation.check_conform(left_value.as_str().unwrap_or_default().to_string(), right_value.as_str().unwrap_or_default().to_string())) + Ok(condition.relevance_relation.check_conform( + left_value.as_str().unwrap_or(left_value.to_string().as_str()).to_string(), + right_value.as_str().unwrap_or(left_value.to_string().as_str()).to_string(), + )) } else { Ok(false) } } FlowTransitionFrontActionRightValue::RealTime => { if let Some(left_value) = current_vars.get(&condition.left_value) { - Ok(condition.relevance_relation.check_conform(left_value.as_str().unwrap_or_default().to_string(), Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true))) + Ok(condition.relevance_relation.check_conform( + left_value.as_str().unwrap_or(left_value.to_string().as_str()).to_string(), + Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true), + )) } else { Ok(false) } diff --git a/middleware/flow/tests/test_flow_scenes_fsm.rs b/middleware/flow/tests/test_flow_scenes_fsm.rs index 59a496995..75b04d43a 100644 --- a/middleware/flow/tests/test_flow_scenes_fsm.rs +++ b/middleware/flow/tests/test_flow_scenes_fsm.rs @@ -738,7 +738,7 @@ pub async fn test(flow_client: &mut TestHttpClient, _kv_client: &mut TestHttpCli .await; assert_eq!(state_and_next_transitions[0].next_flow_transitions.len(), 1); // handle front change - let current_vars = HashMap::from([("status".to_string(), json!("xxx")), ("handle_time".to_string(), json!("2023-10-10"))]); + let current_vars = HashMap::from([("status".to_string(), json!(true)), ("handle_time".to_string(), json!("2023-10-10"))]); let _: Void = flow_client .patch( &format!("/cc/inst/{}/modify_current_vars", req_inst_id2), @@ -764,11 +764,14 @@ pub async fn test(flow_client: &mut TestHttpClient, _kv_client: &mut TestHttpCli "id": state_and_next_transitions[0].next_flow_transitions[0].next_flow_transition_id.clone(), "action_by_front_changes": [ { - "relevance_relation": "<", + "relevance_relation": "in", "relevance_label": "εŒ…ε«", - "left_value": "handle_time", + "left_value": "status", "left_label": "ηŠΆζ€", - "right_value": "real_time" + "right_value": "change_content", + "change_content": [ + true + ], } ] }