From 36574b6d68e4cbc2aec9c32a58ccf762046a0ef1 Mon Sep 17 00:00:00 2001 From: kould <2435992353@qq.com> Date: Wed, 13 Dec 2023 15:19:52 +0800 Subject: [PATCH 1/2] fix: dao bugs --- .env | 3 + .env.template | 3 + .gitignore | 1 + Cargo.toml | 5 ++ migration/README.md | 2 +- .../src/m20220101_000001_create_table.rs | 34 +++++----- src/entity/{dialog_2_kb.rs => dialog2_kb.rs} | 3 +- src/entity/dialog_info.rs | 12 ++-- src/entity/{doc_2_doc.rs => doc2_doc.rs} | 3 +- src/entity/doc_info.rs | 18 +++--- src/entity/{kb_2_doc.rs => kb2_doc.rs} | 3 +- src/entity/kb_info.rs | 16 +++-- src/entity/mod.rs | 18 +++--- src/entity/{tag_2_doc.rs => tag2_doc.rs} | 3 +- src/entity/tag_info.rs | 10 ++- src/entity/user_info.rs | 2 - src/main.rs | 63 +++++++++++++++---- src/service/dialog_info.rs | 26 ++++++++ src/service/mod.rs | 1 + 19 files changed, 149 insertions(+), 77 deletions(-) create mode 100644 .env create mode 100644 .env.template rename src/entity/{dialog_2_kb.rs => dialog2_kb.rs} (94%) rename src/entity/{doc_2_doc.rs => doc2_doc.rs} (94%) rename src/entity/{kb_2_doc.rs => kb2_doc.rs} (94%) rename src/entity/{tag_2_doc.rs => tag2_doc.rs} (94%) create mode 100644 src/service/dialog_info.rs diff --git a/.env b/.env new file mode 100644 index 00000000000..a033ac29a9e --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +HOST=127.0.0.1 +PORT=8000 +DATABASE_URL="postgresql://infiniflow:infiniflow@localhost/docgpt" \ No newline at end of file diff --git a/.env.template b/.env.template new file mode 100644 index 00000000000..a033ac29a9e --- /dev/null +++ b/.env.template @@ -0,0 +1,3 @@ +HOST=127.0.0.1 +PORT=8000 +DATABASE_URL="postgresql://infiniflow:infiniflow@localhost/docgpt" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1a48c9228d9..da300c87002 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ Cargo.lock *.pdb .idea/ +.env diff --git a/Cargo.toml b/Cargo.toml index 779323c7b19..05d060a5edc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,14 @@ edition = "2021" [dependencies] actix-web = "4.3.1" actix-rt = "2.8.0" +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"] } +tracing-subscriber = "0.3.18" +dotenvy = "0.15.7" +listenfd = "1.0.1" +migration = { path = "./migration" } [[bin]] name = "doc_gpt" diff --git a/migration/README.md b/migration/README.md index 3b438d89e31..83c18d5d547 100644 --- a/migration/README.md +++ b/migration/README.md @@ -1,4 +1,4 @@ -# Running Migrator CLI + # Running Migrator CLI - Generate a new migration file ```sh diff --git a/migration/src/m20220101_000001_create_table.rs b/migration/src/m20220101_000001_create_table.rs index e2dfd14b721..5e8721c89e2 100644 --- a/migration/src/m20220101_000001_create_table.rs +++ b/migration/src/m20220101_000001_create_table.rs @@ -61,8 +61,7 @@ impl MigrationTrait for Migration { .table(Tag2Doc::Table) .if_not_exists() .col(ColumnDef::new(Tag2Doc::TagId).big_integer()) - .col(ColumnDef::new(Tag2Doc::Did).big_integer().comment("doc id, did in docinfo")) - .index(Index::create().col(Tag2Doc::TagId)) + .col(ColumnDef::new(Tag2Doc::Did).big_integer()) .to_owned(), ) .await?; @@ -73,8 +72,7 @@ impl MigrationTrait for Migration { .table(Kb2Doc::Table) .if_not_exists() .col(ColumnDef::new(Kb2Doc::KbId).big_integer()) - .col(ColumnDef::new(Kb2Doc::Did).big_integer().comment("doc id, did in docinfo")) - .index(Index::create().col(Kb2Doc::KbId)) + .col(ColumnDef::new(Kb2Doc::Did).big_integer()) .to_owned(), ) .await?; @@ -86,7 +84,6 @@ impl MigrationTrait for Migration { .if_not_exists() .col(ColumnDef::new(Dialog2Kb::DialogId).big_integer()) .col(ColumnDef::new(Dialog2Kb::KbId).big_integer()) - .index(Index::create().col(Dialog2Kb::DialogId)) .to_owned(), ) .await?; @@ -96,9 +93,8 @@ impl MigrationTrait for Migration { Table::create() .table(Doc2Doc::Table) .if_not_exists() - .col(ColumnDef::new(Doc2Doc::ParentId).big_integer().comment("doc id, did in docinfo")) - .col(ColumnDef::new(Doc2Doc::Did).big_integer().comment("doc id, did in docinfo")) - .index(Index::create().col(Doc2Doc::ParentId)) + .col(ColumnDef::new(Doc2Doc::ParentId).big_integer()) + .col(ColumnDef::new(Doc2Doc::Did).big_integer()) .to_owned(), ) .await?; @@ -108,15 +104,16 @@ impl MigrationTrait for Migration { Table::create() .table(KbInfo::Table) .if_not_exists() - .col(ColumnDef::new(KbInfo::KbId).big_integer().auto_increment().not_null()) + .col(ColumnDef::new(KbInfo::KbId).big_integer() + .auto_increment() + .not_null() + .primary_key()) .col(ColumnDef::new(KbInfo::Uid).big_integer().not_null()) .col(ColumnDef::new(KbInfo::KbName).string().not_null()) .col(ColumnDef::new(KbInfo::Icon).big_integer().default(1)) .col(ColumnDef::new(KbInfo::CreatedAt).date().not_null()) .col(ColumnDef::new(KbInfo::UpdatedAt).date().not_null()) .col(ColumnDef::new(KbInfo::IsDeleted).boolean().default(false)) - .index(Index::create().col(KbInfo::KbId)) - .index(Index::create().col(KbInfo::Uid)) .to_owned(), ) .await?; @@ -126,7 +123,10 @@ impl MigrationTrait for Migration { Table::create() .table(DocInfo::Table) .if_not_exists() - .col(ColumnDef::new(DocInfo::Did).big_integer().auto_increment().not_null()) + .col(ColumnDef::new(DocInfo::Did).big_integer() + .not_null() + .auto_increment() + .primary_key()) .col(ColumnDef::new(DocInfo::Uid).big_integer().not_null()) .col(ColumnDef::new(DocInfo::DocName).string().not_null()) .col(ColumnDef::new(DocInfo::Size).big_integer().not_null()) @@ -135,8 +135,6 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(DocInfo::CreatedAt).date().not_null()) .col(ColumnDef::new(DocInfo::UpdatedAt).date().not_null()) .col(ColumnDef::new(DocInfo::IsDeleted).boolean().default(false)) - .index(Index::create().col(DocInfo::Did)) - .index(Index::create().col(DocInfo::Uid)) .to_owned(), ) .await?; @@ -146,15 +144,17 @@ impl MigrationTrait for Migration { Table::create() .table(DialogInfo::Table) .if_not_exists() - .col(ColumnDef::new(DialogInfo::DialogId).big_integer().auto_increment().not_null()) + .col(ColumnDef::new(DialogInfo::DialogId) + .big_integer() + .not_null() + .auto_increment() + .primary_key()) .col(ColumnDef::new(DialogInfo::Uid).big_integer().not_null()) .col(ColumnDef::new(DialogInfo::DialogName).string().not_null()) .col(ColumnDef::new(DialogInfo::History).string().comment("json")) .col(ColumnDef::new(DialogInfo::CreatedAt).date().not_null()) .col(ColumnDef::new(DialogInfo::UpdatedAt).date().not_null()) .col(ColumnDef::new(DialogInfo::IsDeleted).boolean().default(false)) - .index(Index::create().col(DialogInfo::DialogId)) - .index(Index::create().col(DialogInfo::Uid)) .to_owned(), ) .await?; diff --git a/src/entity/dialog_2_kb.rs b/src/entity/dialog2_kb.rs similarity index 94% rename from src/entity/dialog_2_kb.rs rename to src/entity/dialog2_kb.rs index c4cbf734cc1..18420f9eb07 100644 --- a/src/entity/dialog_2_kb.rs +++ b/src/entity/dialog2_kb.rs @@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)] -#[sea_orm(table_name = "dialog_2_kb")] +#[sea_orm(table_name = "dialog2_kb")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub dialog_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub kb_id: i64, diff --git a/src/entity/dialog_info.rs b/src/entity/dialog_info.rs index d426b957fc8..d0c49359b40 100644 --- a/src/entity/dialog_info.rs +++ b/src/entity/dialog_info.rs @@ -6,15 +6,13 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub dialog_id: i64, - #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub uid: i64, pub dialog_name: String, pub history: String, - pub created_at: DateTimeWithTimeZone, - pub updated_at: DateTimeWithTimeZone, - #[sea_orm(soft_delete_column)] - pub is_deleted: bool, + pub created_at: Date, + pub updated_at: Date, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] @@ -22,11 +20,11 @@ pub enum Relation {} impl Related for Entity { fn to() -> RelationDef { - super::dialog_2_kb::Relation::KbInfo.def() + super::dialog2_kb::Relation::KbInfo.def() } fn via() -> Option { - Some(super::dialog_2_kb::Relation::DialogInfo.def().rev()) + Some(super::dialog2_kb::Relation::DialogInfo.def().rev()) } } diff --git a/src/entity/doc_2_doc.rs b/src/entity/doc2_doc.rs similarity index 94% rename from src/entity/doc_2_doc.rs rename to src/entity/doc2_doc.rs index a1c0b4595ec..f987a2d5570 100644 --- a/src/entity/doc_2_doc.rs +++ b/src/entity/doc2_doc.rs @@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)] -#[sea_orm(table_name = "doc_2_doc")] +#[sea_orm(table_name = "doc2_doc")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub parent_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub did: i64, diff --git a/src/entity/doc_info.rs b/src/entity/doc_info.rs index f7c9ae436e6..4e5641b2043 100644 --- a/src/entity/doc_info.rs +++ b/src/entity/doc_info.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub did: i64, - #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub uid: i64, pub doc_name: String, pub size: i64, @@ -14,8 +14,8 @@ pub struct Model { pub r#type: String, pub kb_progress: f64, - pub created_at: DateTimeWithTimeZone, - pub updated_at: DateTimeWithTimeZone, + pub created_at: Date, + pub updated_at: Date, #[sea_orm(soft_delete_column)] pub is_deleted: bool, } @@ -25,31 +25,31 @@ pub enum Relation {} impl Related for Entity { fn to() -> RelationDef { - super::tag_2_doc::Relation::Tag.def() + super::tag2_doc::Relation::Tag.def() } fn via() -> Option { - Some(super::tag_2_doc::Relation::DocInfo.def().rev()) + Some(super::tag2_doc::Relation::DocInfo.def().rev()) } } impl Related for Entity { fn to() -> RelationDef { - super::kb_2_doc::Relation::KbInfo.def() + super::kb2_doc::Relation::KbInfo.def() } fn via() -> Option { - Some(super::kb_2_doc::Relation::DocInfo.def().rev()) + Some(super::kb2_doc::Relation::DocInfo.def().rev()) } } impl Related for Entity { fn to() -> RelationDef { - super::doc_2_doc::Relation::Parent.def() + super::doc2_doc::Relation::Parent.def() } fn via() -> Option { - Some(super::doc_2_doc::Relation::Child.def().rev()) + Some(super::doc2_doc::Relation::Child.def().rev()) } } diff --git a/src/entity/kb_2_doc.rs b/src/entity/kb2_doc.rs similarity index 94% rename from src/entity/kb_2_doc.rs rename to src/entity/kb2_doc.rs index a6406e3f15f..f9d92343043 100644 --- a/src/entity/kb_2_doc.rs +++ b/src/entity/kb2_doc.rs @@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)] -#[sea_orm(table_name = "kb_2_doc")] +#[sea_orm(table_name = "kb2_doc")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub kb_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub uid: i64, diff --git a/src/entity/kb_info.rs b/src/entity/kb_info.rs index 1ad16698740..11cb3b2c24f 100644 --- a/src/entity/kb_info.rs +++ b/src/entity/kb_info.rs @@ -6,15 +6,13 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub kb_id: i64, - #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub uid: i64, pub kn_name: String, pub icon: i64, - pub created_at: DateTimeWithTimeZone, - pub updated_at: DateTimeWithTimeZone, - #[sea_orm(soft_delete_column)] - pub is_deleted: bool, + pub created_at: Date, + pub updated_at: Date, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] @@ -22,21 +20,21 @@ pub enum Relation {} impl Related for Entity { fn to() -> RelationDef { - super::kb_2_doc::Relation::DocInfo.def() + super::kb2_doc::Relation::DocInfo.def() } fn via() -> Option { - Some(super::kb_2_doc::Relation::KbInfo.def().rev()) + Some(super::kb2_doc::Relation::KbInfo.def().rev()) } } impl Related for Entity { fn to() -> RelationDef { - super::dialog_2_kb::Relation::DialogInfo.def() + super::dialog2_kb::Relation::DialogInfo.def() } fn via() -> Option { - Some(super::dialog_2_kb::Relation::KbInfo.def().rev()) + Some(super::dialog2_kb::Relation::KbInfo.def().rev()) } } diff --git a/src/entity/mod.rs b/src/entity/mod.rs index 4189e394b04..bc48fdc1608 100644 --- a/src/entity/mod.rs +++ b/src/entity/mod.rs @@ -1,9 +1,9 @@ -mod user_info; -mod tag_info; -mod tag_2_doc; -mod kb_2_doc; -mod dialog_2_kb; -mod doc_2_doc; -mod kb_info; -mod doc_info; -mod dialog_info; \ No newline at end of file +pub(crate) mod user_info; +pub(crate) mod tag_info; +mod tag2_doc; +mod kb2_doc; +mod dialog2_kb; +mod doc2_doc; +pub(crate) mod kb_info; +pub(crate) mod doc_info; +pub(crate) mod dialog_info; \ No newline at end of file diff --git a/src/entity/tag_2_doc.rs b/src/entity/tag2_doc.rs similarity index 94% rename from src/entity/tag_2_doc.rs rename to src/entity/tag2_doc.rs index 5dba1771477..a4bcddca49b 100644 --- a/src/entity/tag_2_doc.rs +++ b/src/entity/tag2_doc.rs @@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)] -#[sea_orm(table_name = "tag_2_doc")] +#[sea_orm(table_name = "tag2_doc")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(index)] pub tag_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub uid: i64, diff --git a/src/entity/tag_info.rs b/src/entity/tag_info.rs index 4aacddb8957..71a6f01f185 100644 --- a/src/entity/tag_info.rs +++ b/src/entity/tag_info.rs @@ -13,10 +13,8 @@ pub struct Model { pub icon: i64, pub dir: String, - pub created_at: DateTimeWithTimeZone, - pub updated_at: DateTimeWithTimeZone, - #[sea_orm(soft_delete_column)] - pub is_deleted: bool, + pub created_at: Date, + pub updated_at: Date, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] @@ -24,11 +22,11 @@ pub enum Relation {} impl Related for Entity { fn to() -> RelationDef { - super::tag_2_doc::Relation::DocInfo.def() + super::tag2_doc::Relation::DocInfo.def() } fn via() -> Option { - Some(super::tag_2_doc::Relation::Tag.def().rev()) + Some(super::tag2_doc::Relation::Tag.def().rev()) } } diff --git a/src/entity/user_info.rs b/src/entity/user_info.rs index d791c08b17d..464d33e636a 100644 --- a/src/entity/user_info.rs +++ b/src/entity/user_info.rs @@ -16,8 +16,6 @@ pub struct Model { pub created_at: DateTimeWithTimeZone, pub updated_at: DateTimeWithTimeZone, - #[sea_orm(soft_delete_column)] - pub is_deleted: bool, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/src/main.rs b/src/main.rs index 6ef93cea573..84a9db0101b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,22 +2,59 @@ mod api; mod entity; mod service; -use actix_web::{get, web, App, HttpServer, Responder}; +use std::env; +use actix_files::Files; +use actix_web::{web, App, HttpServer, Responder, middleware}; +use listenfd::ListenFd; +use sea_orm::{Database, DatabaseConnection}; +use migration::{Migrator, MigratorTrait}; -#[get("/")] -async fn index() -> impl Responder { - "Hello, World!" -} - -#[get("/{name}")] -async fn hello(name: web::Path) -> impl Responder { - format!("Hello {}!", &name) +#[derive(Debug, Clone)] +struct AppState { + conn: DatabaseConnection, } #[actix_web::main] async fn main() -> std::io::Result<()> { - HttpServer::new(|| App::new().service(index).service(hello)) - .bind(("127.0.0.1", 9090))? - .run() - .await + std::env::set_var("RUST_LOG", "debug"); + tracing_subscriber::fmt::init(); + + // get env vars + dotenvy::dotenv().ok(); + let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file"); + let host = env::var("HOST").expect("HOST is not set in .env file"); + let port = env::var("PORT").expect("PORT is not set in .env file"); + let server_url = format!("{host}:{port}"); + + // establish connection to database and apply migrations + // -> create post table if not exists + let conn = Database::connect(&db_url).await.unwrap(); + Migrator::up(&conn, None).await.unwrap(); + + let state = AppState { conn }; + + // create server and try to serve over socket if possible + let mut listenfd = ListenFd::from_env(); + let mut server = HttpServer::new(move || { + App::new() + .service(Files::new("/static", "./static")) + .app_data(web::Data::new(state.clone())) + .wrap(middleware::Logger::default()) + .configure(init) + }); + + server = match listenfd.take_tcp_listener(0)? { + Some(listener) => server.listen(listener)?, + None => server.bind(&server_url)?, + }; + + println!("Starting server at {server_url}"); + server.run().await?; + + Ok(()) +} + +fn init(cfg: &mut web::ServiceConfig) { + // cfg.service(index); + // cfg.service(hello); } \ No newline at end of file diff --git a/src/service/dialog_info.rs b/src/service/dialog_info.rs new file mode 100644 index 00000000000..b2f9f9d305d --- /dev/null +++ b/src/service/dialog_info.rs @@ -0,0 +1,26 @@ +use sea_orm::{DbConn, DbErr, EntityTrait, PaginatorTrait, QueryOrder}; +use crate::entity::dialog_info; +use crate::entity::dialog_info::Entity; + +pub struct Query; + +impl Query { + pub async fn find_dialog_info_by_id(db: &DbConn, id: i64) -> Result, DbErr> { + Entity::find_by_id(id).one(db).await + } + + pub async fn find_dialog_infos_in_page( + db: &DbConn, + page: u64, + posts_per_page: u64, + ) -> Result<(Vec, u64), DbErr> { + // Setup paginator + let paginator = Entity::find() + .order_by_asc(dialog_info::Column::DialogId) + .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)) + } +} \ No newline at end of file diff --git a/src/service/mod.rs b/src/service/mod.rs index e69de29bb2d..58e1c14765c 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -0,0 +1 @@ +pub(crate) mod dialog_info; \ No newline at end of file From 80b8d332006ae9e05929ce65e807a9849dbd0c06 Mon Sep 17 00:00:00 2001 From: kould <2435992353@qq.com> Date: Wed, 13 Dec 2023 16:27:00 +0800 Subject: [PATCH 2/2] feat impl tags api --- Cargo.toml | 1 + .../src/m20220101_000001_create_table.rs | 4 +- src/api/mod.rs | 10 ++ src/api/tag.rs | 58 ++++++++++++ src/entity/tag2_doc.rs | 2 +- src/entity/tag_info.rs | 1 + src/main.rs | 7 +- src/service/mod.rs | 3 +- src/service/tag_info.rs | 94 +++++++++++++++++++ 9 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 src/api/tag.rs create mode 100644 src/service/tag_info.rs diff --git a/Cargo.toml b/Cargo.toml index 05d060a5edc..e27e50d8cfb 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 5e8721c89e2..4269fdcff42 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 e69de29bb2d..f8cf91d9e91 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 00000000000..3af8a65a85f --- /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 a4bcddca49b..61453c4f3c4 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 71a6f01f185..230ed855862 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 84a9db0101b..25757443eef 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 58e1c14765c..ceecbc1b999 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 00000000000..c0a3ce774e8 --- /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