diff --git a/src/handler/point.rs b/src/handler/point.rs index 1feb455..2900217 100644 --- a/src/handler/point.rs +++ b/src/handler/point.rs @@ -4,7 +4,7 @@ use uuid::Uuid; use validator::Validate; use sqlx::Row; -use crate::util::response::ApiErr; +use crate::util::{response::ApiErr, pagination::{PaginatedResponse, PaginationParams}}; use crate::{ AppState, @@ -12,9 +12,11 @@ use crate::{ }; /// List all points. -#[derive(Deserialize)] +#[derive(Deserialize, Validate)] pub struct GetPointListQuery { pub source_id: Option, + #[serde(flatten)] + pub pagination: PaginationParams, } #[derive(Serialize)] @@ -28,37 +30,26 @@ pub async fn get_point_list( State(state): State, Query(query): Query, ) -> Result { + query.validate()?; let pool = &state.pool; - let points: Vec = match query.source_id { - Some(source_id) => { - sqlx::query_as::<_, Point>( - r#" - SELECT p.* - FROM point p - INNER JOIN node n ON p.node_id = n.id - WHERE n.source_id = $1 - ORDER BY p.created_at - "#, - ) - .bind(source_id) - .fetch_all(pool) - .await? - } - None => { - sqlx::query_as::<_, Point>( - r#"SELECT * FROM point ORDER BY created_at"#, - ) - .fetch_all(pool) - .await? - } - }; + + // 获取总数 + let total = crate::service::get_points_count(pool, query.source_id).await?; + + // 获取分页数据 + let points = crate::service::get_points_paginated( + pool, + query.source_id, + query.pagination.page_size, + query.pagination.offset(), + ).await?; let monitor_guard = state .connection_manager .get_point_monitor_data_read_guard() .await; - let resp: Vec = points + let data: Vec = points .into_iter() .map(|point| { let point_monitor = monitor_guard @@ -68,7 +59,9 @@ pub async fn get_point_list( }) .collect(); - Ok(Json(resp)) + let response = PaginatedResponse::new(data, total, query.pagination.page, query.pagination.page_size); + + Ok(Json(response)) } /// Get a point by id. pub async fn get_point( diff --git a/src/service.rs b/src/service.rs index 68a0171..6352acc 100644 --- a/src/service.rs +++ b/src/service.rs @@ -115,6 +115,108 @@ pub async fn get_points_with_ids( .collect()) } +// ==================== Point 相关服务函数 ==================== + +/// 获取点位总数 +pub async fn get_points_count( + pool: &PgPool, + source_id: Option, +) -> Result { + match source_id { + Some(source_id) => { + sqlx::query_scalar::<_, i64>( + r#" + SELECT COUNT(*) + FROM point p + INNER JOIN node n ON p.node_id = n.id + WHERE n.source_id = $1 + "#, + ) + .bind(source_id) + .fetch_one(pool) + .await + } + None => { + sqlx::query_scalar::<_, i64>( + r#"SELECT COUNT(*) FROM point"#, + ) + .fetch_one(pool) + .await + } + } +} + +/// 获取分页点位列表 +pub async fn get_points_paginated( + pool: &PgPool, + source_id: Option, + page_size: i32, + offset: u32, +) -> Result, sqlx::Error> { + match source_id { + Some(source_id) => { + if page_size == 0 { + Ok(vec![]) + } else if page_size == -1 { + sqlx::query_as::<_, crate::model::Point>( + r#" + SELECT p.* + FROM point p + INNER JOIN node n ON p.node_id = n.id + WHERE n.source_id = $1 + ORDER BY p.created_at + "#, + ) + .bind(source_id) + .fetch_all(pool) + .await + } else { + sqlx::query_as::<_, crate::model::Point>( + r#" + SELECT p.* + FROM point p + INNER JOIN node n ON p.node_id = n.id + WHERE n.source_id = $1 + ORDER BY p.created_at + LIMIT $2 OFFSET $3 + "#, + ) + .bind(source_id) + .bind(page_size as i64) + .bind(offset as i64) + .fetch_all(pool) + .await + } + } + None => { + if page_size == 0 { + Ok(vec![]) + } else if page_size == -1 { + sqlx::query_as::<_, crate::model::Point>( + r#" + SELECT * FROM point + ORDER BY created_at + "#, + ) + .fetch_all(pool) + .await + } else { + sqlx::query_as::<_, crate::model::Point>( + r#" + SELECT * FROM point + ORDER BY created_at + LIMIT $1 OFFSET $2 + "#, + ) + .bind(page_size as i64) + .bind(offset as i64) + .fetch_all(pool) + .await + } + } + } +} + // ==================== Tag 相关服务函数 ==================== /// 获取所有标签