分页查询iscs发布数据接口调整
All checks were successful
build / build-rust (push) Successful in 3m20s

options查询调整
This commit is contained in:
soul-walker 2024-09-20 17:00:03 +08:00
parent 930dbda334
commit ef38fe0566
5 changed files with 71 additions and 42 deletions

View File

@ -2,12 +2,19 @@ use async_graphql::{InputObject, InputType, OutputType, SimpleObject};
use rtss_db::{common::TableColumn, model::DraftDataColumn}; use rtss_db::{common::TableColumn, model::DraftDataColumn};
use rtss_dto::common::IscsStyle; use rtss_dto::common::IscsStyle;
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::Value;
pub trait DataOptions: InputType + OutputType + Serialize + DeserializeOwned { pub trait DataOptions: InputType + OutputType + Serialize + DeserializeOwned {
fn to_data_options_filter_clause(&self) -> String; 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")] #[graphql(input_name = "IscsDataOptionsInput")]
pub struct IscsDataOptions { pub struct IscsDataOptions {
pub style: IscsStyle, pub style: IscsStyle,
@ -34,8 +41,12 @@ mod tests {
style: IscsStyle::DaShiZhiNeng, style: IscsStyle::DaShiZhiNeng,
}; };
let json = serde_json::to_string(&options).unwrap(); let json = serde_json::to_string(&options).unwrap();
let value = serde_json::to_value(options).unwrap();
println!("{}", json); println!("{}", json);
println!("{}", options.style.as_str_name()); println!(
"serialize value: {}",
serde_json::to_string(&value).unwrap()
);
assert_eq!(json, r#"{"style":"DaShiZhiNeng"}"#); assert_eq!(json, r#"{"style":"DaShiZhiNeng"}"#);
let options: IscsDataOptions = serde_json::from_str(&json).unwrap(); let options: IscsDataOptions = serde_json::from_str(&json).unwrap();
assert_eq!(options.style, IscsStyle::DaShiZhiNeng); assert_eq!(options.style, IscsStyle::DaShiZhiNeng);

View File

@ -203,7 +203,7 @@ impl<T: DataOptions> From<UserDraftDataFilterDto<T>> for rtss_db::DraftDataQuery
user_id: Some(value.user_id), user_id: Some(value.user_id),
name: value.name, name: value.name,
data_type: value.data_type, 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, is_shared: value.is_shared,
} }
} }
@ -228,7 +228,7 @@ impl<T: DataOptions> From<SharedDraftDataFilterDto<T>> for rtss_db::DraftDataQue
name: value.name, name: value.name,
data_type: value.data_type, data_type: value.data_type,
is_shared: Some(true), 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<T: DataOptions> From<SharedDraftDataFilterDto<T>> for rtss_db::DraftDataQue
pub struct DraftDataFilterDto { pub struct DraftDataFilterDto {
pub user_id: Option<i32>, pub user_id: Option<i32>,
pub name: Option<String>, pub name: Option<String>,
pub data_type: Option<rtss_dto::common::DataType>, pub data_type: Option<DataType>,
pub options: Option<Value>,
pub is_shared: Option<bool>, pub is_shared: Option<bool>,
} }
@ -249,7 +250,7 @@ impl From<DraftDataFilterDto> for rtss_db::DraftDataQuery {
name: value.name, name: value.name,
data_type: value.data_type, data_type: value.data_type,
is_shared: value.is_shared, is_shared: value.is_shared,
options_filter: None, options: value.options,
} }
} }
} }

View File

