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