mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 23:20:13 +01:00
🎨 改进闪卡存储数据结构,支持一个块对应多张闪卡 https://github.com/siyuan-note/siyuan/issues/7417
This commit is contained in:
parent
fe9abe4b4b
commit
7bceb8e641
4 changed files with 120 additions and 33 deletions
|
|
@ -254,7 +254,7 @@ func deckData(deck *riff.Deck) map[string]interface{} {
|
|||
return map[string]interface{}{
|
||||
"id": deck.ID,
|
||||
"name": deck.Name,
|
||||
"size": len(deck.BlockCard),
|
||||
"size": deck.CountCards(),
|
||||
"created": time.UnixMilli(deck.Created).Format("2006-01-02 15:04:05"),
|
||||
"updated": time.UnixMilli(deck.Updated).Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ require (
|
|||
github.com/siyuan-note/filelock v0.0.0-20230223100551-200cbe1cf84e
|
||||
github.com/siyuan-note/httpclient v0.0.0-20230224113038-40f0e2672f0f
|
||||
github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb
|
||||
github.com/siyuan-note/riff v0.0.0-20230224074237-c16f59420520
|
||||
github.com/siyuan-note/riff v0.0.0-20230224144841-cfbe0748ddb7
|
||||
github.com/steambap/captcha v1.4.1
|
||||
github.com/studio-b12/gowebdav v0.0.0-20230203202212-3282f94193f2
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5
|
||||
|
|
|
|||
|
|
@ -288,6 +288,18 @@ github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb h1:qzz7ZQw7/tH
|
|||
github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb/go.mod h1:6mRFtAAvYPn3cDzqvyv+t8BVPGqpONDMMb5ywOhY1D4=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224074237-c16f59420520 h1:14vDSmi+YYBCnPb41ESSaq8kzgx6Sj4fE1mNJQwVObw=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224074237-c16f59420520/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224124310-d7b524f12a93 h1:sr98gF9C+JansB+A1PbIPMoYMzipaYLo/l7tuzfiVsE=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224124310-d7b524f12a93/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224135851-50a5d05ebc1f h1:WmTcCgdOf+PxsFOBkbxsPLsEtjFoN8G/Iy/XRjfpsKw=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224135851-50a5d05ebc1f/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224140523-e14e716c1b0b h1:mvyYjIIwOK/BqBbwZClldcMB/XUEC7/Mudee1S81WVA=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224140523-e14e716c1b0b/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224141518-b70f9beb2db0 h1:3RGcJ0UOkwm5bQR6yBua3SgZYSxyblrFItjbbbWPIzE=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224141518-b70f9beb2db0/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224143400-ff2c16506fcd h1:KBaZACXvXKcFVX0jWdIRrklxUu/ZHkW7NygoduNuRQs=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224143400-ff2c16506fcd/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224144841-cfbe0748ddb7 h1:Kr8hhMhr6v+U24TMDCP5WdP4dWrXm5maar+TycTZs9I=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224144841-cfbe0748ddb7/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY=
|
||||
|
|
|
|||
|
|
@ -44,22 +44,20 @@ var deckLock = sync.Mutex{}
|
|||
func GetTreeFlashcards(rootID string, page int) (blocks []*Block, total, pageCount int) {
|
||||
blocks = []*Block{}
|
||||
|
||||
treeBlockIDs := getTreeSubTreeChildBlocks(rootID)
|
||||
var allBlockIDs []string
|
||||
const pageSize = 20
|
||||
deck := Decks[builtinDeckID]
|
||||
if nil == deck {
|
||||
return
|
||||
}
|
||||
|
||||
for bID, _ := range deck.BlockCard {
|
||||
if _, ok := treeBlockIDs[bID]; !ok {
|
||||
continue
|
||||
var allBlockIDs []string
|
||||
deckBlockIDs := deck.GetBlockIDs()
|
||||
treeBlockIDs := getTreeSubTreeChildBlocks(rootID)
|
||||
for _, blockID := range deckBlockIDs {
|
||||
if treeBlockIDs[blockID] {
|
||||
allBlockIDs = append(allBlockIDs, blockID)
|
||||
}
|
||||
|
||||
allBlockIDs = append(allBlockIDs, bID)
|
||||
}
|
||||
|
||||
allBlockIDs = gulu.Str.RemoveDuplicatedElem(allBlockIDs)
|
||||
sort.Strings(allBlockIDs)
|
||||
|
||||
|
|
@ -103,9 +101,7 @@ func GetFlashcards(deckID string, page int) (blocks []*Block, total, pageCount i
|
|||
const pageSize = 20
|
||||
if "" == deckID {
|
||||
for _, deck := range Decks {
|
||||
for bID, _ := range deck.BlockCard {
|
||||
allBlockIDs = append(allBlockIDs, bID)
|
||||
}
|
||||
allBlockIDs = append(allBlockIDs, deck.GetBlockIDs()...)
|
||||
}
|
||||
} else {
|
||||
deck := Decks[deckID]
|
||||
|
|
@ -113,9 +109,7 @@ func GetFlashcards(deckID string, page int) (blocks []*Block, total, pageCount i
|
|||
return
|
||||
}
|
||||
|
||||
for bID, _ := range deck.BlockCard {
|
||||
allBlockIDs = append(allBlockIDs, bID)
|
||||
}
|
||||
allBlockIDs = append(allBlockIDs, deck.GetBlockIDs()...)
|
||||
}
|
||||
|
||||
allBlockIDs = gulu.Str.RemoveDuplicatedElem(allBlockIDs)
|
||||
|
|
@ -372,6 +366,84 @@ func getAllDueFlashcards() (ret []*Flashcard) {
|
|||
return
|
||||
}
|
||||
|
||||
func RemoveFlashcardsByCardIDs(deckID string, cardIDs []string) (err error) {
|
||||
deckLock.Lock()
|
||||
defer deckLock.Unlock()
|
||||
|
||||
if syncingStorages {
|
||||
err = errors.New(Conf.Language(81))
|
||||
return
|
||||
}
|
||||
|
||||
var needRemoveDeckAttrBlockIDs []string
|
||||
if "" == deckID {
|
||||
// 在 All 卡包中移除
|
||||
var affectedBlockIDs []string
|
||||
for _, deck := range Decks {
|
||||
changed := false
|
||||
for _, cardID := range cardIDs {
|
||||
card := deck.GetCard(cardID)
|
||||
if nil == card {
|
||||
continue
|
||||
}
|
||||
|
||||
affectedBlockIDs = append(affectedBlockIDs, card.BlockID())
|
||||
deck.RemoveCard(cardID)
|
||||
changed = true
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err = deck.Save(); nil != err {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查刚刚移除的卡片关联的块是否还存在更多关联的卡片
|
||||
affectedBlockIDs = gulu.Str.RemoveDuplicatedElem(affectedBlockIDs)
|
||||
for _, blockID := range affectedBlockIDs {
|
||||
moreRelatedCards := deck.GetCardsByBlockID(blockID)
|
||||
if 1 > len(moreRelatedCards) {
|
||||
needRemoveDeckAttrBlockIDs = append(needRemoveDeckAttrBlockIDs, blockID)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 在指定卡包中移除
|
||||
deck := Decks[deckID]
|
||||
if nil == deck {
|
||||
return
|
||||
}
|
||||
|
||||
var affectedBlockIDs []string
|
||||
for _, cardID := range cardIDs {
|
||||
card := deck.GetCard(cardID)
|
||||
if nil == card {
|
||||
continue
|
||||
}
|
||||
|
||||
affectedBlockIDs = append(affectedBlockIDs, card.BlockID())
|
||||
deck.RemoveCard(cardID)
|
||||
if err = deck.Save(); nil != err {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查刚刚移除的卡片关联的块是否还存在更多关联的卡片
|
||||
affectedBlockIDs = gulu.Str.RemoveDuplicatedElem(affectedBlockIDs)
|
||||
for _, blockID := range affectedBlockIDs {
|
||||
moreRelatedCards := deck.GetCardsByBlockID(blockID)
|
||||
if 1 > len(moreRelatedCards) {
|
||||
needRemoveDeckAttrBlockIDs = append(needRemoveDeckAttrBlockIDs, blockID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = removeBlocksDeckAttr(needRemoveDeckAttrBlockIDs, deckID); nil != err {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) {
|
||||
deckLock.Lock()
|
||||
defer deckLock.Unlock()
|
||||
|
|
@ -381,6 +453,21 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = removeBlocksDeckAttr(blockIDs, deckID); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
if "" == deckID { // 支持在 All 卡包中移除闪卡 https://github.com/siyuan-note/siyuan/issues/7425
|
||||
for _, deck := range Decks {
|
||||
removeFlashcardsByBlockIDs(blockIDs, deck)
|
||||
}
|
||||
} else {
|
||||
removeFlashcardsByBlockIDs(blockIDs, Decks[deckID])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func removeBlocksDeckAttr(blockIDs []string, deckID string) (err error) {
|
||||
var rootIDs []string
|
||||
blockRoots := map[string]string{}
|
||||
for _, blockID := range blockIDs {
|
||||
|
|
@ -394,7 +481,6 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) {
|
|||
}
|
||||
rootIDs = gulu.Str.RemoveDuplicatedElem(rootIDs)
|
||||
|
||||
availableDeckIDs := getDeckIDs()
|
||||
trees := map[string]*parse.Tree{}
|
||||
for _, blockID := range blockIDs {
|
||||
rootID := blockRoots[blockID]
|
||||
|
|
@ -418,6 +504,7 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) {
|
|||
deckAttrs := node.IALAttr("custom-riff-decks")
|
||||
var deckIDs []string
|
||||
if "" != deckID {
|
||||
availableDeckIDs := getDeckIDs()
|
||||
for _, dID := range strings.Split(deckAttrs, ",") {
|
||||
if dID != deckID && gulu.Str.Contains(dID, availableDeckIDs) {
|
||||
deckIDs = append(deckIDs, dID)
|
||||
|
|
@ -450,31 +537,19 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) {
|
|||
pushBroadcastAttrTransactions(trans)
|
||||
}
|
||||
|
||||
if "" == deckID { // 支持在 All 卡包中移除闪卡 https://github.com/siyuan-note/siyuan/issues/7425
|
||||
for _, deck := range Decks {
|
||||
removeFlashcard(blockIDs, deck)
|
||||
}
|
||||
} else {
|
||||
removeFlashcard(blockIDs, Decks[deckID])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func removeFlashcard(blockIDs []string, deck *riff.Deck) {
|
||||
func removeFlashcardsByBlockIDs(blockIDs []string, deck *riff.Deck) {
|
||||
if nil == deck {
|
||||
logging.LogErrorf("deck is nil")
|
||||
return
|
||||
}
|
||||
|
||||
for _, blockID := range blockIDs {
|
||||
// TODO 这里的代码需要重构,要支持一个块对应多张卡
|
||||
cardID := deck.BlockCard[blockID]
|
||||
if "" == cardID {
|
||||
continue
|
||||
cards := deck.GetCardsByBlockIDs(blockIDs)
|
||||
for _, card := range cards {
|
||||
deck.RemoveCard(card.ID())
|
||||
}
|
||||
deck.RemoveCard(cardID)
|
||||
}
|
||||
|
||||
err := deck.Save()
|
||||
if nil != err {
|
||||
logging.LogErrorf("save deck [%s] failed: %s", deck.ID, err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue