From ecca72776ea3ea475ac7b6581399fab3e685a68b Mon Sep 17 00:00:00 2001 From: ZzIsGod1019 <1498852723@qq.com> Date: Tue, 2 Apr 2024 15:16:56 +0800 Subject: [PATCH] open-api: support modify product/spec (#679) --- .../src/serv/pg/stats_pg_conf_fact_serv.rs | 11 ++- support/iam/src/basic/dto/iam_open_dto.rs | 2 +- support/iam/src/basic/dto/iam_res_dto.rs | 2 +- support/iam/src/basic/serv/iam_open_serv.rs | 80 ++++++++++++++++++- .../console_interface/api/iam_ci_open_api.rs | 8 +- support/iam/tests/test_ci_open.rs | 39 +++++++-- 6 files changed, 123 insertions(+), 19 deletions(-) diff --git a/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs b/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs index 24dde3ed8..facb97cbd 100644 --- a/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs +++ b/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs @@ -191,9 +191,12 @@ async fn do_paginate( let mut sql_left = "".to_string(); let mut params: Vec = vec![Value::from(page_size), Value::from((page_number - 1) * page_size)]; if let Some(fact_conf_keys) = &fact_conf_keys { - sql_where.push(format!("fact.key IN ({})", (0..fact_conf_keys.len()).map(|idx| format!("${}", params.len() + idx + 1)).collect::>().join(","))); + sql_where.push(format!( + "fact.key IN ({})", + (0..fact_conf_keys.len()).map(|idx| format!("${}", params.len() + idx + 1)).collect::>().join(",") + )); for fact_conf_key in fact_conf_keys { - params.push(Value::from(format!("{fact_conf_key}"))); + params.push(Value::from(fact_conf_key.to_string())); } } if let Some(show_name) = &show_name { @@ -212,9 +215,9 @@ async fn do_paginate( dim_rel_conf_dim_keys.len() ); for dim_rel_conf_dim_key in dim_rel_conf_dim_keys { - params.push(Value::from(format!("{dim_rel_conf_dim_key}"))); + params.push(Value::from(dim_rel_conf_dim_key.to_string())); } - sql_where.push(format!("fact_col.rel_conf_fact_key IS NOT NULL")); + sql_where.push("fact_col.rel_conf_fact_key IS NOT NULL".to_string()); } } if let Some(desc_by_create) = desc_by_create { diff --git a/support/iam/src/basic/dto/iam_open_dto.rs b/support/iam/src/basic/dto/iam_open_dto.rs index 8d152a78b..a73173cae 100644 --- a/support/iam/src/basic/dto/iam_open_dto.rs +++ b/support/iam/src/basic/dto/iam_open_dto.rs @@ -4,7 +4,7 @@ use tardis::chrono::{self, Utc}; use tardis::{basic::field::TrimString, web::poem_openapi}; #[derive(poem_openapi::Object, Serialize, Deserialize, Debug)] -pub struct IamOpenAddProductReq { +pub struct IamOpenAddOrModifyProductReq { #[oai(validator(min_length = "2", max_length = "255"))] pub code: TrimString, #[oai(validator(min_length = "2", max_length = "255"))] diff --git a/support/iam/src/basic/dto/iam_res_dto.rs b/support/iam/src/basic/dto/iam_res_dto.rs index 00fd574dd..ee921d189 100644 --- a/support/iam/src/basic/dto/iam_res_dto.rs +++ b/support/iam/src/basic/dto/iam_res_dto.rs @@ -58,7 +58,7 @@ impl IamResAddReq { } } -#[derive(poem_openapi::Object, Serialize, Deserialize, Debug)] +#[derive(poem_openapi::Object, Serialize, Deserialize, Debug, Default)] pub struct IamResModifyReq { #[oai(validator(min_length = "2", max_length = "255"))] pub name: Option, diff --git a/support/iam/src/basic/serv/iam_open_serv.rs b/support/iam/src/basic/serv/iam_open_serv.rs index 520e32cef..a3386f1fa 100644 --- a/support/iam/src/basic/serv/iam_open_serv.rs +++ b/support/iam/src/basic/serv/iam_open_serv.rs @@ -30,8 +30,8 @@ use crate::{ iam_cert_conf_dto::IamCertConfAkSkAddOrModifyReq, iam_cert_dto::IamCertAkSkAddReq, iam_filer_dto::IamResFilterReq, - iam_open_dto::{IamOpenAddProductReq, IamOpenAkSkAddReq, IamOpenAkSkResp, IamOpenBindAkProductReq, IamOpenRuleResp}, - iam_res_dto::IamResAddReq, + iam_open_dto::{IamOpenAddOrModifyProductReq, IamOpenAkSkAddReq, IamOpenAkSkResp, IamOpenBindAkProductReq, IamOpenRuleResp}, + iam_res_dto::{IamResAddReq, IamResDetailResp, IamResModifyReq}, }, iam_config::IamConfig, iam_constants::{OPENAPI_GATEWAY_PLUGIN_COUNT, OPENAPI_GATEWAY_PLUGIN_DYNAMIC_ROUTE, OPENAPI_GATEWAY_PLUGIN_LIMIT, OPENAPI_GATEWAY_PLUGIN_TIME_RANGE}, @@ -46,7 +46,81 @@ use super::{ pub struct IamOpenServ; impl IamOpenServ { - pub async fn add_product(add_req: &IamOpenAddProductReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + pub async fn add_or_modify_product(req: &IamOpenAddOrModifyProductReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + if let Some(product) = Self::get_res_detail(req.code.as_str(), IamResKind::Product, funs, ctx).await? { + Self::modify_product(req, &product, funs, ctx).await?; + } else { + Self::add_product(req, funs, ctx).await?; + } + Ok(()) + } + + async fn modify_product(modify_req: &IamOpenAddOrModifyProductReq, product: &IamResDetailResp, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + IamResServ::modify_item( + &product.id, + &mut IamResModifyReq { + name: Some(modify_req.name.clone()), + icon: modify_req.icon.clone(), + scope_level: modify_req.scope_level.clone(), + disabled: modify_req.disabled, + ..Default::default() + }, + funs, + ctx, + ) + .await?; + for spec_req in &modify_req.specifications { + if let Some(spec) = Self::get_res_detail(spec_req.code.as_str(), IamResKind::Spec, funs, ctx).await? { + IamResServ::modify_item( + &spec.id, + &mut IamResModifyReq { + name: Some(spec_req.name.clone()), + icon: spec_req.icon.clone(), + scope_level: spec_req.scope_level.clone(), + disabled: spec_req.disabled, + ..Default::default() + }, + funs, + ctx, + ) + .await?; + } else { + let spec_id = IamResServ::add_item( + &mut IamResAddReq { + code: spec_req.code.clone(), + name: spec_req.name.clone(), + kind: IamResKind::Spec, + scope_level: spec_req.scope_level.clone(), + disabled: spec_req.disabled, + ..Default::default() + }, + funs, + ctx, + ) + .await?; + IamRelServ::add_simple_rel(&IamRelKind::IamProductSpec, &product.id, &spec_id, None, None, false, false, funs, ctx).await?; + } + } + Ok(()) + } + + async fn get_res_detail(code: &str, kind: IamResKind, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult> { + IamResServ::find_one_detail_item( + &IamResFilterReq { + basic: RbumBasicFilterReq { + code: Some(format!("{}/*/{}", kind.to_int(), code)), + ..Default::default() + }, + kind: Some(kind), + ..Default::default() + }, + funs, + ctx, + ) + .await + } + + async fn add_product(add_req: &IamOpenAddOrModifyProductReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { let product_id = IamResServ::add_item( &mut IamResAddReq { code: add_req.code.clone(), diff --git a/support/iam/src/console_interface/api/iam_ci_open_api.rs b/support/iam/src/console_interface/api/iam_ci_open_api.rs index c5ac90317..4922343b2 100644 --- a/support/iam/src/console_interface/api/iam_ci_open_api.rs +++ b/support/iam/src/console_interface/api/iam_ci_open_api.rs @@ -8,7 +8,7 @@ use tardis::web::poem_openapi::param::{Path, Query}; use tardis::web::poem_openapi::payload::Json; use tardis::web::web_resp::{TardisApiResult, TardisResp, Void}; -use crate::basic::dto::iam_open_dto::{IamOpenAddProductReq, IamOpenAkSkAddReq, IamOpenAkSkResp, IamOpenBindAkProductReq, IamOpenRuleResp}; +use crate::basic::dto::iam_open_dto::{IamOpenAddOrModifyProductReq, IamOpenAkSkAddReq, IamOpenAkSkResp, IamOpenBindAkProductReq, IamOpenRuleResp}; use crate::basic::serv::iam_cert_serv::IamCertServ; use crate::basic::serv::iam_open_serv::IamOpenServ; use crate::iam_constants; @@ -21,13 +21,13 @@ pub struct IamCiOpenApi; #[poem_openapi::OpenApi(prefix_path = "/ci/open", tag = "bios_basic::ApiTag::Interface")] impl IamCiOpenApi { /// Add product / 添加产品 - #[oai(path = "/add_product", method = "post")] - async fn add_product(&self, add_req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { + #[oai(path = "/add_or_modify_product", method = "post")] + async fn add_or_modify_product(&self, req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { let mut funs = iam_constants::get_tardis_inst(); unsafe_fill_ctx(request, &funs, &mut ctx.0)?; add_remote_ip(request, &ctx.0).await?; funs.begin().await?; - IamOpenServ::add_product(&add_req.0, &funs, &ctx.0).await?; + IamOpenServ::add_or_modify_product(&req.0, &funs, &ctx.0).await?; funs.commit().await?; ctx.0.execute_task().await?; TardisResp::ok(Void {}) diff --git a/support/iam/tests/test_ci_open.rs b/support/iam/tests/test_ci_open.rs index 1c0da5d34..f0abe9001 100644 --- a/support/iam/tests/test_ci_open.rs +++ b/support/iam/tests/test_ci_open.rs @@ -1,4 +1,4 @@ -use bios_iam::basic::dto::iam_open_dto::{IamOpenAddProductReq, IamOpenAddSpecReq, IamOpenAkSkAddReq, IamOpenBindAkProductReq}; +use bios_iam::basic::dto::iam_open_dto::{IamOpenAddOrModifyProductReq, IamOpenAddSpecReq, IamOpenAkSkAddReq, IamOpenBindAkProductReq}; use bios_iam::basic::serv::iam_open_serv::IamOpenServ; use tardis::basic::dto::TardisContext; use tardis::basic::field::TrimString; @@ -6,9 +6,6 @@ use tardis::basic::result::TardisResult; use tardis::chrono::Utc; use tardis::log::info; -use bios_basic::rbum::dto::rbum_filer_dto::RbumBasicFilterReq; -use bios_basic::rbum::serv::rbum_item_serv::RbumItemCrudOperation; -use bios_iam::basic::dto::iam_app_dto::IamAppModifyReq; use bios_iam::iam_constants; pub async fn test(context1: &TardisContext) -> TardisResult<()> { @@ -18,8 +15,38 @@ pub async fn test(context1: &TardisContext) -> TardisResult<()> { let spec1_code = "spec1".to_string(); let spec2_code = "spec2".to_string(); info!("【test_ci_open】 : Add Product"); - IamOpenServ::add_product( - &IamOpenAddProductReq { + IamOpenServ::add_or_modify_product( + &IamOpenAddOrModifyProductReq { + code: TrimString(product_code.clone()), + name: TrimString("测试产品".to_string()), + icon: None, + scope_level: None, + disabled: None, + specifications: vec![ + IamOpenAddSpecReq { + code: TrimString(spec1_code.clone()), + name: TrimString("测试规格1".to_string()), + icon: None, + url: None, + scope_level: None, + disabled: None, + }, + IamOpenAddSpecReq { + code: TrimString(spec2_code.clone()), + name: TrimString("测试规格2".to_string()), + icon: None, + url: None, + scope_level: None, + disabled: None, + }, + ], + }, + &funs, + context1, + ) + .await?; + IamOpenServ::add_or_modify_product( + &IamOpenAddOrModifyProductReq { code: TrimString(product_code.clone()), name: TrimString("测试产品".to_string()), icon: None,