perf: aggregate homepage data and trim frontend loading
This commit is contained in:
@@ -10,8 +10,10 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
controllers::admin::check_auth,
|
||||
models::_entities::site_settings::{self, ActiveModel, Entity, Model},
|
||||
services::ai,
|
||||
models::_entities::{
|
||||
categories, friend_links, posts, site_settings::{self, ActiveModel, Entity, Model}, tags,
|
||||
},
|
||||
services::{ai, content},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
@@ -154,6 +156,23 @@ pub struct PublicSiteSettingsResponse {
|
||||
pub paragraph_comments_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct HomeCategorySummary {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub slug: String,
|
||||
pub count: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct HomePageResponse {
|
||||
pub site_settings: PublicSiteSettingsResponse,
|
||||
pub posts: Vec<posts::Model>,
|
||||
pub tags: Vec<tags::Model>,
|
||||
pub friend_links: Vec<friend_links::Model>,
|
||||
pub categories: Vec<HomeCategorySummary>,
|
||||
}
|
||||
|
||||
fn normalize_optional_string(value: Option<String>) -> Option<String> {
|
||||
value.and_then(|item| {
|
||||
let trimmed = item.trim().to_string();
|
||||
@@ -664,6 +683,55 @@ fn public_response(model: Model) -> PublicSiteSettingsResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn home(State(ctx): State<AppContext>) -> Result<Response> {
|
||||
content::sync_markdown_posts(&ctx).await?;
|
||||
|
||||
let site_settings = public_response(load_current(&ctx).await?);
|
||||
let posts = posts::Entity::find()
|
||||
.order_by_desc(posts::Column::CreatedAt)
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
let tags = tags::Entity::find().all(&ctx.db).await?;
|
||||
let friend_links = friend_links::Entity::find()
|
||||
.order_by_desc(friend_links::Column::CreatedAt)
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
let category_items = categories::Entity::find()
|
||||
.order_by_asc(categories::Column::Slug)
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
|
||||
let categories = category_items
|
||||
.into_iter()
|
||||
.map(|category| {
|
||||
let name = category
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| category.slug.clone());
|
||||
let count = posts
|
||||
.iter()
|
||||
.filter(|post| post.category.as_deref().map(str::trim) == Some(name.as_str()))
|
||||
.count();
|
||||
|
||||
HomeCategorySummary {
|
||||
id: category.id,
|
||||
name,
|
||||
slug: category.slug,
|
||||
count,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
format::json(HomePageResponse {
|
||||
site_settings,
|
||||
posts,
|
||||
tags,
|
||||
friend_links,
|
||||
categories,
|
||||
})
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn show(State(ctx): State<AppContext>) -> Result<Response> {
|
||||
format::json(public_response(load_current(&ctx).await?))
|
||||
@@ -687,6 +755,7 @@ pub async fn update(
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new()
|
||||
.prefix("api/site_settings/")
|
||||
.add("home", get(home))
|
||||
.add("/", get(show))
|
||||
.add("/", put(update))
|
||||
.add("/", patch(update))
|
||||
|
||||
Reference in New Issue
Block a user