diff --git a/Cargo.toml b/Cargo.toml index 05d060a5e..e27e50d8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/migration/src/m20220101_000001_create_table.rs b/migration/src/m20220101_000001_create_table.rs index 5e8721c89..4269fdcff 100644 --- a/migration/src/m20220101_000001_create_table.rs +++ b/migration/src/m20220101_000001_create_table.rs @@ -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, diff --git a/src/api/mod.rs b/src/api/mod.rs index e69de29bb..f8cf91d9e 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -0,0 +1,10 @@ +use serde::{Deserialize, Serialize}; + +pub(crate) mod tag; + +#[derive(Debug, Deserialize, Serialize)] +struct JsonResponse { + code: u32, + err: String, + data: T, +} \ No newline at end of file diff --git a/src/api/tag.rs b/src/api/tag.rs new file mode 100644 index 000000000..3af8a65a8 --- /dev/null +++ b/src/api/tag.rs @@ -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, data: web::Data) -> Result { + 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, data: web::Data) -> Result { + 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) -> Result { + 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())) +} \ No newline at end of file diff --git a/src/entity/tag2_doc.rs b/src/entity/tag2_doc.rs index a4bcddca4..61453c4f3 100644 --- a/src/entity/tag2_doc.rs +++ b/src/entity/tag2_doc.rs @@ -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(), } } diff --git a/src/entity/tag_info.rs b/src/entity/tag_info.rs index 71a6f01f1..230ed8558 100644 --- a/src/entity/tag_info.rs +++ b/src/entity/tag_info.rs @@ -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, diff --git a/src/main.rs b/src/main.rs index 84a9db010..25757443e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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); } \ No newline at end of file diff --git a/src/service/mod.rs b/src/service/mod.rs index 58e1c1476..ceecbc1b9 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1 +1,2 @@ -pub(crate) mod dialog_info; \ No newline at end of file +pub(crate) mod dialog_info; +pub(crate) mod tag_info; \ No newline at end of file diff --git a/src/service/tag_info.rs b/src/service/tag_info.rs new file mode 100644 index 000000000..c0a3ce774 --- /dev/null +++ b/src/service/tag_info.rs @@ -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, DbErr> { + Entity::find_by_id(id).one(db).await + } + + pub async fn find_tag_infos(db: &DbConn) -> Result, DbErr> { + Entity::find().all(db).await + } + + pub async fn find_tag_infos_in_page( + db: &DbConn, + page: u64, + posts_per_page: u64, + ) -> Result<(Vec, 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 { + 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 { + 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 { + 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 { + Entity::delete_many().exec(db).await + } +} \ No newline at end of file