Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
ljl committed Oct 10, 2023
2 parents c8d4fe8 + 01b0194 commit c57234c
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 24 deletions.
12 changes: 11 additions & 1 deletion middleware/flow/src/api/cc/flow_cc_inst_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tardis::web::web_resp::{TardisApiResult, TardisPage, TardisResp, Void};

use crate::dto::flow_inst_dto::{
FlowInstAbortReq, FlowInstDetailResp, FlowInstFindNextTransitionResp, FlowInstFindNextTransitionsReq, FlowInstFindStateAndTransitionsReq, FlowInstFindStateAndTransitionsResp,
FlowInstModifyAssignedReq, FlowInstStartReq, FlowInstSummaryResp, FlowInstTransferReq, FlowInstTransferResp,
FlowInstModifyAssignedReq, FlowInstModifyCurrentVarsReq, FlowInstStartReq, FlowInstSummaryResp, FlowInstTransferReq, FlowInstTransferResp,
};
use crate::flow_constants;
use crate::serv::flow_inst_serv::FlowInstServ;
Expand Down Expand Up @@ -106,4 +106,14 @@ impl FlowCcInstApi {
funs.commit().await?;
TardisResp::ok(Void {})
}

/// Modify list of variables / 同步当前变量列表
#[oai(path = "/:flow_inst_id/modify_current_vars", method = "patch")]
async fn modify_current_vars(&self, flow_inst_id: Path<String>, modify_req: Json<FlowInstModifyCurrentVarsReq>, ctx: TardisContextExtractor) -> TardisApiResult<Void> {
let mut funs = flow_constants::get_tardis_inst();
funs.begin().await?;
FlowInstServ::modify_current_vars(&flow_inst_id.0, &modify_req.0.vars, &funs, &ctx.0).await?;
funs.commit().await?;
TardisResp::ok(Void {})
}
}
14 changes: 12 additions & 2 deletions middleware/flow/src/dto/flow_inst_dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ use tardis::{
web::poem_openapi,
};

use super::{flow_state_dto::FlowSysStateKind, flow_transition_dto::FlowTransitionDoubleCheckInfo, flow_var_dto::FlowVarInfo};
use super::{
flow_state_dto::{FlowStateRelModelExt, FlowSysStateKind},
flow_transition_dto::FlowTransitionDoubleCheckInfo,
flow_var_dto::FlowVarInfo,
};

