feat: tag api
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
pub mod book;
|
pub mod book;
|
||||||
pub mod category;
|
pub mod category;
|
||||||
|
pub mod tag;
|
||||||
170
src/api/tag.rs
Normal file
170
src/api/tag.rs
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
use axum::routing::{get, post};
|
||||||
|
use axum::{
|
||||||
|
extract::{Path, State},
|
||||||
|
http::StatusCode,
|
||||||
|
Json, Router,
|
||||||
|
};
|
||||||
|
use axum_macros::debug_handler;
|
||||||
|
|
||||||
|
use crate::middleware::auth::Claims;
|
||||||
|
use crate::model::db::tag::ActiveModel as TagActiveModel;
|
||||||
|
use crate::model::db::tag::Column as TagColumn;
|
||||||
|
use crate::model::db::tag::Model as TagModel;
|
||||||
|
use crate::model::db::prelude::Tag;
|
||||||
|
use crate::model::http_body::tag::{TagInfo, TagItem};
|
||||||
|
use crate::model::http_body::common::SimpleResponse;
|
||||||
|
use crate::AppState;
|
||||||
|
use sea_orm::sqlx::types::chrono::Local;
|
||||||
|
use sea_orm::{entity::*, query::*};
|
||||||
|
use sea_orm::{ColumnTrait};
|
||||||
|
|
||||||
|
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
||||||
|
Router::new()
|
||||||
|
.route("/{id}/update",post(update_tag))
|
||||||
|
.route("/{id}",get(get_tag_by_id))
|
||||||
|
.route("/", post(create_tag).get(get_all_tags))
|
||||||
|
}
|
||||||
|
|
||||||
|
// handlers
|
||||||
|
//
|
||||||
|
#[debug_handler]
|
||||||
|
async fn get_all_tags(
|
||||||
|
state: State<AppState>,
|
||||||
|
claims: Claims,
|
||||||
|
) -> Result<Json<Vec<TagItem>>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = claims.uid.clone();
|
||||||
|
let all_tags = Tag::find()
|
||||||
|
.filter(TagColumn::Uid.eq(uid))
|
||||||
|
.all(&state.conn)
|
||||||
|
.await
|
||||||
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||||
|
|
||||||
|
let mut tags: Vec<TagItem> = Vec::new();
|
||||||
|
for b in all_tags {
|
||||||
|
let tag_resp = TagItem {
|
||||||
|
id: b.id.into(),
|
||||||
|
name: b.name,
|
||||||
|
};
|
||||||
|
tags.push(tag_resp);
|
||||||
|
}
|
||||||
|
Ok(Json(tags))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
async fn get_tag_by_id(
|
||||||
|
Path(id): Path<i64>,
|
||||||
|
state: State<AppState>,
|
||||||
|
claims: Claims,
|
||||||
|
) -> Result<Json<TagItem>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = claims.uid.clone();
|
||||||
|
let tag_query = Tag::find()
|
||||||
|
.filter(TagColumn::Uid.eq(uid))
|
||||||
|
.filter(TagColumn::Id.eq(id))
|
||||||
|
.one(&state.conn)
|
||||||
|
.await
|
||||||
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||||
|
|
||||||
|
let tag_resp: TagItem;
|
||||||
|
match tag_query {
|
||||||
|
Some(b) => {
|
||||||
|
tag_resp = TagItem {
|
||||||
|
id: b.id.into(),
|
||||||
|
name: b.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err((StatusCode::NOT_FOUND, "not_found".to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Json(tag_resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
async fn create_tag(
|
||||||
|
state: State<AppState>,
|
||||||
|
claims: Claims,
|
||||||
|
Json(payload): Json<TagInfo>,
|
||||||
|
) -> Result<Json<SimpleResponse>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = claims.uid.clone();
|
||||||
|
|
||||||
|
let tag = TagActiveModel {
|
||||||
|
name: Set(payload.name.clone().to_owned()),
|
||||||
|
uid: Set(uid.to_owned()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = Tag::insert(tag).exec(&state.conn).await;
|
||||||
|
let mut err_code: i64 = 0;
|
||||||
|
let mut msg: String;
|
||||||
|
match res {
|
||||||
|
Ok(_) => {
|
||||||
|
err_code = 0;
|
||||||
|
msg = "ok".to_owned();
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
err_code = 0;
|
||||||
|
msg = e.to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp = SimpleResponse {
|
||||||
|
code: err_code,
|
||||||
|
message: msg,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Json(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
async fn update_tag(
|
||||||
|
Path(id): Path<i64>,
|
||||||
|
state: State<AppState>,
|
||||||
|
claims: Claims,
|
||||||
|
Json(payload): Json<TagInfo>,
|
||||||
|
) -> Result<Json<SimpleResponse>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = claims.uid.clone();
|
||||||
|
|
||||||
|
let exist_tag = Tag::find()
|
||||||
|
.filter(TagColumn::Uid.eq(uid))
|
||||||
|
.filter(TagColumn::Id.eq(id))
|
||||||
|
.one(&state.conn)
|
||||||
|
.await;
|
||||||
|
let tag: TagModel;
|
||||||
|
let mut resp = SimpleResponse {
|
||||||
|
code: 0,
|
||||||
|
message: "ok".to_owned(),
|
||||||
|
};
|
||||||
|
match exist_tag {
|
||||||
|
Ok(b) => match b {
|
||||||
|
Some(bk) => {
|
||||||
|
tag = bk;
|
||||||
|
}
|
||||||
|
_ => return Err((StatusCode::NOT_FOUND, "not_found".to_string())),
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
resp.code = 1;
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"connection_error".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tag_active_model: TagActiveModel = tag.into();
|
||||||
|
tag_active_model.name = Set(payload.name.clone());
|
||||||
|
tag_active_model.updated_at = Set(Local::now().naive_utc());
|
||||||
|
let update_res = tag_active_model.update(&state.conn).await;
|
||||||
|
match update_res {
|
||||||
|
Ok(_) => {
|
||||||
|
resp.code = 0;
|
||||||
|
resp.message = "ok".to_owned();
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"tag_update_fail".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Json(resp))
|
||||||
|
}
|
||||||
@@ -107,6 +107,7 @@ async fn start_server(config: &Config) {
|
|||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.nest("/api/v1/book", api::book::get_nest_handlers())
|
.nest("/api/v1/book", api::book::get_nest_handlers())
|
||||||
.nest("/api/v1/category", api::category::get_nested_handlers())
|
.nest("/api/v1/category", api::category::get_nested_handlers())
|
||||||
|
.nest("/api/v1/tag", api::tag::get_nest_handlers())
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
.layer(global_layer);
|
.layer(global_layer);
|
||||||
let host = config.service.host.clone();
|
let host = config.service.host.clone();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod book;
|
pub mod book;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod category;
|
pub mod category;
|
||||||
|
pub mod tag;
|
||||||
14
src/model/http_body/tag.rs
Normal file
14
src/model/http_body/tag.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use super::common::{number_stringify, OptionalI64};
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct TagItem {
|
||||||
|
#[serde(with="number_stringify")]
|
||||||
|
pub id: OptionalI64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize,Deserialize)]
|
||||||
|
pub struct TagInfo {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user