From 8a2cea373c8df306171851b5204ab8f4bc81adf7 Mon Sep 17 00:00:00 2001 From: ZzIsGod1019 <1498852723@qq.com> Date: Thu, 27 Jun 2024 11:19:44 +0800 Subject: [PATCH 1/3] iam-account:fix bug modify labor_type (#788) --- backend/supports/iam/src/basic/serv/iam_account_serv.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/supports/iam/src/basic/serv/iam_account_serv.rs b/backend/supports/iam/src/basic/serv/iam_account_serv.rs index 56d690247..eae42416d 100644 --- a/backend/supports/iam/src/basic/serv/iam_account_serv.rs +++ b/backend/supports/iam/src/basic/serv/iam_account_serv.rs @@ -125,7 +125,7 @@ impl RbumItemCrudOperation TardisResult> { - if modify_req.icon.is_none() && modify_req.status.is_none() && modify_req.lock_status.is_none() && modify_req.temporary.is_none() { + if modify_req.icon.is_none() && modify_req.status.is_none() && modify_req.lock_status.is_none() && modify_req.temporary.is_none() && modify_req.labor_type.is_none() { return Ok(None); } let mut iam_account = iam_account::ActiveModel { @@ -150,13 +150,14 @@ impl RbumItemCrudOperation Date: Thu, 27 Jun 2024 14:58:22 +0800 Subject: [PATCH 2/3] flow: merge state by same name (#759) * flow: merge state by same name * update --- .../flow/src/api/cc/flow_cc_inst_api.rs | 10 ++ .../flow/src/api/cc/flow_cc_state_api.rs | 22 +++- .../flow/src/api/ci/flow_ci_inst_api.rs | 48 ++++++-- .../flow/src/api/ci/flow_ci_state_api.rs | 8 +- .../flow/src/dto/flow_state_dto.rs | 2 +- .../middlewares/flow/src/flow_initializer.rs | 105 +++++++++++++++++- 6 files changed, 172 insertions(+), 23 deletions(-) diff --git a/backend/middlewares/flow/src/api/cc/flow_cc_inst_api.rs b/backend/middlewares/flow/src/api/cc/flow_cc_inst_api.rs index 4bc364b87..8563f7c10 100644 --- a/backend/middlewares/flow/src/api/cc/flow_cc_inst_api.rs +++ b/backend/middlewares/flow/src/api/cc/flow_cc_inst_api.rs @@ -22,6 +22,7 @@ pub struct FlowCcInstApi; #[poem_openapi::OpenApi(prefix_path = "/cc/inst")] impl FlowCcInstApi { /// Start Instance(Return Instance ID) + /// /// 启动实例(返回实例ID) #[oai(path = "/", method = "post")] async fn start(&self, add_req: Json, ctx: TardisContextExtractor, _request: &Request) -> TardisApiResult { @@ -34,6 +35,7 @@ impl FlowCcInstApi { } /// Abort Instance + /// /// 终止实例 #[oai(path = "/:flow_inst_id", method = "put")] async fn abort(&self, flow_inst_id: Path, abort_req: Json, ctx: TardisContextExtractor, _request: &Request) -> TardisApiResult { @@ -46,6 +48,7 @@ impl FlowCcInstApi { } /// Get Instance By Instance Id + /// /// 获取实例信息 #[oai(path = "/:flow_inst_id", method = "get")] async fn get(&self, flow_inst_id: Path, ctx: TardisContextExtractor, _request: &Request) -> TardisApiResult { @@ -56,6 +59,7 @@ impl FlowCcInstApi { } /// Find Instances + /// /// 获取实例列表 #[oai(path = "/", method = "get")] async fn paginate( @@ -77,6 +81,7 @@ impl FlowCcInstApi { } /// Find Next Transitions + /// /// 获取下一个流转状态列表 #[oai(path = "/:flow_inst_id/transition/next", method = "put")] async fn find_next_transitions( @@ -93,6 +98,7 @@ impl FlowCcInstApi { } /// Find the state and transfer information of the specified model in batch + /// /// 批量获取指定模型的状态及流转信息 #[oai(path = "/batch/state_transitions", method = "put")] async fn find_state_and_next_transitions( @@ -108,6 +114,7 @@ impl FlowCcInstApi { } /// Transfer State By Transaction Id + /// /// 通过动作ID流转状态 #[oai(path = "/:flow_inst_id/transition/transfer", method = "put")] async fn transfer( @@ -126,6 +133,7 @@ impl FlowCcInstApi { } /// Batch transfer State By Transaction Id + /// /// 批量流转 #[oai(path = "/batch/:flow_inst_ids/transition/transfer", method = "put")] async fn batch_transfer( @@ -153,6 +161,7 @@ impl FlowCcInstApi { } /// Modify Assigned [Deprecated] + /// /// 同步执行人信息 [已废弃] #[oai(path = "/:flow_inst_id/transition/modify_assigned", method = "post")] async fn modify_assigned( @@ -169,6 +178,7 @@ impl FlowCcInstApi { } /// Modify list of variables + /// /// 同步当前变量列表 #[oai(path = "/:flow_inst_id/modify_current_vars", method = "patch")] async fn modify_current_vars( diff --git a/backend/middlewares/flow/src/api/cc/flow_cc_state_api.rs b/backend/middlewares/flow/src/api/cc/flow_cc_state_api.rs index 0a8631f7f..ff928822e 100644 --- a/backend/middlewares/flow/src/api/cc/flow_cc_state_api.rs +++ b/backend/middlewares/flow/src/api/cc/flow_cc_state_api.rs @@ -21,7 +21,9 @@ pub struct FlowCcStateApi; /// Flow state process API #[poem_openapi::OpenApi(prefix_path = "/cc/state")] impl FlowCcStateApi { - /// Add State / 添加状态 + /// Add State + /// + /// 添加状态 #[oai(path = "/", method = "post")] async fn add(&self, mut add_req: Json, ctx: TardisContextExtractor, _request: &Request) -> TardisApiResult { let mut funs = flow_constants::get_tardis_inst(); @@ -32,7 +34,9 @@ impl FlowCcStateApi { TardisResp::ok(result) } - /// Modify State By State Id / 修改状态 + /// Modify State By State Id + /// + /// 修改状态 #[oai(path = "/:id", method = "patch")] async fn modify(&self, id: Path, mut modify_req: Json, ctx: TardisContextExtractor, _request: &Request) -> TardisApiResult { let mut funs = flow_constants::get_tardis_inst(); @@ -43,7 +47,9 @@ impl FlowCcStateApi { TardisResp::ok(Void {}) } - /// Get State By State Id / 获取状态 + /// Get State By State Id + /// + /// 获取状态 #[oai(path = "/:id", method = "get")] async fn get(&self, id: Path, ctx: TardisContextExtractor, _request: &Request) -> TardisApiResult { let funs = flow_constants::get_tardis_inst(); @@ -64,7 +70,9 @@ impl FlowCcStateApi { TardisResp::ok(result) } - /// Find States / 获取状态列表 + /// Find States + /// + /// 获取状态列表 #[oai(path = "/", method = "get")] #[allow(clippy::too_many_arguments)] async fn paginate( @@ -144,6 +152,8 @@ impl FlowCcStateApi { } /// Find Names By id set + /// + /// 通过id查找名称集合 #[oai(path = "/names", method = "get")] async fn find_names( &self, @@ -166,7 +176,9 @@ impl FlowCcStateApi { TardisResp::ok(resp) } - /// Count Group By State / 按状态分组统计 + /// Count Group By State + /// + /// 按状态分组统计 #[oai(path = "/count_group_by_state", method = "post")] async fn count_group_by_state( &self, diff --git a/backend/middlewares/flow/src/api/ci/flow_ci_inst_api.rs b/backend/middlewares/flow/src/api/ci/flow_ci_inst_api.rs index d5491ea06..6fd110c4c 100644 --- a/backend/middlewares/flow/src/api/ci/flow_ci_inst_api.rs +++ b/backend/middlewares/flow/src/api/ci/flow_ci_inst_api.rs @@ -24,7 +24,9 @@ pub struct FlowCiInstApi; /// Flow Config process API #[poem_openapi::OpenApi(prefix_path = "/ci/inst")] impl FlowCiInstApi { - /// Start Instance / 启动实例 + /// Start Instance + /// + /// 启动实例 #[oai(path = "/", method = "post")] async fn start(&self, add_req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { let mut funs = flow_constants::get_tardis_inst(); @@ -36,7 +38,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Get Instance By Instance Id / 获取实例信息 + /// Get Instance By Instance Id + /// + /// 获取实例信息 #[oai(path = "/:flow_inst_id", method = "get")] async fn get(&self, flow_inst_id: Path, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { let funs = flow_constants::get_tardis_inst(); @@ -46,7 +50,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Find the state and transfer information of the specified model in batch / 批量获取指定模型的状态及流转信息 + /// Find the state and transfer information of the specified model in batch + /// + /// 批量获取指定模型的状态及流转信息 #[oai(path = "/batch/state_transitions", method = "put")] async fn find_state_and_next_transitions( &self, @@ -61,7 +67,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Abort Instance / 中止实例 + /// Abort Instance + /// + /// 中止实例 #[oai(path = "/:flow_inst_id", method = "put")] async fn abort(&self, flow_inst_id: Path, abort_req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { let mut funs = flow_constants::get_tardis_inst(); @@ -73,7 +81,9 @@ impl FlowCiInstApi { TardisResp::ok(Void {}) } - /// Transfer State By State Id / 流转 + /// Transfer State By State Id + /// + /// 流转 #[oai(path = "/:flow_inst_id/transition/transfer", method = "put")] async fn transfer( &self, @@ -91,7 +101,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Batch transfer State By State Id / 批量流转 + /// Batch transfer State By State Id + /// + /// 批量流转 #[oai(path = "/batch/:flow_inst_ids/transition/transfer", method = "put")] async fn batch_transfer( &self, @@ -119,7 +131,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Modify Assigned / 同步执行人信息 + /// Modify Assigned + /// + /// 同步执行人信息 #[oai(path = "/:flow_inst_id/transition/modify_assigned", method = "post")] async fn modify_assigned( &self, @@ -136,7 +150,9 @@ impl FlowCiInstApi { TardisResp::ok(Void {}) } - /// Modify list of variables / 同步当前变量列表 + /// Modify list of variables + /// + /// 同步当前变量列表 #[oai(path = "/:flow_inst_id/modify_current_vars", method = "patch")] async fn modify_current_vars( &self, @@ -152,7 +168,9 @@ impl FlowCiInstApi { TardisResp::ok(Void {}) } - /// Bind Single Instance / 绑定单个实例 + /// Bind Single Instance + /// + /// 绑定单个实例 #[oai(path = "/bind", method = "post")] async fn bind(&self, add_req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { let mut funs = flow_constants::get_tardis_inst(); @@ -180,7 +198,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Batch Bind Instance / 批量绑定实例 (初始化) + /// Batch Bind Instance + /// + /// 批量绑定实例 (初始化) #[oai(path = "/batch_bind", method = "post")] async fn batch_bind(&self, add_req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult> { let mut funs = flow_constants::get_tardis_inst(); @@ -192,7 +212,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// Get list of instance id by rel_business_obj_id / 通过业务ID获取实例信息 + /// Get list of instance id by rel_business_obj_id + /// + /// 通过业务ID获取实例信息 #[oai(path = "/find_detail_by_obj_ids", method = "get")] async fn find_detail_by_obj_ids(&self, obj_ids: Query, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult> { let funs = flow_constants::get_tardis_inst(); @@ -209,7 +231,9 @@ impl FlowCiInstApi { TardisResp::ok(result) } - /// trigger instance front action / 触发前置动作 + /// trigger instance front action + /// + /// 触发前置动作 #[oai(path = "/trigger_front_action", method = "get")] async fn trigger_front_action(&self) -> TardisApiResult { let funs = flow_constants::get_tardis_inst(); diff --git a/backend/middlewares/flow/src/api/ci/flow_ci_state_api.rs b/backend/middlewares/flow/src/api/ci/flow_ci_state_api.rs index 196546b57..ecf430d3c 100644 --- a/backend/middlewares/flow/src/api/ci/flow_ci_state_api.rs +++ b/backend/middlewares/flow/src/api/ci/flow_ci_state_api.rs @@ -18,7 +18,9 @@ pub struct FlowCiStateApi; /// Flow Config process API #[poem_openapi::OpenApi(prefix_path = "/ci/state")] impl FlowCiStateApi { - /// Find States / 获取状态列表 + /// Find States + /// + /// 获取状态列表 #[oai(path = "/", method = "get")] #[allow(clippy::too_many_arguments)] async fn paginate( @@ -83,7 +85,9 @@ impl FlowCiStateApi { TardisResp::ok(result) } - /// Count Group By State / 按状态分组统计 + /// Count Group By State + /// + /// 按状态分组统计 #[oai(path = "/count_group_by_state", method = "post")] async fn count_group_by_state( &self, diff --git a/backend/middlewares/flow/src/dto/flow_state_dto.rs b/backend/middlewares/flow/src/dto/flow_state_dto.rs index f2118e3eb..674b0097d 100644 --- a/backend/middlewares/flow/src/dto/flow_state_dto.rs +++ b/backend/middlewares/flow/src/dto/flow_state_dto.rs @@ -39,7 +39,7 @@ pub struct FlowStateAddReq { pub disabled: Option, } -#[derive(Serialize, Deserialize, Debug, poem_openapi::Object)] +#[derive(Serialize, Deserialize, Debug, poem_openapi::Object, Default)] pub struct FlowStateModifyReq { #[oai(validator(min_length = "2", max_length = "200"))] pub name: Option, diff --git a/backend/middlewares/flow/src/flow_initializer.rs b/backend/middlewares/flow/src/flow_initializer.rs index e45beb952..e72d0531f 100644 --- a/backend/middlewares/flow/src/flow_initializer.rs +++ b/backend/middlewares/flow/src/flow_initializer.rs @@ -2,16 +2,19 @@ use bios_basic::rbum::{ dto::{rbum_domain_dto::RbumDomainAddReq, rbum_filer_dto::RbumBasicFilterReq, rbum_kind_dto::RbumKindAddReq}, rbum_enumeration::RbumScopeLevelKind, rbum_initializer, - serv::{rbum_crud_serv::RbumCrudOperation, rbum_domain_serv::RbumDomainServ, rbum_item_serv::RbumItemCrudOperation, rbum_kind_serv::RbumKindServ}, + serv::{rbum_crud_serv::RbumCrudOperation, rbum_domain_serv::RbumDomainServ, rbum_item_serv::RbumItemCrudOperation, rbum_kind_serv::RbumKindServ, rbum_rel_serv::RbumRelServ}, }; use bios_sdk_invoke::invoke_initializer; use itertools::Itertools; +use serde_json::json; + use tardis::{ basic::{dto::TardisContext, field::TrimString, result::TardisResult}, db::{ reldb_client::TardisActiveModel, sea_orm::{ + ColumnTrait, EntityTrait, QueryFilter, self, sea_query::{Expr, Query, Table}, }, @@ -34,7 +37,7 @@ use crate::{ domain::{flow_inst, flow_model, flow_state, flow_transition}, dto::{ flow_model_dto::FlowModelFilterReq, - flow_state_dto::FlowSysStateKind, + flow_state_dto::{FlowStateFilterReq, FlowStateModifyReq, FlowStateSummaryResp, FlowSysStateKind}, flow_transition_dto::{FlowTransitionDoubleCheckInfo, FlowTransitionInitInfo}, }, flow_config::{BasicInfo, FlowBasicInfoManager, FlowConfig}, @@ -87,6 +90,7 @@ pub async fn init_db(mut funs: TardisFunsInst) -> TardisResult<()> { funs.begin().await?; if check_initialized(&funs, &ctx).await? { init_basic_info(&funs).await?; + merge_state_by_name(&funs, &ctx).await?; rebind_model_with_template(&funs, &ctx).await?; } else { let db_kind = TardisFuns::reldb().backend(); @@ -101,6 +105,101 @@ pub async fn init_db(mut funs: TardisFunsInst) -> TardisResult<()> { Ok(()) } +pub async fn merge_state_by_name(funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + let kind_state_id = RbumKindServ::get_rbum_kind_id_by_code(flow_constants::RBUM_KIND_STATE_CODE, funs) + .await? + .ok_or_else(|| funs.err().not_found("flow", "merge_state_by_name", "not found state kind", ""))?; + let states = FlowStateServ::find_items( + &FlowStateFilterReq { + basic: RbumBasicFilterReq { + ignore_scope: true, + own_paths: Some("".to_string()), + rel_ctx_owner: true, + rbum_kind_id: Some(kind_state_id), + ..Default::default() + }, + ..Default::default() + }, + None, + None, + funs, + ctx, + ) + .await?; + let mut exists_states: HashMap = HashMap::new(); + for state in states { + if let Some(exists_state) = exists_states.get(&state.name) { + // flow inst + flow_inst::Entity::update_many() + .col_expr(flow_inst::Column::CurrentStateId, Expr::value(exists_state.id.as_str())) + .filter(flow_inst::Column::CurrentStateId.eq(&state.id)) + .exec(funs.db().raw_conn()) + .await?; + // flow model + flow_model::Entity::update_many() + .col_expr(flow_model::Column::InitStateId, Expr::value(exists_state.id.as_str())) + .filter(flow_model::Column::InitStateId.eq(&state.id)) + .exec(funs.db().raw_conn()) + .await?; + // flow transition + flow_transition::Entity::update_many() + .col_expr(flow_transition::Column::FromFlowStateId, Expr::value(exists_state.id.as_str())) + .filter(flow_transition::Column::FromFlowStateId.eq(&state.id)) + .exec(funs.db().raw_conn()) + .await?; + flow_transition::Entity::update_many() + .col_expr(flow_transition::Column::ToFlowStateId, Expr::value(exists_state.id.as_str())) + .filter(flow_transition::Column::ToFlowStateId.eq(&state.id)) + .exec(funs.db().raw_conn()) + .await?; + // rbum rel + join_all( + RbumRelServ::find_to_rels("FlowModelState", &state.id, None, None, funs, ctx) + .await? + .into_iter() + .map(|rel| async move { + let mock_ctx = TardisContext { + own_paths: rel.rel.own_paths, + ..Default::default() + }; + FlowRelServ::add_simple_rel( + &FlowRelKind::FlowModelState, + &rel.rel.from_rbum_id, + &exists_state.id, + None, + None, + false, + true, + Some(json!(rel.rel.ext).to_string()), + funs, + &mock_ctx, + ) + .await + .unwrap(); + FlowRelServ::delete_simple_rel(&FlowRelKind::FlowModelState, &rel.rel.from_rbum_id, &rel.rel.to_rbum_item_id, funs, &mock_ctx).await.unwrap(); + }) + .collect::>(), + ) + .await; + // flow state + FlowStateServ::modify_item( + &exists_state.id, + &mut FlowStateModifyReq { + tags: Some([exists_state.tags.clone().split(',').map(|s| s.to_string()).collect_vec(), vec![state.tags]].concat()), + ..Default::default() + }, + funs, + ctx, + ) + .await?; + FlowStateServ::delete_item(&state.id, funs, ctx).await?; + } else { + exists_states.insert(state.name.clone(), state); + } + } + Ok(()) +} + async fn check_initialized(funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult { RbumDomainServ::exist_rbum( &RbumBasicFilterReq { @@ -1021,7 +1120,7 @@ async fn init_ws_search_client() -> Option { } } -use std::sync::OnceLock; +use std::{collections::HashMap, sync::OnceLock}; tardis::tardis_static! { pub(crate) async ws_flow_client: Option = init_ws_flow_client(); pub(crate) async ws_search_client: Option = init_ws_search_client(); From deb0bcb3b7b97a0bc1634fe5bee65abe05138676 Mon Sep 17 00:00:00 2001 From: ZzIsGod1019 <1498852723@qq.com> Date: Thu, 27 Jun 2024 14:58:36 +0800 Subject: [PATCH 3/3] flow: fix update name when states are modified (#789) * iam-account:fix bug modify labor_type * flow: fix update name when states are modified * iam: fix ldap sync --- .../flow/src/serv/flow_model_serv.rs | 21 ------------------- .../iam/src/basic/dto/iam_cert_conf_dto.rs | 1 + 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/backend/middlewares/flow/src/serv/flow_model_serv.rs b/backend/middlewares/flow/src/serv/flow_model_serv.rs index e26255eca..6965856ec 100644 --- a/backend/middlewares/flow/src/serv/flow_model_serv.rs +++ b/backend/middlewares/flow/src/serv/flow_model_serv.rs @@ -200,24 +200,20 @@ impl RbumItemCrudOperation TardisResult<()> { let model_detail = Self::get_item(flow_model_id, &FlowModelFilterReq::default(), funs, ctx).await?; - let mut refresh_model_name_by_sorted_states = false; if let Some(bind_states) = &modify_req.bind_states { for bind_state in bind_states { Self::bind_state(flow_model_id, bind_state, funs, ctx).await?; } - refresh_model_name_by_sorted_states = true; } if let Some(unbind_states) = &modify_req.unbind_states { for unbind_state in unbind_states { Self::unbind_state(flow_model_id, unbind_state, funs, ctx).await?; } - refresh_model_name_by_sorted_states = true; } if let Some(modify_states) = &modify_req.modify_states { for modify_state in modify_states { Self::modify_rel_state_ext(flow_model_id, modify_state, funs, ctx).await?; } - refresh_model_name_by_sorted_states = true; } if let Some(add_transitions) = &modify_req.add_transitions { Self::add_transitions(flow_model_id, add_transitions, funs, ctx).await?; @@ -264,9 +260,6 @@ impl RbumItemCrudOperation Err(funs.err().not_found("flow_inst_serv", "get_model_id_by_own_paths", "model not found", "404-flow-model-not-found")), } } - - async fn refresh_model_name_by_sorted_states(flow_model_id: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { - Self::modify_item( - flow_model_id, - &mut FlowModelModifyReq { - name: Some(Self::find_sorted_rel_states_by_model_id(flow_model_id, funs, ctx).await?.into_iter().map(|state| state.name).collect_vec().join("-").into()), - ..Default::default() - }, - funs, - ctx, - ) - .await?; - Ok(()) - } } diff --git a/backend/supports/iam/src/basic/dto/iam_cert_conf_dto.rs b/backend/supports/iam/src/basic/dto/iam_cert_conf_dto.rs index 93810384e..9de18dc9d 100644 --- a/backend/supports/iam/src/basic/dto/iam_cert_conf_dto.rs +++ b/backend/supports/iam/src/basic/dto/iam_cert_conf_dto.rs @@ -187,6 +187,7 @@ impl IamCertConfLdapResp { &self.account_field_map.field_display_name, &self.account_field_map.field_email, &self.account_field_map.field_mobile, + &self.account_field_map.field_labor_type, ]; [vec, vec1].concat() }