feat impl tags api

This commit is contained in:
kould 2023-12-13 16:27:00 +08:00
parent 36574b6d68
commit 80b8d33200
9 changed files with 174 additions and 6 deletions

View file

@ -12,6 +12,7 @@ actix-files = "0.6.2"
postgres = "0.19.7"
sea-orm = {version = "0.12.9", features = ["sqlx-postgres", "runtime-tokio-native-tls", "macros"]}
serde = { version = "1", features = ["derive"] }
serde_json = "1.0"
tracing-subscriber = "0.3.18"
dotenvy = "0.15.7"
listenfd = "1.0.1"

View file

@ -37,12 +37,13 @@ impl MigrationTrait for Migration {
.table(TagInfo::Table)
.if_not_exists()
.col(
ColumnDef::new(TagInfo::Uid)
ColumnDef::new(TagInfo::Tid)
.big_integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(TagInfo::Uid).big_integer().not_null())
.col(ColumnDef::new(TagInfo::TagName).string().not_null())
.col(ColumnDef::new(TagInfo::Regx).string())
.col(ColumnDef::new(TagInfo::Color).big_integer().default(1))
@ -221,6 +222,7 @@ enum UserInfo {
#[derive(DeriveIden)]
enum TagInfo {
Table,
Tid,
Uid,
TagName,
Regx,

View file

@ -0,0 +1,10 @@
use serde::{Deserialize, Serialize};
pub(crate) mod tag;
#[derive(Debug, Deserialize, Serialize)]
struct JsonResponse<T> {
code: u32,
err: String,
data: T,
}

58
src/api/tag.rs Normal file
View file

@ -0,0 +1,58 @@
use std::collections::HashMap;
use actix_web::{get, HttpResponse, post, web};
use actix_web::http::Error;
use crate::api::JsonResponse;
use crate::AppState;
use crate::entity::tag_info;
use crate::service::tag_info::{Mutation, Query};
#[post("/v1.0/create_tag")]
async fn create(model: web::Json<tag_info::Model>, data: web::Data<AppState>) -> Result<HttpResponse, Error> {
let model = Mutation::create_tag(&data.conn, model.into_inner()).await.unwrap();
let mut result = HashMap::new();
result.insert("tid", model.uid.unwrap());
let json_response = JsonResponse {
code: 200,
err: "".to_owned(),
data: result,
};
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(serde_json::to_string(&json_response).unwrap()))
}
#[post("/v1.0/delete_tag")]
async fn delete(model: web::Json<tag_info::Model>, data: web::Data<AppState>) -> Result<HttpResponse, Error> {
let _ = Mutation::delete_tag(&data.conn, model.tid).await.unwrap();
let json_response = JsonResponse {
code: 200,
err: "".to_owned(),
data: (),
};
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(serde_json::to_string(&json_response).unwrap()))
}
#[get("/v1.0/tags")]
async fn list(data: web::Data<AppState>) -> Result<HttpResponse, Error> {
let tags = Query::find_tag_infos(&data.conn).await.unwrap();
let mut result = HashMap::new();
result.insert("tags", tags);
let json_response = JsonResponse {
code: 200,
err: "".to_owned(),
data: result,
};
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(serde_json::to_string(&json_response).unwrap()))
}

View file

@ -26,7 +26,7 @@ impl RelationTrait for Relation {
.into(),
Self::Tag => Entity::belongs_to(super::tag_info::Entity)
.from(Column::TagId)
.to(super::tag_info::Column::Uid)
.to(super::tag_info::Column::Tid)
.into(),
}
}

View file

@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
pub struct Model {
#[sea_orm(primary_key)]
#[serde(skip_deserializing)]
pub tid: i64,
pub uid: i64,
pub tag_name: String,
pub regx: String,

View file

@ -4,7 +4,7 @@ mod service;
use std::env;
use actix_files::Files;
use actix_web::{web, App, HttpServer, Responder, middleware};
use actix_web::{web, App, HttpServer, middleware};
use listenfd::ListenFd;
use sea_orm::{Database, DatabaseConnection};
use migration::{Migrator, MigratorTrait};
@ -55,6 +55,7 @@ async fn main() -> std::io::Result<()> {
}
fn init(cfg: &mut web::ServiceConfig) {
// cfg.service(index);
// cfg.service(hello);
cfg.service(api::tag::create);
cfg.service(api::tag::delete);
cfg.service(api::tag::list);
}

View file

@ -1 +1,2 @@
pub(crate) mod dialog_info;
pub(crate) mod dialog_info;
pub(crate) mod tag_info;

94
src/service/tag_info.rs Normal file
View file

@ -0,0 +1,94 @@
use sea_orm::{ActiveModelTrait, DbConn, DbErr, DeleteResult, EntityTrait, PaginatorTrait, QueryOrder};
use sea_orm::ActiveValue::Set;
use crate::entity::tag_info;
use crate::entity::tag_info::Entity;
pub struct Query;
impl Query {
pub async fn find_tag_info_by_id(db: &DbConn, id: i64) -> Result<Option<tag_info::Model>, DbErr> {
Entity::find_by_id(id).one(db).await
}
pub async fn find_tag_infos(db: &DbConn) -> Result<Vec<tag_info::Model>, DbErr> {
Entity::find().all(db).await
}
pub async fn find_tag_infos_in_page(
db: &DbConn,
page: u64,
posts_per_page: u64,
) -> Result<(Vec<tag_info::Model>, u64), DbErr> {
// Setup paginator
let paginator = Entity::find()
.order_by_asc(tag_info::Column::Uid)
.paginate(db, posts_per_page);
let num_pages = paginator.num_pages().await?;
// Fetch paginated posts
paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))
}
}
pub struct Mutation;
impl Mutation {
pub async fn create_tag(
db: &DbConn,
form_data: tag_info::Model,
) -> Result<tag_info::ActiveModel, DbErr> {
tag_info::ActiveModel {
tid: Set(form_data.tid.to_owned()),
uid: Set(form_data.uid.to_owned()),
tag_name: Set(form_data.tag_name.to_owned()),
regx: Set(form_data.regx.to_owned()),
color: Set(form_data.color.to_owned()),
icon: Set(form_data.icon.to_owned()),
dir: Set(form_data.dir.to_owned()),
created_at: Default::default(),
updated_at: Default::default(),
}
.save(db)
.await
}
pub async fn update_tag_by_id(
db: &DbConn,
id: i64,
form_data: tag_info::Model,
) -> Result<tag_info::Model, DbErr> {
let tag: tag_info::ActiveModel = Entity::find_by_id(id)
.one(db)
.await?
.ok_or(DbErr::Custom("Cannot find post.".to_owned()))
.map(Into::into)?;
tag_info::ActiveModel {
tid: tag.tid,
uid: tag.uid,
tag_name: Set(form_data.tag_name.to_owned()),
regx: Set(form_data.regx.to_owned()),
color: Set(form_data.color.to_owned()),
icon: Set(form_data.icon.to_owned()),
dir: Set(form_data.dir.to_owned()),
created_at: Default::default(),
updated_at: Default::default(),
}
.update(db)
.await
}
pub async fn delete_tag(db: &DbConn, tid: i64) -> Result<DeleteResult, DbErr> {
let tag: tag_info::ActiveModel = Entity::find_by_id(tid)
.one(db)
.await?
.ok_or(DbErr::Custom("Cannot find tag.".to_owned()))
.map(Into::into)?;
tag.delete(db).await
}
pub async fn delete_all_tags(db: &DbConn) -> Result<DeleteResult, DbErr> {
Entity::delete_many().exec(db).await
}
}