From 3c0258b42aa9c83279d4cc28634cc46f9afec42c Mon Sep 17 00:00:00 2001 From: khorshuheng Date: Fri, 25 Oct 2024 17:30:56 +0800 Subject: [PATCH] feat: add publish info to template home page --- libs/database-entity/src/dto.rs | 76 +++++------------------- src/biz/template/ops.rs | 100 +++++++++++++++++++++++++++++--- tests/workspace/template.rs | 24 +++++--- 3 files changed, 119 insertions(+), 81 deletions(-) diff --git a/libs/database-entity/src/dto.rs b/libs/database-entity/src/dto.rs index 00a5a67d..24f8abb0 100644 --- a/libs/database-entity/src/dto.rs +++ b/libs/database-entity/src/dto.rs @@ -1329,41 +1329,11 @@ pub struct Template { #[derive(Serialize, Deserialize, Debug)] pub struct TemplateWithPublishInfo { - pub view_id: Uuid, - pub created_at: DateTime, - pub last_updated_at: DateTime, - pub name: String, - pub description: String, - pub about: String, - pub view_url: String, - pub categories: Vec, - pub creator: TemplateCreator, - pub is_new_template: bool, - pub is_featured: bool, - pub related_templates: Vec, + #[serde(flatten)] + pub template: Template, pub publish_info: PublishInfo, } -impl From<(Template, PublishInfo)> for TemplateWithPublishInfo { - fn from((template, publish_info): (Template, PublishInfo)) -> Self { - Self { - view_id: template.view_id, - created_at: template.created_at, - last_updated_at: template.last_updated_at, - name: template.name, - description: template.description, - about: template.about, - view_url: template.view_url, - categories: template.categories, - creator: template.creator, - is_new_template: template.is_new_template, - is_featured: template.is_featured, - related_templates: template.related_templates, - publish_info, - } - } -} - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TemplateMinimal { pub view_id: Uuid, @@ -1380,37 +1350,11 @@ pub struct TemplateMinimal { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TemplateMinimalWithPublishInfo { - pub view_id: Uuid, - pub created_at: DateTime, - pub last_updated_at: DateTime, - pub name: String, - pub description: String, - pub view_url: String, - pub creator: TemplateCreatorMinimal, - pub categories: Vec, - pub is_new_template: bool, - pub is_featured: bool, + #[serde(flatten)] + pub template: TemplateMinimal, pub publish_info: PublishInfo, } -impl From<(TemplateMinimal, PublishInfo)> for TemplateMinimalWithPublishInfo { - fn from((template, publish_info): (TemplateMinimal, PublishInfo)) -> Self { - Self { - view_id: template.view_id, - created_at: template.created_at, - last_updated_at: template.last_updated_at, - name: template.name, - description: template.description, - view_url: template.view_url, - creator: template.creator, - categories: template.categories, - is_new_template: template.is_new_template, - is_featured: template.is_featured, - publish_info, - } - } -} - #[derive(Serialize, Deserialize, Debug)] pub struct Templates { pub templates: Vec, @@ -1457,11 +1401,17 @@ pub struct TemplateGroup { pub templates: Vec, } +#[derive(Serialize, Deserialize, Debug)] +pub struct TemplateGroupWithPublishInfo { + pub category: TemplateCategoryMinimal, + pub templates: Vec, +} + #[derive(Serialize, Deserialize, Debug)] pub struct TemplateHomePage { - pub featured_templates: Vec, - pub new_templates: Vec, - pub template_groups: Vec, + pub featured_templates: Vec, + pub new_templates: Vec, + pub template_groups: Vec, } #[derive(Serialize, Deserialize, Debug)] diff --git a/src/biz/template/ops.rs b/src/biz/template/ops.rs index 4d01ae48..5600720c 100644 --- a/src/biz/template/ops.rs +++ b/src/biz/template/ops.rs @@ -1,4 +1,8 @@ -use std::{collections::HashMap, ops::DerefMut, path::Path}; +use std::{ + collections::{HashMap, HashSet}, + ops::DerefMut, + path::Path, +}; use actix_multipart::form::bytes::Bytes as MPBytes; use anyhow::Context; @@ -11,7 +15,8 @@ use database::{ }; use database_entity::dto::{ AccountLink, PublishInfo, Template, TemplateCategory, TemplateCategoryType, TemplateCreator, - TemplateHomePage, TemplateMinimalWithPublishInfo, TemplateWithPublishInfo, + TemplateGroupWithPublishInfo, TemplateHomePage, TemplateMinimalWithPublishInfo, + TemplateWithPublishInfo, }; use shared_entity::response::AppResponseError; use sqlx::PgPool; @@ -257,7 +262,10 @@ pub async fn get_templates_with_publish_info( .filter_map(|template| { publish_info_map .remove(&template.view_id) - .map(|pub_info| TemplateMinimalWithPublishInfo::from((template, pub_info))) + .map(|publish_info| TemplateMinimalWithPublishInfo { + template, + publish_info, + }) }) .collect(); if templates_with_publish_info.len() != view_ids.len() { @@ -274,9 +282,12 @@ pub async fn get_template_with_publish_info( view_id: Uuid, ) -> Result { let template = select_template_view_by_id(pg_pool, view_id).await?; - let pub_info = select_published_collab_info(pg_pool, &view_id).await?; - let template_with_pub_info = TemplateWithPublishInfo::from((template, pub_info)); - Ok(template_with_pub_info) + let publish_info = select_published_collab_info(pg_pool, &view_id).await?; + let template_with_publish_info = TemplateWithPublishInfo { + template, + publish_info, + }; + Ok(template_with_publish_info) } pub async fn delete_template(pg_pool: &PgPool, view_id: Uuid) -> Result<(), AppResponseError> { @@ -296,10 +307,81 @@ pub async fn get_template_homepage( select_templates(pg_pool, None, Some(true), None, None, Some(per_count)).await?; let new_templates = select_templates(pg_pool, None, None, Some(true), None, Some(per_count)).await?; + let template_groups_view_ids = template_groups + .iter() + .flat_map(|group| group.templates.iter().map(|t| t.view_id)) + .collect::>(); + let feature_templates_view_ids = featured_templates + .iter() + .map(|t| t.view_id) + .collect::>(); + let new_templates_view_ids = new_templates + .iter() + .map(|t| t.view_id) + .collect::>(); + let mut all_view_ids: HashSet = HashSet::new(); + all_view_ids.extend(&template_groups_view_ids); + all_view_ids.extend(&feature_templates_view_ids); + all_view_ids.extend(&new_templates_view_ids); + let all_view_ids: Vec = all_view_ids.into_iter().collect(); + + let publish_info_for_views: Vec = + select_published_collab_info_for_view_ids(pg_pool, &all_view_ids).await?; + let publish_info_map = publish_info_for_views + .into_iter() + .map(|info| (info.view_id, info)) + .collect::>(); + + let template_groups_with_publish_info = template_groups + .into_iter() + .map(|group| { + let templates_with_publish_info = group + .templates + .into_iter() + .filter_map(|template| { + publish_info_map.get(&template.view_id).map(|publish_info| { + TemplateMinimalWithPublishInfo { + template, + publish_info: publish_info.clone(), + } + }) + }) + .collect(); + TemplateGroupWithPublishInfo { + category: group.category.clone(), + templates: templates_with_publish_info, + } + }) + .collect(); + + let featured_templates_with_publish_info = featured_templates + .into_iter() + .filter_map(|template| { + publish_info_map + .get(&template.view_id) + .map(|publish_info| TemplateMinimalWithPublishInfo { + template, + publish_info: publish_info.clone(), + }) + }) + .collect(); + + let new_templates_with_publish_info = new_templates + .into_iter() + .filter_map(|template| { + publish_info_map + .get(&template.view_id) + .map(|publish_info| TemplateMinimalWithPublishInfo { + template, + publish_info: publish_info.clone(), + }) + }) + .collect(); + let homepage = TemplateHomePage { - template_groups, - featured_templates, - new_templates, + template_groups: template_groups_with_publish_info, + featured_templates: featured_templates_with_publish_info, + new_templates: new_templates_with_publish_info, }; Ok(homepage) } diff --git a/tests/workspace/template.rs b/tests/workspace/template.rs index 59e9403d..9e3009ba 100644 --- a/tests/workspace/template.rs +++ b/tests/workspace/template.rs @@ -357,7 +357,7 @@ async fn test_template_crud() { .await .unwrap() .templates; - let view_ids: HashSet = templates.iter().map(|t| t.view_id).collect(); + let view_ids: HashSet = templates.iter().map(|t| t.template.view_id).collect(); assert_eq!(templates.len(), 2); assert!(view_ids.contains(&published_view_ids[2])); assert!(view_ids.contains(&published_view_ids[3])); @@ -376,7 +376,10 @@ async fn test_template_crud() { .await .unwrap() .templates; - let featured_view_ids: HashSet = featured_templates.iter().map(|t| t.view_id).collect(); + let featured_view_ids: HashSet = featured_templates + .iter() + .map(|t| t.template.view_id) + .collect(); assert_eq!(featured_templates.len(), 2); assert!(featured_view_ids.contains(&published_view_ids[0])); assert!(featured_view_ids.contains(&published_view_ids[1])); @@ -386,7 +389,7 @@ async fn test_template_crud() { .await .unwrap() .templates; - let new_view_ids: HashSet = new_templates.iter().map(|t| t.view_id).collect(); + let new_view_ids: HashSet = new_templates.iter().map(|t| t.template.view_id).collect(); assert_eq!(new_templates.len(), 2); assert!(new_view_ids.contains(&published_view_ids[0])); assert!(new_view_ids.contains(&published_view_ids[2])); @@ -395,12 +398,15 @@ async fn test_template_crud() { .get_template(published_view_ids[3]) .await .unwrap(); - assert_eq!(template.view_id, published_view_ids[3]); - assert_eq!(template.creator.id, creator_2.id); - assert_eq!(template.categories.len(), 1); - assert_eq!(template.categories[0].id, category_2.id); - assert_eq!(template.related_templates.len(), 1); - assert_eq!(template.related_templates[0].view_id, published_view_ids[0]); + assert_eq!(template.template.view_id, published_view_ids[3]); + assert_eq!(template.template.creator.id, creator_2.id); + assert_eq!(template.template.categories.len(), 1); + assert_eq!(template.template.categories[0].id, category_2.id); + assert_eq!(template.template.related_templates.len(), 1); + assert_eq!( + template.template.related_templates[0].view_id, + published_view_ids[0] + ); assert_eq!( template.publish_info.namespace.unwrap(), published_view_namespace.clone()