Skip to main content

yggdrasil/api/settings/
trash.rs

1// 与 posts 模块一致:Dioxus `#[server]` 宏触发 deprecated/unit/too_many_arguments
2// 提示,按项目惯例放行(限流/运行器等配置项天然参数多)。
3#![allow(clippy::unused_unit, deprecated, clippy::too_many_arguments)]
4
5use dioxus::prelude::*;
6
7#[cfg(feature = "server")]
8use crate::api::auth::get_current_admin_user;
9#[cfg(feature = "server")]
10use crate::api::error::AppError;
11#[cfg(feature = "server")]
12use crate::db::pool::get_conn;
13use crate::models::settings::TrashSettings;
14
15/// 读取回收站配置。
16///
17/// settings 表缺失键时回退到默认值,保证向后兼容。
18#[server(GetTrashSettings, "/api")]
19pub async fn get_trash_settings() -> Result<TrashSettings, ServerFnError> {
20    let _user = get_current_admin_user().await?;
21
22    #[cfg(feature = "server")]
23    {
24        let client = get_conn().await.map_err(AppError::db_conn)?;
25
26        let enabled: bool = client
27            .query_opt(
28                "SELECT value FROM settings WHERE key = 'trash_auto_purge_enabled'",
29                &[],
30            )
31            .await
32            .map_err(AppError::query)?
33            .and_then(|r| r.get::<_, String>("value").parse().ok())
34            .unwrap_or(crate::models::settings::DEFAULT_AUTO_PURGE_ENABLED);
35
36        let days: i32 = client
37            .query_opt(
38                "SELECT value FROM settings WHERE key = 'trash_retention_days'",
39                &[],
40            )
41            .await
42            .map_err(AppError::query)?
43            .and_then(|r| r.get::<_, String>("value").parse().ok())
44            .unwrap_or(crate::models::settings::DEFAULT_RETENTION_DAYS);
45
46        Ok(TrashSettings {
47            auto_purge_enabled: enabled,
48            retention_days: TrashSettings::clamp_retention(days),
49        })
50    }
51
52    #[cfg(not(feature = "server"))]
53    {
54        Ok(TrashSettings::default())
55    }
56}
57
58/// 更新回收站配置。
59///
60/// retention_days 会被 clamp 到合法范围后写入。
61#[server(UpdateTrashSettings, "/api")]
62pub async fn update_trash_settings(
63    auto_purge_enabled: bool,
64    retention_days: i32,
65) -> Result<TrashSettings, ServerFnError> {
66    let _user = get_current_admin_user().await?;
67
68    let retention_days = TrashSettings::clamp_retention(retention_days);
69
70    #[cfg(feature = "server")]
71    {
72        let client = get_conn().await.map_err(AppError::db_conn)?;
73
74        // UPSERT 两个键。
75        client
76            .execute(
77                "INSERT INTO settings (key, value, updated_at) VALUES ('trash_auto_purge_enabled', $1, NOW())
78                 ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()",
79                &[&auto_purge_enabled.to_string()],
80            )
81            .await
82            .map_err(AppError::query)?;
83
84        client
85            .execute(
86                "INSERT INTO settings (key, value, updated_at) VALUES ('trash_retention_days', $1, NOW())
87                 ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()",
88                &[&retention_days.to_string()],
89            )
90            .await
91            .map_err(AppError::query)?;
92
93        tracing::info!(
94            "Trash settings updated: auto_purge={}, retention_days={}",
95            auto_purge_enabled,
96            retention_days
97        );
98    }
99
100    Ok(TrashSettings {
101        auto_purge_enabled,
102        retention_days,
103    })
104}