yggdrasil/src/api/settings.rs
xfy 373498870a
Some checks failed
CI / check (push) Failing after 5m35s
CI / build (push) Has been skipped
style: apply cargo fmt to workspace
2026-06-29 13:47:40 +08:00

109 lines
3.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 回收站配置接口:读取与更新自动清理设置。
//!
//! 所有接口需要 admin 权限。配置持久化到 settings 键值表。
//! Dioxus server function注册在 `/api` 路径下。
// 与 posts 模块一致Dioxus `#[server]` 宏触发 deprecated/unit 提示,按项目惯例放行。
#![allow(clippy::unused_unit, deprecated)]
use dioxus::prelude::*;
#[cfg(feature = "server")]
use crate::api::auth::get_current_admin_user;
#[cfg(feature = "server")]
use crate::api::error::AppError;
#[cfg(feature = "server")]
use crate::db::pool::get_conn;
use crate::models::settings::TrashSettings;
/// 读取回收站配置。
///
/// settings 表缺失键时回退到默认值,保证向后兼容。
#[server(GetTrashSettings, "/api")]
pub async fn get_trash_settings() -> Result<TrashSettings, ServerFnError> {
let _user = get_current_admin_user().await?;
#[cfg(feature = "server")]
{
let client = get_conn().await.map_err(AppError::db_conn)?;
let enabled: bool = client
.query_opt(
"SELECT value FROM settings WHERE key = 'trash_auto_purge_enabled'",
&[],
)
.await
.map_err(AppError::query)?
.and_then(|r| r.get::<_, String>("value").parse().ok())
.unwrap_or(crate::models::settings::DEFAULT_AUTO_PURGE_ENABLED);
let days: i32 = client
.query_opt(
"SELECT value FROM settings WHERE key = 'trash_retention_days'",
&[],
)
.await
.map_err(AppError::query)?
.and_then(|r| r.get::<_, String>("value").parse().ok())
.unwrap_or(crate::models::settings::DEFAULT_RETENTION_DAYS);
Ok(TrashSettings {
auto_purge_enabled: enabled,
retention_days: TrashSettings::clamp_retention(days),
})
}
#[cfg(not(feature = "server"))]
{
Ok(TrashSettings::default())
}
}
/// 更新回收站配置。
///
/// retention_days 会被 clamp 到合法范围后写入。
#[server(UpdateTrashSettings, "/api")]
pub async fn update_trash_settings(
auto_purge_enabled: bool,
retention_days: i32,
) -> Result<TrashSettings, ServerFnError> {
let _user = get_current_admin_user().await?;
let retention_days = TrashSettings::clamp_retention(retention_days);
#[cfg(feature = "server")]
{
let client = get_conn().await.map_err(AppError::db_conn)?;
// UPSERT 两个键。
client
.execute(
"INSERT INTO settings (key, value, updated_at) VALUES ('trash_auto_purge_enabled', $1, NOW())
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()",
&[&auto_purge_enabled.to_string()],
)
.await
.map_err(AppError::query)?;
client
.execute(
"INSERT INTO settings (key, value, updated_at) VALUES ('trash_retention_days', $1, NOW())
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()",
&[&retention_days.to_string()],
)
.await
.map_err(AppError::query)?;
tracing::info!(
"Trash settings updated: auto_purge={}, retention_days={}",
auto_purge_enabled,
retention_days
);
}
Ok(TrashSettings {
auto_purge_enabled,
retention_days,
})
}