实现配置项相关的CRUD 调整草稿数据管理接口
This commit is contained in:
parent
875788a71d
commit
2a7a2ffc99
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -11,6 +11,7 @@
|
||||
"Joylink",
|
||||
"jsonwebtoken",
|
||||
"mplj",
|
||||
"Neng",
|
||||
"plpgsql",
|
||||
"prost",
|
||||
"proto",
|
||||
|
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2199,6 +2199,8 @@ dependencies = [
|
||||
"anyhow",
|
||||
"rtss_dto",
|
||||
"rtss_log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"thiserror",
|
||||
]
|
||||
@ -2210,6 +2212,7 @@ dependencies = [
|
||||
"async-graphql",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"serde",
|
||||
"sqlx",
|
||||
]
|
||||
|
||||
|
@ -23,6 +23,7 @@ sqlx = { version = "0.8", features = [
|
||||
"chrono",
|
||||
] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.125"
|
||||
anyhow = "1.0"
|
||||
|
||||
[dependencies]
|
||||
|
@ -6,8 +6,8 @@ edition = "2021"
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
|
||||
serde = { version = "1.0.208", features = ["derive"] }
|
||||
serde_json = "1.0.125"
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
axum = "0.7.5"
|
||||
axum-extra = { version = "0.9.3", features = ["typed-header"] }
|
||||
|
@ -1,8 +1,13 @@
|
||||
use async_graphql::{Context, InputObject, Object, SimpleObject};
|
||||
use async_graphql::{InputType, OutputType};
|
||||
use chrono::{DateTime, Local};
|
||||
use rtss_db::common::TableColumn;
|
||||
use rtss_db::model::DraftDataColumn;
|
||||
use rtss_db::DraftDataAccessor;
|
||||
use rtss_db::RtssDbAccessor;
|
||||
use rtss_dto::common::DataType;
|
||||
use rtss_dto::common::{DataType, IscsStyle};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::pagination::PageQueryDto;
|
||||
|
||||
@ -28,12 +33,12 @@ impl DraftDataQuery {
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询用户的草稿数据
|
||||
async fn user_draft_data_paging<'ctx>(
|
||||
async fn user_draft_iscs_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
paging: PageQueryDto,
|
||||
query: UserDraftDataFilterDto,
|
||||
) -> async_graphql::Result<DraftDataPage> {
|
||||
query: UserDraftDataFilterDto<IscsDataOptions>,
|
||||
) -> async_graphql::Result<DraftIscsDataPage> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let paging_result = db_accessor
|
||||
.query_draft_data(query.into(), paging.into())
|
||||
@ -41,12 +46,12 @@ impl DraftDataQuery {
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询共享的草稿数据
|
||||
async fn shared_draft_data_paging<'ctx>(
|
||||
async fn shared_draft_iscs_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
paging: PageQueryDto,
|
||||
query: SharedDraftDataFilterDto,
|
||||
) -> async_graphql::Result<DraftDataPage> {
|
||||
query: SharedDraftDataFilterDto<IscsDataOptions>,
|
||||
) -> async_graphql::Result<DraftIscsDataPage> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let paging_result = db_accessor
|
||||
.query_draft_data(query.into(), paging.into())
|
||||
@ -54,7 +59,11 @@ impl DraftDataQuery {
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 根据id获取草稿数据
|
||||
async fn draft_data(&self, ctx: &Context<'_>, id: i32) -> async_graphql::Result<DraftData> {
|
||||
async fn draft_data(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
id: i32,
|
||||
) -> async_graphql::Result<DraftDataWithStringOptions> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor.query_draft_data_by_id(id).await?;
|
||||
Ok(draft_data.into())
|
||||
@ -74,12 +83,12 @@ impl DraftDataQuery {
|
||||
|
||||
#[Object]
|
||||
impl DraftDataMutation {
|
||||
/// 创建草稿数据
|
||||
async fn create_draft_data(
|
||||
/// 创建草稿ISCS数据
|
||||
async fn create_draft_iscs_data(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
input: CreateDraftDataDto,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
input: CreateDraftDataDto<IscsDataOptions>,
|
||||
) -> async_graphql::Result<DraftData<IscsDataOptions>> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor.create_draft_data(input.into()).await?;
|
||||
Ok(draft_data.into())
|
||||
@ -90,7 +99,7 @@ impl DraftDataMutation {
|
||||
ctx: &Context<'_>,
|
||||
id: i32,
|
||||
name: String,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
) -> async_graphql::Result<DraftDataWithStringOptions> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor.update_draft_data_name(id, &name).await?;
|
||||
Ok(draft_data.into())
|
||||
@ -101,7 +110,7 @@ impl DraftDataMutation {
|
||||
ctx: &Context<'_>,
|
||||
id: i32,
|
||||
data: Vec<u8>,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
) -> async_graphql::Result<DraftDataWithStringOptions> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor
|
||||
.update_draft_data_data(id, data.as_slice())
|
||||
@ -114,7 +123,7 @@ impl DraftDataMutation {
|
||||
ctx: &Context<'_>,
|
||||
id: i32,
|
||||
is_shared: bool,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
) -> async_graphql::Result<DraftDataWithStringOptions> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor.set_draft_data_shared(id, is_shared).await?;
|
||||
Ok(draft_data.into())
|
||||
@ -135,7 +144,7 @@ impl DraftDataMutation {
|
||||
ctx: &Context<'_>,
|
||||
id: i32,
|
||||
release_data_id: i32,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
) -> async_graphql::Result<DraftDataWithStringOptions> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor
|
||||
.set_default_release_data_id(id, release_data_id)
|
||||
@ -149,7 +158,7 @@ impl DraftDataMutation {
|
||||
id: i32,
|
||||
name: String,
|
||||
user_id: i32,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
) -> async_graphql::Result<DraftDataWithStringOptions> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor.save_as_new_draft(id, &name, user_id).await?;
|
||||
Ok(draft_data.into())
|
||||
@ -157,54 +166,87 @@ impl DraftDataMutation {
|
||||
}
|
||||
|
||||
#[derive(Debug, InputObject)]
|
||||
pub struct CreateDraftDataDto {
|
||||
#[graphql(concrete(name = "CreateDraftIscsDto", params(IscsDataOptions)))]
|
||||
pub struct CreateDraftDataDto<T: DataOptions> {
|
||||
pub name: String,
|
||||
pub data_type: rtss_dto::common::DataType,
|
||||
pub data: Vec<u8>,
|
||||
pub options: Option<T>,
|
||||
pub user_id: i32,
|
||||
}
|
||||
|
||||
impl From<CreateDraftDataDto> for rtss_db::CreateDraftData {
|
||||
fn from(value: CreateDraftDataDto) -> Self {
|
||||
Self::new(&value.name, value.data_type, value.user_id).with_data(value.data.as_slice())
|
||||
impl<T: DataOptions> From<CreateDraftDataDto<T>> for rtss_db::CreateDraftData {
|
||||
fn from(value: CreateDraftDataDto<T>) -> Self {
|
||||
let cdd = Self::new(&value.name, DataType::Iscs, value.user_id);
|
||||
if value.options.is_some() {
|
||||
cdd.with_options(serde_json::to_value(value.options).unwrap())
|
||||
} else {
|
||||
cdd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 用户的草稿数据查询条件
|
||||
#[derive(Debug, InputObject)]
|
||||
pub struct UserDraftDataFilterDto {
|
||||
#[graphql(concrete(name = "UserDraftIscsDataFilterDto", params(IscsDataOptions)))]
|
||||
pub struct UserDraftDataFilterDto<T: DataOptions> {
|
||||
pub user_id: i32,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<rtss_dto::common::DataType>,
|
||||
pub options: Option<T>,
|
||||
pub is_shared: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<UserDraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
fn from(value: UserDraftDataFilterDto) -> Self {
|
||||
impl<T: DataOptions> From<UserDraftDataFilterDto<T>> for rtss_db::DraftDataQuery {
|
||||
fn from(value: UserDraftDataFilterDto<T>) -> Self {
|
||||
Self {
|
||||
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()),
|
||||
is_shared: value.is_shared,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DataOptions: InputType + OutputType + Serialize + DeserializeOwned {
|
||||
fn to_data_options_filter_clause(&self) -> String;
|
||||
}
|
||||
|
||||
#[derive(Debug, InputObject, SimpleObject, Serialize, Deserialize)]
|
||||
#[graphql(input_name = "IscsDataOptionsInput")]
|
||||
pub struct IscsDataOptions {
|
||||
pub style: IscsStyle,
|
||||
}
|
||||
|
||||
impl DataOptions for IscsDataOptions {
|
||||
fn to_data_options_filter_clause(&self) -> String {
|
||||
let options_column = DraftDataColumn::Options.name();
|
||||
// format!("{options_column}['style'] = '\"{}\"'", self.style.as_str_name())
|
||||
format!(
|
||||
"{options_column} @> '{}'",
|
||||
serde_json::to_string(self).unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享的草稿数据查询条件
|
||||
#[derive(Debug, InputObject)]
|
||||
pub struct SharedDraftDataFilterDto {
|
||||
#[graphql(concrete(name = "SharedDraftIscsDataFilterDto", params(IscsDataOptions)))]
|
||||
|
||||
pub struct SharedDraftDataFilterDto<T: DataOptions> {
|
||||
pub user_id: Option<i32>,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<rtss_dto::common::DataType>,
|
||||
pub options: Option<T>,
|
||||
}
|
||||
|
||||
impl From<SharedDraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
fn from(value: SharedDraftDataFilterDto) -> Self {
|
||||
impl<T: DataOptions> From<SharedDraftDataFilterDto<T>> for rtss_db::DraftDataQuery {
|
||||
fn from(value: SharedDraftDataFilterDto<T>) -> Self {
|
||||
Self {
|
||||
user_id: value.user_id,
|
||||
name: value.name,
|
||||
data_type: value.data_type,
|
||||
is_shared: Some(true),
|
||||
options_filter: value.options.map(|o| o.to_data_options_filter_clause()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,15 +267,17 @@ impl From<DraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
name: value.name,
|
||||
data_type: value.data_type,
|
||||
is_shared: value.is_shared,
|
||||
options_filter: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, SimpleObject)]
|
||||
pub struct DraftData {
|
||||
pub struct DraftDataWithStringOptions {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub data_type: rtss_dto::common::DataType,
|
||||
pub options: Option<String>,
|
||||
pub data: Option<Vec<u8>>,
|
||||
pub user_id: i32,
|
||||
pub is_shared: bool,
|
||||
@ -241,12 +285,43 @@ pub struct DraftData {
|
||||
pub updated_at: DateTime<Local>,
|
||||
}
|
||||
|
||||
impl From<rtss_db::model::DraftDataModel> for DraftData {
|
||||
impl From<rtss_db::model::DraftDataModel> for DraftDataWithStringOptions {
|
||||
fn from(value: rtss_db::model::DraftDataModel) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
data_type: DataType::try_from(value.data_type).unwrap(),
|
||||
options: value.options.map(|o| serde_json::to_string(&o).unwrap()),
|
||||
data: value.data,
|
||||
user_id: value.user_id,
|
||||
is_shared: value.is_shared,
|
||||
created_at: value.created_at,
|
||||
updated_at: value.updated_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, SimpleObject)]
|
||||
#[graphql(concrete(name = "DraftIscsData", params(IscsDataOptions)))]
|
||||
pub struct DraftData<T: OutputType> {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub data_type: rtss_dto::common::DataType,
|
||||
pub options: Option<T>,
|
||||
pub data: Option<Vec<u8>>,
|
||||
pub user_id: i32,
|
||||
pub is_shared: bool,
|
||||
pub created_at: DateTime<Local>,
|
||||
pub updated_at: DateTime<Local>,
|
||||
}
|
||||
|
||||
impl<T: DataOptions> From<rtss_db::model::DraftDataModel> for DraftData<T> {
|
||||
fn from(value: rtss_db::model::DraftDataModel) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
data_type: DataType::try_from(value.data_type).unwrap(),
|
||||
options: value.options.map(|o| serde_json::from_value(o).unwrap()),
|
||||
data: value.data,
|
||||
user_id: value.user_id,
|
||||
is_shared: value.is_shared,
|
||||
@ -259,7 +334,7 @@ impl From<rtss_db::model::DraftDataModel> for DraftData {
|
||||
#[derive(Debug, SimpleObject)]
|
||||
pub struct DraftDataPage {
|
||||
pub total: i64,
|
||||
pub data: Vec<DraftData>,
|
||||
pub data: Vec<DraftDataWithStringOptions>,
|
||||
}
|
||||
|
||||
impl From<rtss_db::common::PageResult<rtss_db::model::DraftDataModel>> for DraftDataPage {
|
||||
@ -270,3 +345,47 @@ impl From<rtss_db::common::PageResult<rtss_db::model::DraftDataModel>> for Draft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, SimpleObject)]
|
||||
pub struct DraftIscsDataPage {
|
||||
pub total: i64,
|
||||
pub data: Vec<DraftData<IscsDataOptions>>,
|
||||
}
|
||||
|
||||
impl From<rtss_db::common::PageResult<rtss_db::model::DraftDataModel>> for DraftIscsDataPage {
|
||||
fn from(value: rtss_db::common::PageResult<rtss_db::model::DraftDataModel>) -> Self {
|
||||
Self {
|
||||
total: value.total,
|
||||
data: value.data.into_iter().map(|m| m.into()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_iscs_data_options_serialize() {
|
||||
rtss_log::Logging::default().init();
|
||||
let options = IscsDataOptions {
|
||||
style: IscsStyle::DaShiZhiNeng,
|
||||
};
|
||||
let json = serde_json::to_string(&options).unwrap();
|
||||
println!("{}", json);
|
||||
println!("{}", options.style.as_str_name());
|
||||
assert_eq!(json, r#"{"style":"DaShiZhiNeng"}"#);
|
||||
let options: IscsDataOptions = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(options.style, IscsStyle::DaShiZhiNeng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iscs_data_options_into_data_options_filter_clause() {
|
||||
let options = IscsDataOptions {
|
||||
style: IscsStyle::DaShiZhiNeng,
|
||||
};
|
||||
let clause = options.to_data_options_filter_clause();
|
||||
println!("{clause}");
|
||||
assert_eq!(clause, r#"options @> '{"style":"DaShiZhiNeng"}'"#);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
sqlx = { workspace = true, features = [
|
||||
"runtime-tokio",
|
||||
"macros",
|
||||
|
@ -2,6 +2,7 @@ use std::vec;
|
||||
|
||||
use rtss_dto::common::DataType;
|
||||
use rtss_log::tracing::debug;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
common::{PageQuery, PageResult, Sort, SortOrder, TableColumn},
|
||||
@ -69,6 +70,8 @@ pub struct DraftDataQuery {
|
||||
pub user_id: Option<i32>,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<DataType>,
|
||||
/// 选项过滤条件,由业务层构建并确保合法性
|
||||
pub options_filter: Option<String>,
|
||||
pub is_shared: Option<bool>,
|
||||
}
|
||||
|
||||
@ -97,6 +100,11 @@ impl DraftDataQuery {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_options_filter(mut self, options_filter: &str) -> Self {
|
||||
self.options_filter = Some(options_filter.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
fn build_filter(&self) -> String {
|
||||
let mut filters = vec![];
|
||||
if let Some(user_id) = self.user_id {
|
||||
@ -123,6 +131,9 @@ impl DraftDataQuery {
|
||||
is_shared
|
||||
));
|
||||
}
|
||||
if let Some(options_filter) = &self.options_filter {
|
||||
filters.push(options_filter.clone());
|
||||
}
|
||||
if filters.is_empty() {
|
||||
"".to_string()
|
||||
} else {
|
||||
@ -134,6 +145,7 @@ impl DraftDataQuery {
|
||||
pub struct CreateDraftData {
|
||||
name: String,
|
||||
data_type: DataType,
|
||||
options: Option<Value>,
|
||||
data: Option<Vec<u8>>,
|
||||
default_release_data_id: Option<i32>,
|
||||
user_id: i32,
|
||||
@ -144,12 +156,18 @@ impl CreateDraftData {
|
||||
CreateDraftData {
|
||||
name: name.to_string(),
|
||||
data_type,
|
||||
options: None,
|
||||
data: None,
|
||||
default_release_data_id: None,
|
||||
user_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_options(mut self, options: Value) -> Self {
|
||||
self.options = Some(options);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_data(mut self, data: &[u8]) -> Self {
|
||||
self.data = Some(data.to_vec());
|
||||
self
|
||||
@ -240,21 +258,23 @@ impl DraftDataAccessor for RtssDbAccessor {
|
||||
// 插入数据
|
||||
let table = DraftDataColumn::Table.name();
|
||||
let columns = format!(
|
||||
"{}, {}, {}, {}, {}",
|
||||
"{}, {}, {}, {}, {}, {}",
|
||||
DraftDataColumn::Name.name(),
|
||||
DraftDataColumn::DataType.name(),
|
||||
DraftDataColumn::Options.name(),
|
||||
DraftDataColumn::UserId.name(),
|
||||
DraftDataColumn::Data.name(),
|
||||
DraftDataColumn::DefaultReleaseDataId.name(),
|
||||
);
|
||||
let sql =
|
||||
format!("INSERT INTO {table} ({columns}) VALUES ($1, $2, $3, $4, $5) RETURNING *",);
|
||||
format!("INSERT INTO {table} ({columns}) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *",);
|
||||
// log sql
|
||||
debug!("create sql: {}", sql);
|
||||
// 插入数据
|
||||
let draft_data: DraftDataModel = sqlx::query_as(&sql)
|
||||
.bind(create.name)
|
||||
.bind(create.data_type as i32)
|
||||
.bind(create.options)
|
||||
.bind(create.user_id)
|
||||
.bind(create.data)
|
||||
.bind(create.default_release_data_id)
|
||||
@ -380,9 +400,16 @@ impl DraftDataAccessor for RtssDbAccessor {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rtss_dto::common::IscsStyle;
|
||||
use rtss_log::tracing::Level;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct IscsDataOptions {
|
||||
pub style: IscsStyle,
|
||||
}
|
||||
|
||||
// You could also do `use foo_crate::MIGRATOR` and just refer to it as `MIGRATOR` here.
|
||||
#[sqlx::test(migrator = "crate::MIGRATOR")]
|
||||
async fn basic_use_test(pool: PgPool) -> Result<(), DbAccessError> {
|
||||
@ -455,15 +482,7 @@ mod tests {
|
||||
|
||||
// 查询确认当前数据已删除
|
||||
let page = accessor
|
||||
.query_draft_data(
|
||||
DraftDataQuery {
|
||||
user_id: None,
|
||||
name: None,
|
||||
data_type: None,
|
||||
is_shared: None,
|
||||
},
|
||||
PageQuery::new(1, 100),
|
||||
)
|
||||
.query_draft_data(DraftDataQuery::new(), PageQuery::new(1, 100))
|
||||
.await?;
|
||||
assert_eq!(page.total, 0);
|
||||
|
||||
@ -471,11 +490,28 @@ mod tests {
|
||||
// 分四个user_id各插入5条数据
|
||||
for i in 1..5 {
|
||||
for j in 1..6 {
|
||||
let draft = accessor
|
||||
.create_draft_data(CreateDraftData::new(&format!("test{}", j), DataType::Em, i))
|
||||
.await?;
|
||||
if i == 1 {
|
||||
let draft = accessor
|
||||
.create_draft_data(
|
||||
CreateDraftData::new(&format!("test{}", j), DataType::Iscs, i)
|
||||
.with_options(
|
||||
serde_json::to_value(IscsDataOptions {
|
||||
style: IscsStyle::DaShiZhiNeng,
|
||||
})
|
||||
.unwrap(),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
println!("{:?}", draft);
|
||||
accessor.set_draft_data_shared(draft.id, true).await?;
|
||||
} else {
|
||||
accessor
|
||||
.create_draft_data(CreateDraftData::new(
|
||||
&format!("test{}", j),
|
||||
DataType::Em,
|
||||
i,
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -483,7 +519,7 @@ mod tests {
|
||||
let page = accessor
|
||||
.query_draft_data(
|
||||
DraftDataQuery::new()
|
||||
.with_user_id(1)
|
||||
.with_user_id(2)
|
||||
.with_name("test".to_string())
|
||||
.with_data_type(DataType::Em),
|
||||
PageQuery::new(1, 10),
|
||||
@ -505,6 +541,16 @@ mod tests {
|
||||
.await?;
|
||||
assert_eq!(page.total, 5);
|
||||
|
||||
// 查询options
|
||||
let page = accessor
|
||||
.query_draft_data(
|
||||
DraftDataQuery::new()
|
||||
.with_options_filter(r#"options @> '{"style":"DaShiZhiNeng"}'"#),
|
||||
PageQuery::new(1, 10),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(page.total, 5);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
use serde_json::Value;
|
||||
use sqlx::types::chrono::{DateTime, Local};
|
||||
|
||||
use crate::common::TableColumn;
|
||||
|
||||
/// 数据库表 rtss.draft_data 列映射
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum DraftDataColumn {
|
||||
pub enum DraftDataColumn {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
DataType,
|
||||
Options,
|
||||
Data,
|
||||
DefaultReleaseDataId,
|
||||
UserId,
|
||||
@ -23,6 +25,8 @@ pub struct DraftDataModel {
|
||||
pub name: String,
|
||||
pub data_type: i32,
|
||||
#[sqlx(default)]
|
||||
pub options: Option<Value>,
|
||||
#[sqlx(default)]
|
||||
pub data: Option<Vec<u8>>,
|
||||
#[sqlx(default)]
|
||||
pub default_release_data_id: Option<i32>,
|
||||
@ -35,11 +39,12 @@ pub struct DraftDataModel {
|
||||
|
||||
/// 数据库表 rtss.release_data 列映射
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ReleaseDataColumn {
|
||||
pub enum ReleaseDataColumn {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
DataType,
|
||||
Options,
|
||||
UsedVersionId,
|
||||
UserId,
|
||||
IsPublished,
|
||||
@ -53,6 +58,8 @@ pub struct ReleaseDataModel {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub data_type: i32,
|
||||
#[sqlx(default)]
|
||||
pub options: Option<Value>,
|
||||
pub used_version_id: Option<i32>,
|
||||
pub user_id: i32,
|
||||
pub is_published: bool,
|
||||
@ -201,6 +208,7 @@ impl TableColumn for DraftDataColumn {
|
||||
DraftDataColumn::Id => "id",
|
||||
DraftDataColumn::Name => "name",
|
||||
DraftDataColumn::DataType => "data_type",
|
||||
DraftDataColumn::Options => "options",
|
||||
DraftDataColumn::Data => "data",
|
||||
DraftDataColumn::DefaultReleaseDataId => "default_release_data_id",
|
||||
DraftDataColumn::UserId => "user_id",
|
||||
@ -218,6 +226,7 @@ impl TableColumn for ReleaseDataColumn {
|
||||
ReleaseDataColumn::Id => "id",
|
||||
ReleaseDataColumn::Name => "name",
|
||||
ReleaseDataColumn::DataType => "data_type",
|
||||
ReleaseDataColumn::Options => "options",
|
||||
ReleaseDataColumn::UsedVersionId => "used_version_id",
|
||||
ReleaseDataColumn::UserId => "user_id",
|
||||
ReleaseDataColumn::IsPublished => "is_published",
|
||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||
prost = "0.13"
|
||||
async-graphql = { version = "7.0.7", features = ["chrono"] }
|
||||
sqlx = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = "0.13"
|
||||
|
@ -23,6 +23,11 @@ fn main() {
|
||||
.out_dir("src/pb")
|
||||
.type_attribute("common.DataType", "#[derive(sqlx::Type)]")
|
||||
.type_attribute("common.DataType", "#[derive(async_graphql::Enum)]")
|
||||
.type_attribute("common.IscsStyle", "#[derive(async_graphql::Enum)]")
|
||||
.type_attribute(
|
||||
"common.IscsStyle",
|
||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||
)
|
||||
.type_attribute("common.FeatureType", "#[derive(sqlx::Type)]")
|
||||
.compile_protos(
|
||||
&[
|
||||
|
@ -141,6 +141,47 @@ impl DataType {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(
|
||||
async_graphql::Enum,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
::prost::Enumeration,
|
||||
)]
|
||||
#[repr(i32)]
|
||||
pub enum IscsStyle {
|
||||
/// 未知
|
||||
Unknown = 0,
|
||||
/// 达实智能(福州一号线)
|
||||
DaShiZhiNeng = 1,
|
||||
}
|
||||
impl IscsStyle {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
///
|
||||
/// The values are not transformed in any way and thus are considered stable
|
||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
IscsStyle::Unknown => "IscsStyle_Unknown",
|
||||
IscsStyle::DaShiZhiNeng => "DaShiZhiNeng",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"IscsStyle_Unknown" => Some(Self::Unknown),
|
||||
"DaShiZhiNeng" => Some(Self::DaShiZhiNeng),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// 功能特性类型
|
||||
#[derive(
|
||||
sqlx::Type, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration,
|
||||
|
@ -7,6 +7,7 @@ CREATE TABLE
|
||||
id SERIAL PRIMARY KEY, -- id 自增主键
|
||||
name VARCHAR(128) NOT NULL, -- 草稿名称
|
||||
data_type INT NOT NULL, -- 数据类型
|
||||
options JSONB NULL, -- 数据相关的参数项或配置项
|
||||
data BYTEA, -- 草稿数据
|
||||
default_release_data_id INT NULL, -- 默认发布数据id
|
||||
user_id INT NOT NULL, -- 创建用户id
|
||||
@ -22,6 +23,9 @@ CREATE INDEX ON rtss.draft_data (user_id);
|
||||
-- 创建草稿数据类型索引
|
||||
CREATE INDEX ON rtss.draft_data (data_type);
|
||||
|
||||
-- 创建草稿数据配置项索引
|
||||
CREATE INDEX ON rtss.draft_data USING GIN (options);
|
||||
|
||||
-- 注释草稿数据表
|
||||
COMMENT ON TABLE rtss.draft_data IS '草稿数据表';
|
||||
|
||||
@ -32,6 +36,8 @@ COMMENT ON COLUMN rtss.draft_data.name IS '草稿名称';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.data_type IS '数据类型';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.options IS '数据相关的参数项或配置项';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.data IS '草稿数据';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.user_id IS '创建用户id';
|
||||
@ -48,6 +54,7 @@ CREATE TABLE
|
||||
id SERIAL PRIMARY KEY, -- id 自增主键
|
||||
name VARCHAR(128) NOT NULL UNIQUE, -- 发布数据名称(数据唯一标识)
|
||||
data_type INT NOT NULL, -- 数据类型
|
||||
options JSONB NULL, -- 数据相关的参数项或配置项
|
||||
used_version_id INT NULL, -- 使用的版本数据id
|
||||
user_id INT NOT NULL, -- 发布/更新用户id
|
||||
is_published BOOLEAN NOT NULL DEFAULT TRUE, -- 是否上架
|
||||
@ -65,6 +72,8 @@ COMMENT ON COLUMN rtss.release_data.name IS '发布数据名称(数据唯一标
|
||||
|
||||
COMMENT ON COLUMN rtss.release_data.data_type IS '数据类型';
|
||||
|
||||
COMMENT ON COLUMN rtss.release_data.options IS '数据相关的参数项或配置项';
|
||||
|
||||
COMMENT ON COLUMN rtss.release_data.used_version_id IS '使用的版本数据id';
|
||||
|
||||
COMMENT ON COLUMN rtss.release_data.user_id IS '发布/更新用户id';
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 4e447beffa31c94b30bcee57a7cf229dcf01351f
|
||||
Subproject commit a1622410919b58683bc0ec059b4f5de575583c13
|
Loading…
Reference in New Issue
Block a user