瀏覽代碼

:art: 支持笔记本级闪卡复习 https://github.com/siyuan-note/siyuan/issues/7496

Liang Ding 2 年之前
父節點
當前提交
73ec3714cc
共有 3 個文件被更改,包括 96 次插入33 次删除
  1. 20 0
      kernel/api/riff.go
  2. 1 0
      kernel/api/router.go
  3. 75 33
      kernel/model/flashcard.go

+ 20 - 0
kernel/api/riff.go

@@ -85,6 +85,26 @@ func reviewRiffCard(c *gin.Context) {
 	}
 }
 
+func getNotebookRiffDueCards(c *gin.Context) {
+	ret := gulu.Ret.NewResult()
+	defer c.JSON(http.StatusOK, ret)
+
+	arg, ok := util.JsonArg(c, ret)
+	if !ok {
+		return
+	}
+
+	notebookID := arg["notebook"].(string)
+	cards, err := model.GetNotebookDueFlashcards(notebookID)
+	if nil != err {
+		ret.Code = -1
+		ret.Msg = err.Error()
+		return
+	}
+
+	ret.Data = cards
+}
+
 func getTreeRiffDueCards(c *gin.Context) {
 	ret := gulu.Ret.NewResult()
 	defer c.JSON(http.StatusOK, ret)

+ 1 - 0
kernel/api/router.go

@@ -312,6 +312,7 @@ func ServeAPI(ginServer *gin.Engine) {
 	ginServer.Handle("POST", "/api/riff/removeRiffCards", model.CheckAuth, removeRiffCards)
 	ginServer.Handle("POST", "/api/riff/getRiffDueCards", model.CheckAuth, getRiffDueCards)
 	ginServer.Handle("POST", "/api/riff/getTreeRiffDueCards", model.CheckAuth, getTreeRiffDueCards)
+	ginServer.Handle("POST", "/api/riff/getNotebookRiffDueCards", model.CheckAuth, getNotebookRiffDueCards)
 	ginServer.Handle("POST", "/api/riff/reviewRiffCard", model.CheckAuth, reviewRiffCard)
 	ginServer.Handle("POST", "/api/riff/getRiffCards", model.CheckAuth, getRiffCards)
 	ginServer.Handle("POST", "/api/riff/getTreeRiffCards", model.CheckAuth, getTreeRiffCards)

+ 75 - 33
kernel/model/flashcard.go

@@ -180,7 +180,21 @@ type Flashcard struct {
 	NextDues map[riff.Rating]string `json:"nextDues"`
 }
 
-func GetTreeDueFlashcards(rootID string) (ret []*Flashcard, err error) {
+func newFlashcard(card riff.Card, blockID, deckID string, now time.Time) *Flashcard {
+	nextDues := map[riff.Rating]string{}
+	for rating, due := range card.NextDues() {
+		nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
+	}
+
+	return &Flashcard{
+		DeckID:   deckID,
+		CardID:   card.ID(),
+		BlockID:  blockID,
+		NextDues: nextDues,
+	}
+}
+
+func GetNotebookDueFlashcards(boxID string) (ret []*Flashcard, err error) {
 	deckLock.Lock()
 	defer deckLock.Unlock()
 
@@ -189,13 +203,39 @@ func GetTreeDueFlashcards(rootID string) (ret []*Flashcard, err error) {
 		return
 	}
 
+	entries, err := os.ReadDir(filepath.Join(util.DataDir, boxID))
+	if nil != err {
+		logging.LogErrorf("read dir failed: %s", err)
+		return
+	}
+
+	var rootIDs []string
+	for _, entry := range entries {
+		if entry.IsDir() {
+			continue
+		}
+
+		if !strings.HasSuffix(entry.Name(), ".sy") {
+			continue
+		}
+
+		rootIDs = append(rootIDs, strings.TrimSuffix(entry.Name(), ".sy"))
+	}
+
+	treeBlockIDs := map[string]bool{}
+	for _, rootID := range rootIDs {
+		blockIDs := getTreeSubTreeChildBlocks(rootID)
+		for blockID, _ := range blockIDs {
+			treeBlockIDs[blockID] = true
+		}
+	}
+
 	deck := Decks[builtinDeckID]
 	if nil == deck {
 		logging.LogWarnf("builtin deck not found")
 		return
 	}
 
-	treeBlockIDs := getTreeSubTreeChildBlocks(rootID)
 	cards := deck.Dues()
 	now := time.Now()
 	for _, card := range cards {
@@ -204,17 +244,39 @@ func GetTreeDueFlashcards(rootID string) (ret []*Flashcard, err error) {
 			continue
 		}
 
-		nextDues := map[riff.Rating]string{}
-		for rating, due := range card.NextDues() {
-			nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
+		ret = append(ret, newFlashcard(card, blockID, builtinDeckID, now))
+	}
+	if 1 > len(ret) {
+		ret = []*Flashcard{}
+	}
+	return
+}
+
+func GetTreeDueFlashcards(rootID string) (ret []*Flashcard, err error) {
+	deckLock.Lock()
+	defer deckLock.Unlock()
+
+	if syncingStorages {
+		err = errors.New(Conf.Language(81))
+		return
+	}
+
+	deck := Decks[builtinDeckID]
+	if nil == deck {
+		logging.LogWarnf("builtin deck not found")
+		return
+	}
+
+	treeBlockIDs := getTreeSubTreeChildBlocks(rootID)
+	cards := deck.Dues()
+	now := time.Now()
+	for _, card := range cards {
+		blockID := card.BlockID()
+		if !treeBlockIDs[blockID] {
+			continue
 		}
 
-		ret = append(ret, &Flashcard{
-			DeckID:   builtinDeckID,
-			CardID:   card.ID(),
-			BlockID:  blockID,
-			NextDues: nextDues,
-		})
+		ret = append(ret, newFlashcard(card, blockID, builtinDeckID, now))
 	}
 	if 1 > len(ret) {
 		ret = []*Flashcard{}
@@ -294,17 +356,7 @@ func getDueFlashcards(deckID string) (ret []*Flashcard) {
 			continue
 		}
 
-		nextDues := map[riff.Rating]string{}
-		for rating, due := range card.NextDues() {
-			nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
-		}
-
-		ret = append(ret, &Flashcard{
-			DeckID:   deckID,
-			CardID:   card.ID(),
-			BlockID:  blockID,
-			NextDues: nextDues,
-		})
+		ret = append(ret, newFlashcard(card, blockID, deckID, now))
 	}
 	if 1 > len(ret) {
 		ret = []*Flashcard{}
@@ -322,17 +374,7 @@ func getAllDueFlashcards() (ret []*Flashcard) {
 				continue
 			}
 
-			nextDues := map[riff.Rating]string{}
-			for rating, due := range card.NextDues() {
-				nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
-			}
-
-			ret = append(ret, &Flashcard{
-				DeckID:   deck.ID,
-				CardID:   card.ID(),
-				BlockID:  blockID,
-				NextDues: nextDues,
-			})
+			ret = append(ret, newFlashcard(card, blockID, deck.ID, now))
 		}
 	}
 	if 1 > len(ret) {