Skip to main content

yggdrasil/api/settings/
upload.rs

1// 与 posts 模块一致:Leptos `#[server]` 宏触发 deprecated/unit/too_many_arguments
2// 提示,按项目惯例放行(限流/运行器等配置项天然参数多)。
3#![allow(clippy::unused_unit, deprecated, clippy::too_many_arguments)]
4
5use crate::api::error::ApiError;
6use leptos::prelude::*;
7
8#[cfg(feature = "server")]
9use crate::api::auth::get_current_admin_user;
10#[cfg(feature = "server")]
11use crate::api::error::AppError;
12#[cfg(feature = "server")]
13use crate::db::pool::get_conn;
14use crate::models::settings::UploadSettings;
15
16// ============================================================================
17// 素材上传配置
18// ============================================================================
19
20/// 启动时用 `UPLOAD_CONCURRENCY` 环境变量播种素材上传并发数。
21///
22/// 语义与 [`seed_backup_settings_from_env`][crate::api::settings::seed_backup_settings_from_env] 一致:仅当 settings 键**不存在**时
23/// 插入(首次部署),之后以「站点配置」面板写入的 DB 值为准,重启不被 env 覆盖。
24/// 非法值只告警跳过,不影响启动。
25#[cfg(feature = "server")]
26pub(crate) async fn seed_upload_settings_from_env(
27    client: &tokio_postgres::Client,
28) -> Result<(), AppError> {
29    let Ok(v) = std::env::var("UPLOAD_CONCURRENCY") else {
30        return Ok(());
31    };
32    let value = match v.trim().parse::<i32>() {
33        Ok(n) => UploadSettings::clamp_concurrency(n),
34        Err(_) => {
35            tracing::warn!("UPLOAD_CONCURRENCY={v:?} 非法(期望整数),跳过");
36            return Ok(());
37        }
38    };
39    super::insert_env_seeds(client, vec![("upload_concurrency", value.to_string())]).await
40}
41
42/// 读取素材上传配置(上传弹窗并发数)。
43///
44/// settings 表缺失键时回退到默认值,保证向后兼容。
45#[server(GetUploadSettings, endpoint = "get_upload_settings", input = leptos::server_fn::codec::Json)]
46pub async fn get_upload_settings() -> Result<UploadSettings, ApiError> {
47    let _user = get_current_admin_user().await?;
48
49    #[cfg(feature = "server")]
50    {
51        let client = get_conn().await.map_err(AppError::db_conn)?;
52
53        let values = super::load_setting_values(&client, &["upload_concurrency"]).await?;
54
55        let concurrency = values
56            .get("upload_concurrency")
57            .and_then(|v| v.parse().ok())
58            .map(UploadSettings::clamp_concurrency)
59            .unwrap_or(crate::models::settings::DEFAULT_UPLOAD_CONCURRENCY);
60
61        Ok(UploadSettings { concurrency })
62    }
63
64    #[cfg(not(feature = "server"))]
65    {
66        Ok(UploadSettings::default())
67    }
68}
69
70/// 更新素材上传配置。
71///
72/// concurrency 会被 clamp 到合法范围后写入。
73#[server(UpdateUploadSettings, endpoint = "update_upload_settings", input = leptos::server_fn::codec::Json)]
74pub async fn update_upload_settings(concurrency: i32) -> Result<UploadSettings, ApiError> {
75    let _user = get_current_admin_user().await?;
76
77    let concurrency = UploadSettings::clamp_concurrency(concurrency);
78
79    #[cfg(feature = "server")]
80    {
81        let client = get_conn().await.map_err(AppError::db_conn)?;
82
83        super::upsert_setting(&**client, "upload_concurrency", &concurrency.to_string()).await?;
84
85        tracing::info!("Upload settings updated: concurrency={}", concurrency);
86    }
87
88    Ok(UploadSettings { concurrency })
89}