添加草稿数据相关管理接口
This commit is contained in:
parent
e0169dfc06
commit
875788a71d
@ -14,7 +14,7 @@ pub struct DraftDataMutation;
|
||||
|
||||
#[Object]
|
||||
impl DraftDataQuery {
|
||||
/// 分页查询草稿数据
|
||||
/// 分页查询全部草稿数据(系统管理用)
|
||||
async fn draft_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
@ -27,6 +27,32 @@ impl DraftDataQuery {
|
||||
.await?;
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询用户的草稿数据
|
||||
async fn user_draft_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
paging: PageQueryDto,
|
||||
query: UserDraftDataFilterDto,
|
||||
) -> async_graphql::Result<DraftDataPage> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let paging_result = db_accessor
|
||||
.query_draft_data(query.into(), paging.into())
|
||||
.await?;
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询共享的草稿数据
|
||||
async fn shared_draft_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
paging: PageQueryDto,
|
||||
query: SharedDraftDataFilterDto,
|
||||
) -> async_graphql::Result<DraftDataPage> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let paging_result = db_accessor
|
||||
.query_draft_data(query.into(), paging.into())
|
||||
.await?;
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 根据id获取草稿数据
|
||||
async fn draft_data(&self, ctx: &Context<'_>, id: i32) -> async_graphql::Result<DraftData> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
@ -82,6 +108,17 @@ impl DraftDataMutation {
|
||||
.await?;
|
||||
Ok(draft_data.into())
|
||||
}
|
||||
/// 更新草稿数据共享状态
|
||||
async fn update_draft_data_shared(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
id: i32,
|
||||
is_shared: bool,
|
||||
) -> async_graphql::Result<DraftData> {
|
||||
let db_accessor = ctx.data::<RtssDbAccessor>()?;
|
||||
let draft_data = db_accessor.set_draft_data_shared(id, is_shared).await?;
|
||||
Ok(draft_data.into())
|
||||
}
|
||||
/// 删除草稿数据
|
||||
async fn delete_draft_data(
|
||||
&self,
|
||||
@ -123,12 +160,52 @@ impl DraftDataMutation {
|
||||
pub struct CreateDraftDataDto {
|
||||
pub name: String,
|
||||
pub data_type: rtss_dto::common::DataType,
|
||||
pub data: Vec<u8>,
|
||||
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)
|
||||
Self::new(&value.name, value.data_type, value.user_id).with_data(value.data.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
/// 用户的草稿数据查询条件
|
||||
#[derive(Debug, InputObject)]
|
||||
pub struct UserDraftDataFilterDto {
|
||||
pub user_id: i32,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<rtss_dto::common::DataType>,
|
||||
pub is_shared: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<UserDraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
fn from(value: UserDraftDataFilterDto) -> Self {
|
||||
Self {
|
||||
user_id: Some(value.user_id),
|
||||
name: value.name,
|
||||
data_type: value.data_type,
|
||||
is_shared: value.is_shared,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享的草稿数据查询条件
|
||||
#[derive(Debug, InputObject)]
|
||||
pub struct SharedDraftDataFilterDto {
|
||||
pub user_id: Option<i32>,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<rtss_dto::common::DataType>,
|
||||
}
|
||||
|
||||
impl From<SharedDraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
fn from(value: SharedDraftDataFilterDto) -> Self {
|
||||
Self {
|
||||
user_id: value.user_id,
|
||||
name: value.name,
|
||||
data_type: value.data_type,
|
||||
is_shared: Some(true),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,6 +215,7 @@ pub struct DraftDataFilterDto {
|
||||
pub user_id: Option<i32>,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<rtss_dto::common::DataType>,
|
||||
pub is_shared: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<DraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
@ -146,6 +224,7 @@ impl From<DraftDataFilterDto> for rtss_db::DraftDataQuery {
|
||||
user_id: value.user_id,
|
||||
name: value.name,
|
||||
data_type: value.data_type,
|
||||
is_shared: value.is_shared,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,6 +236,7 @@ pub struct DraftData {
|
||||
pub data_type: rtss_dto::common::DataType,
|
||||
pub data: Option<Vec<u8>>,
|
||||
pub user_id: i32,
|
||||
pub is_shared: bool,
|
||||
pub created_at: DateTime<Local>,
|
||||
pub updated_at: DateTime<Local>,
|
||||
}
|
||||
@ -169,6 +249,7 @@ impl From<rtss_db::model::DraftDataModel> for DraftData {
|
||||
data_type: DataType::try_from(value.data_type).unwrap(),
|
||||
data: value.data,
|
||||
user_id: value.user_id,
|
||||
is_shared: value.is_shared,
|
||||
created_at: value.created_at,
|
||||
updated_at: value.updated_at,
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use super::RtssDbAccessor;
|
||||
/// 草稿数据管理
|
||||
#[allow(async_fn_in_trait)]
|
||||
pub trait DraftDataAccessor {
|
||||
/// 查询用户草稿数据
|
||||
/// 查询所有草稿数据
|
||||
async fn query_draft_data(
|
||||
&self,
|
||||
query: DraftDataQuery,
|
||||
@ -41,6 +41,12 @@ pub trait DraftDataAccessor {
|
||||
id: i32,
|
||||
data: &[u8],
|
||||
) -> Result<DraftDataModel, DbAccessError>;
|
||||
/// 设置草稿数据共享
|
||||
async fn set_draft_data_shared(
|
||||
&self,
|
||||
id: i32,
|
||||
is_shared: bool,
|
||||
) -> Result<DraftDataModel, DbAccessError>;
|
||||
/// 删除草稿数据
|
||||
async fn delete_draft_data(&self, id: &[i32]) -> Result<(), DbAccessError>;
|
||||
/// 设置默认发布数据id
|
||||
@ -63,9 +69,14 @@ pub struct DraftDataQuery {
|
||||
pub user_id: Option<i32>,
|
||||
pub name: Option<String>,
|
||||
pub data_type: Option<DataType>,
|
||||
pub is_shared: Option<bool>,
|
||||
}
|
||||
|
||||
impl DraftDataQuery {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn with_user_id(mut self, user_id: i32) -> Self {
|
||||
self.user_id = Some(user_id);
|
||||
self
|
||||
@ -81,6 +92,11 @@ impl DraftDataQuery {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_is_shared(mut self, is_shared: bool) -> Self {
|
||||
self.is_shared = Some(is_shared);
|
||||
self
|
||||
}
|
||||
|
||||
fn build_filter(&self) -> String {
|
||||
let mut filters = vec![];
|
||||
if let Some(user_id) = self.user_id {
|
||||
@ -100,6 +116,13 @@ impl DraftDataQuery {
|
||||
data_type as i32
|
||||
));
|
||||
}
|
||||
if let Some(is_shared) = self.is_shared {
|
||||
filters.push(format!(
|
||||
"{} = {}",
|
||||
DraftDataColumn::IsShared.name(),
|
||||
is_shared
|
||||
));
|
||||
}
|
||||
if filters.is_empty() {
|
||||
"".to_string()
|
||||
} else {
|
||||
@ -283,6 +306,27 @@ impl DraftDataAccessor for RtssDbAccessor {
|
||||
Ok(draft_data)
|
||||
}
|
||||
|
||||
async fn set_draft_data_shared(
|
||||
&self,
|
||||
id: i32,
|
||||
is_shared: bool,
|
||||
) -> Result<DraftDataModel, DbAccessError> {
|
||||
let table = DraftDataColumn::Table.name();
|
||||
let is_shared_column = DraftDataColumn::IsShared.name();
|
||||
let updated_at_column = DraftDataColumn::UpdatedAt.name();
|
||||
let id_column = DraftDataColumn::Id.name();
|
||||
let sql = format!("UPDATE {table} SET {is_shared_column} = $1, {updated_at_column} = 'now()' WHERE {id_column} = $2 RETURNING *",);
|
||||
// log sql
|
||||
debug!("set shared sql: {}", sql);
|
||||
let draft_data = sqlx::query_as(&sql)
|
||||
.bind(is_shared)
|
||||
.bind(id)
|
||||
.fetch_one(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(draft_data)
|
||||
}
|
||||
|
||||
async fn delete_draft_data(&self, ids: &[i32]) -> Result<(), DbAccessError> {
|
||||
let table = DraftDataColumn::Table.name();
|
||||
let id_column = DraftDataColumn::Id.name();
|
||||
@ -384,6 +428,10 @@ mod tests {
|
||||
println!("{:?}", get_by_id);
|
||||
assert!(get_by_id.data.unwrap() == data);
|
||||
|
||||
// set shared测试
|
||||
let get_by_id = accessor.set_draft_data_shared(res.id, true).await?;
|
||||
assert!(get_by_id.is_shared);
|
||||
|
||||
// save as new draft测试
|
||||
let new_draft = accessor.save_as_new_draft(res.id, "new draft", 11).await?;
|
||||
println!("{:?}", new_draft);
|
||||
@ -412,6 +460,7 @@ mod tests {
|
||||
user_id: None,
|
||||
name: None,
|
||||
data_type: None,
|
||||
is_shared: None,
|
||||
},
|
||||
PageQuery::new(1, 100),
|
||||
)
|
||||
@ -422,36 +471,40 @@ mod tests {
|
||||
// 分四个user_id各插入5条数据
|
||||
for i in 1..5 {
|
||||
for j in 1..6 {
|
||||
accessor
|
||||
let draft = accessor
|
||||
.create_draft_data(CreateDraftData::new(&format!("test{}", j), DataType::Em, i))
|
||||
.await?;
|
||||
if i == 1 {
|
||||
accessor.set_draft_data_shared(draft.id, true).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let page = accessor
|
||||
.query_draft_data(
|
||||
DraftDataQuery {
|
||||
user_id: Some(1),
|
||||
name: Some("test".to_string()),
|
||||
data_type: Some(DataType::Em),
|
||||
},
|
||||
DraftDataQuery::new()
|
||||
.with_user_id(1)
|
||||
.with_name("test".to_string())
|
||||
.with_data_type(DataType::Em),
|
||||
PageQuery::new(1, 10),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(page.total, 5);
|
||||
|
||||
let page = accessor
|
||||
.query_draft_data(
|
||||
DraftDataQuery {
|
||||
user_id: None,
|
||||
name: None,
|
||||
data_type: None,
|
||||
},
|
||||
PageQuery::new(1, 100),
|
||||
)
|
||||
.query_draft_data(DraftDataQuery::new(), PageQuery::new(1, 100))
|
||||
.await?;
|
||||
assert_eq!(page.total, 20);
|
||||
|
||||
// 查询共享数据
|
||||
let page = accessor
|
||||
.query_draft_data(
|
||||
DraftDataQuery::new().with_is_shared(true),
|
||||
PageQuery::new(1, 10),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(page.total, 5);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ pub trait ReleaseDataAccessor {
|
||||
name: &str,
|
||||
) -> Result<ReleaseDataModel, DbAccessError>;
|
||||
/// 上架/下架发布数据
|
||||
async fn update_release_data_published(
|
||||
async fn set_release_data_published(
|
||||
&self,
|
||||
release_id: i32,
|
||||
is_published: bool,
|
||||
@ -430,7 +430,7 @@ impl ReleaseDataAccessor for RtssDbAccessor {
|
||||
Ok(rd)
|
||||
}
|
||||
|
||||
async fn update_release_data_published(
|
||||
async fn set_release_data_published(
|
||||
&self,
|
||||
release_id: i32,
|
||||
is_published: bool,
|
||||
@ -614,7 +614,7 @@ mod tests {
|
||||
|
||||
// 测试更新发布数据上架状态
|
||||
let release_data = accessor
|
||||
.update_release_data_published(release_data.id, false)
|
||||
.set_release_data_published(release_data.id, false)
|
||||
.await?;
|
||||
assert_eq!(release_data.is_published, false);
|
||||
assert!(release_data.updated_at > release_data.created_at);
|
||||
|
@ -12,6 +12,7 @@ pub(crate) enum DraftDataColumn {
|
||||
Data,
|
||||
DefaultReleaseDataId,
|
||||
UserId,
|
||||
IsShared,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
@ -26,6 +27,8 @@ pub struct DraftDataModel {
|
||||
#[sqlx(default)]
|
||||
pub default_release_data_id: Option<i32>,
|
||||
pub user_id: i32,
|
||||
#[sqlx(default)]
|
||||
pub is_shared: bool,
|
||||
pub created_at: DateTime<Local>,
|
||||
pub updated_at: DateTime<Local>,
|
||||
}
|
||||
@ -201,6 +204,7 @@ impl TableColumn for DraftDataColumn {
|
||||
DraftDataColumn::Data => "data",
|
||||
DraftDataColumn::DefaultReleaseDataId => "default_release_data_id",
|
||||
DraftDataColumn::UserId => "user_id",
|
||||
DraftDataColumn::IsShared => "is_shared",
|
||||
DraftDataColumn::CreatedAt => "created_at",
|
||||
DraftDataColumn::UpdatedAt => "updated_at",
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ CREATE TABLE
|
||||
data BYTEA, -- 草稿数据
|
||||
default_release_data_id INT NULL, -- 默认发布数据id
|
||||
user_id INT NOT NULL, -- 创建用户id
|
||||
is_shared BOOLEAN NOT NULL DEFAULT FALSE, -- 是否共享
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT 'now()', -- 创建时间
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT 'now()', -- 更新时间
|
||||
UNIQUE (name, user_id) -- 一个用户的草稿名称唯一
|
||||
@ -35,6 +36,8 @@ COMMENT ON COLUMN rtss.draft_data.data IS '草稿数据';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.user_id IS '创建用户id';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.is_shared IS '是否共享';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.created_at IS '创建时间';
|
||||
|
||||
COMMENT ON COLUMN rtss.draft_data.updated_at IS '更新时间';
|
||||
|
Loading…
Reference in New Issue
Block a user