feat(blog) add pagination for get_post_list

This commit is contained in:
lumither committed 2024-07-22 21:33:20 +08:00
1 parent 1917630265
commit ee413c5dee
1 file changed
+39 -33
+39 -33
View File
@@ -1,17 +1,29 @@
use axum::{extract::State, http::StatusCode, Json}; use axum::{extract::State, http::StatusCode, Json};
use axum::extract::Query;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use futures::future::join_all; use futures::future::join_all;
use serde::Deserialize;
use serde_json::{json, Map, Value}; use serde_json::{json, Map, Value};
use sqlx::{postgres::PgRow, query, PgPool, Row}; use sqlx::{PgPool, postgres::PgRow, query, Row};
use tracing::error; use tracing::error;
use uuid::Uuid; use uuid::Uuid;
#[derive(Deserialize)]
pub struct Params {
page: Option<u32>,
}
const PAGE_SIZE: u32 = 6;
pub async fn get_post_list( pub async fn get_post_list(
State(db_connection): State<PgPool>, State(db_connection): State<PgPool>,
Query(params): Query<Params>,
) -> Result<Json<Value>, (StatusCode, Json<Value>)> { ) -> Result<Json<Value>, (StatusCode, Json<Value>)> {
let post_list = sqlx::query( let offset = PAGE_SIZE * (params.page.unwrap_or(1) - 1);
"select post_id, title, sub_title, summary, last_update, first_update, header_img, category from post",
) let post_list = sqlx::query("SELECT * FROM post ORDER BY first_update DESC LIMIT $1 OFFSET $2")
.bind(PAGE_SIZE as i32)
.bind(offset as i32)
.fetch_all(&db_connection) .fetch_all(&db_connection)
.await; .await;
let post_list = match post_list { let post_list = match post_list {
@@ -41,35 +53,29 @@ pub async fn get_post_list(
} }
async fn analyze_post(db_connection: &PgPool, post: PgRow) -> Value { async fn analyze_post(db_connection: &PgPool, post: PgRow) -> Value {
let mut tmp = Map::new();
let post_id: Uuid = post.get("post_id"); let post_id: Uuid = post.get("post_id");
let title: String = post.get("title"); let tags = fetch_post_tags(db_connection, post_id).await;
let category: String = post.get("category");
let header_img: String = post.get("header_img");
let sub_title: String = post.get("sub_title");
let summary: String = post.get("summary");
let last_update: DateTime<Utc> = post.get("last_update");
let first_update: DateTime<Utc> = post.get("first_update");
let tags_future = query("SELECT tag FROM Tag WHERE post_id = $1") json!({
.bind(post_id) "post_id": post_id.to_string(),
.fetch_all(db_connection); "title": post.get::<String, _>("title"),
let tags: Vec<String> = match tags_future.await { "category": post.get::<String, _>("category"),
Ok(res) => res.iter().map(|tag| tag.get::<String, _>("tag")).collect(), "header_img": post.get::<String, _>("header_img"),
Err(_) => { "sub_title": post.get::<String, _>("sub_title"),
vec![] "summary": post.get::<String, _>("summary"),
} "last_update": post.get::<DateTime<Utc>, _>("last_update"),
}; "first_update": post.get::<DateTime<Utc>, _>("first_update"),
"tags": tags,
tmp.insert("post_id".to_string(), json!(post_id.to_string())); })
tmp.insert("title".to_string(), json!(title)); }
tmp.insert("category".to_string(), json!(category));
tmp.insert("header_img".to_string(), json!(header_img)); async fn fetch_post_tags(db_connection: &PgPool, post_id: Uuid) -> Vec<String> {
tmp.insert("sub_title".to_string(), json!(sub_title)); match query("SELECT tag FROM Tag WHERE post_id = $1")
tmp.insert("summary".to_string(), json!(summary)); .bind(post_id)
tmp.insert("last_update".to_string(), json!(last_update)); .fetch_all(db_connection)
tmp.insert("first_update".to_string(), json!(first_update)); .await
tmp.insert("tags".to_string(), json!(tags)); {
Ok(res) => res.iter().map(|tag| tag.get::<String, _>("tag")).collect(),
Value::from(tmp) Err(_) => vec![],
}
} }