Ensure the API correctly returns an empty array, add deduplication logic, and remove redundant sorting steps when updating fields

This commit is contained in:
Jeffrey Chen 2025-11-07 01:19:36 +08:00
parent f6217c0b50
commit 6419f5c7fb

View file

@ -51,15 +51,25 @@ type OutlineDoc struct {
var recentDocLock = sync.Mutex{} var recentDocLock = sync.Mutex{}
// 三种类型各保留 32 条记录,并清空 Title 和 Icon // normalizeRecentDocs 规范化最近文档列表:去重、清空 Title/Icon、按类型截取 32 条记录
func trimRecentDocs(recentDocs []*RecentDoc) []*RecentDoc { func normalizeRecentDocs(recentDocs []*RecentDoc) []*RecentDoc {
if len(recentDocs) <= 32 { // 去重
// 清空 Title 和 Icon seen := make(map[string]struct{}, len(recentDocs))
deduplicated := make([]*RecentDoc, 0, len(recentDocs))
for _, doc := range recentDocs { for _, doc := range recentDocs {
if _, ok := seen[doc.RootID]; !ok {
seen[doc.RootID] = struct{}{}
deduplicated = append(deduplicated, doc)
}
}
if len(deduplicated) <= 32 {
// 清空 Title 和 Icon
for _, doc := range deduplicated {
doc.Title = "" doc.Title = ""
doc.Icon = "" doc.Icon = ""
} }
return recentDocs return deduplicated
} }
// 分别统计三种类型的记录 // 分别统计三种类型的记录
@ -67,7 +77,7 @@ func trimRecentDocs(recentDocs []*RecentDoc) []*RecentDoc {
var openedDocs []*RecentDoc var openedDocs []*RecentDoc
var closedDocs []*RecentDoc var closedDocs []*RecentDoc
for _, doc := range recentDocs { for _, doc := range deduplicated {
if doc.ViewedAt > 0 { if doc.ViewedAt > 0 {
viewedDocs = append(viewedDocs, doc) viewedDocs = append(viewedDocs, doc)
} }
@ -131,7 +141,7 @@ func UpdateRecentDocOpenTime(rootID string) (err error) {
recentDocLock.Lock() recentDocLock.Lock()
defer recentDocLock.Unlock() defer recentDocLock.Unlock()
recentDocs, err := getRecentDocs("") recentDocs, err := loadRecentDocsRaw()
if err != nil { if err != nil {
return return
} }
@ -168,7 +178,7 @@ func UpdateRecentDocViewTime(rootID string) (err error) {
recentDocLock.Lock() recentDocLock.Lock()
defer recentDocLock.Unlock() defer recentDocLock.Unlock()
recentDocs, err := getRecentDocs("") recentDocs, err := loadRecentDocsRaw()
if err != nil { if err != nil {
return return
} }
@ -214,7 +224,7 @@ func BatchUpdateRecentDocCloseTime(rootIDs []string) (err error) {
recentDocLock.Lock() recentDocLock.Lock()
defer recentDocLock.Unlock() defer recentDocLock.Unlock()
recentDocs, err := getRecentDocs("") recentDocs, err := loadRecentDocsRaw()
if err != nil { if err != nil {
return return
} }
@ -266,7 +276,7 @@ func GetRecentDocs(sortBy string) (ret []*RecentDoc, err error) {
} }
func setRecentDocs(recentDocs []*RecentDoc) (err error) { func setRecentDocs(recentDocs []*RecentDoc) (err error) {
recentDocs = trimRecentDocs(recentDocs) recentDocs = normalizeRecentDocs(recentDocs)
dirPath := filepath.Join(util.DataDir, "storage") dirPath := filepath.Join(util.DataDir, "storage")
if err = os.MkdirAll(dirPath, 0755); err != nil { if err = os.MkdirAll(dirPath, 0755); err != nil {
@ -289,8 +299,7 @@ func setRecentDocs(recentDocs []*RecentDoc) (err error) {
return return
} }
func getRecentDocs(sortBy string) (ret []*RecentDoc, err error) { func loadRecentDocsRaw() (ret []*RecentDoc, err error) {
var tmp []*RecentDoc
dataPath := filepath.Join(util.DataDir, "storage/recent-doc.json") dataPath := filepath.Join(util.DataDir, "storage/recent-doc.json")
if !filelock.IsExist(dataPath) { if !filelock.IsExist(dataPath) {
return return
@ -302,7 +311,7 @@ func getRecentDocs(sortBy string) (ret []*RecentDoc, err error) {
return return
} }
if err = gulu.JSON.UnmarshalJSON(data, &tmp); err != nil { if err = gulu.JSON.UnmarshalJSON(data, &ret); err != nil {
logging.LogErrorf("unmarshal storage [recent-doc] failed: %s", err) logging.LogErrorf("unmarshal storage [recent-doc] failed: %s", err)
if err = setRecentDocs([]*RecentDoc{}); err != nil { if err = setRecentDocs([]*RecentDoc{}); err != nil {
logging.LogErrorf("reset storage [recent-doc] failed: %s", err) logging.LogErrorf("reset storage [recent-doc] failed: %s", err)
@ -310,14 +319,33 @@ func getRecentDocs(sortBy string) (ret []*RecentDoc, err error) {
ret = []*RecentDoc{} ret = []*RecentDoc{}
return return
} }
return
}
func getRecentDocs(sortBy string) (ret []*RecentDoc, err error) {
ret = []*RecentDoc{} // 初始化为空切片,确保 API 始终返回非 nil
recentDocs, err := loadRecentDocsRaw()
if err != nil {
return
}
// 去重
seen := make(map[string]struct{}, len(recentDocs))
var deduplicated []*RecentDoc
for _, doc := range recentDocs {
if _, ok := seen[doc.RootID]; !ok {
seen[doc.RootID] = struct{}{}
deduplicated = append(deduplicated, doc)
}
}
var rootIDs []string var rootIDs []string
for _, doc := range tmp { for _, doc := range deduplicated {
rootIDs = append(rootIDs, doc.RootID) rootIDs = append(rootIDs, doc.RootID)
} }
bts := treenode.GetBlockTrees(rootIDs) bts := treenode.GetBlockTrees(rootIDs)
var notExists []string var notExists []string
for _, doc := range tmp { for _, doc := range deduplicated {
if bt := bts[doc.RootID]; nil != bt { if bt := bts[doc.RootID]; nil != bt {
// 获取最新的文档标题和图标 // 获取最新的文档标题和图标
doc.Title = path.Base(bt.HPath) // Recent docs not updated after renaming https://github.com/siyuan-note/siyuan/issues/7827 doc.Title = path.Base(bt.HPath) // Recent docs not updated after renaming https://github.com/siyuan-note/siyuan/issues/7827
@ -332,9 +360,9 @@ func getRecentDocs(sortBy string) (ret []*RecentDoc, err error) {
} }
if 0 < len(notExists) { if 0 < len(notExists) {
err := setRecentDocs(ret) err = setRecentDocs(ret)
if err != nil { if err != nil {
return nil, err return
} }
} }
@ -391,39 +419,46 @@ func getRecentDocs(sortBy string) (ret []*RecentDoc, err error) {
ret = append(ret, doc) ret = append(ret, doc)
} }
case "closedAt": // 按关闭时间排序 case "closedAt": // 按关闭时间排序
var filtered []*RecentDoc filtered := []*RecentDoc{} // 初始化为空切片,确保 API 始终返回非 nil
for _, doc := range ret { for _, doc := range ret {
if doc.ClosedAt > 0 { if doc.ClosedAt > 0 {
filtered = append(filtered, doc) filtered = append(filtered, doc)
} }
} }
ret = filtered ret = filtered
if 0 < len(ret) {
sort.Slice(ret, func(i, j int) bool { sort.Slice(ret, func(i, j int) bool {
return ret[i].ClosedAt > ret[j].ClosedAt return ret[i].ClosedAt > ret[j].ClosedAt
}) })
}
case "openAt": // 按打开时间排序 case "openAt": // 按打开时间排序
var filtered []*RecentDoc filtered := []*RecentDoc{} // 初始化为空切片,确保 API 始终返回非 nil
for _, doc := range ret { for _, doc := range ret {
if doc.OpenAt > 0 { if doc.OpenAt > 0 {
filtered = append(filtered, doc) filtered = append(filtered, doc)
} }
} }
ret = filtered ret = filtered
if 0 < len(ret) {
sort.Slice(ret, func(i, j int) bool { sort.Slice(ret, func(i, j int) bool {
return ret[i].OpenAt > ret[j].OpenAt return ret[i].OpenAt > ret[j].OpenAt
}) })
default: // 默认按浏览时间排序 }
var filtered []*RecentDoc case "viewedAt": // 按浏览时间排序
default:
filtered := []*RecentDoc{} // 初始化为空切片,确保 API 始终返回非 nil
for _, doc := range ret { for _, doc := range ret {
if doc.ViewedAt > 0 { if doc.ViewedAt > 0 {
filtered = append(filtered, doc) filtered = append(filtered, doc)
} }
} }
ret = filtered ret = filtered
if 0 < len(ret) {
sort.Slice(ret, func(i, j int) bool { sort.Slice(ret, func(i, j int) bool {
return ret[i].ViewedAt > ret[j].ViewedAt return ret[i].ViewedAt > ret[j].ViewedAt
}) })
} }
}
return return
} }