Skip to content

Commit

Permalink
feat: 标签集查询
Browse files Browse the repository at this point in the history
  • Loading branch information
yanghua committed Feb 7, 2025
1 parent 1e6b778 commit 6728bcb
Show file tree
Hide file tree
Showing 30 changed files with 638 additions and 101 deletions.
3 changes: 1 addition & 2 deletions backend-rust/src/api/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use axum::{routing::get, Router};
use crate::AppState;

pub fn new() -> Router<Arc<AppState>> {
Router::new()
.route("/", get(ping))
Router::new().route("/", get(ping))
}

async fn ping() -> &'static str {
Expand Down
13 changes: 13 additions & 0 deletions backend-rust/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
use std::sync::Arc;

use axum::Router;

use crate::AppState;

pub mod auth;
pub mod user;

pub fn new() -> Router<Arc<AppState>> {
Router::new()
.nest("/api/auth", auth::new())
.nest("/api/user", user::new())
}
23 changes: 23 additions & 0 deletions backend-rust/src/api/user.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::sync::Arc;

use axum::{extract::State, routing::put, Router};

use crate::AppState;

pub fn new() -> Router<Arc<AppState>> {
Router::new().route("/", put(registry))
}

async fn registry(State(app_state): State<Arc<AppState>>) -> String {
// 提取用户名与密码
let result: Result<(i64,), sqlx::Error> = sqlx::query_as("select $1")
.bind(86_i64)
.fetch_one(&app_state.pool)
.await;

if let Ok(row) = result {
return format!("{}", row.0);
}

String::from("LPL")
}
40 changes: 10 additions & 30 deletions backend-rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
use std::sync::Arc;

use axum::{
extract::State, routing::get, Router
};
use clap::Parser;
use store::db;

mod store;
mod api;
mod store;

#[derive(Parser,Debug)]
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[arg(long)]
host: String,
#[arg(long)]
port: String,
#[arg(long)]
db:String,
db: String,
#[arg(long)]
user: String,
#[arg(long)]
pass:String,
pass: String,
}

