Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2025-09-03 09:41:54 +08:00
commit d8bb794437
8 changed files with 164 additions and 134 deletions

View file

@ -128,7 +128,7 @@ func listDocTree(c *gin.Context) {
doctree = append(doctree, parent)
subPath := filepath.Join(root, entry.Name())
if err = walkDocTree(subPath, parent, &ids); err != nil {
if err = walkDocTree(subPath, parent, ids); err != nil {
ret.Code = -1
ret.Msg = err.Error()
return
@ -152,7 +152,7 @@ type DocFile struct {
Children []*DocFile `json:"children,omitempty"`
}
func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
func walkDocTree(p string, docFile *DocFile, ids map[string]bool) (err error) {
dir, err := os.ReadDir(p)
if err != nil {
return
@ -169,7 +169,7 @@ func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
}
parent := &DocFile{ID: entry.Name()}
(*ids)[parent.ID] = true
ids[parent.ID] = true
docFile.Children = append(docFile.Children, parent)
subPath := filepath.Join(p, entry.Name())
@ -178,10 +178,10 @@ func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
}
} else {
doc := &DocFile{ID: strings.TrimSuffix(entry.Name(), ".sy")}
if !(*ids)[doc.ID] {
if !ids[doc.ID] {
docFile.Children = append(docFile.Children, doc)
}
(*ids)[doc.ID] = true
ids[doc.ID] = true
}
}
return

View file

@ -27,7 +27,8 @@ import (
// ViewFilter 描述了视图过滤规则的结构。
type ViewFilter struct {
Column string `json:"column"` // 列字段ID
Operator FilterOperator `json:"operator"` // 过滤操作符
Qualifier FilterQuantifier `json:"quantifier,omitempty"` // 量词
Operator FilterOperator `json:"operator"` // 操作符
Value *Value `json:"value"` // 过滤值
RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间
RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween
@ -76,7 +77,16 @@ const (
FilterOperatorIsFalse FilterOperator = "Is false"
)
func Filter(viewable Viewable, attrView *AttributeView) {
type FilterQuantifier string
const (
FilterQuantifierUndefined FilterQuantifier = ""
FilterQuantifierAny FilterQuantifier = "Any"
FilterQuantifierAll FilterQuantifier = "All"
FilterQuantifierNone FilterQuantifier = "None"
)
func Filter(viewable Viewable, attrView *AttributeView, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) {
collection := viewable.(Collection)
filters := collection.GetFilters()
if 1 > len(filters) {
@ -94,8 +104,6 @@ func Filter(viewable Viewable, attrView *AttributeView) {
}
var items []Item
attrViewCache := map[string]*AttributeView{}
attrViewCache[attrView.ID] = attrView
for _, item := range collection.GetItems() {
pass := true
values := item.GetValues()
@ -116,7 +124,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
break
}
if !values[index].Filter(filters[j], attrView, item.GetID(), &attrViewCache) {
if !values[index].Filter(filters[j], attrView, item.GetID(), rollupFurtherCollections, cachedAttrViews) {
pass = false
break
}
@ -128,7 +136,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
collection.SetItems(items)
}
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID string, attrViewCache *map[string]*AttributeView) bool {
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, itemID string, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) bool {
if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) {
return true
}
@ -149,7 +157,6 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) {
// 单独处理汇总类型的比较
// 处理值比较
key, _ := attrView.GetKey(value.KeyID)
if nil == key {
return false
@ -160,16 +167,16 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return false
}
relVal := attrView.GetValue(relKey.ID, rowID)
relVal := attrView.GetValue(relKey.ID, itemID)
if nil == relVal || nil == relVal.Relation {
return false
}
destAv := (*attrViewCache)[relKey.Relation.AvID]
destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv {
destAv, _ = ParseAttributeView(relKey.Relation.AvID)
if nil != destAv {
(*attrViewCache)[relKey.Relation.AvID] = destAv
cachedAttrViews[relKey.Relation.AvID] = destAv
}
}
if nil == destAv {
@ -181,7 +188,10 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return false
}
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, nil)
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, rollupFurtherCollections[key.ID])
switch filter.Qualifier {
case FilterQuantifierUndefined, FilterQuantifierAny:
for _, content := range value.Rollup.Contents {
switch filter.Operator {
case FilterOperatorContains:
@ -189,8 +199,7 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return true
}
case FilterOperatorDoesNotContain:
ret := content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator)
if !ret {
if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return false
}
default:
@ -199,16 +208,22 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
}
}
}
switch filter.Operator {
case FilterOperatorContains:
case FilterQuantifierAll:
for _, content := range value.Rollup.Contents {
if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return false
case FilterOperatorDoesNotContain:
}
}
return true
default:
case FilterQuantifierNone:
for _, content := range value.Rollup.Contents {
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return false
}
}
return true
}
}
if nil != value.Relation && KeyTypeRelation == value.Type && nil != filter.Value && KeyTypeRelation == filter.Value.Type &&
nil != filter.Value.Relation && 0 < len(filter.Value.Relation.BlockIDs) {
@ -523,17 +538,17 @@ func filterRelativeTime(valueMills int64, valueIsNotEmpty bool, operator FilterO
switch operator {
case FilterOperatorIsEqual:
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && valueTime.Before(otherValueEnd)
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd))
case FilterOperatorIsNotEqual:
return valueTime.Before(otherValueStart) || valueTime.After(otherValueEnd)
case FilterOperatorIsGreater:
return valueTime.After(otherValueStart)
return valueTime.After(otherValueEnd)
case FilterOperatorIsGreaterOrEqual:
return valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)
case FilterOperatorIsLess:
return valueTime.Before(otherValueStart)
case FilterOperatorIsLessOrEqual:
return valueTime.Before(otherValueStart) || valueTime.Equal(otherValueStart)
return valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd)
case FilterOperatorIsBetween:
if RelativeDateDirectionBefore == direction {
if RelativeDateDirectionBefore == direction2 {

View file

@ -1465,16 +1465,16 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
return
}
attrViewCache := map[string]*av.AttributeView{}
cachedAttrViews := map[string]*av.AttributeView{}
avIDs := strings.Split(avs, ",")
for _, avID := range avIDs {
attrView := attrViewCache[avID]
attrView := cachedAttrViews[avID]
if nil == attrView {
attrView, _ = av.ParseAttributeView(avID)
if nil == attrView {
return
}
attrViewCache[avID] = attrView
cachedAttrViews[avID] = attrView
}
if !attrView.ExistBoundBlock(nodeID) {
@ -1572,42 +1572,7 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
// 再渲染关联和汇总
rollupFurtherCollections := map[string]av.Collection{}
for _, kv := range keyValues {
if av.KeyTypeRollup != kv.Key.Type {
continue
}
relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
if nil == relKey {
continue
}
destAv := attrViewCache[relKey.Relation.AvID]
if nil == destAv {
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
if nil == destAv {
continue
}
attrViewCache[relKey.Relation.AvID] = destAv
}
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
if nil == destKey {
continue
}
isSameAv := destAv.ID == attrView.ID
var furtherCollection av.Collection
if av.KeyTypeTemplate == destKey.Type || (!isSameAv && (av.KeyTypeUpdated == destKey.Type || av.KeyTypeCreated == destKey.Type)) {
viewable := sql.RenderView(destAv, destAv.Views[0], "")
if nil != viewable {
furtherCollection = viewable.(av.Collection)
}
}
rollupFurtherCollections[kv.Key.ID] = furtherCollection
}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
for _, kv := range keyValues {
switch kv.Key.Type {
case av.KeyTypeRollup:
@ -1622,13 +1587,13 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID)
if nil != relVal && nil != relVal.Relation {
destAv := attrViewCache[relKey.Relation.AvID]
destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv {
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
if nil == destAv {
break
}
attrViewCache[relKey.Relation.AvID] = destAv
cachedAttrViews[relKey.Relation.AvID] = destAv
}
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
@ -1642,14 +1607,14 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
break
}
destAv := attrViewCache[kv.Key.Relation.AvID]
destAv := cachedAttrViews[kv.Key.Relation.AvID]
if nil == destAv {
destAv, _ = av.ParseAttributeView(kv.Key.Relation.AvID)
if nil == destAv {
break
}
attrViewCache[kv.Key.Relation.AvID] = destAv
cachedAttrViews[kv.Key.Relation.AvID] = destAv
}
blocks := map[string]*av.Value{}
@ -2070,8 +2035,10 @@ func GetCurrentAttributeViewImages(avID, viewID, query string) (ret []string, er
view = attrView.GetView(attrView.ViewID)
}
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
table := getAttrViewTable(attrView, view, query)
av.Filter(table, attrView)
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(table, attrView)
ids := map[string]bool{}
@ -2566,6 +2533,7 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr
for _, filter := range masterView.Filters {
view.Filters = append(view.Filters, &av.ViewFilter{
Column: filter.Column,
Qualifier: filter.Qualifier,
Operator: filter.Operator,
Value: filter.Value,
RelativeDate: filter.RelativeDate,
@ -3284,8 +3252,10 @@ func getNewValueByNearItem(nearItem av.Item, key *av.Key, addingBlockID string)
}
func getNearItem(attrView *av.AttributeView, view, groupView *av.View, previousItemID string) (ret av.Item) {
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
viewable := sql.RenderGroupView(attrView, view, groupView, "")
av.Filter(viewable, attrView)
av.Filter(viewable, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(viewable, attrView)
items := viewable.(av.Collection).GetItems()
if 0 < len(items) {

View file

@ -377,7 +377,9 @@ func renderViewableInstance(viewable av.Viewable, view *av.View, attrView *av.At
return
}
av.Filter(viewable, attrView)
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
av.Filter(viewable, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(viewable, attrView)
av.Calc(viewable, attrView)

View file

@ -83,7 +83,9 @@ func ExportAv2CSV(avID, blockID string) (zipPath string, err error) {
table := getAttrViewTable(attrView, view, "")
// 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474
av.Filter(table, attrView)
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(table, attrView)
exportFolder := filepath.Join(util.TempDir, "export", "csv", name)
@ -273,7 +275,7 @@ func Export2Liandi(id string) (err error) {
".md", 3, 1, 1,
"#", "#",
"", "",
false, false, nil, true, false, &map[string]*parse.Tree{})
false, false, nil, true, false, map[string]*parse.Tree{})
result := gulu.Ret.NewResult()
request := httpclient.NewCloudRequest30s()
request = request.
@ -584,7 +586,7 @@ func Preview(id string, fillCSSVar bool) (retStdHTML string) {
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
"#", "#", // 这里固定使用 # 包裹标签,否则无法正确解析标签 https://github.com/siyuan-note/siyuan/issues/13857
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, &map[string]*parse.Tree{})
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, map[string]*parse.Tree{})
luteEngine := NewLute()
enableLuteInlineSyntax(luteEngine)
luteEngine.SetFootnotes(true)
@ -722,7 +724,7 @@ func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, &map[string]*parse.Tree{})
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, map[string]*parse.Tree{})
name = path.Base(tree.HPath)
name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614
savePath = strings.TrimSpace(savePath)
@ -884,7 +886,7 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, &map[string]*parse.Tree{})
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, map[string]*parse.Tree{})
adjustHeadingLevel(bt, tree)
name = path.Base(tree.HPath)
name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614
@ -1518,7 +1520,7 @@ func ExportStdMarkdown(id string, assetsDestSpace2Underscore, fillCSSVar, adjust
".md", Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, Conf.Export.InlineMemo, defBlockIDs, true, fillCSSVar, &map[string]*parse.Tree{})
Conf.Export.AddTitle, Conf.Export.InlineMemo, defBlockIDs, true, fillCSSVar, map[string]*parse.Tree{})
}
func ExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) {
@ -1684,7 +1686,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(70), fmt.Sprintf("%d/%d %s", count, len(docPaths), tree.Root.IALAttr("title"))))
refs := map[string]*parse.Tree{}
exportRefTrees(tree, &[]string{}, &refs, &treeCache)
exportRefTrees(tree, &[]string{}, refs, treeCache)
for refTreeID, refTree := range refs {
if nil == trees[refTreeID] {
refTrees[refTreeID] = refTree
@ -2012,7 +2014,7 @@ func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar
".md", refMode, embedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, Conf.Export.InlineMemo, nil, true, fillCSSVar, &map[string]*parse.Tree{})
Conf.Export.AddTitle, Conf.Export.InlineMemo, nil, true, fillCSSVar, map[string]*parse.Tree{})
docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
if addYfm {
exportedMd = yfm(docIAL) + exportedMd
@ -2020,7 +2022,7 @@ func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar
return
}
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache *map[string]*parse.Tree) (tree *parse.Tree, exportedMd string, isEmpty bool) {
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache map[string]*parse.Tree) (tree *parse.Tree, exportedMd string, isEmpty bool) {
tree, err := loadTreeWithCache(id, treeCache)
if err != nil {
logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
@ -2055,7 +2057,7 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
func exportMarkdownContent0(id string, tree *parse.Tree, cloudAssetsBase string, assetsDestSpace2Underscore, adjustHeadingLv, imgTag bool,
ext string, blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
tagOpenMarker, tagCloseMarker string, blockRefTextLeft, blockRefTextRight string,
addTitle, inlineMemo bool, defBlockIDs []string, singleFile, fillCSSVar bool, treeCache *map[string]*parse.Tree) (ret string) {
addTitle, inlineMemo bool, defBlockIDs []string, singleFile, fillCSSVar bool, treeCache map[string]*parse.Tree) (ret string) {
tree = exportTree(tree, false, false, false,
blockRefMode, blockEmbedMode, fileAnnotationRefMode,
tagOpenMarker, tagCloseMarker,
@ -2182,11 +2184,11 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
tagOpenMarker, tagCloseMarker string,
blockRefTextLeft, blockRefTextRight string,
addTitle, inlineMemo, addDocAnchorSpan, singleFile bool, treeCache *map[string]*parse.Tree) (ret *parse.Tree) {
addTitle, inlineMemo, addDocAnchorSpan, singleFile bool, treeCache map[string]*parse.Tree) (ret *parse.Tree) {
luteEngine := NewLute()
ret = tree
id := tree.Root.ID
(*treeCache)[tree.ID] = tree
treeCache[tree.ID] = tree
// 解析查询嵌入节点
depth := 0
@ -2544,7 +2546,9 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
table := getAttrViewTable(attrView, view, "")
// 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474
av.Filter(table, attrView)
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(table, attrView)
var aligns []int
@ -2821,7 +2825,7 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
return ret
}
func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tree, currentTreeNodeIDs map[string]bool, blockRefTextLeft, blockRefTextRight string, treeCache *map[string]*parse.Tree) (footnotesDefBlock *ast.Node) {
func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tree, currentTreeNodeIDs map[string]bool, blockRefTextLeft, blockRefTextRight string, treeCache map[string]*parse.Tree) (footnotesDefBlock *ast.Node) {
if 1 > len(*refFootnotes) {
return nil
}
@ -2955,7 +2959,7 @@ func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tr
return
}
func blockLink2Ref(currentTree *parse.Tree, id string, treeCache *map[string]*parse.Tree, depth *int) {
func blockLink2Ref(currentTree *parse.Tree, id string, treeCache map[string]*parse.Tree, depth *int) {
*depth++
if 4096 < *depth {
return
@ -2985,7 +2989,7 @@ func blockLink2Ref(currentTree *parse.Tree, id string, treeCache *map[string]*pa
return
}
func blockLink2Ref0(currentTree *parse.Tree, node *ast.Node, treeCache *map[string]*parse.Tree, depth *int) {
func blockLink2Ref0(currentTree *parse.Tree, node *ast.Node, treeCache map[string]*parse.Tree, depth *int) {
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
@ -3006,7 +3010,7 @@ func blockLink2Ref0(currentTree *parse.Tree, node *ast.Node, treeCache *map[stri
})
}
func collectFootnotesDefs(currentTree *parse.Tree, id string, refFootnotes *[]*refAsFootnotes, treeCache *map[string]*parse.Tree, depth *int) {
func collectFootnotesDefs(currentTree *parse.Tree, id string, refFootnotes *[]*refAsFootnotes, treeCache map[string]*parse.Tree, depth *int) {
*depth++
if 4096 < *depth {
return
@ -3035,7 +3039,7 @@ func collectFootnotesDefs(currentTree *parse.Tree, id string, refFootnotes *[]*r
return
}
func collectFootnotesDefs0(currentTree *parse.Tree, node *ast.Node, refFootnotes *[]*refAsFootnotes, treeCache *map[string]*parse.Tree, depth *int) {
func collectFootnotesDefs0(currentTree *parse.Tree, node *ast.Node, refFootnotes *[]*refAsFootnotes, treeCache map[string]*parse.Tree, depth *int) {
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
@ -3143,7 +3147,7 @@ func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode i
}
func exportPandocConvertZip(baseFolderName string, docPaths, defBlockIDs []string,
pandocFrom, pandocTo, ext string, treeCache *map[string]*parse.Tree) (zipPath string) {
pandocFrom, pandocTo, ext string, treeCache map[string]*parse.Tree) (zipPath string) {
defer util.ClearPushProgress(100)
dir, name := path.Split(baseFolderName)
@ -3296,9 +3300,9 @@ func getExportBlockRefLinkText(blockRef *ast.Node, blockRefTextLeft, blockRefTex
return
}
func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees *map[string]*parse.Tree, relatedDocPaths []string) {
trees = &map[string]*parse.Tree{}
treeCache := &map[string]*parse.Tree{}
func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees map[string]*parse.Tree, relatedDocPaths []string) {
trees = map[string]*parse.Tree{}
treeCache := map[string]*parse.Tree{}
defBlockIDs = []string{}
for i, p := range docPaths {
rootID := strings.TrimSuffix(path.Base(p), ".sy")
@ -3315,18 +3319,18 @@ func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees *map[str
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(70), fmt.Sprintf("%d/%d %s", i+1, len(docPaths), tree.Root.IALAttr("title"))))
}
for _, tree := range *trees {
for _, tree := range trees {
relatedDocPaths = append(relatedDocPaths, tree.Path)
}
relatedDocPaths = gulu.Str.RemoveDuplicatedElem(relatedDocPaths)
return
}
func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache *map[string]*parse.Tree) {
if nil != (*retTrees)[tree.ID] {
func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache map[string]*parse.Tree) {
if nil != retTrees[tree.ID] {
return
}
(*retTrees)[tree.ID] = tree
retTrees[tree.ID] = tree
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
@ -3345,14 +3349,14 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
var defTree *parse.Tree
var err error
if (*treeCache)[defBlock.RootID] != nil {
defTree = (*treeCache)[defBlock.RootID]
if treeCache[defBlock.RootID] != nil {
defTree = treeCache[defBlock.RootID]
} else {
defTree, err = loadTreeWithCache(defBlock.RootID, treeCache)
if err != nil {
return ast.WalkSkipChildren
}
(*treeCache)[defBlock.RootID] = defTree
treeCache[defBlock.RootID] = defTree
}
*defBlockIDs = append(*defBlockIDs, defID)
@ -3369,14 +3373,14 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
var defTree *parse.Tree
var err error
if (*treeCache)[defBlock.RootID] != nil {
defTree = (*treeCache)[defBlock.RootID]
if treeCache[defBlock.RootID] != nil {
defTree = treeCache[defBlock.RootID]
} else {
defTree, err = loadTreeWithCache(defBlock.RootID, treeCache)
if err != nil {
return ast.WalkSkipChildren
}
(*treeCache)[defBlock.RootID] = defTree
treeCache[defBlock.RootID] = defTree
}
*defBlockIDs = append(*defBlockIDs, defID)
@ -3412,14 +3416,14 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
var defTree *parse.Tree
var err error
if (*treeCache)[defBlock.RootID] != nil {
defTree = (*treeCache)[defBlock.RootID]
if treeCache[defBlock.RootID] != nil {
defTree = treeCache[defBlock.RootID]
} else {
defTree, err = loadTreeWithCache(defBlock.RootID, treeCache)
if err != nil {
continue
}
(*treeCache)[defBlock.RootID] = defTree
treeCache[defBlock.RootID] = defTree
}
*defBlockIDs = append(*defBlockIDs, val.BlockID)
@ -3432,13 +3436,13 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
*defBlockIDs = gulu.Str.RemoveDuplicatedElem(*defBlockIDs)
}
func loadTreeWithCache(id string, treeCache *map[string]*parse.Tree) (tree *parse.Tree, err error) {
if tree = (*treeCache)[id]; nil != tree {
func loadTreeWithCache(id string, treeCache map[string]*parse.Tree) (tree *parse.Tree, err error) {
if tree = treeCache[id]; nil != tree {
return
}
tree, err = LoadTreeByBlockID(id)
if nil == err && nil != tree {
(*treeCache)[id] = tree
treeCache[id] = tree
}
return
}

View file

@ -280,10 +280,10 @@ func generateAttrViewItems(attrView *av.AttributeView, view *av.View) (ret map[s
return
}
func filterNotFoundAttrViewItems(keyValuesMap *map[string][]*av.KeyValues) {
func filterNotFoundAttrViewItems(keyValuesMap map[string][]*av.KeyValues) {
var notFound []string
var toCheckBlockIDs []string
for blockID, keyValues := range *keyValuesMap {
for blockID, keyValues := range keyValuesMap {
blockValue := getBlockValue(keyValues)
if nil == blockValue || nil == blockValue.Block {
notFound = append(notFound, blockID)
@ -308,7 +308,7 @@ func filterNotFoundAttrViewItems(keyValuesMap *map[string][]*av.KeyValues) {
}
}
for _, blockID := range notFound {
delete(*keyValuesMap, blockID)
delete(keyValuesMap, blockID)
}
}
@ -518,6 +518,45 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection
}
}
func GetFurtherCollections(attrView *av.AttributeView, cachedAttrViews map[string]*av.AttributeView) (ret map[string]av.Collection) {
ret = map[string]av.Collection{}
for _, kv := range attrView.KeyValues {
if av.KeyTypeRollup != kv.Key.Type {
continue
}
relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
if nil == relKey {
continue
}
destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv {
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
if nil == destAv {
continue
}
cachedAttrViews[relKey.Relation.AvID] = destAv
}
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
if nil == destKey {
continue
}
isSameAv := destAv.ID == attrView.ID
var furtherCollection av.Collection
if av.KeyTypeTemplate == destKey.Type || (!isSameAv && (av.KeyTypeUpdated == destKey.Type || av.KeyTypeCreated == destKey.Type)) {
viewable := RenderView(destAv, destAv.Views[0], "")
if nil != viewable {
furtherCollection = viewable.(av.Collection)
}
}
ret[kv.Key.ID] = furtherCollection
}
return
}
func fillAttributeViewTemplateValues(attrView *av.AttributeView, view *av.View, collection av.Collection, ials map[string]map[string]string) (err error) {
items := generateAttrViewItems(attrView, view)
existTemplateField := false

View file

@ -62,7 +62,7 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
}
cardsValues := generateAttrViewItems(attrView, view) // 生成卡片
filterNotFoundAttrViewItems(&cardsValues) // 过滤掉不存在的卡片
filterNotFoundAttrViewItems(cardsValues) // 过滤掉不存在的卡片
// 批量加载绑定块对应的树
var ialIDs []string

View file

@ -62,7 +62,7 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s
}
rowsValues := generateAttrViewItems(attrView, view) // 生成行
filterNotFoundAttrViewItems(&rowsValues) // 过滤掉不存在的行
filterNotFoundAttrViewItems(rowsValues) // 过滤掉不存在的行
// 生成行单元格
for rowID, rowValues := range rowsValues {