gitdataai/libs/service/user/preferences.rs
2026-04-14 19:02:01 +08:00

152 lines
5.3 KiB
Rust

use crate::AppService;
use crate::error::AppError;
use chrono::Utc;
use models::users::{user_activity_log, user_preferences};
use sea_orm::*;
use serde::{Deserialize, Serialize};
use session::Session;
use uuid::Uuid;
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
pub struct PreferencesParams {
pub language: Option<String>,
pub theme: Option<String>,
pub timezone: Option<String>,
pub email_notifications: Option<bool>,
pub in_app_notifications: Option<bool>,
}
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
pub struct PreferencesResponse {
pub language: String,
pub theme: String,
pub timezone: String,
pub email_notifications: bool,
pub in_app_notifications: bool,
pub created_at: chrono::DateTime<Utc>,
pub updated_at: chrono::DateTime<Utc>,
}
impl From<user_preferences::Model> for PreferencesResponse {
fn from(prefs: user_preferences::Model) -> Self {
PreferencesResponse {
language: prefs.language,
theme: prefs.theme,
timezone: prefs.timezone,
email_notifications: prefs.email_notifications,
in_app_notifications: prefs.in_app_notifications,
created_at: prefs.created_at,
updated_at: prefs.updated_at,
}
}
}
impl AppService {
pub async fn user_get_preferences(
&self,
context: &Session,
) -> Result<PreferencesResponse, AppError> {
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
let prefs = user_preferences::Entity::find_by_id(user_uid)
.one(&self.db)
.await?;
if let Some(prefs) = prefs {
Ok(PreferencesResponse::from(prefs))
} else {
self.user_create_default_preferences(user_uid).await
}
}
pub async fn user_update_preferences(
&self,
context: &Session,
params: PreferencesParams,
) -> Result<PreferencesResponse, AppError> {
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
let prefs = user_preferences::Entity::find_by_id(user_uid)
.one(&self.db)
.await?;
let updated_prefs = if let Some(prefs) = prefs {
let mut active_prefs: user_preferences::ActiveModel = prefs.into();
if let Some(language) = params.language.clone() {
active_prefs.language = Set(language);
}
if let Some(theme) = params.theme.clone() {
active_prefs.theme = Set(theme);
}
if let Some(timezone) = params.timezone.clone() {
active_prefs.timezone = Set(timezone);
}
if let Some(email_notifications) = params.email_notifications {
active_prefs.email_notifications = Set(email_notifications);
}
if let Some(in_app_notifications) = params.in_app_notifications {
active_prefs.in_app_notifications = Set(in_app_notifications);
}
active_prefs.updated_at = Set(Utc::now());
active_prefs.update(&self.db).await?
} else {
let new_prefs = user_preferences::ActiveModel {
user: Set(user_uid),
language: Set(params.language.clone().unwrap_or_else(|| "en".to_string())),
theme: Set(params.theme.clone().unwrap_or_else(|| "light".to_string())),
timezone: Set(params.timezone.clone().unwrap_or_else(|| "UTC".to_string())),
email_notifications: Set(params.email_notifications.unwrap_or(true)),
in_app_notifications: Set(params.in_app_notifications.unwrap_or(true)),
created_at: Set(Utc::now()),
updated_at: Set(Utc::now()),
};
new_prefs.insert(&self.db).await?
};
let _ = user_activity_log::ActiveModel {
user_uid: Set(Some(user_uid)),
action: Set("preferences_update".to_string()),
ip_address: Set(context.ip_address()),
user_agent: Set(context.user_agent()),
details: Set(serde_json::json!({
"updated_fields": {
"language": params.language.is_some(),
"theme": params.theme.is_some(),
"timezone": params.timezone.is_some(),
"email_notifications": params.email_notifications.is_some(),
"in_app_notifications": params.in_app_notifications.is_some(),
}
})),
created_at: Set(Utc::now()),
..Default::default()
}
.insert(&self.db)
.await;
Ok(PreferencesResponse::from(updated_prefs))
}
async fn user_create_default_preferences(
&self,
user_uid: Uuid,
) -> Result<PreferencesResponse, AppError> {
let prefs = user_preferences::ActiveModel {
user: Set(user_uid),
language: Set("en".to_string()),
theme: Set("light".to_string()),
timezone: Set("UTC".to_string()),
email_notifications: Set(true),
in_app_notifications: Set(true),
created_at: Set(Utc::now()),
updated_at: Set(Utc::now()),
};
let created_prefs = prefs.insert(&self.db).await?;
Ok(PreferencesResponse::from(created_prefs))
}
}