81 lines
3.6 KiB
Rust
81 lines
3.6 KiB
Rust
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<String>,
|
|
pub response_params: Option<String>,
|
|
pub status_code: i32,
|
|
pub user_id: Option<i64>,
|
|
pub username: Option<String>,
|
|
pub request_time: DateTime<FixedOffset>,
|
|
pub duration_ms: i64,
|
|
}
|
|
|
|
pub async fn create(db: &Db, input: CreateLogInput) -> anyhow::Result<i64> {
|
|
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<String>,
|
|
pub response_params: Option<String>,
|
|
pub status_code: i32,
|
|
pub user_id: Option<i64>,
|
|
pub username: Option<String>,
|
|
pub request_time: chrono::DateTime<FixedOffset>,
|
|
pub duration_ms: i64,
|
|
}
|
|
impl From<request_log::Model> 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<T> { pub items: Vec<T>, pub total: u64, pub page: u64, pub page_size: u64 }
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct ListParams { pub page: Option<u64>, pub page_size: Option<u64>, pub path: Option<String>, pub start_time: Option<String>, pub end_time: Option<String> }
|
|
|
|
pub async fn list(db: &Db, p: ListParams) -> anyhow::Result<PageResp<LogInfo>> {
|
|
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::<chrono::DateTime<FixedOffset>>() { selector = selector.filter(request_log::Column::RequestTime.gte(dt)); } }
|
|
if let Some(end) = p.end_time.as_deref() { if let Ok(dt) = end.parse::<chrono::DateTime<FixedOffset>>() { 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<i64>) -> anyhow::Result<u64> {
|
|
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)
|
|
} |