yggdrasil/api/comments/
check.rs1use dioxus::prelude::*;
7
8#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
10pub struct PendingStatusItem {
11 pub id: i64,
13 pub status: String,
15}
16
17#[server(CheckPendingStatus, "/api")]
22pub async fn check_pending_status(ids: Vec<i64>) -> Result<Vec<PendingStatusItem>, ServerFnError> {
23 #[cfg(feature = "server")]
25 {
26 use crate::api::error::AppError;
27 use crate::db::pool::get_conn;
28
29 if ids.is_empty() {
31 return Ok(vec![]);
32 }
33 if ids.len() > 100 {
35 return Ok(vec![]);
36 }
37
38 if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
42 let parts = ctx.parts_mut();
43 let ip = crate::api::rate_limit::get_client_ip(&parts.headers);
44 if let Err(_msg) = crate::api::rate_limit::check_strict_limit(&ip) {
45 return Err(ServerFnError::new("请求过于频繁,请稍后再试"));
46 }
47 }
48
49 let client = get_conn().await.map_err(AppError::db_conn)?;
50
51 let rows = client
52 .query(
53 "SELECT id, status FROM comments WHERE id = ANY($1)",
54 &[&ids],
55 )
56 .await
57 .map_err(AppError::query)?;
58
59 let found: std::collections::HashMap<i64, String> = rows
61 .iter()
62 .map(|r| (r.get::<_, i64>(0), r.get::<_, String>(1)))
63 .collect();
64
65 let result: Vec<PendingStatusItem> = ids
66 .into_iter()
67 .map(|id| {
68 let status = found
69 .get(&id)
70 .cloned()
71 .unwrap_or_else(|| "gone".to_string());
72 PendingStatusItem { id, status }
73 })
74 .collect();
75
76 Ok(result)
77 }
78 #[cfg(not(feature = "server"))]
79 unreachable!()
80}