#[derive(Clone)]
Expand All @@ -31,40 +28,23 @@ struct AppState {

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {

let args = Args::parse();

let store_db = store::db::new(db::Config{
let store_db = store::db::new(db::Config {
host: args.host.clone(),
port: args.port.clone(),
user: args.user.clone(),
pass: args.pass.clone(),
db: args.db.clone(),
}).await?;
})
.await?;

let app_state = Arc::new(AppState {
let app = api::new().with_state(Arc::new(AppState {
pool: store_db.pool,
});

let auth_api = api::auth::new();
}));

let app = Router::new()
.route("/", get(root))
.nest("/user", auth_api)
.with_state(app_state);

let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
let listener = tokio::net::TcpListener::bind("0.0.0.0:5623").await.unwrap();
axum::serve(listener, app).await.unwrap();

Ok(())
}

async fn root(State(app):State<Arc<AppState>>) -> &'static str{
let result :Result<(i64,), sqlx::Error> = sqlx::query_as("select $1")
.bind(150_i64)
.fetch_one(&app.pool).await;
if let Ok(row) = result {
println!("{}", row.0);
}
"hello, anqzi!"
}
1 change: 1 addition & 0 deletions backend-rust/src/store/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod db;
pub mod user;
Empty file added backend-rust/src/store/user.rs
Empty file.
48 changes: 48 additions & 0 deletions backend/api/memo/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func NewMemoApi(group fiber.Router) fiber.Router {
memoApi.Patch("", UpdateMemo)
memoApi.Post("/all", QueryMemos)
memoApi.Post("/tags", QueryTags)
memoApi.Post("/filter", QueryMemosByFilter)
memoApi.Post("/:id", QueryMemoById)

return memoApi
Expand Down Expand Up @@ -183,6 +184,53 @@ func QueryMemos(c *fiber.Ctx) error {
return c.JSON(memos)
}

type MemoQueryFilter struct {
PageNo int64 `json:"pageNo"`
PageSize int64 `json:"pageSize"`
Tags []string `json:"tags"`
}

func QueryMemosByFilter(c *fiber.Ctx) error {

memoQueryFilter := MemoQueryFilter{}

err := c.BodyParser(&memoQueryFilter)

if err != nil {
return errors.New("请求参数错误")
}

if memoQueryFilter.PageNo == 0 {
memoQueryFilter.PageNo = 1
}
if memoQueryFilter.PageSize == 0 {
memoQueryFilter.PageSize = 10
}

_store, _ := c.Locals("store").(*store.Store)
userId, _ := c.Locals("user_id").(string)

memos, err := store.QueryMemos(store.MemoQuery{
CreatorId: userId,
PageNo: memoQueryFilter.PageNo,
PageSize: memoQueryFilter.PageSize,
Tags: memoQueryFilter.Tags,
}, *_store)

if err != nil {
return err
}

// markdown转换为html
for index := range memos {
text := []byte(memos[index].Content)
tokens := parser.Parser(text)
memos[index].Content = render.RenderToHtml(text, tokens)
}

return c.JSON(memos)
}

func QueryMemoById(c *fiber.Ctx) error {

id := c.Params("id")
Expand Down
111 changes: 69 additions & 42 deletions backend/store/memo.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type MemoQuery struct {
CreatorId string
PageSize int64
PageNo int64
Tags []string
}

type Tag struct {
Expand Down Expand Up @@ -73,26 +74,16 @@ func CreateMemo(memoCreate MemoCreate, store Store) (Memo, error) {
return Memo{}, err
}
defer tx.Rollback()
// 查询已经存在的tags
// rows, err := tx.Query("select name, creator_id from tags where creator_id=$1", memoCreate.CreatorId)
// if err != nil {
// return Memo{}, err
// }
// defer rows.Close()

// tagsMap := make(map[string]bool, len(memoCreate.Tags))
// for _, tag := range memoCreate.Tags {
// tagsMap[tag] = false
// }
// for rows.Next() {
// var name string
// err = rows.Scan(&name)
// if err != nil {
// return Memo{}, err
// }
// tagsMap[name] = true
// }
// 过滤不存在标签

err = tx.QueryRow(
"insert into memos (markdown, creator_id) values ($1, $2) returning id, created_at, updated_at;",
memoCreate.Content,
memoCreate.CreatorId,
).Scan(&memo.Id, &memo.CreateAt, &memo.UpdateAt)

if err != nil {
return Memo{}, err
}

if len(memoCreate.Tags) > 0 {
valuesStr := make([]any, 0, len(memoCreate.Tags)*2)
Expand All @@ -101,21 +92,42 @@ func CreateMemo(memoCreate MemoCreate, store Store) (Memo, error) {
valuesStr = append(valuesStr, tag, memoCreate.CreatorId)
placeholderStr[index] = fmt.Sprintf("($%d,$%d)", 2*index+1, 2*index+2)
}
queryStmt := fmt.Sprintf(`insert into tags (name, creator_id) values %s on conflict (name, creator_id) do update set name=excluded.name, creator_id=excluded.creator_id;`, strings.Join(placeholderStr, ","))
queryStmt := fmt.Sprintf(`insert into tags (name, creator_id) values %s on conflict (name, creator_id) do update set name=excluded.name, creator_id=excluded.creator_id returning id, name;`, strings.Join(placeholderStr, ","))

rows, err := tx.Query(queryStmt, valuesStr...)

if _, err = tx.Exec(queryStmt, valuesStr...); err != nil {
if err != nil {
return Memo{}, err
}
}

err = tx.QueryRow(
"insert into memos (markdown, creator_id) values ($1, $2) returning id, created_at, updated_at;",
memoCreate.Content,
memoCreate.CreatorId,
).Scan(&memo.Id, &memo.CreateAt, &memo.UpdateAt)
defer rows.Close()

if err != nil {
return Memo{}, err
memoTagPairStr := make([]any, 0, len(memoCreate.Tags)*2)

for rows.Next() {

tagMemo := TagMemo{
MemoId: memo.Id,
// CreatorId: memo.CreatorId,
}

err = rows.Scan(&tagMemo.TagId, &tagMemo.TagName)

if err != nil {
return Memo{}, err
}

memoTagPairStr = append(memoTagPairStr, tagMemo.TagId, tagMemo.MemoId)
}

// 插入memo-tag
queryStmt = fmt.Sprintf(`insert into memo_tag (tag_id, memo_id) values %s on conflict (tag_id, memo_id) do update set tag_id=excluded.tag_id, memo_id=excluded.memo_id;`, strings.Join(placeholderStr, ","))

_, err = tx.Exec(queryStmt, memoTagPairStr...)

if err != nil {
return Memo{}, err
}
}

if err = tx.Commit(); err != nil {
Expand Down Expand Up @@ -260,20 +272,35 @@ func QueryMemos(memoQuery MemoQuery, store Store) ([]Memo, error) {
var rows *sql.Rows
var err error

if memoQuery.PageNo != 0 && memoQuery.PageSize != 0 {
rows, err = store.db.Query(
"select memos.id, memos.markdown, memos.created_at, memos.updated_at, memos.creator_id, memos.status, users.username from memos left join users on memos.creator_id = users.id where creator_id=$1 order by created_at desc limit $2 offset $3",
memoQuery.CreatorId,
memoQuery.PageSize,
(memoQuery.PageNo-1)*memoQuery.PageSize,
)
} else {
rows, err = store.db.Query(
"select memos.id, memos.markdown, memos.created_at, memos.updated_at, memos.creator_id, memos.status, users.username from memos left join users on memos.creator_id = users.id where creator_id=$1 order by created_at desc",
memoQuery.CreatorId,
)
tags := ""
queryResultFiled := "memos.id, memos.markdown, memos.created_at, memos.updated_at, memos.creator_id, memos.status, users.username"
queryTags := ""
queryWhere := "creator_id=$1"
if len(memoQuery.Tags) > 0 {
tags = fmt.Sprintf("memo_tag.tag_id in (%s)", strings.Join(memoQuery.Tags, ","))
queryWhere += fmt.Sprintf(" and %s", tags)
queryTags = "join memo_tag on memos.id = memo_tag.memo_id"
}

if memoQuery.PageNo == 0 {
memoQuery.PageNo = 1
}
if memoQuery.PageSize == 0 {
memoQuery.PageSize = 10
}

rows, err = store.db.Query(
fmt.Sprintf(
"select %s from memos %s join users on memos.creator_id = users.id where %s group by memos.id, users.username order by created_at desc limit $2 offset $3",
queryResultFiled,
queryTags,
queryWhere,
),
memoQuery.CreatorId,
memoQuery.PageSize,
(memoQuery.PageNo-1)*memoQuery.PageSize,
)

if err != nil {
return []Memo{}, err
}
Expand Down
9 changes: 5 additions & 4 deletions mark-parser/parser/inline/inline.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ type Indexes struct {
}

const (
Code InlineType = 1
Blob InlineType = 2
Tag InlineType = 3
Link InlineType = 4
Code InlineType = 1
Blob InlineType = 2
Tag InlineType = 3
Link InlineType = 4
MemoLink InlineType = 5
)

func InlineParse(text []byte, tokens []token.Token, blockStartIndex int, parsers []Inline) []token.Token {
Expand Down
22 changes: 22 additions & 0 deletions mark-parser/parser/inline/memo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package inline

import "regexp"

const (
MemoRegexp = `^@\[(.*)\]`
)

func FindMemoIndex(texts []byte) (Indexes, bool) {
re, _ := regexp.Compile(MemoRegexp)

matches := re.FindSubmatchIndex(texts)

if len(matches) == 4 {
return Indexes{
Indexes: matches,
Type: MemoLink,
Matches: matches[2:],
}, true
}
return Indexes{}, false
}
5 changes: 5 additions & 0 deletions mark-parser/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func Parser(text []byte) []token.Token {
Tag: "link",
Matcher: inline.FindLinkIndex,
},
{
Type: inline.MemoLink,
Tag: "memo",
Matcher: inline.FindMemoIndex,
},
}

tokens := []token.Token{}
Expand Down
3 changes: 3 additions & 0 deletions mark-parser/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ func RenderInline(texts []byte, token token.Token) string {
case int(inline.Link):
link := string(texts[token.BlockStartIndex+token.Matches[2] : token.BlockStartIndex+token.Matches[3]])
return fmt.Sprintf("<a class=\"outlink\" target=\"_blank\" href=\"%s\">%s</a>", link, text)
case int(inline.MemoLink):
link := string(texts[token.BlockStartIndex+token.Matches[0] : token.BlockStartIndex+token.Matches[1]])
return fmt.Sprintf("<a class=\"memo-link\"><span class=\"memo-link-mark i-lucide:link\"></span>%s</a>", link)
}

return text
Expand Down
Loading

0 comments on commit 6728bcb

Please sign in to comment.