🎨 When deleting a referenced definition block, a pop-up window will prompt the user https://github.com/siyuan-note/siyuan/issues/13396

This commit is contained in:
Daniel 2025-03-16 20:04:08 +08:00
parent fe3caaaa6b
commit 5dab0ecdf6
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
4 changed files with 77 additions and 15 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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"`

View file

@ -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 <cardID, card> 用于复习时缓存卡片,以便支持撤销。
reviewCardCache = map[string]riff.Card{}