use crate::{db::Db, models::request_log}; use sea_orm::{ActiveModelTrait, Set, EntityTrait, ColumnTrait, QueryFilter, PaginatorTrait, QueryOrder}; use chrono::{DateTime, FixedOffset, Utc}; #[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] pub struct CreateLogInput { pub path: String, pub method: String, pub request_params: Option, pub response_params: Option, pub status_code: i32, pub user_id: Option, pub username: Option, pub request_time: DateTime, pub duration_ms: i64, } pub async fn create(db: &Db, input: CreateLogInput) -> anyhow::Result { let am = request_log::ActiveModel { id: Set(crate::utils::generate_request_log_id()), path: Set(input.path), method: Set(input.method), request_params: Set(input.request_params), response_params: Set(input.response_params), status_code: Set(input.status_code), user_id: Set(input.user_id), username: Set(input.username), request_time: Set(input.request_time), duration_ms: Set(input.duration_ms), created_at: Set(Utc::now().with_timezone(&FixedOffset::east_opt(0).unwrap())), }; let m = am.insert(db).await?; Ok(m.id) } #[derive(serde::Serialize, Clone, Debug)] pub struct LogInfo { pub id: i64, pub path: String, pub method: String, pub request_params: Option, pub response_params: Option, pub status_code: i32, pub user_id: Option, pub username: Option, pub request_time: chrono::DateTime, pub duration_ms: i64, } impl From for LogInfo { fn from(m: request_log::Model) -> Self { Self { id: m.id, path: m.path, method: m.method, request_params: m.request_params, response_params: m.response_params, status_code: m.status_code, user_id: m.user_id, username: m.username, request_time: m.request_time, duration_ms: m.duration_ms } } } #[derive(serde::Serialize)] pub struct PageResp { pub items: Vec, pub total: u64, pub page: u64, pub page_size: u64 } #[derive(serde::Deserialize)] pub struct ListParams { pub page: Option, pub page_size: Option, pub path: Option, pub start_time: Option, pub end_time: Option } pub async fn list(db: &Db, p: ListParams) -> anyhow::Result> { let page = p.page.unwrap_or(1); let page_size = p.page_size.unwrap_or(10); let mut selector = request_log::Entity::find(); if let Some(path) = p.path { let like = format!("%{}%", path); selector = selector.filter(request_log::Column::Path.like(like)); } if let Some(start) = p.start_time.as_deref() { if let Ok(dt) = start.parse::>() { selector = selector.filter(request_log::Column::RequestTime.gte(dt)); } } if let Some(end) = p.end_time.as_deref() { if let Ok(dt) = end.parse::>() { selector = selector.filter(request_log::Column::RequestTime.lte(dt)); } } let paginator = selector.order_by_desc(request_log::Column::Id).paginate(db, page_size); let total = paginator.num_items().await? as u64; let models = paginator.fetch_page(if page>0 { page-1 } else { 0 }).await?; Ok(PageResp { items: models.into_iter().map(Into::into).collect(), total, page, page_size }) } // 新增:批量删除系统请求日志 pub async fn delete_many(db: &Db, ids: Vec) -> anyhow::Result { if ids.is_empty() { return Ok(0); } let res = request_log::Entity::delete_many() .filter(request_log::Column::Id.is_in(ids)) .exec(db) .await?; Ok(res.rows_affected as u64) }