From 5dab0ecdf6509bb6403908b1d946b9751907f984 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 16 Mar 2025 20:04:08 +0800 Subject: [PATCH] :art: When deleting a referenced definition block, a pop-up window will prompt the user https://github.com/siyuan-note/siyuan/issues/13396 --- kernel/api/block.go | 19 +++++++++++++ kernel/api/router.go | 1 + kernel/model/block.go | 56 ++++++++++++++++++++++++++++----------- kernel/model/flashcard.go | 16 +++++++++++ 4 files changed, 77 insertions(+), 15 deletions(-) diff --git a/kernel/api/block.go b/kernel/api/block.go index e0f776a54..3948d4c67 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -31,6 +31,25 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func checkBlockRef(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + idsArg := arg["ids"].([]interface{}) + var ids []string + for _, id := range idsArg { + ids = append(ids, id.(string)) + } + ids = gulu.Str.RemoveDuplicatedElem(ids) + + ret.Data = model.CheckBlockRef(ids) +} + func getBlockTreeInfos(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/router.go b/kernel/api/router.go index 142e5ed3c..f4788bf91 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -214,6 +214,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/transferBlockRef", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, transferBlockRef) ginServer.Handle("POST", "/api/block/getBlockSiblingID", model.CheckAuth, getBlockSiblingID) ginServer.Handle("POST", "/api/block/getBlockTreeInfos", model.CheckAuth, getBlockTreeInfos) + ginServer.Handle("POST", "/api/block/checkBlockRef", model.CheckAuth, checkBlockRef) ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile) ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, putFile) diff --git a/kernel/model/block.go b/kernel/model/block.go index 432ce4a2a..aec7721f4 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "github.com/88250/gulu" "github.com/88250/lute/ast" "github.com/88250/lute/parse" "github.com/88250/lute/render" @@ -76,21 +77,6 @@ type RiffCard struct { LastReview time.Time `json:"lastReview"` } -func getRiffCard(card *fsrs.Card) *RiffCard { - due := card.Due - if due.IsZero() { - due = time.Now() - } - - return &RiffCard{ - Due: due, - Reps: card.Reps, - Lapses: card.Lapses, - State: card.State, - LastReview: card.LastReview, - } -} - func (block *Block) IsContainerBlock() bool { switch block.Type { case "NodeDocument", "NodeBlockquote", "NodeList", "NodeListItem", "NodeSuperBlock": @@ -120,6 +106,46 @@ type Path struct { Created string `json:"created"` // 创建时间 } +func CheckBlockRef(ids []string) bool { + bts := treenode.GetBlockTrees(ids) + + var rootIDs, blockIDs []string + for _, bt := range bts { + if "d" == bt.Type { + rootIDs = append(rootIDs, bt.ID) + } else { + blockIDs = append(blockIDs, bt.ID) + } + } + rootIDs = gulu.Str.RemoveDuplicatedElem(rootIDs) + blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs) + + existRef := func(refCounts map[string]int) bool { + for _, refCount := range refCounts { + if 0 < refCount { + return true + } + } + return false + } + + for _, rootID := range rootIDs { + refCounts := sql.QueryRootChildrenRefCount(rootID) + if existRef(refCounts) { + return true + } + } + + refCounts := sql.QueryRefCount(blockIDs) + if existRef(refCounts) { + return true + } + + // TODO 还需要考虑容器块的子块引用计数 https://github.com/siyuan-note/siyuan/issues/13396 + + return false +} + type BlockTreeInfo struct { ID string `json:"id"` Type string `json:"type"` diff --git a/kernel/model/flashcard.go b/kernel/model/flashcard.go index 38f7b3c01..471788f94 100644 --- a/kernel/model/flashcard.go +++ b/kernel/model/flashcard.go @@ -29,6 +29,7 @@ import ( "github.com/88250/gulu" "github.com/88250/lute/ast" "github.com/88250/lute/parse" + "github.com/open-spaced-repetition/go-fsrs/v3" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" "github.com/siyuan-note/riff" @@ -434,6 +435,21 @@ func getCardsBlocks(cards []riff.Card, page, pageSize int) (blocks []*Block, tot return } +func getRiffCard(card *fsrs.Card) *RiffCard { + due := card.Due + if due.IsZero() { + due = time.Now() + } + + return &RiffCard{ + Due: due, + Reps: card.Reps, + Lapses: card.Lapses, + State: card.State, + LastReview: card.LastReview, + } +} + var ( // reviewCardCache 用于复习时缓存卡片,以便支持撤销。 reviewCardCache = map[string]riff.Card{}