#[derive(Serialize, Deserialize, Debug, poem_openapi::Object)]
pub struct FlowInstStartReq {
Expand Down Expand Up @@ -143,7 +147,6 @@ pub struct FlowInstFindNextTransitionResp {
pub next_flow_state_color: String,

pub vars_collect: Option<Vec<FlowVarInfo>>,

pub double_check: Option<FlowTransitionDoubleCheckInfo>,
}

Expand All @@ -159,6 +162,7 @@ pub struct FlowInstFindStateAndTransitionsResp {
pub current_flow_state_name: String,
pub current_flow_state_kind: FlowSysStateKind,
pub current_flow_state_color: String,
pub current_flow_state_ext: FlowStateRelModelExt,
pub finish_time: Option<DateTime<Utc>>,
pub next_flow_transitions: Vec<FlowInstFindNextTransitionResp>,
}
Expand All @@ -178,6 +182,7 @@ pub struct FlowInstTransferResp {
pub new_flow_state_id: String,
pub new_flow_state_name: String,
pub new_flow_state_color: String,
pub new_flow_state_ext: FlowStateRelModelExt,
pub finish_time: Option<DateTime<Utc>>,

pub vars: Option<HashMap<String, Value>>,
Expand All @@ -188,3 +193,8 @@ pub struct FlowInstTransferResp {
pub struct FlowInstModifyAssignedReq {
pub current_assigned: String,
}

#[derive(Serialize, Deserialize, Debug, poem_openapi::Object)]
pub struct FlowInstModifyCurrentVarsReq {
pub vars: HashMap<String, Value>,
}
62 changes: 58 additions & 4 deletions middleware/flow/src/dto/flow_transition_dto.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bios_basic::{dto::BasicQueryCondInfo, basic_enumeration::BasicQueryOpKind};
use bios_basic::dto::BasicQueryCondInfo;
use serde::{Deserialize, Serialize};
use strum::Display;
use tardis::{basic::field::TrimString, db::sea_orm, serde_json::Value, web::poem_openapi, TardisFuns};

use super::flow_var_dto::FlowVarInfo;
Expand Down Expand Up @@ -322,17 +323,70 @@ pub struct FlowTransitionInitInfo {

#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, poem_openapi::Object)]
pub struct FlowTransitionFrontActionInfo {
pub relevance_relation: BasicQueryOpKind,
pub relevance_relation: FlowTransitionFrontActionInfoRelevanceRelation,
pub relevance_label: String,
pub left_value: String,
pub left_label: String,
pub right_value: FlowTransitionFrontActionRightValue,
pub select_field: Option<String>,
pub change_content: Option<String>,
pub real_time: Option<bool>,
pub select_field_label: Option<String>,
pub change_content: Option<Value>,
pub change_content_label: Option<String>,
}

#[derive(Display, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, poem_openapi::Enum)]
pub enum FlowTransitionFrontActionInfoRelevanceRelation {
#[serde(rename = "=")]
#[oai(rename = "=")]
Eq,
#[serde(rename = "!=")]
#[oai(rename = "!=")]
Ne,
#[serde(rename = ">")]
#[oai(rename = ">")]
Gt,
#[serde(rename = ">=")]
#[oai(rename = ">=")]
Ge,
#[serde(rename = "<")]
#[oai(rename = "<")]
Lt,
#[serde(rename = "<=")]
#[oai(rename = "<=")]
Le,
#[serde(rename = "like")]
#[oai(rename = "like")]
Like,
#[serde(rename = "not_like")]
#[oai(rename = "not_like")]
NotLike,
#[serde(rename = "in")]
#[oai(rename = "in")]
In,
#[serde(rename = "not_in")]
#[oai(rename = "not_in")]
NotIn,
}

impl FlowTransitionFrontActionInfoRelevanceRelation {
pub fn check_conform(&self, left_value: String, right_value: String) -> bool {
match self {
FlowTransitionFrontActionInfoRelevanceRelation::Eq => left_value == right_value,
FlowTransitionFrontActionInfoRelevanceRelation::Ne => left_value != right_value,
FlowTransitionFrontActionInfoRelevanceRelation::Gt => left_value > right_value,
FlowTransitionFrontActionInfoRelevanceRelation::Ge => left_value >= right_value,
FlowTransitionFrontActionInfoRelevanceRelation::Lt => left_value < right_value,
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::<Vec<String>>(&right_value).unwrap_or_default().contains(&left_value),
FlowTransitionFrontActionInfoRelevanceRelation::NotIn => !TardisFuns::json.str_to_obj::<Vec<String>>(&right_value).unwrap_or_default().contains(&left_value),
}
}
}

#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, poem_openapi::Enum)]
#[serde(rename_all = "snake_case")]
pub enum FlowTransitionFrontActionRightValue {
#[oai(rename = "select_field")]
SelectField,
Expand Down
124 changes: 118 additions & 6 deletions middleware/flow/src/serv/flow_inst_serv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,19 @@ use crate::{
FlowInstTransitionInfo, FlowOperationContext,
},
flow_model_dto::{FlowModelDetailResp, FlowModelFilterReq},
flow_state_dto::{FlowStateFilterReq, FlowSysStateKind},
flow_state_dto::{FlowStateFilterReq, FlowStateRelModelExt, FlowSysStateKind},
flow_transition_dto::{
FlowTransitionActionByStateChangeInfo, FlowTransitionActionChangeAgg, FlowTransitionActionChangeInfo, FlowTransitionActionChangeKind, FlowTransitionDetailResp,
StateChangeConditionOp,
FlowTransitionFrontActionInfo, FlowTransitionFrontActionRightValue, StateChangeConditionOp,
},
},
serv::{flow_model_serv::FlowModelServ, flow_state_serv::FlowStateServ},
};

use super::flow_external_serv::FlowExternalServ;
use super::{
flow_external_serv::FlowExternalServ,
flow_rel_serv::{FlowRelKind, FlowRelServ},
};

pub struct FlowInstServ;

Expand Down Expand Up @@ -758,6 +761,14 @@ impl FlowInstServ {
prev_flow_state_id: prev_flow_state.id,
prev_flow_state_name: prev_flow_state.name,
prev_flow_state_color: prev_flow_state.color,
new_flow_state_ext: TardisFuns::json.str_to_obj::<FlowStateRelModelExt>(
&FlowRelServ::find_from_simple_rels(&FlowRelKind::FlowModelState, &flow_model.id, None, None, funs, ctx)
.await?
.into_iter()
.find(|rel| next_flow_state.id == rel.rel_id)
.ok_or_else(|| funs.err().not_found("flow_inst", "do_find_next_transitions", "flow state is not found", "404-flow-state-not-found"))?
.ext,
)?,
new_flow_state_id: next_flow_state.id,
new_flow_state_name: next_flow_state.name,
new_flow_state_color: next_flow_state.color,
Expand Down Expand Up @@ -1116,14 +1127,23 @@ impl FlowInstServ {
funs,
ctx,
)
.await?;
.await?
.ok_or_else(|| funs.err().not_found("flow_inst", "do_find_next_transitions", "flow state is not found", "404-flow-state-not-found"))?;

let state_and_next_transitions = FlowInstFindStateAndTransitionsResp {
flow_inst_id: flow_inst.id.to_string(),
finish_time: flow_inst.finish_time,
current_flow_state_name: flow_inst.current_state_name.as_ref().unwrap_or(&"".to_string()).to_string(),
current_flow_state_kind: current_flow_state.as_ref().map(|state| state.sys_state.clone()).unwrap_or(FlowSysStateKind::Finish),
current_flow_state_color: current_flow_state.as_ref().map(|state| state.color.clone()).unwrap_or_default(),
current_flow_state_kind: current_flow_state.sys_state.clone(),
current_flow_state_color: current_flow_state.color.clone(),
current_flow_state_ext: TardisFuns::json.str_to_obj::<FlowStateRelModelExt>(
&FlowRelServ::find_from_simple_rels(&FlowRelKind::FlowModelState, &flow_inst.rel_flow_model_id, None, None, funs, ctx)
.await?
.into_iter()
.find(|rel| current_flow_state.id == rel.rel_id)
.ok_or_else(|| funs.err().not_found("flow_inst", "do_find_next_transitions", "flow state is not found", "404-flow-state-not-found"))?
.ext,
)?,
next_flow_transitions: next_transitions,
};
Ok(state_and_next_transitions)
Expand All @@ -1148,4 +1168,96 @@ impl FlowInstServ {
Ok(false)
}
}

pub async fn modify_current_vars(flow_inst_id: &str, current_vars: &HashMap<String, Value>, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> {
let flow_inst_detail = Self::get(flow_inst_id, funs, ctx).await?;
let mut new_vars: HashMap<String, Value> = HashMap::new();
if let Some(old_current_vars) = &flow_inst_detail.current_vars {
new_vars.extend(old_current_vars.clone());
}
new_vars.extend(current_vars.clone());
let flow_inst = flow_inst::ActiveModel {
id: Set(flow_inst_id.to_string()),
current_vars: Set(Some(TardisFuns::json.obj_to_json(&new_vars)?)),
..Default::default()
};
funs.db().update_one(flow_inst, ctx).await?;

Ok(())
}

async fn do_front_change(flow_inst_detail: &FlowInstDetailResp, ctx: &TardisContext, funs: &TardisFunsInst) -> TardisResult<()> {
let flow_model = FlowModelServ::get_item(
&flow_inst_detail.rel_flow_model_id,
&FlowModelFilterReq {
basic: RbumBasicFilterReq {
with_sub_own_paths: true,
own_paths: Some("".to_string()),
..Default::default()
},
..Default::default()
},
funs,
ctx,
)
.await?;
let flow_transitions = flow_model
.transitions()
.into_iter()
.filter(|trans| trans.from_flow_state_id == flow_inst_detail.current_state_id && !trans.action_by_front_changes().is_empty())
.collect_vec();
if flow_transitions.is_empty() {
return Ok(());
}

Ok(())
}

async fn check_front_conditions(
flow_inst_detail: &FlowInstDetailResp,
conditions: Vec<FlowTransitionFrontActionInfo>,
ctx: &TardisContext,
funs: &TardisFunsInst,
) -> TardisResult<bool> {
if flow_inst_detail.current_vars.is_none() {
return Ok(false);
}
let current_vars = flow_inst_detail.current_vars.clone().unwrap();
for condition in conditions {
if !Self::do_check_front_condition(&current_vars, &condition)? {
return Ok(false);
}
}

Ok(true)
}

fn do_check_front_condition(current_vars: &HashMap<String, Value>, condition: &FlowTransitionFrontActionInfo) -> TardisResult<bool> {
match condition.right_value {
FlowTransitionFrontActionRightValue::ChangeContent => {
if let Some(left_value) = current_vars.get(&condition.left_value) {
Ok(condition.relevance_relation.check_conform(left_value.to_string(), condition.change_content.clone().unwrap_or_default().to_string()))
} else {
Ok(false)
}
}
FlowTransitionFrontActionRightValue::SelectField => {
if let (Some(left_value), Some(right_value)) = (
current_vars.get(&condition.left_value),
current_vars.get(&condition.select_field.clone().unwrap_or_default()),
) {
Ok(condition.relevance_relation.check_conform(left_value.to_string(), right_value.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.to_string(), Utc::now().to_string()))
} else {
Ok(false)
}
}
}
}
}
Loading

0 comments on commit c57234c

Please sign in to comment.