From 8df06f272ea094b7f3599d1dd29cfec325143bb4 Mon Sep 17 00:00:00 2001 From: ZzIsGod1019 <1498852723@qq.com> Date: Fri, 20 Dec 2024 16:13:06 +0800 Subject: [PATCH] flow: fix bug (inst search failed) (#884) --- .../spacegate-plugins/src/extension.rs | 2 +- .../src/extension/notification.rs | 1 - .../gateways/spacegate-plugins/src/plugin.rs | 2 +- .../middlewares/flow/src/dto/flow_inst_dto.rs | 28 +- .../flow/src/dto/flow_model_dto.rs | 2 +- .../flow/src/dto/flow_state_dto.rs | 2 +- .../flow/src/dto/flow_transition_dto.rs | 5 +- .../flow/src/serv/clients/search_client.rs | 47 +- .../flow/src/serv/flow_external_serv.rs | 7 +- .../flow/src/serv/flow_inst_serv.rs | 561 +++++++++++------- .../flow/src/serv/flow_model_serv.rs | 134 +++-- .../flow/src/serv/flow_model_version_serv.rs | 13 +- .../invoke/src/clients/spi_search_client.rs | 3 +- .../sdks/invoke/src/dto/search_item_dto.rs | 2 +- 14 files changed, 490 insertions(+), 319 deletions(-) diff --git a/backend/gateways/spacegate-plugins/src/extension.rs b/backend/gateways/spacegate-plugins/src/extension.rs index b8d27d2f..557f47fd 100644 --- a/backend/gateways/spacegate-plugins/src/extension.rs +++ b/backend/gateways/spacegate-plugins/src/extension.rs @@ -7,8 +7,8 @@ use self::audit_log_param::LogParamContent; pub mod audit_log_param; pub mod before_encrypt_body; pub mod cert_info; -pub mod request_crypto_status; pub mod notification; +pub mod request_crypto_status; pub enum ExtensionPackEnum { LogParamContent(), None, diff --git a/backend/gateways/spacegate-plugins/src/extension/notification.rs b/backend/gateways/spacegate-plugins/src/extension/notification.rs index fd6f65e3..9de8e419 100644 --- a/backend/gateways/spacegate-plugins/src/extension/notification.rs +++ b/backend/gateways/spacegate-plugins/src/extension/notification.rs @@ -43,7 +43,6 @@ impl NotificationContext { } } - #[derive(Debug, Serialize)] pub struct ReachMsgSendReq { pub scene_code: String, diff --git a/backend/gateways/spacegate-plugins/src/plugin.rs b/backend/gateways/spacegate-plugins/src/plugin.rs index 6f7a1a5c..f335721f 100644 --- a/backend/gateways/spacegate-plugins/src/plugin.rs +++ b/backend/gateways/spacegate-plugins/src/plugin.rs @@ -3,6 +3,6 @@ pub mod anti_xss; pub mod audit_log; pub mod auth; pub mod ip_time; +pub mod notify; pub mod op_redis_publisher; pub mod rewrite_ns_b_ip; -pub mod notify; \ No newline at end of file diff --git a/backend/middlewares/flow/src/dto/flow_inst_dto.rs b/backend/middlewares/flow/src/dto/flow_inst_dto.rs index 2d7112a8..075ba6f9 100644 --- a/backend/middlewares/flow/src/dto/flow_inst_dto.rs +++ b/backend/middlewares/flow/src/dto/flow_inst_dto.rs @@ -10,7 +10,10 @@ use tardis::{ }; use super::{ - flow_model_dto::FlowModelRelTransitionExt, flow_state_dto::{FlowGuardConf, FlowStateKind, FlowStateOperatorKind, FlowStateRelModelExt, FlowStateVar, FlowSysStateKind}, flow_transition_dto::FlowTransitionDoubleCheckInfo, flow_var_dto::FlowVarInfo + flow_model_dto::FlowModelRelTransitionExt, + flow_state_dto::{FlowGuardConf, FlowStateKind, FlowStateOperatorKind, FlowStateRelModelExt, FlowStateVar, FlowSysStateKind}, + flow_transition_dto::FlowTransitionDoubleCheckInfo, + flow_var_dto::FlowVarInfo, }; #[derive(Serialize, Deserialize, Debug, poem_openapi::Object)] @@ -234,17 +237,17 @@ pub struct FlowInstArtifacts { // 流程实例中数据存储更新 #[derive(Serialize, Deserialize, PartialEq, Clone, Debug, Default, sea_orm::FromJsonQueryResult)] pub struct FlowInstArtifactsModifyReq { - pub guard_conf: Option, // 当前操作人权限 - pub prohibit_guard_conf_account_ids: Option>, // 禁止操作人ID列表 - pub guard_conf_account_ids: Option>, // 更新操作人列表 - pub add_approval_result: Option<(String, FlowApprovalResultKind)>, // 增加审批结果 - pub form_state_map: Option>, // 录入节点映射 key为节点ID,对应的value为节点中的录入的参数 - pub clear_form_result: Option, // 清除节点录入信息 - pub clear_approval_result: Option, // 清除节点录入信息 - pub prev_non_auto_state_id: Option>, // 上一个非自动节点ID - pub prev_non_auto_account_id: Option, // 上一个节点操作人ID - pub curr_approval_total: Option, // 当前审批总数 - pub curr_vars: Option>, // 当前参数列表 + pub guard_conf: Option, // 当前操作人权限 + pub prohibit_guard_conf_account_ids: Option>, // 禁止操作人ID列表 + pub guard_conf_account_ids: Option>, // 更新操作人列表 + pub add_approval_result: Option<(String, FlowApprovalResultKind)>, // 增加审批结果 + pub form_state_map: Option>, // 录入节点映射 key为节点ID,对应的value为节点中的录入的参数 + pub clear_form_result: Option, // 清除节点录入信息 + pub clear_approval_result: Option, // 清除节点录入信息 + pub prev_non_auto_state_id: Option>, // 上一个非自动节点ID + pub prev_non_auto_account_id: Option, // 上一个节点操作人ID + pub curr_approval_total: Option, // 当前审批总数 + pub curr_vars: Option>, // 当前参数列表 } /// 审批结果类型 @@ -478,6 +481,7 @@ pub struct FlowInstFilterReq { pub ids: Option>, pub code: Option, /// 关联模型ID + pub flow_model_id: Option, pub flow_version_id: Option, /// 业务ID pub rel_business_obj_ids: Option>, diff --git a/backend/middlewares/flow/src/dto/flow_model_dto.rs b/backend/middlewares/flow/src/dto/flow_model_dto.rs index 5a10e485..35fd1890 100644 --- a/backend/middlewares/flow/src/dto/flow_model_dto.rs +++ b/backend/middlewares/flow/src/dto/flow_model_dto.rs @@ -477,4 +477,4 @@ pub struct FlowModelSyncModifiedFieldReq { /// 参数列表 pub add_fields: Vec, pub delete_fields: Vec, -} \ No newline at end of file +} diff --git a/backend/middlewares/flow/src/dto/flow_state_dto.rs b/backend/middlewares/flow/src/dto/flow_state_dto.rs index 4a8b33f6..9829052d 100644 --- a/backend/middlewares/flow/src/dto/flow_state_dto.rs +++ b/backend/middlewares/flow/src/dto/flow_state_dto.rs @@ -470,4 +470,4 @@ impl FromStr for FlowStateOperatorKind { _ => Err(TardisError::bad_request(&format!("invalid FlowStateOperatorKind: {}", s), "400-operator-invalid-param")), } } -} \ No newline at end of file +} diff --git a/backend/middlewares/flow/src/dto/flow_transition_dto.rs b/backend/middlewares/flow/src/dto/flow_transition_dto.rs index 20562eb1..442e6994 100644 --- a/backend/middlewares/flow/src/dto/flow_transition_dto.rs +++ b/backend/middlewares/flow/src/dto/flow_transition_dto.rs @@ -629,10 +629,7 @@ impl FlowTransitionFrontActionInfoRelevanceRelation { { let left_values = TardisFuns::json.str_to_obj::>(&left_value).unwrap_or_default(); if left_values.len() == 1 { - left_value = left_values - .first().cloned() - .unwrap_or_default().as_str() - .unwrap_or("").to_string(); + left_value = left_values.first().cloned().unwrap_or_default().as_str().unwrap_or("").to_string(); } else { return false; } diff --git a/backend/middlewares/flow/src/serv/clients/search_client.rs b/backend/middlewares/flow/src/serv/clients/search_client.rs index c52f9210..d05f1031 100644 --- a/backend/middlewares/flow/src/serv/clients/search_client.rs +++ b/backend/middlewares/flow/src/serv/clients/search_client.rs @@ -6,19 +6,27 @@ use bios_sdk_invoke::{ event_client::{get_topic, EventCenterClient, SPI_RPC_TOPIC}, spi_search_client::SpiSearchClient, }, - dto::search_item_dto::{SearchItemAddReq, SearchItemModifyReq, SearchItemQueryReq, SearchItemSearchCtxReq, SearchItemSearchPageReq, SearchItemSearchReq, SearchItemSearchResp, SearchItemVisitKeysReq}, + dto::search_item_dto::{ + SearchItemAddReq, SearchItemModifyReq, SearchItemQueryReq, SearchItemSearchCtxReq, SearchItemSearchPageReq, SearchItemSearchReq, SearchItemSearchResp, + SearchItemVisitKeysReq, + }, }; use itertools::Itertools; use serde_json::json; use tardis::{ - basic::{dto::TardisContext, field::TrimString, result::TardisResult}, log::debug, tokio, web::web_resp::TardisPage, TardisFuns, TardisFunsInst + basic::{dto::TardisContext, field::TrimString, result::TardisResult}, + log::debug, + tokio, + web::web_resp::TardisPage, + TardisFuns, TardisFunsInst, }; use crate::{ dto::{ flow_inst_dto::FlowInstFilterReq, flow_model_dto::{FlowModelDetailResp, FlowModelFilterReq, FlowModelRelTransitionExt}, - flow_model_version_dto::FlowModelVersionFilterReq, flow_state_dto::FlowGuardConf, + flow_model_version_dto::FlowModelVersionFilterReq, + flow_state_dto::FlowGuardConf, }, flow_constants, serv::{ @@ -258,10 +266,7 @@ impl FlowSearchClient { } pub async fn search_guard_account_num(guard_conf: &FlowGuardConf, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult> { - if guard_conf.guard_by_spec_account_ids.is_empty() - && guard_conf.guard_by_spec_org_ids.is_empty() - && guard_conf.guard_by_spec_role_ids.is_empty() - { + if guard_conf.guard_by_spec_account_ids.is_empty() && guard_conf.guard_by_spec_org_ids.is_empty() && guard_conf.guard_by_spec_role_ids.is_empty() { debug!("flow search_guard_account_num result : 0"); return Ok(Some(0)); } @@ -279,18 +284,24 @@ impl FlowSearchClient { if !guard_conf.guard_by_spec_role_ids.is_empty() { search_ctx_req.roles = Some(guard_conf.guard_by_spec_role_ids.clone()); } - let result = SpiSearchClient::search(&SearchItemSearchReq { - tag: "iam_account".to_string(), - ctx: search_ctx_req, - query: SearchItemQueryReq { ..Default::default() }, - adv_query: None, - sort: None, - page:SearchItemSearchPageReq { - number: 1, - size: 1, - fetch_total: true, + let result = SpiSearchClient::search( + &SearchItemSearchReq { + tag: "iam_account".to_string(), + ctx: search_ctx_req, + query: SearchItemQueryReq { ..Default::default() }, + adv_query: None, + sort: None, + page: SearchItemSearchPageReq { + number: 1, + size: 1, + fetch_total: true, + }, }, - }, funs, ctx).await?.map(|result| result.total_size); + funs, + ctx, + ) + .await? + .map(|result| result.total_size); debug!("flow search_guard_account_num result : {:?}", result); Ok(result) } diff --git a/backend/middlewares/flow/src/serv/flow_external_serv.rs b/backend/middlewares/flow/src/serv/flow_external_serv.rs index 80b3e18e..1ef8711b 100644 --- a/backend/middlewares/flow/src/serv/flow_external_serv.rs +++ b/backend/middlewares/flow/src/serv/flow_external_serv.rs @@ -1,7 +1,9 @@ use bios_sdk_invoke::{clients::spi_kv_client::SpiKvClient, invoke_constants::TARDIS_CONTEXT}; use itertools::Itertools; use tardis::{ - basic::{dto::TardisContext, result::TardisResult}, log::debug, tokio, TardisFuns, TardisFunsInst + basic::{dto::TardisContext, result::TardisResult}, + log::debug, + tokio, TardisFuns, TardisFunsInst, }; use crate::{ @@ -12,7 +14,8 @@ use crate::{ }, flow_state_dto::FlowSysStateKind, flow_transition_dto::{FlowTransitionActionByVarChangeInfoChangedKind, FlowTransitionDetailResp, TagRelKind}, - }, flow_constants + }, + flow_constants, }; pub struct FlowExternalServ; diff --git a/backend/middlewares/flow/src/serv/flow_inst_serv.rs b/backend/middlewares/flow/src/serv/flow_inst_serv.rs index 2c66f041..4446213f 100644 --- a/backend/middlewares/flow/src/serv/flow_inst_serv.rs +++ b/backend/middlewares/flow/src/serv/flow_inst_serv.rs @@ -7,10 +7,13 @@ use async_recursion::async_recursion; use bios_basic::{ dto::BasicQueryCondInfo, rbum::{ - dto::rbum_filer_dto::RbumBasicFilterReq, helper::rbum_scope_helper, rbum_enumeration::RbumScopeLevelKind, serv::{ + dto::rbum_filer_dto::RbumBasicFilterReq, + helper::rbum_scope_helper, + rbum_enumeration::RbumScopeLevelKind, + serv::{ rbum_crud_serv::{ID_FIELD, NAME_FIELD, REL_DOMAIN_ID_FIELD, REL_KIND_ID_FIELD}, rbum_item_serv::{RbumItemCrudOperation, RBUM_ITEM_TABLE}, - } + }, }, }; use bios_sdk_invoke::dto::search_item_dto::{SearchItemQueryReq, SearchItemSearchCtxReq, SearchItemSearchPageReq, SearchItemSearchReq}; @@ -34,13 +37,22 @@ use tardis::{ use crate::{ domain::{flow_inst, flow_model_version}, dto::{ - flow_external_dto::{FlowExternalCallbackOp, FlowExternalParams}, flow_inst_dto::{ + flow_external_dto::{FlowExternalCallbackOp, FlowExternalParams}, + flow_inst_dto::{ FLowInstStateApprovalConf, FLowInstStateConf, FLowInstStateFormConf, FlowApprovalResultKind, FlowInstAbortReq, FlowInstArtifacts, FlowInstArtifactsModifyReq, FlowInstBatchBindReq, FlowInstBatchBindResp, FlowInstCommentInfo, FlowInstCommentReq, FlowInstDetailResp, FlowInstFilterReq, FlowInstFindNextTransitionResp, FlowInstFindNextTransitionsReq, FlowInstFindStateAndTransitionsReq, FlowInstFindStateAndTransitionsResp, FlowInstOperateReq, FlowInstQueryKind, FlowInstSearchPageReq, FlowInstSearchReq, FlowInstSearchSortReq, FlowInstStartReq, FlowInstSummaryResp, FlowInstSummaryResult, FlowInstTransferReq, FlowInstTransferResp, FlowInstTransitionInfo, FlowOperationContext, - }, flow_model_dto::{FlowModelDetailResp, FlowModelFilterReq, FlowModelRelTransitionExt}, flow_model_version_dto::{FlowModelVersionDetailResp, FlowModelVersionFilterReq}, flow_state_dto::{FLowStateKindConf, FlowStateAggResp, FlowStateCountersignKind, FlowStateFilterReq, FlowStateKind, FlowStateOperatorKind, FlowStateRelModelExt, FlowStatusAutoStrategyKind, FlowStatusMultiApprovalKind, FlowSysStateKind}, flow_transition_dto::FlowTransitionDetailResp, flow_var_dto::FillType + }, + flow_model_dto::{FlowModelDetailResp, FlowModelFilterReq, FlowModelRelTransitionExt}, + flow_model_version_dto::{FlowModelVersionDetailResp, FlowModelVersionFilterReq}, + flow_state_dto::{ + FLowStateKindConf, FlowStateAggResp, FlowStateCountersignKind, FlowStateFilterReq, FlowStateKind, FlowStateOperatorKind, FlowStateRelModelExt, + FlowStatusAutoStrategyKind, FlowStatusMultiApprovalKind, FlowSysStateKind, + }, + flow_transition_dto::FlowTransitionDetailResp, + flow_var_dto::FillType, }, flow_constants, helper::loop_check_helper, @@ -48,7 +60,10 @@ use crate::{ }; use super::{ - clients::{flow_log_client::{FlowLogClient, LogParamContent, LogParamExt, LogParamOp, LogParamTag}, search_client::FlowSearchClient}, + clients::{ + flow_log_client::{FlowLogClient, LogParamContent, LogParamExt, LogParamOp, LogParamTag}, + search_client::FlowSearchClient, + }, flow_event_serv::FlowEventServ, flow_external_serv::FlowExternalServ, flow_model_version_serv::FlowModelVersionServ, @@ -67,6 +82,20 @@ impl FlowInstServ { } } async fn start_main_flow(start_req: &FlowInstStartReq, current_state_name: Option, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult { + if !Self::find_details( + &FlowInstFilterReq { + rel_business_obj_ids: Some(vec![start_req.rel_business_obj_id.clone()]), + main: Some(true), + ..Default::default() + }, + funs, + ctx, + ) + .await? + .is_empty() + { + return Err(funs.err().internal_error("flow_inst_serv", "start", "The same instance exist", "500-flow-inst-exist")); + } // get model by own_paths let flow_model = FlowModelServ::get_model_id_by_own_paths_and_rel_template_id(&start_req.tag, None, funs, ctx).await?; let inst_id = TardisFuns::field.nanoid(); @@ -115,7 +144,7 @@ impl FlowInstServ { if !Self::find_details( &FlowInstFilterReq { rel_business_obj_ids: Some(vec![start_req.rel_business_obj_id.to_string()]), - flow_version_id: Some(flow_model.current_version_id.clone()), + flow_model_id: Some(flow_model.id.clone()), finish: Some(false), ..Default::default() }, @@ -147,10 +176,16 @@ impl FlowInstServ { ..Default::default() }; funs.db().insert_one(flow_inst, ctx).await?; - Self::modify_inst_artifacts(&inst_id, &FlowInstArtifactsModifyReq { - curr_vars: start_req.create_vars.clone(), - ..Default::default() - }, funs, ctx).await?; + Self::modify_inst_artifacts( + &inst_id, + &FlowInstArtifactsModifyReq { + curr_vars: start_req.create_vars.clone(), + ..Default::default() + }, + funs, + ctx, + ) + .await?; FlowSearchClient::modify_business_obj_search(&start_req.rel_business_obj_id, &flow_model.tag, funs, ctx).await?; let inst = Self::get(&inst_id, funs, ctx).await?; Self::add_start_log(start_req, &inst, &create_vars, &flow_model, ctx).await?; @@ -189,7 +224,8 @@ impl FlowInstServ { let create_vars = Self::get_new_vars(&flow_model.tag, rel_business_obj.rel_business_obj_id.clone().unwrap_or_default(), funs, ctx).await?; - let current_state_id = FlowStateServ::match_state_id_by_name(&flow_model.current_version_id, &rel_business_obj.current_state_name.clone().unwrap_or_default(), funs, ctx).await?; + let current_state_id = + FlowStateServ::match_state_id_by_name(&flow_model.current_version_id, &rel_business_obj.current_state_name.clone().unwrap_or_default(), funs, ctx).await?; let mut inst_id = Self::get_inst_ids_by_rel_business_obj_id(vec![rel_business_obj.rel_business_obj_id.clone().unwrap_or_default()], Some(true), funs, ctx).await?.pop(); if inst_id.is_none() { let id = TardisFuns::field.nanoid(); @@ -247,15 +283,9 @@ impl FlowInstServ { Expr::col((flow_model_version_table.clone(), Alias::new("rel_model_id"))).if_null(""), Alias::new("rel_flow_model_id"), ) - .expr_as( - Expr::col((flow_state_item.clone(), NAME_FIELD.clone())).if_null(""), - Alias::new("current_state_name"), - ) + .expr_as(Expr::col((flow_state_item.clone(), NAME_FIELD.clone())).if_null(""), Alias::new("current_state_name")) .expr_as(Expr::col((RBUM_ITEM_TABLE.clone(), NAME_FIELD.clone())).if_null(""), Alias::new("rel_flow_model_name")) - .expr_as( - Expr::col((rel_model_table.clone(), Alias::new("ext"))).if_null(""), - Alias::new("rel_transition"), - ) + .expr_as(Expr::col((rel_model_table.clone(), Alias::new("ext"))).if_null(""), Alias::new("rel_transition")) .from(flow_inst::Entity) .join_as( JoinType::LeftJoin, @@ -291,6 +321,9 @@ impl FlowInstServ { if let Some(flow_version_id) = &filter.flow_version_id { query.and_where(Expr::col((flow_inst::Entity, flow_inst::Column::RelFlowVersionId)).eq(flow_version_id)); } + if let Some(flow_model_id) = &filter.flow_model_id { + query.and_where(Expr::col((flow_model_version::Entity, flow_model_version::Column::RelModelId)).eq(flow_model_id)); + } if let Some(tag) = &filter.tag { query.and_where(Expr::col((flow_inst::Entity, flow_inst::Column::Tag)).eq(tag)); } @@ -478,10 +511,7 @@ impl FlowInstServ { Expr::col((rel_model_version_table.clone(), NAME_FIELD.clone())).if_null(""), Alias::new("rel_flow_model_name"), ) - .expr_as( - Expr::col((rel_model_table.clone(), Alias::new("ext"))).if_null(""), - Alias::new("rel_transition"), - ) + .expr_as(Expr::col((rel_model_table.clone(), Alias::new("ext"))).if_null(""), Alias::new("rel_transition")) .from(flow_inst::Entity) .join_as( JoinType::LeftJoin, @@ -520,8 +550,7 @@ impl FlowInstServ { JoinType::LeftJoin, flow_model_version_table.clone(), flow_model_version_table.clone(), - Cond::all() - .add(Expr::col((flow_model_version_table.clone(), ID_FIELD.clone())).equals((flow_inst::Entity, flow_inst::Column::RelFlowVersionId))), + Cond::all().add(Expr::col((flow_model_version_table.clone(), ID_FIELD.clone())).equals((flow_inst::Entity, flow_inst::Column::RelFlowVersionId))), ) .join_as( JoinType::LeftJoin, @@ -536,67 +565,70 @@ impl FlowInstServ { let flow_insts = funs.db().find_dtos::(&query).await?; let result = flow_insts - .into_iter() - .map(|inst| { - let current_state_kind_conf = inst - .current_state_kind_conf - .clone() - .map(|current_state_kind_conf| TardisFuns::json.json_to_obj::(current_state_kind_conf).unwrap_or_default()); - let artifacts = inst.artifacts.clone().map(|artifacts| TardisFuns::json.json_to_obj::(artifacts).unwrap_or_default()); - let rel_transition = inst.rel_transition.map(|ext| { - if ext.is_empty() { - return FlowModelRelTransitionExt::default(); + .into_iter() + .map(|inst| { + let current_state_kind_conf = inst + .current_state_kind_conf + .clone() + .map(|current_state_kind_conf| TardisFuns::json.json_to_obj::(current_state_kind_conf).unwrap_or_default()); + let artifacts = inst.artifacts.clone().map(|artifacts| TardisFuns::json.json_to_obj::(artifacts).unwrap_or_default()); + let rel_transition = inst.rel_transition.map(|ext| { + if ext.is_empty() { + return FlowModelRelTransitionExt::default(); + } + TardisFuns::json.str_to_obj::(&ext).unwrap_or_default() + }); + FlowInstDetailResp { + id: inst.id, + code: inst.code, + rel_flow_version_id: inst.rel_flow_version_id, + rel_flow_model_name: inst.rel_flow_model_name, + tag: inst.tag, + main: inst.main, + create_vars: inst.create_vars.map(|create_vars| TardisFuns::json.json_to_obj(create_vars).unwrap()), + create_ctx: inst.create_ctx, + create_time: inst.create_time, + finish_ctx: inst.finish_ctx, + finish_time: inst.finish_time, + finish_abort: inst.finish_abort, + output_message: inst.output_message, + own_paths: inst.own_paths, + transitions: inst.transitions.map(|transitions| TardisFuns::json.json_to_obj(transitions).unwrap()), + artifacts: artifacts.clone(), + comments: inst.comments.map(|comments| TardisFuns::json.json_to_obj(comments).unwrap()), + rel_transition, + current_state_id: inst.current_state_id.clone(), + current_state_name: inst.current_state_name, + current_state_color: inst.current_state_color, + current_state_sys_kind: inst.current_state_sys_kind, + current_state_kind: inst.current_state_kind.clone(), + current_state_ext: inst.current_state_ext.map(|ext| TardisFuns::json.str_to_obj::(&ext).unwrap_or_default()), + current_state_conf: Self::get_state_conf( + &inst.current_state_id, + &inst.current_state_kind.unwrap_or_default(), + current_state_kind_conf, + artifacts, + ctx, + ), + current_vars: inst.current_vars.map(|current_vars| TardisFuns::json.json_to_obj(current_vars).unwrap()), + rel_business_obj_id: inst.rel_business_obj_id, } - TardisFuns::json.str_to_obj::(&ext).unwrap_or_default() - }); - FlowInstDetailResp { - id: inst.id, - code: inst.code, - rel_flow_version_id: inst.rel_flow_version_id, - rel_flow_model_name: inst.rel_flow_model_name, - tag: inst.tag, - main: inst.main, - create_vars: inst.create_vars.map(|create_vars| TardisFuns::json.json_to_obj(create_vars).unwrap()), - create_ctx: inst.create_ctx, - create_time: inst.create_time, - finish_ctx: inst.finish_ctx, - finish_time: inst.finish_time, - finish_abort: inst.finish_abort, - output_message: inst.output_message, - own_paths: inst.own_paths, - transitions: inst.transitions.map(|transitions| TardisFuns::json.json_to_obj(transitions).unwrap()), - artifacts: artifacts.clone(), - comments: inst.comments.map(|comments| TardisFuns::json.json_to_obj(comments).unwrap()), - rel_transition, - current_state_id: inst.current_state_id.clone(), - current_state_name: inst.current_state_name, - current_state_color: inst.current_state_color, - current_state_sys_kind: inst.current_state_sys_kind, - current_state_kind: inst.current_state_kind.clone(), - current_state_ext: inst.current_state_ext.map(|ext| TardisFuns::json.str_to_obj::(&ext).unwrap_or_default()), - current_state_conf: Self::get_state_conf( - &inst.current_state_id, - &inst.current_state_kind.unwrap_or_default(), - current_state_kind_conf, - artifacts, - ctx, - ), - current_vars: inst.current_vars.map(|current_vars| TardisFuns::json.json_to_obj(current_vars).unwrap()), - rel_business_obj_id: inst.rel_business_obj_id, - } - }) - .collect_vec(); - Ok(result.into_iter().map(|mut inst_detail| { - let mut artifacts = inst_detail.artifacts.clone(); - if let Some(artifacts) = artifacts.as_mut() { - let mut curr_vars= artifacts.curr_vars.clone().unwrap_or_default(); - curr_vars.extend(Self::get_modify_vars(&inst_detail)); + }) + .collect_vec(); + Ok(result + .into_iter() + .map(|mut inst_detail| { + let mut artifacts = inst_detail.artifacts.clone(); + if let Some(artifacts) = artifacts.as_mut() { + let mut curr_vars = artifacts.curr_vars.clone().unwrap_or_default(); + curr_vars.extend(Self::get_modify_vars(&inst_detail)); - artifacts.curr_vars = Some(curr_vars); - } - inst_detail.artifacts = artifacts; - inst_detail - }).collect_vec()) + artifacts.curr_vars = Some(curr_vars); + } + inst_detail.artifacts = artifacts; + inst_detail + }) + .collect_vec()) } pub async fn paginate( @@ -1335,24 +1367,32 @@ impl FlowInstServ { async fn get_new_vars(tag: &str, rel_business_obj_id: String, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult> { let tag_search_map = FlowSearchClient::get_tag_search_map(); - let new_vars = if let Some(mut search_resp) = FlowSearchClient::search(&SearchItemSearchReq { - tag: tag_search_map.get(tag).ok_or_else(|| funs.err().not_found("flow_inst", "get_new_vars", "illegal response", "404-flow-tag-not-found"))?.clone(), - ctx: SearchItemSearchCtxReq::default(), - query: SearchItemQueryReq { - keys: Some(vec![rel_business_obj_id.into()]), - ..Default::default() + let new_vars = if let Some(mut search_resp) = FlowSearchClient::search( + &SearchItemSearchReq { + tag: tag_search_map.get(tag).ok_or_else(|| funs.err().not_found("flow_inst", "get_new_vars", "illegal response", "404-flow-tag-not-found"))?.clone(), + ctx: SearchItemSearchCtxReq::default(), + query: SearchItemQueryReq { + keys: Some(vec![rel_business_obj_id.into()]), + ..Default::default() + }, + adv_query: None, + sort: None, + page: SearchItemSearchPageReq { + number: 1, + size: 1, + fetch_total: false, + }, }, - adv_query: None, - sort: None, - page: SearchItemSearchPageReq { - number: 1, - size: 1, - fetch_total: false, - }}, funs, ctx).await? { - search_resp.records.pop().map(|item| item.ext) - } else { - None - }.unwrap_or_default(); + funs, + ctx, + ) + .await? + { + search_resp.records.pop().map(|item| item.ext) + } else { + None + } + .unwrap_or_default(); Ok(TardisFuns::json.json_to_obj(new_vars).unwrap_or_default()) } @@ -1360,14 +1400,7 @@ impl FlowInstServ { let mut current_vars = flow_inst.current_vars.clone(); if current_vars.is_none() || !current_vars.clone().unwrap_or_default().contains_key(key) { let new_vars = Self::get_new_vars(&flow_inst.tag, flow_inst.rel_business_obj_id.clone(), funs, ctx).await?; - Self::modify_current_vars( - flow_inst, - &new_vars, - loop_check_helper::InstancesTransition::default(), - funs, - ctx, - ) - .await?; + Self::modify_current_vars(flow_inst, &new_vars, loop_check_helper::InstancesTransition::default(), funs, ctx).await?; current_vars = Self::get(&flow_inst.id, funs, ctx).await?.current_vars; } @@ -1574,7 +1607,8 @@ impl FlowInstServ { }); } if form_conf.guard_by_assigned { - let _ = Self::get_main_inst_vars(flow_inst_detail, funs, ctx).await? + let _ = Self::get_main_inst_vars(flow_inst_detail, funs, ctx) + .await? .get("assigned_to") .unwrap_or(&json!("")) .as_str() @@ -1594,11 +1628,12 @@ impl FlowInstServ { Self::modify_inst_artifacts(&flow_inst_detail.id, &modify_req, funs, ctx).await?; // 当操作人为空时的逻辑 let curr_guard_conf = Self::get(&flow_inst_detail.id, funs, ctx).await?.artifacts.unwrap_or_default().guard_conf; - if FlowSearchClient::search_guard_account_num(&curr_guard_conf, funs, ctx).await?.unwrap_or_default() == 0 - && form_conf.auto_transfer_when_empty_kind.is_some() { + if FlowSearchClient::search_guard_account_num(&curr_guard_conf, funs, ctx).await?.unwrap_or_default() == 0 && form_conf.auto_transfer_when_empty_kind.is_some() { match form_conf.auto_transfer_when_empty_kind.unwrap_or_default() { FlowStatusAutoStrategyKind::Autoskip => { - if let Some(next_transition) = FlowInstServ::find_next_transitions(flow_inst_detail, &FlowInstFindNextTransitionsReq { vars: None }, funs, ctx).await?.pop() { + if let Some(next_transition) = + FlowInstServ::find_next_transitions(flow_inst_detail, &FlowInstFindNextTransitionsReq { vars: None }, funs, ctx).await?.pop() + { Self::transfer( flow_inst_detail, &FlowInstTransferReq { @@ -1614,15 +1649,15 @@ impl FlowInstServ { ) .await?; } - }, + } FlowStatusAutoStrategyKind::SpecifyAgent => { modify_req.guard_conf = Some(form_conf.auto_transfer_when_empty_guard_custom_conf.clone().unwrap_or_default()); modify_req.prohibit_guard_conf_account_ids = Some(vec![]); Self::modify_inst_artifacts(&flow_inst_detail.id, &modify_req, funs, ctx).await?; - }, + } FlowStatusAutoStrategyKind::TransferState => { // 当前版本不支持 - }, + } } } } @@ -1639,7 +1674,8 @@ impl FlowInstServ { }); } if approval_conf.guard_by_assigned { - let _ = Self::get_main_inst_vars(flow_inst_detail, funs, ctx).await? + let _ = Self::get_main_inst_vars(flow_inst_detail, funs, ctx) + .await? .get("assigned_to") .unwrap_or(&json!("")) .as_str() @@ -1647,10 +1683,11 @@ impl FlowInstServ { .split(',') .collect_vec() .into_iter() - .map(|str| {if !str.is_empty() { - guard_custom_conf.guard_by_spec_account_ids.push(str.to_string()); - }} - ) + .map(|str| { + if !str.is_empty() { + guard_custom_conf.guard_by_spec_account_ids.push(str.to_string()); + } + }) .collect::>(); } modify_req.guard_conf = Some(guard_custom_conf.clone()); @@ -1664,11 +1701,13 @@ impl FlowInstServ { let curr_inst = Self::get(&flow_inst_detail.id, funs, ctx).await?; // 当操作人为空时的逻辑 let curr_guard_conf = curr_inst.artifacts.unwrap_or_default().guard_conf; - if FlowSearchClient::search_guard_account_num(&curr_guard_conf, funs, ctx).await?.unwrap_or_default() == 0 - && approval_conf.auto_transfer_when_empty_kind.is_some() { + if FlowSearchClient::search_guard_account_num(&curr_guard_conf, funs, ctx).await?.unwrap_or_default() == 0 && approval_conf.auto_transfer_when_empty_kind.is_some() + { match approval_conf.auto_transfer_when_empty_kind.unwrap_or_default() { FlowStatusAutoStrategyKind::Autoskip => { - if let Some(next_transition) = FlowInstServ::find_next_transitions(flow_inst_detail, &FlowInstFindNextTransitionsReq { vars: None }, funs, ctx).await?.pop() { + if let Some(next_transition) = + FlowInstServ::find_next_transitions(flow_inst_detail, &FlowInstFindNextTransitionsReq { vars: None }, funs, ctx).await?.pop() + { Self::transfer( flow_inst_detail, &FlowInstTransferReq { @@ -1684,15 +1723,15 @@ impl FlowInstServ { ) .await?; } - }, + } FlowStatusAutoStrategyKind::SpecifyAgent => { modify_req.guard_conf = Some(approval_conf.auto_transfer_when_empty_guard_custom_conf.clone().unwrap_or_default()); modify_req.prohibit_guard_conf_account_ids = Some(vec![]); Self::modify_inst_artifacts(&flow_inst_detail.id, &modify_req, funs, ctx).await?; - }, + } FlowStatusAutoStrategyKind::TransferState => { // @TODO 当前版本不支持 - }, + } } } } @@ -1882,11 +1921,25 @@ impl FlowInstServ { let mut operators = HashMap::new(); let artifacts = artifacts.clone().unwrap_or_default(); if artifacts.guard_conf.check(ctx) - && !artifacts.prohibit_guard_by_spec_account_ids.clone().unwrap_or_default().contains(&ctx.owner) - && !( - artifacts.approval_result.get(state_id).cloned().unwrap_or_default().get(FlowApprovalResultKind::Pass.to_string().as_str()).cloned().unwrap_or_default().contains(&ctx.owner) - || artifacts.approval_result.get(state_id).cloned().unwrap_or_default().get(FlowApprovalResultKind::Overrule.to_string().as_str()).cloned().unwrap_or_default().contains(&ctx.owner) - ) + && !artifacts.prohibit_guard_by_spec_account_ids.clone().unwrap_or_default().contains(&ctx.owner) + && !(artifacts + .approval_result + .get(state_id) + .cloned() + .unwrap_or_default() + .get(FlowApprovalResultKind::Pass.to_string().as_str()) + .cloned() + .unwrap_or_default() + .contains(&ctx.owner) + || artifacts + .approval_result + .get(state_id) + .cloned() + .unwrap_or_default() + .get(FlowApprovalResultKind::Overrule.to_string().as_str()) + .cloned() + .unwrap_or_default() + .contains(&ctx.owner)) { operators.insert(FlowStateOperatorKind::Pass, approval.pass_btn_name.clone()); operators.insert(FlowStateOperatorKind::Overrule, approval.overrule_btn_name.clone()); @@ -1931,8 +1984,20 @@ impl FlowInstServ { }, funs, ctx, - ).await?; - Self::add_operate_log(operate_req, inst, if current_state.state_kind == FlowStateKind::Approval {LogParamOp::Approval} else {LogParamOp::Form}, funs, ctx).await?; + ) + .await?; + Self::add_operate_log( + operate_req, + inst, + if current_state.state_kind == FlowStateKind::Approval { + LogParamOp::Approval + } else { + LogParamOp::Form + }, + funs, + ctx, + ) + .await?; let mut modify_artifacts = FlowInstArtifactsModifyReq::default(); if let Some(all_vars) = &operate_req.all_vars { modify_artifacts.curr_vars = Some(all_vars.clone()); @@ -1950,22 +2015,22 @@ impl FlowInstServ { prohibit_guard_by_spec_account_ids.push(ctx.owner.clone()); modify_artifacts.prohibit_guard_conf_account_ids = Some(prohibit_guard_by_spec_account_ids); } - Self::modify_inst_artifacts( - &inst.id, - &modify_artifacts, - funs, - ctx, - ) - .await?; + Self::modify_inst_artifacts(&inst.id, &modify_artifacts, funs, ctx).await?; } // 撤销 FlowStateOperatorKind::Revoke => { let mut prev_non_auto_state_id = inst.artifacts.clone().unwrap_or_default().prev_non_auto_state_id.unwrap_or_default(); if let Some(target_state_id) = prev_non_auto_state_id.pop() { - Self::modify_inst_artifacts(&inst.id, &FlowInstArtifactsModifyReq { - prev_non_auto_state_id: Some(prev_non_auto_state_id), - ..Default::default() - }, funs, ctx).await?; + Self::modify_inst_artifacts( + &inst.id, + &FlowInstArtifactsModifyReq { + prev_non_auto_state_id: Some(prev_non_auto_state_id), + ..Default::default() + }, + funs, + ctx, + ) + .await?; Self::transfer_spec_state(inst, &target_state_id, funs, ctx).await?; } else { Self::abort(&inst.id, &FlowInstAbortReq { message: "".to_string() }, funs, ctx).await?; @@ -2004,10 +2069,16 @@ impl FlowInstServ { FlowStateOperatorKind::Back => { let mut prev_non_auto_state_id = inst.artifacts.clone().unwrap_or_default().prev_non_auto_state_id.unwrap_or_default(); if let Some(target_state_id) = prev_non_auto_state_id.pop() { - Self::modify_inst_artifacts(&inst.id, &FlowInstArtifactsModifyReq { - prev_non_auto_state_id: Some(prev_non_auto_state_id), - ..Default::default() - }, funs, ctx).await?; + Self::modify_inst_artifacts( + &inst.id, + &FlowInstArtifactsModifyReq { + prev_non_auto_state_id: Some(prev_non_auto_state_id), + ..Default::default() + }, + funs, + ctx, + ) + .await?; Self::transfer_spec_state(inst, &target_state_id, funs, ctx).await?; } else { Self::abort(&inst.id, &FlowInstAbortReq { message: "".to_string() }, funs, ctx).await?; @@ -2027,7 +2098,18 @@ impl FlowInstServ { .await?; if Self::check_approval_cond(inst, FlowApprovalResultKind::Pass, funs, ctx).await? { if let Some(next_transition) = FlowInstServ::find_next_transitions(inst, &FlowInstFindNextTransitionsReq { vars: None }, funs, ctx).await?.pop() { - Self::add_operate_log(operate_req, inst, if current_state.state_kind == FlowStateKind::Approval {LogParamOp::ApprovalTransfer} else {LogParamOp::FormTransfer}, funs, ctx).await?; + Self::add_operate_log( + operate_req, + inst, + if current_state.state_kind == FlowStateKind::Approval { + LogParamOp::ApprovalTransfer + } else { + LogParamOp::FormTransfer + }, + funs, + ctx, + ) + .await?; Self::transfer( inst, &FlowInstTransferReq { @@ -2058,7 +2140,18 @@ impl FlowInstServ { ) .await?; if Self::check_approval_cond(inst, FlowApprovalResultKind::Overrule, funs, ctx).await? { - Self::add_operate_log(operate_req, inst, if current_state.state_kind == FlowStateKind::Approval {LogParamOp::ApprovalTransfer} else {LogParamOp::FormTransfer}, funs, ctx).await?; + Self::add_operate_log( + operate_req, + inst, + if current_state.state_kind == FlowStateKind::Approval { + LogParamOp::ApprovalTransfer + } else { + LogParamOp::FormTransfer + }, + funs, + ctx, + ) + .await?; Self::abort(&inst.id, &FlowInstAbortReq { message: "".to_string() }, funs, ctx).await?; } } @@ -2067,7 +2160,7 @@ impl FlowInstServ { } // 判断审批条件是否满足 - async fn check_approval_cond(inst: &FlowInstDetailResp , kind: FlowApprovalResultKind, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult { + async fn check_approval_cond(inst: &FlowInstDetailResp, kind: FlowApprovalResultKind, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult { let current_state_kind_conf = FlowStateServ::get_item( &inst.current_state_id, &FlowStateFilterReq { @@ -2080,14 +2173,14 @@ impl FlowInstServ { }, funs, ctx, - ).await?.kind_conf().unwrap_or_default().approval; + ) + .await? + .kind_conf() + .unwrap_or_default() + .approval; let artifacts = inst.artifacts.clone().unwrap_or_default(); let approval_total = artifacts.approval_total.unwrap_or_default().get(&inst.current_state_id).cloned().unwrap_or_default(); - let approval_result = artifacts - .approval_result - .get(&inst.current_state_id) - .cloned() - .unwrap_or_default(); + let approval_result = artifacts.approval_result.get(&inst.current_state_id).cloned().unwrap_or_default(); if let Some(current_state_kind_conf) = current_state_kind_conf { // 或签直接通过 if current_state_kind_conf.multi_approval_kind == FlowStatusMultiApprovalKind::Orsign { @@ -2096,44 +2189,49 @@ impl FlowInstServ { // 会签但是人数为空,直接通过 if current_state_kind_conf.multi_approval_kind == FlowStatusMultiApprovalKind::Countersign && approval_total == 0 { return Ok(true); - } + } let countersign_conf = current_state_kind_conf.countersign_conf; // 指定人通过,则通过 - if kind == FlowApprovalResultKind::Pass - && countersign_conf.specified_pass_guard.unwrap_or(false) - && countersign_conf.specified_pass_guard_conf.is_some() - && countersign_conf.specified_pass_guard_conf.unwrap().check(ctx) { + if kind == FlowApprovalResultKind::Pass + && countersign_conf.specified_pass_guard.unwrap_or(false) + && countersign_conf.specified_pass_guard_conf.is_some() + && countersign_conf.specified_pass_guard_conf.unwrap().check(ctx) + { return Ok(true); } // 指定人拒绝,则拒绝 - if kind == FlowApprovalResultKind::Overrule - && countersign_conf.specified_overrule_guard.unwrap_or(false) - && countersign_conf.specified_overrule_guard_conf.is_some() - && countersign_conf.specified_overrule_guard_conf.unwrap().check(ctx) { + if kind == FlowApprovalResultKind::Overrule + && countersign_conf.specified_overrule_guard.unwrap_or(false) + && countersign_conf.specified_overrule_guard_conf.is_some() + && countersign_conf.specified_overrule_guard_conf.unwrap().check(ctx) + { return Ok(true); } match countersign_conf.kind { FlowStateCountersignKind::All => { if kind == FlowApprovalResultKind::Overrule // 要求全数通过则出现一个拒绝,即拒绝 || ( - kind == FlowApprovalResultKind::Pass + kind == FlowApprovalResultKind::Pass && approval_result.get(&FlowApprovalResultKind::Pass.to_string()).cloned().unwrap_or_default().len() + 1 >= approval_total && approval_result.get(&FlowApprovalResultKind::Overrule.to_string()).cloned().unwrap_or_default().len().is_empty() // 要求全数通过则通过人数达到审核人数同时没有一个拒绝 - ) { + ) + { return Ok(true); } - }, + } FlowStateCountersignKind::Most => { if countersign_conf.most_percent.is_none() { return Ok(false); } let pass_total = approval_total * countersign_conf.most_percent.unwrap_or_default() / 100; // 需满足通过的人员数量 - let overrule_total = approval_total - pass_total;// 需满足拒绝的人员数量 + let overrule_total = approval_total - pass_total; // 需满足拒绝的人员数量 if (kind == FlowApprovalResultKind::Pass && approval_result.get(&FlowApprovalResultKind::Pass.to_string()).cloned().unwrap_or_default().len() + 1 >= pass_total) // 要求大多数通过则通过人数达到通过的比例 - || (kind == FlowApprovalResultKind::Overrule && approval_result.get(&FlowApprovalResultKind::Overrule.to_string()).cloned().unwrap_or_default().len() + 1 >= overrule_total) {// 要求大多数通过则拒绝人数达到拒绝的比例 + || (kind == FlowApprovalResultKind::Overrule && approval_result.get(&FlowApprovalResultKind::Overrule.to_string()).cloned().unwrap_or_default().len() + 1 >= overrule_total) + { + // 要求大多数通过则拒绝人数达到拒绝的比例 return Ok(true); } - }, + } } } Ok(false) @@ -2336,7 +2434,9 @@ impl FlowInstServ { rel_flow_model_id: item.try_get("", "rel_flow_model_id")?, rel_flow_model_name: item.try_get("", "rel_flow_model_name")?, rel_business_obj_id: item.try_get("", "rel_business_obj_id")?, - rel_transition: item.try_get::>("", "rel_transition")?.map(|ext| TardisFuns::json.str_to_obj::(&ext).unwrap_or_default()), + rel_transition: item + .try_get::>("", "rel_transition")? + .map(|ext| TardisFuns::json.str_to_obj::(&ext).unwrap_or_default()), current_state_id: item.try_get("", "current_state_id")?, current_state_name: item.try_get("", "current_state_name")?, create_ctx: item.try_get("", "create_ctx")?, @@ -2400,7 +2500,8 @@ impl FlowInstServ { or_where_fragments.push(format!("(current_state.state_kind = 'form' AND ({}))", child_or_where_fragments.join(" OR "))); } if query_kinds.contains(&FlowInstQueryKind::Approval) { - and_where_fragments.push(format!("{table_alias_name}.id not in ( + and_where_fragments.push(format!( + "{table_alias_name}.id not in ( SELECT id FROM @@ -2408,37 +2509,39 @@ impl FlowInstServ { WHERE {table_alias_name}.artifacts -> 'approval_result' -> {table_alias_name}.current_state_id -> 'PASS' @> '[\"{}\"]' :: jsonb OR {table_alias_name}.artifacts -> 'approval_result' -> {table_alias_name}.current_state_id -> 'OVERRULE' @> '[\"{}\"]' :: jsonb - )",ctx.owner, ctx.owner)); + )", + ctx.owner, ctx.owner + )); let mut child_or_where_fragments = vec![]; - sql_vals.push(sea_orm::Value::from(ctx.owner.clone())); + sql_vals.push(sea_orm::Value::from(ctx.owner.clone())); + child_or_where_fragments.push(format!( + "EXISTS (SELECT 1 FROM jsonb_array_elements_text({}.artifacts->'guard_conf'->'guard_by_spec_account_ids') AS elem WHERE elem IN (${}))", + table_alias_name, + sql_vals.len() + )); + if !ctx.roles.is_empty() { + sql_vals.push(sea_orm::Value::from(ctx.roles.clone().join(", ").to_string())); child_or_where_fragments.push(format!( - "EXISTS (SELECT 1 FROM jsonb_array_elements_text({}.artifacts->'guard_conf'->'guard_by_spec_account_ids') AS elem WHERE elem IN (${}))", + "EXISTS (SELECT 1 FROM jsonb_array_elements_text({}.artifacts->'guard_conf'->'guard_by_spec_role_ids') AS elem WHERE elem IN (${}))", table_alias_name, sql_vals.len() )); - if !ctx.roles.is_empty() { - sql_vals.push(sea_orm::Value::from(ctx.roles.clone().join(", ").to_string())); - child_or_where_fragments.push(format!( - "EXISTS (SELECT 1 FROM jsonb_array_elements_text({}.artifacts->'guard_conf'->'guard_by_spec_role_ids') AS elem WHERE elem IN (${}))", - table_alias_name, - sql_vals.len() - )); - } - if !ctx.groups.is_empty() { - sql_vals.push(sea_orm::Value::from(ctx.groups.clone().join(", ").to_string())); - child_or_where_fragments.push(format!( - "EXISTS (SELECT 1 FROM jsonb_array_elements_text({}.artifacts->'guard_conf'->'guard_by_spec_org_ids') AS elem WHERE elem IN (${}))", - table_alias_name, - sql_vals.len() - )); - } - or_where_fragments.push(format!("(current_state.state_kind = 'approval' AND ({}))", child_or_where_fragments.join(" OR "))); + } + if !ctx.groups.is_empty() { + sql_vals.push(sea_orm::Value::from(ctx.groups.clone().join(", ").to_string())); + child_or_where_fragments.push(format!( + "EXISTS (SELECT 1 FROM jsonb_array_elements_text({}.artifacts->'guard_conf'->'guard_by_spec_org_ids') AS elem WHERE elem IN (${}))", + table_alias_name, + sql_vals.len() + )); + } + or_where_fragments.push(format!("(current_state.state_kind = 'approval' AND ({}))", child_or_where_fragments.join(" OR "))); } if !and_where_fragments.is_empty() { where_fragments.push(format!("( {} )", and_where_fragments.join(" AND "))); } if !or_where_fragments.is_empty() { - where_fragments.push(format!("( {} )", or_where_fragments.join(" AND "))); + where_fragments.push(format!("( {} )", or_where_fragments.join(" OR "))); } Ok(()) } @@ -2534,15 +2637,12 @@ impl FlowInstServ { // 获取主实例的参数列表 async fn get_main_inst_vars(flow_inst: &FlowInstDetailResp, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult> { - let main_inst_id = Self::get_inst_ids_by_rel_business_obj_id(vec![flow_inst.rel_business_obj_id.clone()], Some(true), funs, ctx).await? - .pop() - .ok_or_else(|| funs.err().not_found("flow_inst", "get_guard_by_assigned", "illegal response", "404-flow-inst-not-found"))?; + let main_inst_id = Self::get_inst_ids_by_rel_business_obj_id(vec![flow_inst.rel_business_obj_id.clone()], Some(true), funs, ctx) + .await? + .pop() + .ok_or_else(|| funs.err().not_found("flow_inst", "get_guard_by_assigned", "illegal response", "404-flow-inst-not-found"))?; let main_inst = Self::get(&main_inst_id, funs, ctx).await?; - Ok(main_inst - .current_vars - .clone() - .unwrap_or_default() - ) + Ok(main_inst.current_vars.clone().unwrap_or_default()) } // 生成实例编码 @@ -2562,18 +2662,18 @@ impl FlowInstServ { } // 添加审批流发起日志 - async fn add_start_log(start_req: &FlowInstStartReq, flow_inst_detail: &FlowInstDetailResp, create_vars: &HashMap, flow_model: &FlowModelDetailResp, ctx: &TardisContext) -> TardisResult<()> { + async fn add_start_log( + start_req: &FlowInstStartReq, + flow_inst_detail: &FlowInstDetailResp, + create_vars: &HashMap, + flow_model: &FlowModelDetailResp, + ctx: &TardisContext, + ) -> TardisResult<()> { let rel_transition = flow_model.rel_transition().unwrap_or_default(); let operand = match rel_transition.id.as_str() { - "__EDIT__" => { - "编辑审批".to_string() - }, - "__DELETE__" => { - "删除审批".to_string() - } - _ => { - format!("{}({})", rel_transition.name, rel_transition.from_flow_state_name).to_string() - }, + "__EDIT__" => "编辑审批".to_string(), + "__DELETE__" => "删除审批".to_string(), + _ => format!("{}({})", rel_transition.name, rel_transition.from_flow_state_name).to_string(), }; let mut log_ext = LogParamExt { scene_kind: Some(vec!["approval_flow".to_string()]), @@ -2599,7 +2699,6 @@ impl FlowInstServ { } else { log_content.old_content = Some(create_vars.get("content").map_or("".to_string(), |val| val.as_str().unwrap_or("").to_string())); log_content.new_content = start_req.create_vars.clone().unwrap_or_default().get("content").map(|content| content.as_str().unwrap_or("").to_string()); - log_content.detail = None; // @TODO 暂未实现 log_ext.include_detail = Some(true); } FlowLogClient::add_ctx_task( @@ -2618,7 +2717,13 @@ impl FlowInstServ { } // 添加审批流操作日志 - async fn add_operate_log(operate_req: &FlowInstOperateReq, flow_inst_detail: &FlowInstDetailResp, op_kind: LogParamOp, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + async fn add_operate_log( + operate_req: &FlowInstOperateReq, + flow_inst_detail: &FlowInstDetailResp, + op_kind: LogParamOp, + funs: &TardisFunsInst, + ctx: &TardisContext, + ) -> TardisResult<()> { let current_state = FlowStateServ::get_item( &flow_inst_detail.current_state_id, &FlowStateFilterReq { @@ -2631,7 +2736,8 @@ impl FlowInstServ { }, funs, ctx, - ).await?; + ) + .await?; let subject_text = match current_state.state_kind { FlowStateKind::Approval => "审批节点".to_string(), FlowStateKind::Form => "录入节点".to_string(), @@ -2650,7 +2756,6 @@ impl FlowInstServ { sub_kind: Some(FlowLogClient::get_junp_kind(&flow_inst_detail.tag)), flow_message: operate_req.output_message.clone(), flow_result: Some(operate_req.operate.to_string().to_uppercase()), - detail: operate_req.log_text.clone(), ..Default::default() }; if operate_req.vars.is_none() { @@ -2658,9 +2763,10 @@ impl FlowInstServ { log_content.old_content = Some("".to_string()); log_content.new_content = Some("".to_string()); } else { - log_content.old_content = Some(flow_inst_detail.create_vars.clone().unwrap_or_default().get("content").map_or("".to_string(), |val| val.as_str().unwrap_or("").to_string())); + log_content.old_content = + Some(flow_inst_detail.create_vars.clone().unwrap_or_default().get("content").map_or("".to_string(), |val| val.as_str().unwrap_or("").to_string())); log_content.new_content = operate_req.vars.clone().unwrap_or_default().get("content").map(|content| content.as_str().unwrap_or("").to_string()); - log_content.detail = None; // @TODO 缺少翻译逻辑 + log_content.detail = operate_req.log_text.clone(); log_ext.include_detail = Some(true); } if operate_req.output_message.is_some() { @@ -2712,15 +2818,9 @@ impl FlowInstServ { .await?; let rel_transition = flow_model.rel_transition().unwrap_or_default(); let subject_text = match rel_transition.id.as_str() { - "__EDIT__" => { - "编辑审批".to_string() - }, - "__DELETE__" => { - "删除审批".to_string() - } - _ => { - format!("{}({})", rel_transition.name, rel_transition.from_flow_state_name).to_string() - }, + "__EDIT__" => "编辑审批".to_string(), + "__DELETE__" => "删除审批".to_string(), + _ => format!("{}({})", rel_transition.name, rel_transition.from_flow_state_name).to_string(), }; let log_ext = LogParamExt { scene_kind: Some(vec!["approval_flow".to_string()]), @@ -2756,6 +2856,7 @@ impl FlowInstServ { pub fn get_modify_vars(flow_inst_detail: &FlowInstDetailResp) -> HashMap { let mut vars_collect = HashMap::new(); if let Some(artifacts) = &flow_inst_detail.artifacts { + vars_collect = artifacts.curr_vars.clone().unwrap_or_default(); let mut state_ids = vec![]; for tran in flow_inst_detail.transitions.clone().unwrap_or_default() { let current_state_id = tran.from_state_id.clone().unwrap_or_default(); @@ -2769,7 +2870,7 @@ impl FlowInstServ { } } }; - + vars_collect } } diff --git a/backend/middlewares/flow/src/serv/flow_model_serv.rs b/backend/middlewares/flow/src/serv/flow_model_serv.rs index 2ef6c576..7308f481 100644 --- a/backend/middlewares/flow/src/serv/flow_model_serv.rs +++ b/backend/middlewares/flow/src/serv/flow_model_serv.rs @@ -48,7 +48,11 @@ use super::{ clients::{ flow_log_client::{FlowLogClient, LogParamContent, LogParamTag}, search_client::FlowSearchClient, - }, flow_model_version_serv::FlowModelVersionServ, flow_rel_serv::{FlowRelKind, FlowRelServ}, flow_state_serv::FlowStateServ, flow_transition_serv::FlowTransitionServ + }, + flow_model_version_serv::FlowModelVersionServ, + flow_rel_serv::{FlowRelKind, FlowRelServ}, + flow_state_serv::FlowStateServ, + flow_transition_serv::FlowTransitionServ, }; pub struct FlowModelServ; @@ -117,9 +121,11 @@ impl RbumItemCrudOperation TardisResult<()> { let model_detail = Self::get_item(flow_model_id, &FlowModelFilterReq::default(), funs, ctx).await?; + if modify_req.name.is_some() { + // 同步修改名称到版本 + for model_id in FlowModelVersionServ::find_id_items( + &FlowModelVersionFilterReq { + rel_model_ids: Some(vec![flow_model_id.to_string()]), + ..Default::default() + }, + None, + None, + funs, + ctx, + ) + .await? + { + FlowModelVersionServ::modify_item( + &model_id, + &mut FlowModelVersionModifyReq { + name: modify_req.name.clone(), + ..Default::default() + }, + funs, + ctx, + ) + .await?; + } + } if modify_req.status == Some(FlowModelStatus::Enabled) && model_detail.current_version_id.is_empty() { return Err(funs.err().internal_error("flow_model_serv", "after_modify_item", "Current model is not enabled", "500-flow_model-prohibit-enabled")); } @@ -637,14 +669,14 @@ impl RbumItemCrudOperation TardisResult<()> { - let models = Self::find_detail_items(&FlowModelFilterReq { - basic: RbumBasicFilterReq { - enabled: Some(true), + let models = Self::find_detail_items( + &FlowModelFilterReq { + basic: RbumBasicFilterReq { + enabled: Some(true), + ..Default::default() + }, + main: Some(false), + rel_template_id: req.rel_template_id.clone(), + tags: Some(vec![req.tag.clone()]), ..Default::default() }, - main: Some(false), - rel_template_id: req.rel_template_id.clone(), - tags: Some(vec![req.tag.clone()]), - ..Default::default() - }, None, None, funs, ctx).await?; + None, + None, + funs, + ctx, + ) + .await?; for model in models { let states = model.states(); for state in states { let add_default_conf = match state.state_kind { - FlowStateKind::Form => { - state.kind_conf.clone().unwrap_or_default().form.unwrap_or_default().add_default_field.unwrap_or_default() - }, - FlowStateKind::Approval => { - state.kind_conf.clone().unwrap_or_default().approval.unwrap_or_default().add_default_field.unwrap_or_default() - }, - _ => { FlowStateVar::default()}, + FlowStateKind::Form => state.kind_conf.clone().unwrap_or_default().form.unwrap_or_default().add_default_field.unwrap_or_default(), + FlowStateKind::Approval => state.kind_conf.clone().unwrap_or_default().approval.unwrap_or_default().add_default_field.unwrap_or_default(), + _ => FlowStateVar::default(), }; let mut kind_conf = state.kind_conf.clone().unwrap_or_default(); for add_field in req.add_fields.clone() { match state.state_kind { FlowStateKind::Form => { kind_conf.form.as_mut().map(|form| form.vars_collect.insert(add_field, add_default_conf.clone())); - }, + } FlowStateKind::Approval => { kind_conf.approval.as_mut().map(|form| form.vars_collect.insert(add_field, add_default_conf.clone())); - }, - _ => { }, + } + _ => {} } } for delete_field in &req.delete_fields { match state.state_kind { FlowStateKind::Form => { kind_conf.form.as_mut().map(|form| form.vars_collect.remove(delete_field)); - }, + } FlowStateKind::Approval => { kind_conf.approval.as_mut().map(|form| form.vars_collect.remove(delete_field)); - }, - _ => { }, + } + _ => {} } } - FlowStateServ::modify_item(&state.id, &mut FlowStateModifyReq { - kind_conf: Some(kind_conf), - ..Default::default() - }, funs, ctx).await?; + FlowStateServ::modify_item( + &state.id, + &mut FlowStateModifyReq { + kind_conf: Some(kind_conf), + ..Default::default() + }, + funs, + ctx, + ) + .await?; } } - + Ok(()) } } diff --git a/backend/middlewares/flow/src/serv/flow_model_version_serv.rs b/backend/middlewares/flow/src/serv/flow_model_version_serv.rs index 87c766b7..03ae023d 100644 --- a/backend/middlewares/flow/src/serv/flow_model_version_serv.rs +++ b/backend/middlewares/flow/src/serv/flow_model_version_serv.rs @@ -10,11 +10,16 @@ use bios_basic::rbum::{ }; use itertools::Itertools; use tardis::{ - basic::{dto::TardisContext, result::TardisResult}, chrono::Utc, db::sea_orm::{ + basic::{dto::TardisContext, result::TardisResult}, + chrono::Utc, + db::sea_orm::{ prelude::Expr, sea_query::{Alias, SelectStatement}, EntityName, Set, - }, futures::future::join_all, serde_json::json, TardisFuns, TardisFunsInst + }, + futures::future::join_all, + serde_json::json, + TardisFuns, TardisFunsInst, }; use crate::{ @@ -132,11 +137,13 @@ impl } let mut flow_mode_version = flow_model_version::ActiveModel { id: Set(id.to_string()), - update_time: Set(Utc::now()), ..Default::default() }; if let Some(status) = &modify_req.status { flow_mode_version.status = Set(status.clone()); + if *status != FlowModelVesionState::Disabled { + flow_mode_version.update_time = Set(Utc::now()); + } } if let Some(init_state_id) = &modify_req.init_state_id { flow_mode_version.init_state_id = Set(init_state_id.clone()); diff --git a/frontend/sdks/invoke/src/clients/spi_search_client.rs b/frontend/sdks/invoke/src/clients/spi_search_client.rs index a8ad66df..b1cad260 100644 --- a/frontend/sdks/invoke/src/clients/spi_search_client.rs +++ b/frontend/sdks/invoke/src/clients/spi_search_client.rs @@ -79,7 +79,8 @@ impl SpiSearchClient { pub async fn search(search_req: &SearchItemSearchReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult>> { let search_url = BaseSpiClient::module_url(InvokeModuleKind::Search, funs).await?; let headers = BaseSpiClient::headers(None, funs, ctx).await?; - let resp = funs.web_client().put::>>(format!("{search_url}/ci/item/search"), search_req, headers.clone()).await?; + let resp = + funs.web_client().put::>>(format!("{search_url}/ci/item/search"), search_req, headers.clone()).await?; BaseSpiClient::package_resp(resp) } } diff --git a/frontend/sdks/invoke/src/dto/search_item_dto.rs b/frontend/sdks/invoke/src/dto/search_item_dto.rs index 06153dff..bc90782a 100644 --- a/frontend/sdks/invoke/src/dto/search_item_dto.rs +++ b/frontend/sdks/invoke/src/dto/search_item_dto.rs @@ -242,4 +242,4 @@ pub struct SearchItemSearchResp { pub ext: Value, pub rank_title: f32, pub rank_content: f32, -} \ No newline at end of file +}