diff --git a/crates/rtss_api/src/apis/common.rs b/crates/rtss_api/src/apis/common.rs index e73c570..c59a857 100644 --- a/crates/rtss_api/src/apis/common.rs +++ b/crates/rtss_api/src/apis/common.rs @@ -2,12 +2,19 @@ use async_graphql::{InputObject, InputType, OutputType, SimpleObject}; use rtss_db::{common::TableColumn, model::DraftDataColumn}; use rtss_dto::common::IscsStyle; use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde_json::Value; pub trait DataOptions: InputType + OutputType + Serialize + DeserializeOwned { fn to_data_options_filter_clause(&self) -> String; } -#[derive(Debug, InputObject, SimpleObject, Serialize, Deserialize)] +impl DataOptions for Value { + fn to_data_options_filter_clause(&self) -> String { + format!("options @> '{}'", self) + } +} + +#[derive(Debug, Clone, Copy, InputObject, SimpleObject, Serialize, Deserialize)] #[graphql(input_name = "IscsDataOptionsInput")] pub struct IscsDataOptions { pub style: IscsStyle, @@ -34,8 +41,12 @@ mod tests { style: IscsStyle::DaShiZhiNeng, }; let json = serde_json::to_string(&options).unwrap(); + let value = serde_json::to_value(options).unwrap(); println!("{}", json); - println!("{}", options.style.as_str_name()); + println!( + "serialize value: {}", + serde_json::to_string(&value).unwrap() + ); assert_eq!(json, r#"{"style":"DaShiZhiNeng"}"#); let options: IscsDataOptions = serde_json::from_str(&json).unwrap(); assert_eq!(options.style, IscsStyle::DaShiZhiNeng); diff --git a/crates/rtss_api/src/apis/draft_data.rs b/crates/rtss_api/src/apis/draft_data.rs index 11092e7..6285fd9 100644 --- a/crates/rtss_api/src/apis/draft_data.rs +++ b/crates/rtss_api/src/apis/draft_data.rs @@ -203,7 +203,7 @@ impl From> for rtss_db::DraftDataQuery user_id: Some(value.user_id), name: value.name, data_type: value.data_type, - options_filter: value.options.map(|o| o.to_data_options_filter_clause()), + options: value.options.map(|o| serde_json::to_value(o).unwrap()), is_shared: value.is_shared, } } @@ -228,7 +228,7 @@ impl From> for rtss_db::DraftDataQue name: value.name, data_type: value.data_type, is_shared: Some(true), - options_filter: value.options.map(|o| o.to_data_options_filter_clause()), + options: value.options.map(|o| serde_json::to_value(o).unwrap()), } } } @@ -238,7 +238,8 @@ impl From> for rtss_db::DraftDataQue pub struct DraftDataFilterDto { pub user_id: Option, pub name: Option, - pub data_type: Option, + pub data_type: Option, + pub options: Option, pub is_shared: Option, } @@ -249,7 +250,7 @@ impl From for rtss_db::DraftDataQuery { name: value.name, data_type: value.data_type, is_shared: value.is_shared, - options_filter: None, + options: value.options, } } } diff --git a/crates/rtss_api/src/apis/release_data.rs b/crates/rtss_api/src/apis/release_data.rs index ee683c2..fba7c68 100644 --- a/crates/rtss_api/src/apis/release_data.rs +++ b/crates/rtss_api/src/apis/release_data.rs @@ -29,7 +29,7 @@ impl ReleaseDataQuery { &self, ctx: &Context<'_>, page: PageQueryDto, - query: ReleaseDataFilterDto, + query: ReleaseTypedDataFilterDto, ) -> async_graphql::Result> { let db_accessor = ctx.data::()?; let paging = db_accessor @@ -38,12 +38,12 @@ impl ReleaseDataQuery { Ok(paging.into()) } - /// 分页查询用户发布的ISCS数据 - async fn user_release_iscs_data_paging( + /// 分页查询发布的ISCS数据 + async fn release_iscs_data_paging( &self, ctx: &Context<'_>, page: PageQueryDto, - mut query: UserReleaseDataFilterDto, + mut query: ReleaseTypedDataFilterDto, ) -> async_graphql::Result> { let db_accessor = ctx.data::()?; query.data_type = Some(DataType::Iscs); @@ -193,17 +193,10 @@ impl ReleaseDataMutation { } #[derive(Debug, InputObject)] -pub struct ReleaseDataFilterDto { - pub name: Option, +#[graphql(concrete(name = "ReleaseDataFilterDto", params(Value)))] +#[graphql(concrete(name = "ReleaseIscsDataFilterDto", params(IscsDataOptions)))] +pub struct ReleaseTypedDataFilterDto { pub user_id: Option, - pub data_type: Option, - pub is_published: Option, -} - -#[derive(Debug, InputObject)] -#[graphql(concrete(name = "UserReleaseIscsDataFilterDto", params(IscsDataOptions)))] -pub struct UserReleaseDataFilterDto { - pub user_id: i32, pub name: Option, /// 数据类型,在某个具体类型查询时不传,传了也不生效 pub data_type: Option, @@ -211,23 +204,13 @@ pub struct UserReleaseDataFilterDto { pub is_published: Option, } -impl From> for rtss_db::ReleaseDataQuery { - fn from(value: UserReleaseDataFilterDto) -> Self { - Self { - name: value.name, - user_id: Some(value.user_id), - data_type: value.data_type, - is_published: value.is_published, - } - } -} - -impl From for rtss_db::ReleaseDataQuery { - fn from(value: ReleaseDataFilterDto) -> Self { +impl From> for rtss_db::ReleaseDataQuery { + fn from(value: ReleaseTypedDataFilterDto) -> Self { Self { name: value.name, user_id: value.user_id, data_type: value.data_type, + options: value.options.map(|o| serde_json::to_value(o).unwrap()), is_published: value.is_published, } } diff --git a/crates/rtss_db/src/db_access/draft_data.rs b/crates/rtss_db/src/db_access/draft_data.rs index b168e80..c060877 100644 --- a/crates/rtss_db/src/db_access/draft_data.rs +++ b/crates/rtss_db/src/db_access/draft_data.rs @@ -70,8 +70,7 @@ pub struct DraftDataQuery { pub user_id: Option, pub name: Option, pub data_type: Option, - /// 选项过滤条件,由业务层构建并确保合法性 - pub options_filter: Option, + pub options: Option, pub is_shared: Option, } @@ -100,8 +99,13 @@ impl DraftDataQuery { self } - pub fn with_options_filter(mut self, options_filter: &str) -> Self { - self.options_filter = Some(options_filter.to_string()); + pub fn with_option_options(mut self, options: Option) -> Self { + self.options = options; + self + } + + pub fn with_options(mut self, options: Value) -> Self { + self.options = Some(options); self } @@ -131,8 +135,12 @@ impl DraftDataQuery { is_shared )); } - if let Some(options_filter) = &self.options_filter { - filters.push(options_filter.clone()); + if let Some(options) = &self.options { + filters.push(format!( + "{} @> '{}'", + DraftDataColumn::Options.name(), + serde_json::to_string(options).unwrap() + )); } if filters.is_empty() { "".to_string() @@ -568,8 +576,12 @@ mod tests { // 查询options let page = accessor .query_draft_data( - DraftDataQuery::new() - .with_options_filter(r#"options @> '{"style":"DaShiZhiNeng"}'"#), + DraftDataQuery::new().with_options( + serde_json::to_value(IscsDataOptions { + style: IscsStyle::DaShiZhiNeng, + }) + .unwrap(), + ), PageQuery::new(1, 10), ) .await?; diff --git a/crates/rtss_db/src/db_access/release_data.rs b/crates/rtss_db/src/db_access/release_data.rs index 2a5895a..329ecc4 100644 --- a/crates/rtss_db/src/db_access/release_data.rs +++ b/crates/rtss_db/src/db_access/release_data.rs @@ -1,4 +1,5 @@ use rtss_dto::common::DataType; +use serde_json::Value; use sqlx::{types::chrono, Postgres}; use crate::{ @@ -102,6 +103,7 @@ pub struct ReleaseDataQuery { pub name: Option, pub user_id: Option, pub data_type: Option, + pub options: Option, pub is_published: Option, } @@ -117,6 +119,7 @@ impl ReleaseDataQuery { name: None, user_id: None, data_type: None, + options: None, is_published: None, } } @@ -136,6 +139,16 @@ impl ReleaseDataQuery { self } + pub fn with_option_options(mut self, options: Option) -> Self { + self.options = options; + self + } + + pub fn with_options(mut self, options: Value) -> Self { + self.options = Some(options); + self + } + pub fn with_is_published(mut self, is_published: bool) -> Self { self.is_published = Some(is_published); self @@ -156,6 +169,13 @@ impl ReleaseDataQuery { if let Some(data_type) = self.data_type { filters.push(format!("{rd_data_type} = {}", data_type as i32)); } + if let Some(options) = &self.options { + let options_column = ReleaseDataColumn::Options.name(); + filters.push(format!( + "{options_column} @> '{}'", + serde_json::to_string(options).unwrap() + )); + } if let Some(is_published) = self.is_published { filters.push(format!("{rd_is_published} = {is_published}")); } @@ -409,11 +429,13 @@ impl ReleaseDataAccessor for RtssDbAccessor { ) -> Result, DbAccessError> { // 查询发布数据版本 let rdv_table = ReleaseDataVersionColumn::Table.name(); + let rdv_release_id = ReleaseDataVersionColumn::ReleaseDataId.name(); // let where_clause = query.build_filter(); - let count_clause = format!("SELECT COUNT(*) FROM {rdv_table}"); + let count_clause = format!("SELECT COUNT(*) FROM {rdv_table} WHERE {rdv_release_id} = $1",); // 查询总数 let total = sqlx::query_scalar(&count_clause) + .bind(release_id) .fetch_one(&self.pool) .await?; if total == 0 {