feat: init book handler

This commit is contained in:
brian
2025-06-08 20:42:24 +08:00
parent 50913eecbb
commit 27c94f4276
26 changed files with 4307 additions and 3 deletions

48
src/api/book.rs Normal file
View File

@@ -0,0 +1,48 @@
use axum::routing::{get, post};
use axum::{
extract::{Path, State},
http::StatusCode,
Json, Router,
};
use axum_macros::debug_handler;
use sea_orm::ColumnTrait;
use sea_orm::{entity::*, query::*,};
use crate::model::db::prelude::Book;
use crate::model::db::book::Model as BookModel;
use crate::model::db::book::Column as BookColumn;
use crate::model::http_body::book;
use crate::AppState;
use crate::model::http_body::book::BookItem;
pub fn get_nest_handlers() -> Router<crate::AppState> {
Router::new()
.route("/", get(get_all_books_handler))
// .route("/{id}", post(update_book).get(get_book))
}
// handlers
//
#[debug_handler]
async fn get_all_books_handler(
state: State<AppState>
) -> Result<Json<Vec<book::BookItem>>,(StatusCode,String)> {
// let conn = state.conn.get_postgres_connection_pool();
let uid :i64 = 1;
let all_books = Book::find()
.filter(BookColumn::Uid.eq(uid))
.all(&state.conn)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR,e.to_string()))?;
let mut books: Vec<BookItem> = Vec::new();
for b in all_books {
let book_resp = BookItem{
id: b.id,
name: b.name,
};
books.push(book_resp);
}
Ok(Json(books))
}

1
src/api/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod book;

View File

@@ -1,3 +1,99 @@
fn main() {
println!("Hello, world!");
use axum::Router;
use clap::Parser;
use sea_orm::{Database, DatabaseConnection};
use serde::Deserialize;
// Project modules
mod api;
mod model;
#[tokio::main]
async fn main() {
dotenvy::dotenv().unwrap();
// initialize tracing
tracing_subscriber::fmt::init();
let cli = Cli::parse();
match cli.command {
Command::Serve { config_path } => {
if let Ok(config) = load_config(&config_path).await {
println!("Loaded config.");
println!("{},{}", config.service.host.clone(), config.service.port);
// Proceed with server initialization using `config`
start_server(&config).await;
} else {
eprintln!("Failed to load config from {}", config_path);
}
}
}
}
#[derive(Clone)]
struct AppState {
conn: DatabaseConnection,
}
#[derive(Deserialize)]
struct Key {
jwt: String,
user: String,
}
#[derive(Deserialize)]
struct DatabaseConf {
connection: String,
}
#[derive(Deserialize)]
struct ServiceConf {
host: String,
port: u32,
}
#[derive(Deserialize)]
struct Config {
service: ServiceConf,
database: DatabaseConf,
keys: Key,
}
#[derive(clap::Parser)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(clap::Subcommand)]
enum Command {
Serve {
#[arg(long = "conf")]
config_path: String,
},
}
async fn load_config(path: &str) -> Result<Config, Box<dyn std::error::Error>> {
let content = tokio::fs::read_to_string(path).await?;
let config: Config = toml::from_str(&content)?;
Ok(config)
}
// ====== Commands ======
// start http server
async fn start_server(config: &Config){
// Define the router
// let app = Router.new()
// .nest();
let conn = Database::connect(&config.database.connection)
.await
.expect("Database connection failed.");
let state = AppState{conn };
let app = Router::new()
.nest("/api/v1/book", api::book::get_nest_handlers())
.with_state(state);
let host = config.service.host.clone();
let port = config.service.port;
let server_url = format!("{host}:{port}");
let listener = tokio::net::TcpListener::bind(&server_url).await.unwrap();
axum::serve(listener, app).await.expect("Service panic happened");
}

22
src/model/db/account.rs Normal file
View File

@@ -0,0 +1,22 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "account")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub name: String,
pub r#type: i32,
pub uid: i64,
pub is_deleted: bool,
pub created_at: DateTime,
pub updated_at: DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

21
src/model/db/book.rs Normal file
View File

@@ -0,0 +1,21 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "book")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub name: String,
pub uid: i64,
pub is_deleted: bool,
pub created_at: DateTime,
pub updated_at: DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

22
src/model/db/category.rs Normal file
View File

@@ -0,0 +1,22 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "category")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub name: String,
pub uid: i64,
pub parent_id: i64,
pub is_deleted: bool,
pub created_at: DateTime,
pub updated_at: DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

9
src/model/db/mod.rs Normal file
View File

@@ -0,0 +1,9 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
pub mod prelude;
pub mod account;
pub mod book;
pub mod category;
pub mod tag;
pub mod transaction;

7
src/model/db/prelude.rs Normal file
View File

@@ -0,0 +1,7 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
pub use super::account::Entity as Account;
pub use super::book::Entity as Book;
pub use super::category::Entity as Category;
pub use super::tag::Entity as Tag;
pub use super::transaction::Entity as Transaction;

21
src/model/db/tag.rs Normal file
View File

@@ -0,0 +1,21 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "tag")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub name: String,
pub uid: i64,
pub is_deleted: bool,
pub created_at: DateTime,
pub updated_at: DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View File

@@ -0,0 +1,25 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "transaction")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub uid: i64,
pub r#type: i32,
pub book_id: i64,
pub category_id: i64,
pub description: String,
pub transaction_time: DateTimeWithTimeZone,
pub is_deleted: bool,
pub created_at: DateTime,
pub updated_at: DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View File

@@ -0,0 +1,7 @@
use serde::Serialize;
#[derive(Serialize)]
pub struct BookItem {
pub id: i64,
pub name: String,
}

View File

@@ -0,0 +1 @@
pub mod book;

2
src/model/mod.rs Normal file
View File

@@ -0,0 +1,2 @@
pub mod db;
pub mod http_body;