use axum::extract::Path;
use axum::{extract::State, routing::get};
use axum::{Form, Json};
use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder};
use tracing::debug;
use crate::entities::{prelude::*, *};
use crate::AppStat;
pub(crate) fn route(state: AppStat) -> axum::Router<AppStat> {
axum::Router::new()
.route("/listbook", get(list_book))
.route("/listauthor", get(listauthor))
.route("/getauthor/:author", get(get_author_by_id))
.route("/searchauthor", get(get_authors_by_name))
.route("/getbook/:book", get(getbook_by_id))
.route("/searchbook", get(getbooks_by_name))
.route_layer(
tower::ServiceBuilder::new()
.layer(axum::middleware::from_fn_with_state(
state,
super::middleware::user_auth::user_auth,
))
.layer(axum::middleware::from_fn(
super::middleware::log_system::log_sys,
)),
)
}
#[derive(Debug, serde::Deserialize)]
enum QueryAscDesc {
Asc,
Desc,
}
#[derive(Debug, serde::Deserialize)]
enum QueryBy {
Id,
Name,
DateAdded,
}
#[derive(Debug, serde::Deserialize)]
struct ListArgs {
page: u64,
page_size: u64,
}
#[derive(Debug, serde::Serialize)]
struct ListResult<T> {
total_pages: u64,
page: u64,
books: Vec<T>,
}
async fn list_book(
State(state): State<AppStat>,
Form(args): Form<ListArgs>,
) -> Json<ListResult<music::Model>> {
debug!("list book");
let books = Music::find()
.order_by_asc(music::Column::Id)
.paginate(&state.connections.db, args.page_size);
let total_pages = books.num_pages().await.unwrap();
let pages = books.fetch_page(args.page).await.unwrap();
Json(ListResult {
total_pages,
page: args.page,
books: pages.into_iter().map(Into::into).collect(),
})
}
async fn listauthor(
State(state): State<AppStat>,
Form(args): Form<ListArgs>,
) -> Json<ListResult<author::Model>> {
debug!("list book");
let authors = Author::find()
.order_by_asc(author::Column::Id)
.paginate(&state.connections.db, args.page_size);
let total_pages = authors.num_pages().await.unwrap();
let pages = authors.fetch_page(args.page).await.unwrap();
Json(ListResult {
total_pages,
page: args.page,
books: pages,
})
}
#[derive(Debug, serde::Serialize)]
enum GetResult<T> {
Found(T),
NotFound(String),
}
async fn get_author_by_id(
State(state): State<AppStat>,
Path(id): Path<i32>,
) -> Json<GetResult<author::Model>> {
debug!("get author by id:{}", id);
let author = Author::find_by_id(id)
.one(&state.connections.db)
.await
.unwrap();
match author {
Some(author) => Json(GetResult::Found(author)),
None => Json(GetResult::NotFound(format!("author {} not found", id))),
}
}
async fn get_authors_by_name(
State(state): State<AppStat>,
Form(args): Form<SearchArgs>,
) -> Json<ListResult<author::Model>> {
let authors = Author::find()
.filter(author::Column::Name.contains(args.name))
.order_by_asc(author::Column::Id)
.paginate(&state.connections.db, args.page_size);
let total_pages = authors.num_pages().await.unwrap();
let pages = authors.fetch_page(args.page).await.unwrap();
Json(ListResult {
total_pages,
page: args.page,
books: pages,
})
}
async fn getbook_by_id(
State(state): State<AppStat>,
Path(id): Path<i32>,
) -> Json<GetResult<music::Model>> {
debug!("get author by id:{}", id);
let music = Music::find_by_id(id)
.one(&state.connections.db)
.await
.unwrap();
match music {
Some(music) => Json(GetResult::Found(music)),
None => Json(GetResult::NotFound(format!("author {} not found", id))),
}
}
#[derive(Debug, serde::Deserialize)]
struct SearchArgs {
name: String,
page: u64,
page_size: u64,
}
async fn getbooks_by_name(
State(state): State<AppStat>,
Form(args): Form<SearchArgs>,
) -> Json<ListResult<music::Model>> {
let books = Music::find()
.filter(music::Column::Name.contains(args.name))
.order_by_asc(music::Column::Id)
.paginate(&state.connections.db, args.page_size);
let total_pages = books.num_pages().await.unwrap();
let pages = books.fetch_page(args.page).await.unwrap();
Json(ListResult {
total_pages,
page: args.page,
books: pages,
})
}