use crate::AppService; use crate::error::AppError; use models::users::{user, user_activity_log}; use sea_orm::prelude::Expr; use sea_orm::*; use session::Session; use std::io; impl AppService { pub async fn user_avatar_upload( &self, context: Session, file: Vec, file_ext: &str, ) -> Result { let user_id = context.user().ok_or(AppError::Unauthorized)?; let time = chrono::Utc::now().timestamp(); let file_name = format!("{}-{}", user_id, time); self.avatar .upload(file, file_name.clone(), file_ext) .await .map_err(|e| { AppError::Io(io::Error::new( io::ErrorKind::Other, format!("Failed to upload avatar: {}", e), )) })?; let static_url = self .config .static_domain() .unwrap_or_else(|_| "/static".to_string()); let file_url = format!( "{}/{}", static_url.trim_end_matches('/'), format!("{}.{}", file_name, file_ext) ); user::Entity::update_many() .filter(user::Column::Uid.eq(user_id)) .col_expr(user::Column::AvatarUrl, Expr::value(file_url.clone())) .exec(&self.db) .await?; let _ = user_activity_log::ActiveModel { user_uid: Set(Some(user_id)), action: Set("avatar_upload".to_string()), ip_address: Set(context.ip_address()), user_agent: Set(context.user_agent()), details: Set(serde_json::json!({ "file_url": file_url })), created_at: Set(chrono::Utc::now()), ..Default::default() } .insert(&self.db) .await; Ok(file_url) } }