// use std::sync::Arc; use axum::routing::{get, post}; use axum::{ extract::{Path, State}, http::StatusCode, Json, Router, }; use axum_macros::debug_handler; use diesel::prelude::*; // use diesel::update; use serde::{Deserialize, Serialize}; // use serde_json::to_string; use crate::model::db_model; use crate::model::schema; use crate::util; // use crate::model::schema::categories::dsl::categories; use crate::util::req::CommonResp; use chrono::prelude::*; use tracing::info; use crate::middleware::auth; use crate::middleware::auth::Claims; #[derive(Serialize)] pub struct CreateCategoryResponse { id: i64, name: String, level: i32, parent_category_id: i64, } pub fn get_nest_handlers() -> Router { Router::new() .route("/", post(create_category).get(get_all_categories)) .route("/:id", post(update_category).get(get_category)) } #[derive(Deserialize)] pub struct CreateCategoryRequest { name: String, level: i32, parent_category_id: i64, } #[debug_handler] pub async fn create_category( State(app_state): State, claims: Claims, Json(payload): Json, ) -> Result, (StatusCode, String)> { let uid: i64 = claims.uid.clone(); // TODO replace with actual user id. // let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()}; let conn = app_state .db .get() .await .map_err(util::req::internal_error)?; let new_category = db_model::CategoryForm { name: payload.name, uid: uid, level: payload.level, parent_category_id: payload.parent_category_id, }; let res = conn .interact(move |conn| { diesel::insert_into(schema::categories::table) .values(&new_category) .returning(db_model::Category::as_returning()) .get_result(conn) }) .await .map_err(util::req::internal_error)? .map_err(util::req::internal_error)?; // let ret = CreateCategoryResponse{id: res.id, name: res.name}; Ok(Json(res)) } pub async fn update_category( Path(id): Path, State(app_state): State, claims: Claims, Json(payload): Json, ) -> Result, (StatusCode, String)> { let uid: i64 = claims.uid.clone(); // TODO replace with actual user id. // let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()}; let conn = app_state .db .get() .await .map_err(util::req::internal_error)?; let now = Utc::now().naive_utc(); let res = conn .interact(move |conn| { diesel::update(schema::categories::table) .filter(schema::categories::id.eq(id)) .filter(schema::categories::uid.eq(uid)) .set(( schema::categories::name.eq(payload.name), schema::categories::level.eq(payload.level), schema::categories::parent_category_id.eq(payload.parent_category_id), schema::categories::update_at.eq(now), )) .execute(conn) }) .await .map_err(util::req::internal_error)? .map_err(util::req::internal_error)?; // let ret = CreateCategoryResponse{id: res.id, name: res.name}; let resp = util::req::CommonResp { code: 0 }; Ok(Json(resp)) } pub async fn get_category( Path(id): Path, State(app_state): State, claims: Claims, ) -> Result, (StatusCode, String)> { let uid: i64 = claims.uid.clone(); let conn = app_state .db .get() .await .map_err(util::req::internal_error)?; let res = conn .interact(move |conn| { schema::categories::table .filter(schema::categories::id.eq(id)) .filter(schema::categories::uid.eq(uid)) .select(db_model::Category::as_select()) .limit(1) .get_result(conn) }) .await .map_err(util::req::internal_error)? .map_err(util::req::internal_error)?; Ok(Json(res)) } pub async fn get_all_categories( State(app_state): State, claims: Claims, ) -> Result>, (StatusCode, String)> { let uid: i64 = claims.uid.clone(); let conn = app_state .db .get() .await .map_err(util::req::internal_error)?; let res = conn .interact(move |conn| { schema::categories::table .filter(schema::categories::uid.eq(uid)) .select(db_model::Category::as_select()) .load(conn) }) .await .map_err(util::req::internal_error)? .map_err(util::req::internal_error)?; Ok(Json(res)) }