@ -29,7 +29,7 @@ impl ReleaseDataQuery {
&self, &self,
ctx: &Context<'_>, ctx: &Context<'_>,
page: PageQueryDto, page: PageQueryDto,
query: ReleaseDataFilterDto, query: ReleaseTypedDataFilterDto<Value>,
) -> async_graphql::Result<PageDto<ReleaseDataDto>> { ) -> async_graphql::Result<PageDto<ReleaseDataDto>> {
let db_accessor = ctx.data::<RtssDbAccessor>()?; let db_accessor = ctx.data::<RtssDbAccessor>()?;
let paging = db_accessor let paging = db_accessor
@ -38,12 +38,12 @@ impl ReleaseDataQuery {
Ok(paging.into()) Ok(paging.into())
} }
/// 分页查询用户发布的ISCS数据 /// 分页查询发布的ISCS数据
async fn user_release_iscs_data_paging( async fn release_iscs_data_paging(
&self, &self,
ctx: &Context<'_>, ctx: &Context<'_>,
page: PageQueryDto, page: PageQueryDto,
mut query: UserReleaseDataFilterDto<IscsDataOptions>, mut query: ReleaseTypedDataFilterDto<IscsDataOptions>,
) -> async_graphql::Result<PageDto<ReleaseIscsDataWithoutVersionDto>> { ) -> async_graphql::Result<PageDto<ReleaseIscsDataWithoutVersionDto>> {
let db_accessor = ctx.data::<RtssDbAccessor>()?; let db_accessor = ctx.data::<RtssDbAccessor>()?;
query.data_type = Some(DataType::Iscs); query.data_type = Some(DataType::Iscs);
@ -193,17 +193,10 @@ impl ReleaseDataMutation {
} }
#[derive(Debug, InputObject)] #[derive(Debug, InputObject)]
pub struct ReleaseDataFilterDto { #[graphql(concrete(name = "ReleaseDataFilterDto", params(Value)))]
pub name: Option<String>, #[graphql(concrete(name = "ReleaseIscsDataFilterDto", params(IscsDataOptions)))]
pub struct ReleaseTypedDataFilterDto<T: DataOptions> {
pub user_id: Option<i32>, pub user_id: Option<i32>,
pub data_type: Option<DataType>,
pub is_published: Option<bool>,
}
#[derive(Debug, InputObject)]
#[graphql(concrete(name = "UserReleaseIscsDataFilterDto", params(IscsDataOptions)))]
pub struct UserReleaseDataFilterDto<T: DataOptions> {
pub user_id: i32,
pub name: Option<String>, pub name: Option<String>,
/// 数据类型,在某个具体类型查询时不传,传了也不生效 /// 数据类型,在某个具体类型查询时不传,传了也不生效
pub data_type: Option<DataType>, pub data_type: Option<DataType>,
@ -211,23 +204,13 @@ pub struct UserReleaseDataFilterDto<T: DataOptions> {
pub is_published: Option<bool>, pub is_published: Option<bool>,
} }
impl<T: DataOptions> From<UserReleaseDataFilterDto<T>> for rtss_db::ReleaseDataQuery { impl<T: DataOptions> From<ReleaseTypedDataFilterDto<T>> for rtss_db::ReleaseDataQuery {
fn from(value: UserReleaseDataFilterDto<T>) -> Self { fn from(value: ReleaseTypedDataFilterDto<T>) -> Self {
Self {
name: value.name,
user_id: Some(value.user_id),
data_type: value.data_type,
is_published: value.is_published,
}
}
}
impl From<ReleaseDataFilterDto> for rtss_db::ReleaseDataQuery {
fn from(value: ReleaseDataFilterDto) -> Self {
Self { Self {
name: value.name, name: value.name,
user_id: value.user_id, user_id: value.user_id,
data_type: value.data_type, data_type: value.data_type,
options: value.options.map(|o| serde_json::to_value(o).unwrap()),
is_published: value.is_published, is_published: value.is_published,
} }
} }

View File

@ -70,8 +70,7 @@ pub struct DraftDataQuery {
pub user_id: Option<i32>, pub user_id: Option<i32>,
pub name: Option<String>, pub name: Option<String>,
pub data_type: Option<DataType>, pub data_type: Option<DataType>,
/// 选项过滤条件,由业务层构建并确保合法性 pub options: Option<Value>,
pub options_filter: Option<String>,
pub is_shared: Option<bool>, pub is_shared: Option<bool>,
} }
@ -100,8 +99,13 @@ impl DraftDataQuery {
self self
} }
pub fn with_options_filter(mut self, options_filter: &str) -> Self { pub fn with_option_options(mut self, options: Option<Value>) -> Self {
self.options_filter = Some(options_filter.to_string()); self.options = options;
self
}
pub fn with_options(mut self, options: Value) -> Self {
self.options = Some(options);
self self
} }
@ -131,8 +135,12 @@ impl DraftDataQuery {
is_shared is_shared
)); ));
} }
if let Some(options_filter) = &self.options_filter { if let Some(options) = &self.options {
filters.push(options_filter.clone()); filters.push(format!(
"{} @> '{}'",
DraftDataColumn::Options.name(),
serde_json::to_string(options).unwrap()
));
} }
if filters.is_empty() { if filters.is_empty() {
"".to_string() "".to_string()
@ -568,8 +576,12 @@ mod tests {
// 查询options // 查询options
let page = accessor let page = accessor
.query_draft_data( .query_draft_data(
DraftDataQuery::new() DraftDataQuery::new().with_options(
.with_options_filter(r#"options @> '{"style":"DaShiZhiNeng"}'"#), serde_json::to_value(IscsDataOptions {
style: IscsStyle::DaShiZhiNeng,
})
.unwrap(),
),
PageQuery::new(1, 10), PageQuery::new(1, 10),
) )
.await?; .await?;

View File

@ -1,4 +1,5 @@
use rtss_dto::common::DataType; use rtss_dto::common::DataType;
use serde_json::Value;
use sqlx::{types::chrono, Postgres}; use sqlx::{types::chrono, Postgres};
use crate::{ use crate::{
@ -102,6 +103,7 @@ pub struct ReleaseDataQuery {
pub name: Option<String>, pub name: Option<String>,
pub user_id: Option<i32>, pub user_id: Option<i32>,
pub data_type: Option<rtss_dto::common::DataType>, pub data_type: Option<rtss_dto::common::DataType>,
pub options: Option<Value>,
pub is_published: Option<bool>, pub is_published: Option<bool>,
} }
@ -117,6 +119,7 @@ impl ReleaseDataQuery {
name: None, name: None,
user_id: None, user_id: None,
data_type: None, data_type: None,
options: None,
is_published: None, is_published: None,
} }
} }
@ -136,6 +139,16 @@ impl ReleaseDataQuery {
self self
} }
pub fn with_option_options(mut self, options: Option<Value>) -> 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 { pub fn with_is_published(mut self, is_published: bool) -> Self {
self.is_published = Some(is_published); self.is_published = Some(is_published);
self self
@ -156,6 +169,13 @@ impl ReleaseDataQuery {
if let Some(data_type) = self.data_type { if let Some(data_type) = self.data_type {
filters.push(format!("{rd_data_type} = {}", data_type as i32)); 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 { if let Some(is_published) = self.is_published {
filters.push(format!("{rd_is_published} = {is_published}")); filters.push(format!("{rd_is_published} = {is_published}"));
} }
@ -409,11 +429,13 @@ impl ReleaseDataAccessor for RtssDbAccessor {
) -> Result<PageResult<ReleaseDataVersionModel>, DbAccessError> { ) -> Result<PageResult<ReleaseDataVersionModel>, DbAccessError> {
// 查询发布数据版本 // 查询发布数据版本
let rdv_table = ReleaseDataVersionColumn::Table.name(); let rdv_table = ReleaseDataVersionColumn::Table.name();
let rdv_release_id = ReleaseDataVersionColumn::ReleaseDataId.name();
// let where_clause = query.build_filter(); // 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) let total = sqlx::query_scalar(&count_clause)
.bind(release_id)
.fetch_one(&self.pool) .fetch_one(&self.pool)
.await?; .await?;
if total == 0 { if total == 0 {