From 5ef830517f1b3d93c33f7557cc3f486590a48080 Mon Sep 17 00:00:00 2001 From: ZzIsGod1019 <1498852723@qq.com> Date: Tue, 23 Apr 2024 14:11:02 +0800 Subject: [PATCH] spi-search: es support adv_query && improve test (#716) --- backend/basic/src/dto.rs | 6 +- backend/basic/src/enumeration.rs | 16 +- backend/basic/src/helper/db_helper.rs | 2 +- backend/basic/src/helper/request_helper.rs | 4 +- backend/basic/src/lib.rs | 8 +- backend/basic/src/process/ci_processor.rs | 4 +- backend/basic/src/process/task_processor.rs | 30 +- .../basic/src/rbum/domain/rbum_cert_conf.rs | 2 +- backend/basic/src/rbum/domain/rbum_domain.rs | 26 +- backend/basic/src/rbum/dto/rbum_domain_dto.rs | 6 +- .../src/rbum/helper/rbum_scope_helper.rs | 5 +- backend/basic/src/rbum/serv/rbum_crud_serv.rs | 1 - backend/basic/src/spi.rs | 6 +- backend/basic/src/spi/api/spi_ci_bs_api.rs | 18 +- backend/basic/src/spi/domain/spi_bs.rs | 4 +- backend/basic/src/spi/dto/spi_bs_dto.rs | 126 ++++----- backend/basic/src/spi/macros.rs | 10 +- backend/basic/src/spi/spi_funs.rs | 10 + .../src/plugin/anti_replay.rs | 5 +- .../flow/src/serv/flow_inst_serv.rs | 14 +- backend/spi/spi-kv/src/serv/kv_item_serv.rs | 2 +- .../spi/spi-search/src/dto/search_item_dto.rs | 10 + .../src/serv/es/search_es_item_serv.rs | 258 ++++++++++++++---- .../src/serv/pg/search_pg_item_serv.rs | 24 +- .../spi-search/tests/init_search_container.rs | 2 +- backend/spi/spi-search/tests/test_search.rs | 17 +- .../spi/spi-search/tests/test_search_item.rs | 93 ++++++- .../src/serv/pg/stats_pg_conf_dim_serv.rs | 6 +- .../serv/pg/stats_pg_conf_fact_col_serv.rs | 7 +- .../src/console_app/api/iam_ca_role_api.rs | 2 +- .../api/iam_ci_account_api.rs | 2 +- .../console_interface/api/iam_ci_cert_api.rs | 4 +- .../console_interface/api/iam_ci_open_api.rs | 10 +- .../api/iam_ci_tenant_api.rs | 4 +- .../console_passport/api/iam_cp_cert_api.rs | 10 +- .../src/console_system/api/iam_cs_cert_api.rs | 2 +- .../src/console_system/api/iam_cs_org_api.rs | 1 - .../console_tenant/api/iam_ct_app_set_api.rs | 2 +- .../api/iam_ct_cert_manage_api.rs | 1 - .../src/console_tenant/api/iam_ct_org_api.rs | 4 +- .../reach_api_ct_msg_signature.rs | 1 - .../reach_api_ct/reach_api_ct_msg_template.rs | 1 - .../reach_api_ct_trigger_global.rs | 1 - .../reach_api_ct_trigger_instance.rs | 1 - 44 files changed, 507 insertions(+), 261 deletions(-) diff --git a/backend/basic/src/dto.rs b/backend/basic/src/dto.rs index b292de44f..9e0f58a1f 100644 --- a/backend/basic/src/dto.rs +++ b/backend/basic/src/dto.rs @@ -1,5 +1,5 @@ //! Basic DTOs -//! +//! //! 基础的DTOs use std::collections::HashMap; @@ -11,7 +11,7 @@ use crate::enumeration::BasicQueryOpKind; use tardis::web::poem_openapi; /// Basic query condition object -/// +/// /// 基础的查询条件对象 #[derive(Serialize, Deserialize, Debug, Clone)] #[cfg_attr(feature = "default", derive(poem_openapi::Object))] @@ -27,7 +27,7 @@ pub struct BasicQueryCondInfo { impl BasicQueryCondInfo { /// Check if the ``check_vars`` passed in meet the conditions in ``conds`` - /// + /// /// 检查传入的 ``check_vars`` 是否满足 ``conds`` 中的条件 /// /// The outer level is the `OR` relationship, the inner level is the `AND` relationship diff --git a/backend/basic/src/enumeration.rs b/backend/basic/src/enumeration.rs index 27ddc6148..f81806a34 100644 --- a/backend/basic/src/enumeration.rs +++ b/backend/basic/src/enumeration.rs @@ -5,45 +5,45 @@ use tardis::derive_more::Display; use tardis::web::poem_openapi; /// API classification -/// +/// /// API分类 #[derive(Display, Debug)] #[cfg_attr(feature = "default", derive(poem_openapi::Tags))] pub enum ApiTag { /// Common Console, mostly starting with ``cc``, generally do not require authentication. - /// + /// /// 公共类型, 多使用 ``cc`` 开头,一般不需要认证 #[oai(rename = "Common Console")] Common, /// Tenant Console, mostly starting with ``ct`` - /// + /// /// 租户类型, 多使用 ``ct`` 开头 #[oai(rename = "Tenant Console")] Tenant, /// App Console, mostly starting with ``ca`` - /// + /// /// 应用类型, 多使用 ``ca`` 开头 #[oai(rename = "App Console")] App, /// System Console, mostly starting with ``cs`` - /// + /// /// 系统类型, 多使用 ``cs`` 开头 #[oai(rename = "System Console")] System, /// Passport Console, mostly starting with ``cp`` - /// + /// /// 通行证类型, 多使用 ``cp`` 开头 #[oai(rename = "Passport Console")] Passport, /// Interface Console, mostly starting with ``ci``, used for system-to-system calls, this type of interface generally uses ak/sk authentication - /// + /// /// 接口类型, 多使用 ``ci`` 开头, 用于系统间调用, 此类型接口一般使用ak/sk认证 #[oai(rename = "Interface Console")] Interface, } /// Basic query operator -/// +/// /// 基础查询操作符 #[derive(Display, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[cfg_attr(feature = "default", derive(poem_openapi::Enum))] diff --git a/backend/basic/src/helper/db_helper.rs b/backend/basic/src/helper/db_helper.rs index 13e8ee8f8..09fa16ce3 100644 --- a/backend/basic/src/helper/db_helper.rs +++ b/backend/basic/src/helper/db_helper.rs @@ -1,5 +1,5 @@ //! Database operations helper -//! +//! //! 数据库操作辅助操作 use tardis::{ chrono::{DateTime, ParseError, Utc}, diff --git a/backend/basic/src/helper/request_helper.rs b/backend/basic/src/helper/request_helper.rs index 79029f940..7f703cda4 100644 --- a/backend/basic/src/helper/request_helper.rs +++ b/backend/basic/src/helper/request_helper.rs @@ -1,5 +1,5 @@ //! Http request helper -//! +//! //! Http请求辅助操作 use std::{collections::HashMap, net::IpAddr, str::FromStr}; @@ -26,7 +26,7 @@ pub async fn try_set_real_ip_from_req_to_ctx(request: &Request, ctx: &TardisCont } /// Parse the Forwarded header to get the IP -/// +/// /// Forwarded format: `Forwarded: by=; for=<,for=>; host=; proto=` /// /// ``` diff --git a/backend/basic/src/lib.rs b/backend/basic/src/lib.rs index 87ed54c50..c77384a88 100644 --- a/backend/basic/src/lib.rs +++ b/backend/basic/src/lib.rs @@ -1,5 +1,5 @@ //! Basic library for BIOS -//! +//! //! BIOS的基础库 //! //! This library provides the following functions: @@ -30,20 +30,20 @@ pub use enumeration::ApiTag; use tardis::{TardisFuns, TardisFunsInst}; /// Extractor for ``TardisFunInst`` -/// +/// /// 提取 ``TardisFunsInst`` pub trait TardisFunInstExtractor { fn tardis_fun_inst(&self) -> TardisFunsInst; } /// Extract ``TardisFunInst`` from request path -/// +/// /// 从请求路径中自动提取 ``TardisFunInst`` /// /// Get the first path segment from the request path as the service domain. /// If there is a configuration parameter ``csm.X`` with the same name as the service domain, use this configuration parameter, /// otherwise use the default configuration parameter. -/// +/// /// 从请求路径中找到第一个路径段作为服务域名,如果存在与该服务域名同名的配置参数 ``csm.X``, 则使用该配置参数,否则使用默认配置参数. #[cfg(feature = "default")] impl TardisFunInstExtractor for tardis::web::poem::Request { diff --git a/backend/basic/src/process/ci_processor.rs b/backend/basic/src/process/ci_processor.rs index 6f8866bbc..c6ab2afa3 100644 --- a/backend/basic/src/process/ci_processor.rs +++ b/backend/basic/src/process/ci_processor.rs @@ -1,9 +1,9 @@ //! CI (Interface Console) Processor -//! +//! //! CI (接口控制台) 处理器 //! //! The CI type interface is mostly used for calls between systems, and the interface is authenticated by Ak/Sk to ensure the security of the interface. -//! +//! //! CI类型的接口多用于系统之间的调用,通过Ak/Sk进行签名认证,保证接口的安全性。 use serde::{Deserialize, Serialize}; use tardis::{basic::result::TardisResult, chrono::Utc, TardisFuns}; diff --git a/backend/basic/src/process/task_processor.rs b/backend/basic/src/process/task_processor.rs index 931f94c60..446194aeb 100644 --- a/backend/basic/src/process/task_processor.rs +++ b/backend/basic/src/process/task_processor.rs @@ -1,5 +1,5 @@ //! Async task processor -//! +//! //! 异步任务处理器 use std::{collections::HashMap, future::Future, sync::Arc}; @@ -36,7 +36,7 @@ pub struct TaskProcessor; impl TaskProcessor { /// Initialize the asynchronous task status - /// + /// /// 初始化异步任务状态 pub async fn init_status(cache_key: &str, task_id: Option, cache_client: &TardisCacheClient) -> TardisResult { let task_id = task_id.unwrap_or(Local::now().timestamp_nanos_opt().expect("maybe in 23rd century") as u64); @@ -51,7 +51,7 @@ impl TaskProcessor { } /// Check the status of the asynchronous task (whether it is completed) - /// + /// /// 检查异步任务状态(是否完成) pub async fn check_status(cache_key: &str, task_id: u64, cache_client: &TardisCacheClient) -> TardisResult { let result1 = cache_client.getbit(&format!("{cache_key}:1"), (task_id / u32::MAX as u64) as usize).await?; @@ -60,7 +60,7 @@ impl TaskProcessor { } /// Set the status of the asynchronous task (whether it is completed) - /// + /// /// 设置异步任务状态(是否完成) pub async fn set_status(cache_key: &str, task_id: u64, status: bool, cache_client: &TardisCacheClient) -> TardisResult<()> { cache_client.setbit(&format!("{cache_key}:1"), (task_id / u32::MAX as u64) as usize, status).await?; @@ -69,7 +69,7 @@ impl TaskProcessor { } /// Set the status of the asynchronous task (whether it is completed) and send an event - /// + /// /// 设置异步任务状态(是否完成)并发送事件 pub async fn set_status_with_event( cache_key: &str, @@ -96,7 +96,7 @@ impl TaskProcessor { } /// Set the processing data of the asynchronous task - /// + /// /// 设置异步任务处理数据 pub async fn set_process_data(cache_key: &str, task_id: u64, data: Value, cache_client: &TardisCacheClient) -> TardisResult<()> { cache_client.set_ex(&format!("{cache_key}:{task_id}"), &TardisFuns::json.json_to_string(data)?, TASK_PROCESSOR_DATA_EX_SEC).await?; @@ -104,7 +104,7 @@ impl TaskProcessor { } /// Set the processing data of the asynchronous task and send an event - /// + /// /// 设置异步任务处理数据并发送事件 pub async fn set_process_data_with_event( cache_key: &str, @@ -132,7 +132,7 @@ impl TaskProcessor { } /// Fetch the processing data of the asynchronous task - /// + /// /// 获取异步任务处理数据 pub async fn get_process_data(cache_key: &str, task_id: u64, cache_client: &TardisCacheClient) -> TardisResult { if let Some(result) = cache_client.get(&format!("{cache_key}:{task_id}")).await? { @@ -143,7 +143,7 @@ impl TaskProcessor { } /// Execute asynchronous task - /// + /// /// 执行异步任务 pub async fn execute_task(cache_key: &str, process_fun: P, cache_client: &Arc) -> TardisResult where @@ -154,7 +154,7 @@ impl TaskProcessor { } /// Execute asynchronous task and send event - /// + /// /// 执行异步任务并发送事件 pub async fn execute_task_with_ctx( cache_key: &str, @@ -227,7 +227,7 @@ impl TaskProcessor { } /// Execute asynchronous task (without asynchronous function, only used to mark the start of the task) - /// + /// /// 执行异步任务(不带异步函数,仅用于标记任务开始执行) pub async fn execute_task_without_fun( cache_key: &str, @@ -254,14 +254,14 @@ impl TaskProcessor { } /// Stop asynchronous task - /// + /// /// 停止异步任务 pub async fn stop_task(cache_key: &str, task_id: u64, cache_client: &TardisCacheClient) -> TardisResult<()> { Self::stop_task_with_event(cache_key, task_id, cache_client, None, "".to_string(), None).await } /// Stop asynchronous task and send event - /// + /// /// 停止异步任务并发送事件 pub async fn stop_task_with_event( cache_key: &str, @@ -291,11 +291,11 @@ impl TaskProcessor { } /// Fetch the asynchronous task IDs in the context - /// + /// /// 获取异步任务IDs /// /// Use ``,`` to separate multiple tasks - /// + /// /// 多个任务使用``,``分隔 pub async fn get_task_id_with_ctx(ctx: &TardisContext) -> TardisResult> { ctx.get_ext(TASK_IN_CTX_FLAG).await diff --git a/backend/basic/src/rbum/domain/rbum_cert_conf.rs b/backend/basic/src/rbum/domain/rbum_cert_conf.rs index b58acba01..bbba27bb6 100644 --- a/backend/basic/src/rbum/domain/rbum_cert_conf.rs +++ b/backend/basic/src/rbum/domain/rbum_cert_conf.rs @@ -14,7 +14,7 @@ use tardis::TardisCreateIndex; /// This is a general certificate configuration model that describes various types of certificate configurations. /// It can handle database connections, web system authentication, host ssh, etc. /// -/// 这是一个通用的凭证配置模型,用于描述各种类型的凭证配置。可处理包含数据库连接、web系统认证、主机ssh谁等。 +/// 这是一个通用的凭证配置模型,用于描述各种类型的凭证配置。可处理包含数据库连接、web系统认证、主机ssh等。 /// /// Certificate configuration is bound to a subject that can be a resource domain [`Self::rel_rbum_domain_id`] or a resource item [`Self::rel_rbum_item_id`]. /// It is required that the same binding subject has the same certificate configuration type [`Self::kind`] and certificate configuration supplier [`Self::supplier`] unique. diff --git a/backend/basic/src/rbum/domain/rbum_domain.rs b/backend/basic/src/rbum/domain/rbum_domain.rs index 5d0702675..fb1da31fc 100644 --- a/backend/basic/src/rbum/domain/rbum_domain.rs +++ b/backend/basic/src/rbum/domain/rbum_domain.rs @@ -8,53 +8,53 @@ use tardis::db::sea_orm::*; use tardis::TardisCreateIndex; /// Resource domain model -/// +/// /// 资源域模型 /// /// The resource domain is the unit of ownership of the resource, indicating the owner of the resource. /// Each resource is required to belong to a resource domain. -/// +/// /// 资源域是资源的归属单位,表示资源的所有者。每个资源都要求归属于一个资源域。 /// /// E.g. All menu resources are provided by IAM components, and all IaaS resources are provided by CMDB components. /// IAM components and CMDB components are resource domains. -/// +/// /// 例如:所有菜单资源由IAM组件提供,所有IaaS资源由CMDB组件提供。IAM组件和CMDB组件是资源域。 #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, TardisCreateIndex)] #[sea_orm(table_name = "rbum_domain")] pub struct Model { /// Resource domain id - /// + /// /// 资源域id #[sea_orm(primary_key, auto_increment = false)] pub id: String, /// Resource domain code - /// + /// /// 资源域编码 - /// + /// /// Global unique - /// + /// /// 全局唯一 - /// + /// /// Which is required to conform to the host specification in the uri, matching the regular: ^[a-z0-9-.]+$. - /// + /// /// 需要符合uri中的host规范,匹配正则:^[a-z0-9-.]+$。 #[index(unique)] pub code: String, /// Resource domain name - /// + /// /// 资源域名称 pub name: String, /// Resource domain note - /// + /// /// 资源域备注 pub note: String, /// Resource domain icon - /// + /// /// 资源域图标 pub icon: String, /// Resource domain sort - /// + /// /// 资源域排序 pub sort: i64, diff --git a/backend/basic/src/rbum/dto/rbum_domain_dto.rs b/backend/basic/src/rbum/dto/rbum_domain_dto.rs index 1e8ca47d6..69d19fe93 100644 --- a/backend/basic/src/rbum/dto/rbum_domain_dto.rs +++ b/backend/basic/src/rbum/dto/rbum_domain_dto.rs @@ -76,11 +76,11 @@ pub struct RbumDomainModifyReq { /// 资源域排序 pub sort: Option, /// Resource domain scope level - /// + /// /// 资源域作用域级别 - /// + /// /// Default is ``private`` - /// + /// /// 默认为``私有`` pub scope_level: Option, } diff --git a/backend/basic/src/rbum/helper/rbum_scope_helper.rs b/backend/basic/src/rbum/helper/rbum_scope_helper.rs index a40e29448..67544ce37 100644 --- a/backend/basic/src/rbum/helper/rbum_scope_helper.rs +++ b/backend/basic/src/rbum/helper/rbum_scope_helper.rs @@ -253,11 +253,8 @@ where /// Warning: This operation is unsafe, and it should only be used in scenarios where there is no security risk. #[cfg(feature = "default")] pub fn check_without_owner_and_unsafe_fill_ctx(request: &tardis::web::poem::Request, funs: &TardisFunsInst, ctx: &mut TardisContext) -> TardisResult<()> { - use tardis::log::warn; - if !ctx.owner.is_empty() { - warn!("[Auth.Check] ctx.owner is not empty, ctx: {:?}", ctx.owner); - // return Err(TardisError::forbidden("[Basic] Request context owner is not empty", "403-rbum-req-ctx-owner-is-not-empty")); + return Err(TardisError::forbidden("[Basic] Request context owner is not empty", "403-rbum-req-ctx-owner-is-not-empty")); } unsafe_fill_ctx(request, funs, ctx) } diff --git a/backend/basic/src/rbum/serv/rbum_crud_serv.rs b/backend/basic/src/rbum/serv/rbum_crud_serv.rs index 52ce733cc..d63ec000d 100644 --- a/backend/basic/src/rbum/serv/rbum_crud_serv.rs +++ b/backend/basic/src/rbum/serv/rbum_crud_serv.rs @@ -254,7 +254,6 @@ where Ok(E::Entity::find().filter(Expr::col(ID_FIELD.clone()).eq(id))) } - async fn after_delete_rbum(_: &str, _: &Option, _: &TardisFunsInst, _: &TardisContext) -> TardisResult<()> { Ok(()) } diff --git a/backend/basic/src/spi.rs b/backend/basic/src/spi.rs index 527e06b95..c80ebfa1e 100644 --- a/backend/basic/src/spi.rs +++ b/backend/basic/src/spi.rs @@ -1,11 +1,11 @@ //! SPI (Service Provider Interface) module -//! +//! //! SPI (服务提供接口) 模块 //! //! The SPI in BIOS is used to provide different scenario-oriented capabilities. //! These capabilities are abstracted into standardized service interfaces for other modules to call. //! Based on these standardized service interfaces, different backend implementations can be extended and interfaced. -//! +//! //! BIOS中的SPI用于提供面向不同场景的能力。这些能力抽象成标准化的服务接口,供其他模块调用。基于这些标准化的服务接口,可扩展对接不同的后端实现。 //! //! # Example of invoke flow: full-text search service / 调用流程举例:全文搜索服务: @@ -32,7 +32,7 @@ //! | | 7. Request some apis //! | | //! 8. Init and return backend client | | -//! (spi_funs) | | +//! (spi_funs) | | //! | | 9. Call client to execute request //! | | //! | | 10. Response data diff --git a/backend/basic/src/spi/api/spi_ci_bs_api.rs b/backend/basic/src/spi/api/spi_ci_bs_api.rs index cc32eed64..6ab4778c0 100644 --- a/backend/basic/src/spi/api/spi_ci_bs_api.rs +++ b/backend/basic/src/spi/api/spi_ci_bs_api.rs @@ -1,5 +1,5 @@ //! SPI common operation interface -//! +//! //! SPI公共操作接口 use tardis::web::context_extractor::TardisContextExtractor; use tardis::web::poem::Request; @@ -17,12 +17,12 @@ use crate::TardisFunInstExtractor; pub struct SpiCiBsApi; /// Interface Console Backend Service API -/// +/// /// 接口控制台后端服务API #[poem_openapi::OpenApi(prefix_path = "/ci/manage/bs", tag = "crate::ApiTag::Interface")] impl SpiCiBsApi { /// Add backend service - /// + /// /// 添加后端服务实例 /// /// # Parameters @@ -40,7 +40,7 @@ impl SpiCiBsApi { } /// Modify backend service - /// + /// /// 修改后端服务 /// /// # Parameters @@ -56,7 +56,7 @@ impl SpiCiBsApi { } /// Get backend service - /// + /// /// 获取后端服务 /// /// # Parameters @@ -72,7 +72,7 @@ impl SpiCiBsApi { } /// Find backend services - /// + /// /// 查找后端服务 /// /// # Parameters @@ -120,7 +120,7 @@ impl SpiCiBsApi { } /// Delete backend service - /// + /// /// 删除后端服务 /// /// # Parameters @@ -135,7 +135,7 @@ impl SpiCiBsApi { } /// Bind Backend Service to App/Tenant - /// + /// /// 绑定后端服务到应用/租户 /// /// # Parameters @@ -151,7 +151,7 @@ impl SpiCiBsApi { } /// Unbind Backend Service from App/Tenant - /// + /// /// 解绑后端服务与应用/租户 /// /// # Parameters diff --git a/backend/basic/src/spi/domain/spi_bs.rs b/backend/basic/src/spi/domain/spi_bs.rs index 4e83cd174..84ed50e0f 100644 --- a/backend/basic/src/spi/domain/spi_bs.rs +++ b/backend/basic/src/spi/domain/spi_bs.rs @@ -5,7 +5,7 @@ use tardis::db::sea_orm::sea_query::{ColumnDef, IndexCreateStatement, Table, Tab use tardis::db::sea_orm::*; /// SPI backend service model, extended from [`crate::rbum::domain::rbum_item`] -/// +/// /// SPI后端服务模型,扩展于[`crate::rbum::domain::rbum_item`] #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] #[sea_orm(table_name = "spi_bs")] @@ -13,7 +13,7 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub id: String, /// Is private. When it is private, this service is exclusive. Can only be used by one subject of request (tenant or application). - /// + /// /// 是否私有。当为私有时,这个服务为独占式的。只能给一个请求主体(租户或应用)使用。 pub private: bool, diff --git a/backend/basic/src/spi/dto/spi_bs_dto.rs b/backend/basic/src/spi/dto/spi_bs_dto.rs index 48ba74a4d..e6d688fbd 100644 --- a/backend/basic/src/spi/dto/spi_bs_dto.rs +++ b/backend/basic/src/spi/dto/spi_bs_dto.rs @@ -9,244 +9,244 @@ use crate::rbum::dto::rbum_filer_dto::{RbumBasicFilterReq, RbumItemFilterFetcher use crate::spi::spi_funs; /// Add request for backend service -/// +/// /// 后端服务添加请求 #[derive(Serialize, Deserialize, Debug)] #[cfg_attr(feature = "default", derive(poem_openapi::Object))] pub struct SpiBsAddReq { /// Service name - /// + /// /// 服务名称 #[oai(validator(min_length = "2", max_length = "255"))] pub name: TrimString, /// SPI service type Id. Used to partition the type corresponding to this service - /// + /// /// SPI服务类型Id。用于分区该服务对应的类型 #[oai(validator(min_length = "2", max_length = "255"))] pub kind_id: TrimString, /// Connection URI - /// + /// /// 连接URI #[oai(validator(min_length = "2", max_length = "2000"))] pub conn_uri: String, /// 连接用户名/凭证名 - /// + /// /// Connection username/credential name pub ak: TrimString, /// 连接密码/凭证密码 - /// + /// /// Connection password/credential password pub sk: TrimString, /// Extended information. Such as connection pool information - /// + /// /// 扩展信息。比如连接池信息 pub ext: String, /// Is private. Private service can only be used by one subject of request (tenant or application) - /// + /// /// 是否私有。私有的服务只能用于一个请求主体(租户或应用) pub private: bool, /// Is disabled - /// + /// /// 是否禁用 pub disabled: Option, } /// Modify request for backend service -/// +/// /// 后端服务修改请求 #[derive(Serialize, Deserialize, Debug)] #[cfg_attr(feature = "default", derive(poem_openapi::Object))] pub struct SpiBsModifyReq { /// Service name - /// + /// /// 服务名称 #[oai(validator(min_length = "2", max_length = "255"))] pub name: Option, /// SPI service type Id. Used to partition the type corresponding to this service - /// + /// /// SPI服务类型Id。用于分区该服务对应的类型 #[oai(validator(min_length = "2", max_length = "255"))] pub kind_id: Option, /// Connection URI - /// + /// /// 连接URI #[oai(validator(min_length = "2", max_length = "2000"))] pub conn_uri: Option, /// Connection username/credential name - /// + /// /// 连接用户名/凭证名 #[oai(validator(min_length = "2"))] pub ak: Option, /// Connection password/credential password - /// + /// /// 连接密码/凭证密码 #[oai(validator(min_length = "2"))] pub sk: Option, /// Extended information. Such as connection pool information - /// + /// /// 扩展信息。比如连接池信息 pub ext: Option, /// Is private. Private service can only be used by one subject of request (tenant or application) - /// + /// /// 是否私有。私有的服务只能用于一个请求主体(租户或应用) pub private: Option, /// Is disabled - /// + /// /// 是否禁用 pub disabled: Option, } /// Backend service summary information -/// +/// /// 后端服务概要信息 #[derive(Serialize, Deserialize, Debug)] #[cfg_attr(feature = "default", derive(poem_openapi::Object, sea_orm::FromQueryResult))] pub struct SpiBsSummaryResp { /// Service Id - /// + /// /// 服务Id pub id: String, /// Service name - /// + /// /// 服务名称 pub name: String, /// SPI service type Id - /// + /// /// SPI服务类型Id pub kind_id: String, /// SPI service type code - /// + /// /// SPI服务类型编码 pub kind_code: String, /// SPI service type name - /// + /// /// SPI服务类型名称 pub kind_name: String, /// Connection URI - /// + /// /// 连接URI pub conn_uri: String, /// Connection username/credential name - /// + /// /// 连接用户名/凭证名 pub ak: String, /// Connection password/credential password - /// + /// /// 连接密码/凭证密码 pub sk: String, /// Extended information. Such as connection pool information - /// + /// /// 扩展信息。比如连接池信息 pub ext: String, /// Is private. Private service can only be used by one subject of request (tenant or application) - /// + /// /// 是否私有。私有的服务只能用于一个请求主体(租户或应用) pub private: bool, /// Is disabled - /// + /// /// 是否禁用 pub disabled: bool, /// Create time - /// + /// /// 创建时间 pub create_time: DateTime, /// Update time - /// + /// /// 更新时间 pub update_time: DateTime, } /// Backend service detail information -/// +/// /// 后端服务详细信息 #[derive(Serialize, Deserialize, Debug)] #[cfg_attr(feature = "default", derive(poem_openapi::Object, sea_orm::FromQueryResult))] pub struct SpiBsDetailResp { /// Service Id - /// + /// /// 服务Id pub id: String, /// Service name - /// + /// /// 服务名称 pub name: String, /// SPI service type Id - /// + /// /// SPI服务类型Id pub kind_id: String, /// SPI service type code - /// + /// /// SPI服务类型编码 pub kind_code: String, /// SPI service type name - /// + /// /// SPI服务类型名称 pub kind_name: String, /// Connection URI - /// + /// /// 连接URI pub conn_uri: String, /// Connection username/credential name - /// + /// /// 连接用户名/凭证名 pub ak: String, /// Connection password/credential password - /// + /// /// 连接密码/凭证密码 pub sk: String, /// Extended information. Such as connection pool information - /// + /// /// 扩展信息。比如连接池信息 pub ext: String, /// Is private. Private service can only be used by one subject of request (tenant or application) - /// + /// /// 是否私有。私有的服务只能用于一个请求主体(租户或应用) pub private: bool, /// Is disabled - /// + /// /// 是否禁用 pub disabled: bool, /// Create time - /// + /// /// 创建时间 pub create_time: DateTime, /// Update time - /// + /// /// 更新时间 pub update_time: DateTime, /// Bound tenant or application Id - /// + /// /// 绑定的租户或应用Id pub rel_app_tenant_ids: Vec, } /// Backend service certificate information -/// +/// /// 后端服务凭证信息 #[derive(Serialize, Deserialize, Debug)] pub struct SpiBsCertResp { /// SPI service type code - /// + /// /// SPI服务类型编码 pub kind_code: String, /// Connection URI - /// + /// /// 连接URI pub conn_uri: String, /// Connection username/credential name - /// + /// /// 连接用户名/凭证名 pub ak: String, /// Connection password/credential password - /// + /// /// 连接密码/凭证密码 pub sk: String, /// Extended information. Such as connection pool information - /// + /// /// 扩展信息。比如连接池信息 pub ext: String, /// Is private. Private service can only be used by one subject of request (tenant or application) - /// + /// /// 是否私有。私有的服务只能用于一个请求主体(租户或应用) pub private: bool, } @@ -258,42 +258,42 @@ impl SpiBsCertResp { } /// Backend service query filter request -/// +/// /// 后端服务的查询过滤请求 #[derive(Serialize, Deserialize, Debug, Clone, Default)] #[cfg_attr(feature = "default", derive(poem_openapi::Object))] #[serde(default)] pub struct SpiBsFilterReq { /// Basic filter - /// + /// /// 基础过滤 pub basic: RbumBasicFilterReq, /// Relational filter - /// + /// /// 关联过滤 pub rel: Option, /// Relational filter 2 - /// + /// /// 关联过滤2 pub rel2: Option, /// Is private - /// + /// /// 是否私有 pub private: Option, /// SPI service type code - /// + /// /// SPI服务类型编码 pub kind_code: Option, /// SPI service type codes - /// + /// /// SPI服务类型编码集合 pub kind_codes: Option>, /// SPI service type Id - /// + /// /// SPI服务类型Id pub kind_id: Option, /// SPI service domain Id - /// + /// /// SPI服务Domain Id pub domain_code: Option, } diff --git a/backend/basic/src/spi/macros.rs b/backend/basic/src/spi/macros.rs index 5eff078de..55bceff3b 100644 --- a/backend/basic/src/spi/macros.rs +++ b/backend/basic/src/spi/macros.rs @@ -35,11 +35,11 @@ macro_rules! spi_dispatch_function { } /// SPI request dispatch macro -/// +/// /// SPI请求分发宏 /// /// Used to generate request dispatch code in the SPI service -/// +/// /// 用于批量生成请求分发代码 #[macro_export] macro_rules! spi_dispatch_service { @@ -48,15 +48,15 @@ macro_rules! spi_dispatch_service { /// 是否是管理模式 @mgr: $mgr: expr, /// Backend service initialization method, called when the backend service instance is not initialized - /// + /// /// 后端服务初始化方法,当后端服务实例未初始化时调用 @init: $init: expr, /// Service object to dispatch to - /// + /// /// 分发到的服务对象 @dispatch: $dispatch:tt, /// Collection of request methods - /// + /// /// 请求的方法集合 @method: { $( diff --git a/backend/basic/src/spi/spi_funs.rs b/backend/basic/src/spi/spi_funs.rs index ae6df8f63..b77cd2e26 100644 --- a/backend/basic/src/spi/spi_funs.rs +++ b/backend/basic/src/spi/spi_funs.rs @@ -62,6 +62,8 @@ pub trait SpiBsInstExtractor { T: Future> + Send; fn bs_not_implemented(&self, bs_code: &str) -> TardisError; + + async fn remove_bs_inst_cache<'a>(&self, ctx: &'a TardisContext) -> TardisResult<()>; } #[async_trait] @@ -141,6 +143,14 @@ impl SpiBsInstExtractor for TardisFunsInst { fn bs_not_implemented(&self, bs_code: &str) -> TardisError { bs_not_implemented(bs_code) } + + async fn remove_bs_inst_cache<'a>(&self, ctx: &'a TardisContext) -> TardisResult<()> { + let cache_key = format!("{}-{}", self.module_code(), ctx.ak); + info!("[SPI] Remove bs inst cache key:{}", cache_key.clone()); + let mut write = get_spi_bs_caches().write().await; + write.remove(&cache_key); + Ok(()) + } } pub fn bs_not_implemented(bs_code: &str) -> TardisError { diff --git a/backend/gateways/spacegate-plugins/src/plugin/anti_replay.rs b/backend/gateways/spacegate-plugins/src/plugin/anti_replay.rs index 4690d89e8..af3e5540d 100644 --- a/backend/gateways/spacegate-plugins/src/plugin/anti_replay.rs +++ b/backend/gateways/spacegate-plugins/src/plugin/anti_replay.rs @@ -10,10 +10,7 @@ use spacegate_shell::spacegate_ext_redis::{redis::AsyncCommands, RedisClient}; use spacegate_shell::{BoxError, SgBody, SgRequestExt, SgResponseExt}; use tardis::serde_json; -use tardis::{ - basic::result::TardisResult, - tokio, -}; +use tardis::{basic::result::TardisResult, tokio}; #[cfg(feature = "schema")] use spacegate_plugin::schemars; diff --git a/backend/middlewares/flow/src/serv/flow_inst_serv.rs b/backend/middlewares/flow/src/serv/flow_inst_serv.rs index 5a16f11a3..397769570 100644 --- a/backend/middlewares/flow/src/serv/flow_inst_serv.rs +++ b/backend/middlewares/flow/src/serv/flow_inst_serv.rs @@ -1042,12 +1042,14 @@ impl FlowInstServ { } } crate::dto::flow_var_dto::DefaultValueType::AutoFill => { - match FillType::from_str(default.value.as_str().ok_or_else(|| funs.err().bad_request( - "flow_transitions", - "default_value_type_parse", - "AutoFill default value type is not string", - "400-flow-inst-vars-field-missing", - ))?) + match FillType::from_str(default.value.as_str().ok_or_else(|| { + funs.err().bad_request( + "flow_transitions", + "default_value_type_parse", + "AutoFill default value type is not string", + "400-flow-inst-vars-field-missing", + ) + })?) .map_err(|err| { funs.err().internal_error("flow_transitions", "default_value_type_parse", &err.to_string(), "400-flow-inst-vars-field-missing") })? { diff --git a/backend/spi/spi-kv/src/serv/kv_item_serv.rs b/backend/spi/spi-kv/src/serv/kv_item_serv.rs index f50a654b9..4ffaffa13 100644 --- a/backend/spi/spi-kv/src/serv/kv_item_serv.rs +++ b/backend/spi/spi-kv/src/serv/kv_item_serv.rs @@ -38,4 +38,4 @@ spi_dispatch_service! { match_items(match_req: KvItemMatchReq) -> TardisResult>; delete_item(key: String) -> TardisResult<()>; } -} \ No newline at end of file +} diff --git a/backend/spi/spi-search/src/dto/search_item_dto.rs b/backend/spi/spi-search/src/dto/search_item_dto.rs index d0b6dc1b9..c03e73ce8 100644 --- a/backend/spi/spi-search/src/dto/search_item_dto.rs +++ b/backend/spi/spi-search/src/dto/search_item_dto.rs @@ -160,6 +160,16 @@ pub struct AdvBasicQueryCondInfo { pub value: Value, } +impl From for BasicQueryCondInfo { + fn from(value: AdvBasicQueryCondInfo) -> Self { + Self { + field: value.field, + op: value.op, + value: value.value, + } + } +} + #[derive(poem_openapi::Object, Serialize, Deserialize, Debug, Default)] pub struct SearchItemQueryReq { pub in_q_content: Option, diff --git a/backend/spi/spi-search/src/serv/es/search_es_item_serv.rs b/backend/spi/spi-search/src/serv/es/search_es_item_serv.rs index c3316c313..2c9551851 100644 --- a/backend/spi/spi-search/src/serv/es/search_es_item_serv.rs +++ b/backend/spi/spi-search/src/serv/es/search_es_item_serv.rs @@ -57,7 +57,7 @@ fn gen_data_mappings(ext: &Option) -> String { "title":{{"type": "text"}}, "content":{{"type": "text"}}, "owner":{{"type": "keyword"}}, - "own_paths":{{"type": "text"}}, + "own_paths":{{"type": "keyword"}}, "create_time":{{"type": "date"}}, "update_time":{{"type": "date"}}, "ext":{{{ext_string}}}, @@ -153,10 +153,7 @@ pub async fn modify(tag: &str, key: &str, modify_req: &mut SearchItemModifyReq, adv_query: None, })?; let mut search_result = client.raw_search(&index, &q, Some(1), Some(0), None).await?; - if search_result.hits.hits.is_empty() { - return Err(funs.err().conflict("search_es_item_serv", "modify", "not found record", "404-not-found-record")); - } - let id = search_result.hits.hits.pop().unwrap()._id.clone(); + let id = search_result.hits.hits.pop().ok_or_else(|| funs.err().conflict("search_es_item_serv", "modify", "not found record", "404-not-found-record"))?._id.clone(); let mut query = HashMap::new(); if let Some(kind) = &modify_req.kind { query.insert("kind".to_string(), json!(kind.clone()).to_string()); @@ -499,54 +496,30 @@ fn gen_query_dsl(search_req: &SearchItemSearchReq) -> TardisResult { } } if let Some(kinds) = &search_req.query.kinds { - let mut kinds_q = vec![]; - for kind in kinds { - kinds_q.push(json!({ - "term": {"kind": kind}, - })); - } must_q.push(json!({ - "bool": { - "should": kinds_q, + "terms": { + "kind": kinds.clone() } })); } if let Some(keys) = &search_req.query.keys { - let mut keys_q = vec![]; - for key in keys { - keys_q.push(json!({ - "term": {"key": key.to_string()}, - })); - } must_q.push(json!({ - "bool": { - "should": keys_q, + "terms": { + "key": keys.clone() } })); } if let Some(owners) = &search_req.query.owners { - let mut owners_q = vec![]; - for owner in owners { - owners_q.push(json!({ - "term": {"owner": owner}, - })); - } must_q.push(json!({ - "bool": { - "should": owners_q, + "terms": { + "owner": owners.clone() } })); } if let Some(own_paths) = &search_req.query.own_paths { - let mut own_paths_q = vec![]; - for own_path in own_paths { - own_paths_q.push(json!({ - "prefix": {"own_paths": own_path}, - })); - } must_q.push(json!({ - "bool": { - "should": own_paths_q, + "terms": { + "own_paths": own_paths.clone() } })); } @@ -562,51 +535,49 @@ fn gen_query_dsl(search_req: &SearchItemSearchReq) -> TardisResult { } if let Some(ext) = &search_req.query.ext { for cond_info in ext { + let field = format!("ext.{}", cond_info.field.clone()); match cond_info.op { BasicQueryOpKind::Eq => { - let field = format!("ext.{}", cond_info.field.clone()); must_q.push(json!({ "term": {field: cond_info.value.clone()} })); } BasicQueryOpKind::Ne => { - let field = format!("ext.{}", cond_info.field.clone()); must_not_q.push(json!({ "term": { field: cond_info.value.clone()} })); } BasicQueryOpKind::Gt => { - let field = format!("ext.{}", cond_info.field.clone()); filter_q.push(json!({ "range": {field: {"gt": cond_info.value.clone()}}, })); } BasicQueryOpKind::Ge => { - let field = format!("ext.{}", cond_info.field.clone()); filter_q.push(json!({ "range": {field: {"gte": cond_info.value.clone()}}, })); } BasicQueryOpKind::Lt => { - let field = format!("ext.{}", cond_info.field.clone()); filter_q.push(json!({ "range": {field: {"lt": cond_info.value.clone()}}, })); } BasicQueryOpKind::Le => { - let field = format!("ext.{}", cond_info.field.clone()); filter_q.push(json!({ "range": {field: {"lte": cond_info.value.clone()}}, })); } BasicQueryOpKind::Like => { - let field = format!("ext.{}", cond_info.field.clone()); must_q.push(json!({ "match": {field: cond_info.value.clone()} })); } + BasicQueryOpKind::NotLike => { + must_not_q.push(json!({ + "match": { field: cond_info.value.clone()} + })); + } BasicQueryOpKind::In => { - let field = format!("ext.{}", cond_info.field.clone()); let value = if cond_info.value.is_array() { cond_info.value.clone() } else { @@ -618,14 +589,201 @@ fn gen_query_dsl(search_req: &SearchItemSearchReq) -> TardisResult { } })); } - BasicQueryOpKind::NotLike => {} - BasicQueryOpKind::NotIn => {} - BasicQueryOpKind::IsNull => {} - BasicQueryOpKind::IsNotNull => {} - BasicQueryOpKind::IsNullOrEmpty => {} + BasicQueryOpKind::NotIn => { + let value = if cond_info.value.is_array() { + cond_info.value.clone() + } else { + json!(vec![cond_info.value.clone()]) + }; + must_not_q.push(json!({ + "terms": { field: value} + })); + } + BasicQueryOpKind::IsNull => { + must_not_q.push(json!({ + "exists": {"field": field} + })); + } + BasicQueryOpKind::IsNotNull => { + must_q.push(json!({ + "exists": {"field": field} + })); + } + BasicQueryOpKind::IsNullOrEmpty => { + must_q.push(json!({ + "bool": { + "should": [ + {"term": {field.clone(): "".to_string()}}, + {"bool": { + "must_not": [{ + "exists": {"field": field} + }], + }} + ] + } + })); + } } } } + if let Some(adv_query) = &search_req.adv_query { + let mut adv_query_must_q = vec![]; + let mut adv_query_should_q = vec![]; + for group_query in adv_query { + let mut group_query_q: Vec = vec![]; + for cond_info in group_query.ext.clone().unwrap_or_default() { + let field = if cond_info.in_ext.unwrap_or(true) { + format!("ext.{}", cond_info.field) + } else { + cond_info.field.clone() + }; + match cond_info.op { + BasicQueryOpKind::Eq => { + group_query_q.push(json!({ + "term": {field: cond_info.value.clone()} + })); + } + BasicQueryOpKind::Ne => { + group_query_q.push(json!({ + "bool": { + "must_not": { + "term": { field: cond_info.value.clone()} + } + } + })); + } + BasicQueryOpKind::Gt => { + group_query_q.push(json!({ + "bool": { + "filter": { + "range": {field: {"gt": cond_info.value.clone()}}, + } + } + })); + } + BasicQueryOpKind::Ge => { + group_query_q.push(json!({ + "bool": { + "filter": { + "range": {field: {"gte": cond_info.value.clone()}}, + } + } + })); + } + BasicQueryOpKind::Lt => { + group_query_q.push(json!({ + "bool": { + "filter": { + "range": {field: {"lt": cond_info.value.clone()}}, + } + } + })); + } + BasicQueryOpKind::Le => { + group_query_q.push(json!({ + "bool": { + "filter": { + "range": {field: {"lte": cond_info.value.clone()}}, + } + } + })); + } + BasicQueryOpKind::Like => { + group_query_q.push(json!({ + "match": {field: cond_info.value.clone()} + })); + } + BasicQueryOpKind::NotLike => { + group_query_q.push(json!({ + "bool": { + "must_not": { + "match": { field: cond_info.value.clone()} + } + } + })); + } + BasicQueryOpKind::In => { + let value = if cond_info.value.is_array() { + cond_info.value.clone() + } else { + json!(vec![cond_info.value.clone()]) + }; + group_query_q.push(json!({ + "terms": { + field: value + } + })); + } + BasicQueryOpKind::NotIn => { + let value = if cond_info.value.is_array() { + cond_info.value.clone() + } else { + json!(vec![cond_info.value.clone()]) + }; + group_query_q.push(json!({ + "bool": { + "must_not": { + "terms": { field: value} + } + } + })); + } + BasicQueryOpKind::IsNull => { + group_query_q.push(json!({ + "bool": { + "must_not": { + "exists": {"field": field} + } + } + })); + } + BasicQueryOpKind::IsNotNull => { + group_query_q.push(json!({ + "exists": {"field": field} + })); + } + BasicQueryOpKind::IsNullOrEmpty => { + group_query_q.push(json!({ + "bool": { + "should": [ + {"term": {field.clone(): "".to_string()}}, + {"bool": { + "must_not": [{ + "exists": {"field": field} + }], + }} + ] + } + })); + } + } + } + match group_query.group_by_or.unwrap_or(false) { + true => { + adv_query_must_q.push(json!({ + "bool": { + "must": if group_query.ext_by_or.unwrap_or(false) { group_query_q.clone() } else { vec![] }, + "should": if group_query.ext_by_or.unwrap_or(false) { vec![] } else { group_query_q.clone() }, + } + })); + } + false => { + adv_query_should_q.push(json!({ + "bool": { + "must": if group_query.ext_by_or.unwrap_or(false) { group_query_q.clone() } else { vec![] }, + "should": if group_query.ext_by_or.unwrap_or(false) { vec![] } else { group_query_q.clone() }, + } + })); + } + } + } + must_q.push(json!({ + "bool": { + "must": adv_query_must_q, + "should": adv_query_should_q, + } + })); + } if let Some(sorts) = &search_req.sort { for sort_item in sorts { if sort_item.field.to_lowercase() == "key" diff --git a/backend/spi/spi-search/src/serv/pg/search_pg_item_serv.rs b/backend/spi/spi-search/src/serv/pg/search_pg_item_serv.rs index 108cf4be4..a8ad991a6 100644 --- a/backend/spi/spi-search/src/serv/pg/search_pg_item_serv.rs +++ b/backend/spi/spi-search/src/serv/pg/search_pg_item_serv.rs @@ -82,7 +82,7 @@ pub async fn add(add_req: &mut SearchItemAddReq, funs: &TardisFunsInst, ctx: &Ta conn.execute_one( &format!( r#"INSERT INTO {table_name} - (kind, key, title, title_tsv,content, content_tsv, owner, own_paths, create_time, update_time, ext, visit_keys) + (kind, key, title, title_tsv, content, content_tsv, owner, own_paths, create_time, update_time, ext, visit_keys) VALUES ($1, $2, $3, to_tsvector('{word_combinations_way}', $4), $5, to_tsvector('public.chinese_zh', $6), $7, $8, $9, $10, $11, {})"#, if add_req.visit_keys.is_some() { "$12" } else { "null" }, @@ -256,7 +256,7 @@ pub async fn search(search_req: &mut SearchItemSearchReq, funs: &TardisFunsInst, }) .collect::(); sql_vals.push(Value::from(q.as_str())); - from_fragments = format!(", plainto_tsquery('public.chinese_zh', ${}) AS query", sql_vals.len()); + from_fragments = format!(", to_tsquery('public.chinese_zh', ${}) AS query", sql_vals.len()); match search_req.query.q_scope.as_ref().unwrap_or(&SearchItemSearchQScopeKind::Title) { SearchItemSearchQScopeKind::Title => { select_fragments = ", COALESCE(ts_rank(title_tsv, query), 0::float4) AS rank_title, 0::float4 AS rank_content".to_string(); @@ -498,18 +498,10 @@ pub async fn search(search_req: &mut SearchItemSearchReq, funs: &TardisFunsInst, if let Some(adv_query) = &search_req.adv_query { for group_query in adv_query { let mut sql_and_where = vec![]; - let err_not_found = |ext_item: &AdvBasicQueryCondInfo| { - Err(funs.err().not_found( - "item", - "search", - &format!("The ext field=[{}] value=[{}] operation=[{}] is not legal.", &ext_item.field, ext_item.value, &ext_item.op,), - "404-spi-search-op-not-legal", - )) - }; if let Some(ext) = &group_query.ext { for ext_item in ext { let value = db_helper::json_to_sea_orm_value(&ext_item.value, ext_item.op == BasicQueryOpKind::Like || ext_item.op == BasicQueryOpKind::NotLike); - let Some(mut value) = value else { return err_not_found(ext_item) }; + let Some(mut value) = value else { return err_not_found(&ext_item.clone().into()) }; if ext_item.in_ext.unwrap_or(true) { if ext_item.op == BasicQueryOpKind::In { if value.len() == 1 { @@ -549,7 +541,7 @@ pub async fn search(search_req: &mut SearchItemSearchReq, funs: &TardisFunsInst, )); } else { if value.len() > 1 { - return err_not_found(ext_item); + return err_not_found(&ext_item.clone().into()); } let Some(value) = value.pop() else { return Err(funs.err().bad_request("item", "search", "Request item using 'IN' operator show hava a value", "400-spi-item-op-in-without-value")); @@ -619,10 +611,10 @@ pub async fn search(search_req: &mut SearchItemSearchReq, funs: &TardisFunsInst, sql_and_where.push(format!("({} is null or {} = '' )", ext_item.field, ext_item.field)); } else { if value.len() > 1 { - return err_not_found(ext_item); + return err_not_found(&ext_item.clone().into()); } let Some(value) = value.pop() else { - return Err(funs.err().bad_request("item", "search", "Request item using 'IN' operator show hava a value", "400-spi-item-op-in-without-value")); + return Err(funs.err().bad_request("item", "search", "Request item using 'IN' operator show have a value", "400-spi-item-op-in-without-value")); }; if let Value::Bool(_) = value { sql_and_where.push(format!("({}::boolean) {} ${}", ext_item.field, ext_item.op.to_sql(), sql_vals.len() + 1)); @@ -764,7 +756,7 @@ pub async fn query_metrics(query_req: &SearchQueryMetricsReq, funs: &TardisFunsI }) .collect::(); params.push(Value::from(q.as_str())); - from_fragments = format!(", plainto_tsquery('public.chinese_zh', ${}) AS query", params.len()); + from_fragments = format!(", to_tsquery('public.chinese_zh', ${}) AS query", params.len()); match query_req.query.q_scope.as_ref().unwrap_or(&SearchItemSearchQScopeKind::Title) { SearchItemSearchQScopeKind::Title => { select_fragments = ", COALESCE(ts_rank(title_tsv, query), 0::float4) AS rank_title, 0::float4 AS rank_content".to_string(); @@ -1393,7 +1385,7 @@ pub async fn query_metrics(query_req: &SearchQueryMetricsReq, funs: &TardisFunsI let bs_inst = inst.inst::(); let (conn, table_name) = search_pg_initializer::init_table_and_conn(bs_inst, &query_req.tag, ctx, false).await?; - let ignore_group_agg = !(!sql_part_groups.is_empty() && query_req.group_agg.unwrap_or(false)); + let ignore_group_agg = sql_part_groups.is_empty() || !query_req.group_agg.unwrap_or(false); let final_sql = format!( r#"SELECT {sql_part_outer_selects}{} FROM ( diff --git a/backend/spi/spi-search/tests/init_search_container.rs b/backend/spi/spi-search/tests/init_search_container.rs index b45b124cd..48dbe7380 100644 --- a/backend/spi/spi-search/tests/init_search_container.rs +++ b/backend/spi/spi-search/tests/init_search_container.rs @@ -31,7 +31,7 @@ pub async fn init(docker: &Cli) -> TardisResult> { let es_container = TardisTestContainer::es_custom(docker); let port = es_container.get_host_port_ipv4(9200); - let url = format!("https://elastic:123456@127.0.0.1:{}", port); + let url = format!("http://elastic:123456@127.0.0.1:{}", port); env::set_var("TARDIS_FW.ES.URL", url); let mq_container = TardisTestContainer::rabbit_custom(docker); diff --git a/backend/spi/spi-search/tests/test_search.rs b/backend/spi/spi-search/tests/test_search.rs index a28ae4aea..77f3b6972 100644 --- a/backend/spi/spi-search/tests/test_search.rs +++ b/backend/spi/spi-search/tests/test_search.rs @@ -5,6 +5,7 @@ use bios_basic::rbum::rbum_config::RbumConfig; use bios_basic::rbum::serv::rbum_kind_serv::RbumKindServ; use bios_basic::spi::dto::spi_bs_dto::SpiBsAddReq; use bios_basic::spi::spi_constants; +use bios_basic::spi::spi_funs::SpiBsInstExtractor; use bios_basic::test::test_http_client::TestHttpClient; use bios_spi_search::search_constants::DOMAIN_CODE; use bios_spi_search::search_initializer; @@ -23,12 +24,13 @@ async fn test_search() -> TardisResult<()> { let docker = testcontainers::clients::Cli::default(); let _x = init_search_container::init(&docker).await?; - init_data().await?; + init_data(spi_constants::SPI_ES_KIND_CODE, &env::var("TARDIS_FW.ES.URL").unwrap()).await?; + init_data(spi_constants::SPI_PG_KIND_CODE, &env::var("TARDIS_FW.DB.URL").unwrap()).await?; Ok(()) } -async fn init_data() -> TardisResult<()> { +async fn init_data(code: &str, conn_uri: &str) -> TardisResult<()> { // Initialize RBUM bios_basic::rbum::rbum_initializer::init(DOMAIN_CODE, RbumConfig::default()).await?; @@ -43,8 +45,8 @@ async fn init_data() -> TardisResult<()> { sleep(Duration::from_millis(500)).await; let funs = TardisFuns::inst_with_db_conn(DOMAIN_CODE.to_string(), None); - let kind_id = RbumKindServ::get_rbum_kind_id_by_code(spi_constants::SPI_PG_KIND_CODE, &funs).await?.unwrap(); - let ctx = TardisContext { + let kind_id = RbumKindServ::get_rbum_kind_id_by_code(code, &funs).await?.unwrap(); + let mut ctx = TardisContext { own_paths: "".to_string(), ak: "".to_string(), roles: vec![], @@ -63,7 +65,7 @@ async fn init_data() -> TardisResult<()> { &SpiBsAddReq { name: TrimString("test-spi".to_string()), kind_id: TrimString(kind_id), - conn_uri: env::var("TARDIS_FW.DB.URL").unwrap(), + conn_uri: conn_uri.to_string(), ak: TrimString("".to_string()), sk: TrimString("".to_string()), ext: "{\"max_connections\":20,\"min_connections\":10}".to_string(), @@ -77,5 +79,10 @@ async fn init_data() -> TardisResult<()> { test_search_item::test(&mut client).await?; + client.set_auth(&ctx)?; + client.delete(&format!("/ci/manage/bs/{}", bs_id)).await; + ctx.ak = "app001".to_string(); + funs.remove_bs_inst_cache(&ctx).await?; + Ok(()) } diff --git a/backend/spi/spi-search/tests/test_search_item.rs b/backend/spi/spi-search/tests/test_search_item.rs index 02c4ba2cc..bfb49ba2b 100644 --- a/backend/spi/spi-search/tests/test_search_item.rs +++ b/backend/spi/spi-search/tests/test_search_item.rs @@ -9,7 +9,7 @@ use tardis::web::web_resp::{TardisPage, TardisResp, Void}; pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { client.set_auth(&TardisContext { own_paths: "t1/app001".to_string(), - ak: "".to_string(), + ak: "app001".to_string(), roles: vec![], groups: vec![], owner: "app001".to_string(), @@ -48,7 +48,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "own_paths":"t001/a001", "create_time":"2022-09-26T23:23:56.000Z", "update_time": "2022-09-27T01:20:20.000Z", - "ext":{"start_time":"2022-10-25T14:23:20.000Z","end_time":"2022-10-30T14:23:20.000Z","rel_accounts":["acc01","acc03"],"version":"1.3"}, + "ext":{"start_time":"2022-10-25T14:23:20.000Z","end_time":"2022-10-30T14:23:20.000Z","rel_accounts":["acc01","acc03"],"version":"1.3", "empty_value":""}, "visit_keys":{"apps":["003"],"tenants":["001"],"roles":["sys"]} }), ) @@ -109,6 +109,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "tag":"feed", "ctx":{}, "query":{}, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -228,6 +229,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "value":["acc01"] }] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -250,6 +252,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "value":["acc01","acc02"] }] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -272,6 +275,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "value":"acc01" }] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -294,6 +298,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "value":"2022-10-30T14:23:20.000Z" }] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -325,6 +330,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "value":1.1 }] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -343,6 +349,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "query":{ "kinds": ["req","task"] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -359,6 +366,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "query":{ "kinds": ["task"] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -376,6 +384,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { }, "query":{ }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) @@ -477,7 +486,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "query":{ "q": "新增", "q_scope": "title_content", - "own_paths":["t001"], + "own_paths":["t001/a001", "t001/a002"], "ext": [{ "field":"end_time", "op":"<=", @@ -500,6 +509,82 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { .await; assert_eq!(search_result.total_size, 2); assert_eq!(search_result.records[0].key, "002"); + let search_result: TardisPage = client + .put( + "/ci/item/search", + &json!({ + "tag":"feed", + "ctx":{ + "apps":["003"], + "tenants":["001"], + "roles":["root","sys"] + }, + "query": {}, + "adv_query":[ + { + "ext": [ + {"field": "own_paths", "value": ["t001/a001", "t001/a002"], "op": "in", "in_ext": false}, + {"field": "end_time", "value": "2022-10-30T14:23:20.000Z", "op": "<=", "in_ext": true}, + ], + "group_by_or": true + }, + ], + "sort":[{ + "field":"end_time", + "order":"asc" + },{ + "field":"rank_title", + "order":"desc" + },{ + "field":"rank_content", + "order":"desc" + }], + "page":{"number":2,"size":1,"fetch_total":true} + }), + ) + .await; + assert_eq!(search_result.total_size, 2); + assert_eq!(search_result.records[0].key, "002"); + + let search_result: TardisPage = client + .put( + "/ci/item/search", + &json!({ + "tag":"feed", + "ctx":{}, + "query":{ + "ext": [{ + "field":"null_field", + "op":"is_null", + "value":"" + }] + }, + "sort":[{"field":"key","order":"asc"}], + "page":{"number":1,"size":10,"fetch_total":true} + }), + ) + .await; + assert_eq!(search_result.total_size, 3); + + let search_result: TardisPage = client + .put( + "/ci/item/search", + &json!({ + "tag":"feed", + "ctx":{}, + "query":{ + "ext": [{ + "field":"empty_field", + "op":"is_null_or_empty", + "value":"" + }] + }, + "sort":[{"field":"key","order":"asc"}], + "page":{"number":1,"size":10,"fetch_total":true} + }), + ) + .await; + assert_eq!(search_result.total_size, 3); // Delete let search_result: TardisPage = client @@ -516,7 +601,6 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { ) .await; assert_eq!(search_result.total_size, 1); - client.delete(&format!("/ci/item/{}/{}", "feed", "001")).await; sleep(std::time::Duration::from_secs(1)).await; let search_result: TardisPage = client @@ -528,6 +612,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { "query":{ "keys": ["001"] }, + "sort":[{"field":"key","order":"asc"}], "page":{"number":1,"size":10,"fetch_total":true} }), ) diff --git a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs index f647112c3..d7965c56a 100644 --- a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs +++ b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs @@ -237,9 +237,9 @@ WHERE } /// Create dimension instance table. -/// +/// /// 创建维度实例表 -/// +/// /// The table name is `starsys_stats_inst_dim_` /// The table fields are: /// - key the incoming primary key value / 维度实例主键值 @@ -248,7 +248,7 @@ WHERE /// - [key0 .. keyN] when the hierarchy is greater than 0, it indicates the primary key value of each level, which is used for drilling up and down / 当层级大于0时,表示每个层级的主键值,用于上下钻 /// - ct create time / 创建时间 /// - et expiration time, when the data of a certain dimension is deleted, et will be set as the deletion time / 过期时间,当某个维度的数据被删除时,et会被设置为删除时间 -/// +/// /// # Examples /// ``` /// CREATE TABLE spi617070303031.starsys_stats_inst_dim_address ( diff --git a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs index 4bf23bc7f..46086c3ce 100644 --- a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs +++ b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs @@ -253,12 +253,7 @@ pub(crate) async fn delete( Ok(()) } -pub(crate) async fn find_by_fact_conf_key( - fact_conf_key: &str, - _funs: &TardisFunsInst, - ctx: &TardisContext, - inst: &SpiBsInst, -) -> TardisResult> { +pub(crate) async fn find_by_fact_conf_key(fact_conf_key: &str, _funs: &TardisFunsInst, ctx: &TardisContext, inst: &SpiBsInst) -> TardisResult> { let bs_inst = inst.inst::(); let (conn, _) = stats_pg_initializer::init_conf_fact_col_table_and_conn(bs_inst, ctx, true).await?; if !common_pg::check_table_exit("stats_conf_fact_col", &conn, ctx).await? { diff --git a/backend/supports/iam/src/console_app/api/iam_ca_role_api.rs b/backend/supports/iam/src/console_app/api/iam_ca_role_api.rs index 15b1adc2f..917fc421d 100644 --- a/backend/supports/iam/src/console_app/api/iam_ca_role_api.rs +++ b/backend/supports/iam/src/console_app/api/iam_ca_role_api.rs @@ -46,7 +46,7 @@ impl IamCaRoleApi { /// Modify Role By Role Id /// 根据角色ID修改角色 - /// + /// /// When code = 202, the return value is the asynchronous task id /// 当 code = 202 时,返回值为异步任务ID #[oai(path = "/:id", method = "put")] diff --git a/backend/supports/iam/src/console_interface/api/iam_ci_account_api.rs b/backend/supports/iam/src/console_interface/api/iam_ci_account_api.rs index 5dc266bb8..33616285a 100644 --- a/backend/supports/iam/src/console_interface/api/iam_ci_account_api.rs +++ b/backend/supports/iam/src/console_interface/api/iam_ci_account_api.rs @@ -137,7 +137,7 @@ impl IamCiAccountApi { TardisResp::ok(TardisFuns::crypto.base64.encode(TardisFuns::json.obj_to_string(&ctx_resp).unwrap_or_default())) } - /// Get Account By Account Id + /// Get Account By Account Id /// 通过帐户Id获取帐户 #[oai(path = "/:id", method = "get")] async fn get(&self, id: Path, tenant_id: Query>, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { diff --git a/backend/supports/iam/src/console_interface/api/iam_ci_cert_api.rs b/backend/supports/iam/src/console_interface/api/iam_ci_cert_api.rs index 0621e9752..c2297479e 100644 --- a/backend/supports/iam/src/console_interface/api/iam_ci_cert_api.rs +++ b/backend/supports/iam/src/console_interface/api/iam_ci_cert_api.rs @@ -117,9 +117,9 @@ impl IamCiCertApi { /// - `supplier` is only used when kind is `Ldap` /// - `ldap_origin` is only used when kind is `Ldap` and default is false. /// when true,return ak will be original DN - /// + /// /// 根据kind和supplier查询证书 - /// + /// /// 如果kind为空,查询默认kind(UserPwd) /// - `supplier`仅在kind为`Ldap`时使用 /// - `ldap_origin`仅在kind为`Ldap`时使用,默认为false diff --git a/backend/supports/iam/src/console_interface/api/iam_ci_open_api.rs b/backend/supports/iam/src/console_interface/api/iam_ci_open_api.rs index f6ecee567..a205c9263 100644 --- a/backend/supports/iam/src/console_interface/api/iam_ci_open_api.rs +++ b/backend/supports/iam/src/console_interface/api/iam_ci_open_api.rs @@ -20,7 +20,7 @@ pub struct IamCiOpenApi; /// 接口控制台管理开放API #[poem_openapi::OpenApi(prefix_path = "/ci/open", tag = "bios_basic::ApiTag::Interface")] impl IamCiOpenApi { - /// Add product + /// Add product /// 添加产品 #[oai(path = "/add_or_modify_product", method = "post")] async fn add_or_modify_product(&self, req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { @@ -34,7 +34,7 @@ impl IamCiOpenApi { TardisResp::ok(Void {}) } - /// Cert bind product_and_spec + /// Cert bind product_and_spec /// 凭证绑定产品和规格 #[oai(path = "/:id/bind_cert_product_and_spec", method = "post")] async fn bind_cert_product_and_spec( @@ -54,7 +54,7 @@ impl IamCiOpenApi { TardisResp::ok(Void {}) } - /// Add aksk Cert by open platform + /// Add aksk Cert by open platform /// 生成AKSK通过开放平台 #[oai(path = "/aksk", method = "post")] async fn add_aksk(&self, add_req: Json, mut ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { @@ -69,7 +69,7 @@ impl IamCiOpenApi { TardisResp::ok(result) } - /// Get account rule info + /// Get account rule info /// 获取账号规则信息 #[oai(path = "/", method = "get")] async fn get_rule_info(&self, cert_id: Query>, ak: Query>, _request: &Request) -> TardisApiResult { @@ -85,7 +85,7 @@ impl IamCiOpenApi { TardisResp::ok(result) } - /// Refresh cumulative number of api calls + /// Refresh cumulative number of api calls /// 刷新API累计调用数 (定时任务) #[oai(path = "/refresh_cert_cumulative_count", method = "post")] async fn refresh_cert_cumulative_count(&self, _request: &Request) -> TardisApiResult { diff --git a/backend/supports/iam/src/console_interface/api/iam_ci_tenant_api.rs b/backend/supports/iam/src/console_interface/api/iam_ci_tenant_api.rs index cdae69722..15f103036 100644 --- a/backend/supports/iam/src/console_interface/api/iam_ci_tenant_api.rs +++ b/backend/supports/iam/src/console_interface/api/iam_ci_tenant_api.rs @@ -46,9 +46,9 @@ impl IamCiTenantApi { /// /// * Without parameters: Query the whole tree /// * ``parent_sys_code=true`` : query only the next level. This can be used to query level by level when the tree is too large - /// + /// /// 通过当前租户查找组织树 - /// + /// /// * 无参数:查询整个树 /// * ``parent_sys_code=true``:仅查询下一级。当树太大时,可以逐级查询 #[oai(path = "/orgs", method = "get")] diff --git a/backend/supports/iam/src/console_passport/api/iam_cp_cert_api.rs b/backend/supports/iam/src/console_passport/api/iam_cp_cert_api.rs index 615110dc9..33b7cc686 100644 --- a/backend/supports/iam/src/console_passport/api/iam_cp_cert_api.rs +++ b/backend/supports/iam/src/console_passport/api/iam_cp_cert_api.rs @@ -54,11 +54,11 @@ impl IamCpCertApi { /// First access `PUT /cp/login/userpwd` api to get `token` . /// This api input `token` and return base64 encoded `tardis context` , /// set `tardis context` to the `Tardis-Context` request header. - /// + /// /// 获取TardisContext通过Token - /// + /// /// 该API仅用于测试! - /// + /// /// 首先访问 `PUT /cp/login/userpwd` api 获取 `token` 。 /// 该api输入 `token` 并返回base64编码的 `tardis context`, /// 将 `tardis context` 设置到请求头的 `Tardis-Context`。 @@ -413,9 +413,9 @@ impl IamCpCertLdapApi { /// if ak param is None then create new userpwd cert \ /// else bind with ldap cert /// name-password -ldap login - /// + /// /// 绑定用户名密码证书通过LDAP - /// + /// /// 如果ak参数为None,则创建新的用户密码证书 /// 否则与ldap证书绑定 /// 用户名-密码-ldap登录 diff --git a/backend/supports/iam/src/console_system/api/iam_cs_cert_api.rs b/backend/supports/iam/src/console_system/api/iam_cs_cert_api.rs index b55c4bdf8..d9ff3484d 100644 --- a/backend/supports/iam/src/console_system/api/iam_cs_cert_api.rs +++ b/backend/supports/iam/src/console_system/api/iam_cs_cert_api.rs @@ -220,7 +220,7 @@ impl IamCsCertConfigLdapApi { funs.commit().await?; TardisResp::ok(Void {}) } - + /// Get Ldap Cert Conf /// 获取LDAP证书配置 #[oai(path = "/", method = "get")] diff --git a/backend/supports/iam/src/console_system/api/iam_cs_org_api.rs b/backend/supports/iam/src/console_system/api/iam_cs_org_api.rs index 7c3fbbbde..60d236ad1 100644 --- a/backend/supports/iam/src/console_system/api/iam_cs_org_api.rs +++ b/backend/supports/iam/src/console_system/api/iam_cs_org_api.rs @@ -177,7 +177,6 @@ impl IamCsOrgApi { /// 系统控制台组织项API #[poem_openapi::OpenApi(prefix_path = "/cs/org/item", tag = "bios_basic::ApiTag::System")] impl IamCsOrgItemApi { - /// Batch Add Org Item /// 批量添加组织项 #[oai(path = "/batch", method = "put")] diff --git a/backend/supports/iam/src/console_tenant/api/iam_ct_app_set_api.rs b/backend/supports/iam/src/console_tenant/api/iam_ct_app_set_api.rs index d1c07af35..bcf21a2dc 100644 --- a/backend/supports/iam/src/console_tenant/api/iam_ct_app_set_api.rs +++ b/backend/supports/iam/src/console_tenant/api/iam_ct_app_set_api.rs @@ -60,7 +60,7 @@ impl IamCtAppSetApi { /// * ``only_related=true`` : Invalidate the parent_sys_code parameter when this parameter is turned on, it is used to query only the tree nodes with related resources(including children nodes) /// /// 根据当前租户查询应用树 - /// + /// /// * 无参数:查询整个树 /// * ``parent_sys_code=true``:查询下一级,当树太大时可以用来逐级查询 /// * ``only_related=true``:打开此参数时失效parent_sys_code参数,用来查询只有相关资源的树节点(包括子节点) diff --git a/backend/supports/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs b/backend/supports/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs index 23dd0eb8b..196ec849e 100644 --- a/backend/supports/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs +++ b/backend/supports/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs @@ -22,7 +22,6 @@ pub struct IamCtCertManageApi; /// 租户控制台证书管理API #[poem_openapi::OpenApi(prefix_path = "/ct/cert/manage", tag = "bios_basic::ApiTag::Tenant")] impl IamCtCertManageApi { - /// Add Manage Cert /// 添加凭证 #[oai(path = "/", method = "post")] diff --git a/backend/supports/iam/src/console_tenant/api/iam_ct_org_api.rs b/backend/supports/iam/src/console_tenant/api/iam_ct_org_api.rs index 459d34566..87918b898 100644 --- a/backend/supports/iam/src/console_tenant/api/iam_ct_org_api.rs +++ b/backend/supports/iam/src/console_tenant/api/iam_ct_org_api.rs @@ -72,9 +72,9 @@ impl IamCtOrgApi { /// /// * Without parameters: Query the whole tree /// * ``parent_sys_code=true`` : query only the next level. This can be used to query level by level when the tree is too large - /// + /// /// 根据当前租户查找组织树 - /// + /// /// * 无参数:查询整个树 /// * ``parent_sys_code=true``:仅查询下一级。当树太大时,可以逐级查询 #[oai(path = "/tree", method = "get")] diff --git a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_signature.rs b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_signature.rs index 55563c31c..058cea7d2 100644 --- a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_signature.rs +++ b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_signature.rs @@ -24,7 +24,6 @@ pub struct ReachMsgSignatureCtApi; #[cfg_attr(feature = "simple-client", bios_sdk_invoke::simple_invoke_client(Client<'_>))] #[poem_openapi::OpenApi(prefix_path = "/ct/msg/signature", tag = "bios_basic::ApiTag::Tenant")] impl ReachMsgSignatureCtApi { - /// Page find all user reach message signature data /// 获取所有用户触达消息签名模板数据分页 #[oai(method = "get", path = "/page")] diff --git a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_template.rs b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_template.rs index 3423b6cd1..2c06802c5 100644 --- a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_template.rs +++ b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_msg_template.rs @@ -24,7 +24,6 @@ pub struct ReachMessageTemplateCtApi; #[cfg_attr(feature = "simple-client", bios_sdk_invoke::simple_invoke_client(Client<'_>))] #[poem_openapi::OpenApi(prefix_path = "/ct/msg/template", tag = "bios_basic::ApiTag::Tenant")] impl ReachMessageTemplateCtApi { - /// Page find all user reach message message template data /// 获取所有用户触达消息消息模板数据分页 #[oai(method = "get", path = "/page")] diff --git a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_global.rs b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_global.rs index 7a1e7f04d..9b1e02763 100644 --- a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_global.rs +++ b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_global.rs @@ -21,7 +21,6 @@ pub struct ReachTriggerGlobalConfigCtApi; #[cfg_attr(feature = "simple-client", bios_sdk_invoke::simple_invoke_client(Client<'_>))] #[poem_openapi::OpenApi(prefix_path = "/ct/trigger/global/config", tag = "bios_basic::ApiTag::Tenant")] impl ReachTriggerGlobalConfigCtApi { - /// Find all user reach trigger global config data /// 获取所有用户触达触发全局配置数据 #[oai(method = "get", path = "/")] diff --git a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_instance.rs b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_instance.rs index 1e456c359..d40849515 100644 --- a/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_instance.rs +++ b/backend/supports/reach/src/api/reach_api_ct/reach_api_ct_trigger_instance.rs @@ -21,7 +21,6 @@ pub struct ReachTriggerInstanceConfigCtApi; #[cfg_attr(feature = "simple-client", bios_sdk_invoke::simple_invoke_client(Client<'_>))] #[poem_openapi::OpenApi(prefix_path = "/ct/trigger/instance/config", tag = "bios_basic::ApiTag::Tenant")] impl ReachTriggerInstanceConfigCtApi { - /// Find all user reach trigger instance config data /// 根据类型获取所有用户触达触发实例配置数据 #[oai(method = "get", path = "/")]