From 008cce474a7b9480aeab9ec7ec2d34d38c1c4415 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 13:16:29 +0800 Subject: [PATCH 01/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 98 ++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 17 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 4c5cef3ca..7b6babf0c 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1740,7 +1740,7 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { v.GroupItemIDs = append(v.GroupItemIDs, item.GetID()) } - v.Name = "" + v.Name = "" // 分组视图的名称在渲染时才填充 v.GroupValue = name view.Groups = append(view.Groups, v) } @@ -1755,26 +1755,90 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { } } - // 恢复分组视图的顺序 - if len(groupStates) > 0 { - sort.SliceStable(view.Groups, func(i, j int) bool { - if stateI, ok := groupStates[view.Groups[i].GroupValue]; ok { - if stateJ, ok := groupStates[view.Groups[j].GroupValue]; ok { - return stateI.Sort < stateJ.Sort + if av.GroupOrderMan == view.Group.Order { + // 恢复分组视图的自定义顺序 + if len(groupStates) > 0 { + sort.SliceStable(view.Groups, func(i, j int) bool { + if stateI, ok := groupStates[view.Groups[i].GroupValue]; ok { + if stateJ, ok := groupStates[view.Groups[j].GroupValue]; ok { + return stateI.Sort < stateJ.Sort + } + } + return false + }) + } + } else { + if av.GroupMethodDateRelative == view.Group.Method { + var monthGroups []*av.View + var last30Days, last7Days, yesterday, today, tomorrow, next7Days, next30Days *av.View + for _, groupView := range view.Groups { + _, err := time.Parse("2006-01", groupView.GroupValue) + if nil == err { // 如果能解析出来说明是 30 天之前或 30 天之后的分组形式 + monthGroups = append(monthGroups, groupView) + } else { // 否则是相对日期分组形式 + switch groupView.GroupValue { + case groupValueLast30Days: + last30Days = groupView + case groupValueLast7Days: + last7Days = groupView + case groupValueYesterday: + yesterday = groupView + case groupValueToday: + today = groupView + case groupValueTomorrow: + tomorrow = groupView + case groupValueNext7Days: + next7Days = groupView + case groupValueNext30Days: + next30Days = groupView + } } } - return false - }) - } - if av.GroupOrderMan != view.Group.Order { - sort.SliceStable(view.Groups, func(i, j int) bool { - iVal, jVal := view.Groups[i].GroupValue, view.Groups[j].GroupValue - if av.GroupOrderAsc == view.Group.Order { - return util.NaturalCompare(iVal, jVal) + sort.SliceStable(monthGroups, func(i, j int) bool { + return monthGroups[i].GroupValue < monthGroups[j].GroupValue + }) + + var idx int + thisMonth := todayStart.Format("2006-01") + for i, monthGroup := range monthGroups { + if monthGroup.GroupValue > thisMonth { + idx = i + break + } } - return util.NaturalCompare(jVal, iVal) - }) + + if nil != next30Days { + util.InsertElem(monthGroups, idx, next30Days) + } + if nil != next7Days { + util.InsertElem(monthGroups, idx, next7Days) + } + if nil != tomorrow { + util.InsertElem(monthGroups, idx, tomorrow) + } + if nil != today { + util.InsertElem(monthGroups, idx, today) + } + if nil != yesterday { + util.InsertElem(monthGroups, idx, yesterday) + } + if nil != last7Days { + util.InsertElem(monthGroups, idx, last7Days) + } + if nil != last30Days { + util.InsertElem(monthGroups, idx, last30Days) + } + view.Groups = monthGroups + } else { + sort.SliceStable(view.Groups, func(i, j int) bool { + iVal, jVal := view.Groups[i].GroupValue, view.Groups[j].GroupValue + if av.GroupOrderAsc == view.Group.Order { + return util.NaturalCompare(iVal, jVal) + } + return util.NaturalCompare(jVal, iVal) + }) + } } } From 99a5d4c2145561b5a82dd83a9668e60c8d318786 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 13:19:10 +0800 Subject: [PATCH 02/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 7b6babf0c..c83c4b158 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1809,25 +1809,25 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { } if nil != next30Days { - util.InsertElem(monthGroups, idx, next30Days) + monthGroups = util.InsertElem(monthGroups, idx, next30Days) } if nil != next7Days { - util.InsertElem(monthGroups, idx, next7Days) + monthGroups = util.InsertElem(monthGroups, idx, next7Days) } if nil != tomorrow { - util.InsertElem(monthGroups, idx, tomorrow) + monthGroups = util.InsertElem(monthGroups, idx, tomorrow) } if nil != today { - util.InsertElem(monthGroups, idx, today) + monthGroups = util.InsertElem(monthGroups, idx, today) } if nil != yesterday { - util.InsertElem(monthGroups, idx, yesterday) + monthGroups = util.InsertElem(monthGroups, idx, yesterday) } if nil != last7Days { - util.InsertElem(monthGroups, idx, last7Days) + monthGroups = util.InsertElem(monthGroups, idx, last7Days) } if nil != last30Days { - util.InsertElem(monthGroups, idx, last30Days) + monthGroups = util.InsertElem(monthGroups, idx, last30Days) } view.Groups = monthGroups } else { From 1af2dba15071b279aaed73374bcba676f811266d Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 13:19:44 +0800 Subject: [PATCH 03/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index c83c4b158..1b0f017fd 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1769,12 +1769,12 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { } } else { if av.GroupMethodDateRelative == view.Group.Method { - var monthGroups []*av.View + var relativeDateGroups []*av.View var last30Days, last7Days, yesterday, today, tomorrow, next7Days, next30Days *av.View for _, groupView := range view.Groups { _, err := time.Parse("2006-01", groupView.GroupValue) if nil == err { // 如果能解析出来说明是 30 天之前或 30 天之后的分组形式 - monthGroups = append(monthGroups, groupView) + relativeDateGroups = append(relativeDateGroups, groupView) } else { // 否则是相对日期分组形式 switch groupView.GroupValue { case groupValueLast30Days: @@ -1795,13 +1795,13 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { } } - sort.SliceStable(monthGroups, func(i, j int) bool { - return monthGroups[i].GroupValue < monthGroups[j].GroupValue + sort.SliceStable(relativeDateGroups, func(i, j int) bool { + return relativeDateGroups[i].GroupValue < relativeDateGroups[j].GroupValue }) var idx int thisMonth := todayStart.Format("2006-01") - for i, monthGroup := range monthGroups { + for i, monthGroup := range relativeDateGroups { if monthGroup.GroupValue > thisMonth { idx = i break @@ -1809,27 +1809,27 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { } if nil != next30Days { - monthGroups = util.InsertElem(monthGroups, idx, next30Days) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, next30Days) } if nil != next7Days { - monthGroups = util.InsertElem(monthGroups, idx, next7Days) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, next7Days) } if nil != tomorrow { - monthGroups = util.InsertElem(monthGroups, idx, tomorrow) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, tomorrow) } if nil != today { - monthGroups = util.InsertElem(monthGroups, idx, today) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, today) } if nil != yesterday { - monthGroups = util.InsertElem(monthGroups, idx, yesterday) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, yesterday) } if nil != last7Days { - monthGroups = util.InsertElem(monthGroups, idx, last7Days) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, last7Days) } if nil != last30Days { - monthGroups = util.InsertElem(monthGroups, idx, last30Days) + relativeDateGroups = util.InsertElem(relativeDateGroups, idx, last30Days) } - view.Groups = monthGroups + view.Groups = relativeDateGroups } else { sort.SliceStable(view.Groups, func(i, j int) bool { iVal, jVal := view.Groups[i].GroupValue, view.Groups[j].GroupValue From a6f5705681f23a9ffe0c37a3b452416484bb6bad Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 13:44:17 +0800 Subject: [PATCH 04/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 53 +++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 1b0f017fd..5577459ce 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1799,35 +1799,42 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { return relativeDateGroups[i].GroupValue < relativeDateGroups[j].GroupValue }) - var idx int + var lastNext30Days []*av.View + if nil != last30Days { + lastNext30Days = append(lastNext30Days, last30Days) + } + if nil != last7Days { + lastNext30Days = append(lastNext30Days, last7Days) + } + if nil != yesterday { + lastNext30Days = append(lastNext30Days, yesterday) + } + if nil != today { + lastNext30Days = append(lastNext30Days, today) + } + if nil != tomorrow { + lastNext30Days = append(lastNext30Days, tomorrow) + } + if nil != next7Days { + lastNext30Days = append(lastNext30Days, next7Days) + } + if nil != next30Days { + lastNext30Days = append(lastNext30Days, next30Days) + } + + startIdx := -1 thisMonth := todayStart.Format("2006-01") for i, monthGroup := range relativeDateGroups { if monthGroup.GroupValue > thisMonth { - idx = i - break + startIdx = i } } - - if nil != next30Days { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, next30Days) + if -1 == startIdx { + slices.Reverse(lastNext30Days) + startIdx = 0 } - if nil != next7Days { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, next7Days) - } - if nil != tomorrow { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, tomorrow) - } - if nil != today { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, today) - } - if nil != yesterday { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, yesterday) - } - if nil != last7Days { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, last7Days) - } - if nil != last30Days { - relativeDateGroups = util.InsertElem(relativeDateGroups, idx, last30Days) + for _, g := range lastNext30Days { + relativeDateGroups = util.InsertElem(relativeDateGroups, startIdx, g) } view.Groups = relativeDateGroups } else { From e575324483cd9e5487e3241279e5eb115a9f1c16 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 13:51:01 +0800 Subject: [PATCH 05/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 5577459ce..a4385fc24 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1825,8 +1825,8 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { startIdx := -1 thisMonth := todayStart.Format("2006-01") for i, monthGroup := range relativeDateGroups { - if monthGroup.GroupValue > thisMonth { - startIdx = i + if monthGroup.GroupValue < thisMonth { + startIdx = i + 1 } } if -1 == startIdx { From 1b07033cd3d4892df333ce4fb95d33da4c40651c Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 13:54:15 +0800 Subject: [PATCH 06/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index a4385fc24..1aeafe4e4 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1800,26 +1800,27 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { }) var lastNext30Days []*av.View - if nil != last30Days { - lastNext30Days = append(lastNext30Days, last30Days) - } - if nil != last7Days { - lastNext30Days = append(lastNext30Days, last7Days) - } - if nil != yesterday { - lastNext30Days = append(lastNext30Days, yesterday) - } - if nil != today { - lastNext30Days = append(lastNext30Days, today) - } - if nil != tomorrow { - lastNext30Days = append(lastNext30Days, tomorrow) + if nil != next30Days { + lastNext30Days = append(lastNext30Days, next30Days) } if nil != next7Days { lastNext30Days = append(lastNext30Days, next7Days) } - if nil != next30Days { - lastNext30Days = append(lastNext30Days, next30Days) + if nil != tomorrow { + lastNext30Days = append(lastNext30Days, tomorrow) + } + if nil != today { + lastNext30Days = append(lastNext30Days, today) + } + if nil != yesterday { + lastNext30Days = append(lastNext30Days, yesterday) + } + + if nil != last7Days { + lastNext30Days = append(lastNext30Days, last7Days) + } + if nil != last30Days { + lastNext30Days = append(lastNext30Days, last30Days) } startIdx := -1 @@ -1830,7 +1831,6 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { } } if -1 == startIdx { - slices.Reverse(lastNext30Days) startIdx = 0 } for _, g := range lastNext30Days { From b138ff9d7fe81b333c2dbfccf66aeda3b4037a78 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 14:02:54 +0800 Subject: [PATCH 07/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 1aeafe4e4..e7f15b1a4 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -3268,14 +3268,10 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er for _, blockID := range srcIDs { view.ItemIDs = gulu.Str.RemoveElem(view.ItemIDs, blockID) } - - for _, groupView := range view.Groups { - for _, blockID := range srcIDs { - groupView.GroupItemIDs = gulu.Str.RemoveElem(groupView.GroupItemIDs, blockID) - } - } } + regenAttrViewViewGroups(attrView, "force") + relatedAvIDs := av.GetSrcAvIDs(avID) for _, relatedAvID := range relatedAvIDs { ReloadAttrView(relatedAvID) From 287edba74c21ab2f605271b7f0dd42a02ca183b6 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 14:07:36 +0800 Subject: [PATCH 08/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index e7f15b1a4..5e0a6239e 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1519,8 +1519,9 @@ func renderAttributeView(attrView *av.AttributeView, blockID, viewID, query stri regenAttrViewViewGroups(attrView, "force") av.SaveAttributeView(attrView) } + } - groupKey := view.GetGroupKey(attrView) + if groupKey := view.GetGroupKey(attrView); nil != groupKey { for _, groupView := range view.Groups { switch groupView.GroupValue { case groupValueDefault: From 548857dc4b73e45569948ebf0675893405851e5c Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 14:11:03 +0800 Subject: [PATCH 09/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 5e0a6239e..d303ba23b 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1521,6 +1521,7 @@ func renderAttributeView(attrView *av.AttributeView, blockID, viewID, query stri } } + // 如果存在分组的话渲染分组视图 if groupKey := view.GetGroupKey(attrView); nil != groupKey { for _, groupView := range view.Groups { switch groupView.GroupValue { @@ -1546,27 +1547,26 @@ func renderAttributeView(attrView *av.AttributeView, blockID, viewID, query stri groupView.Name = groupView.GroupValue } } - } - // 如果存在分组的话渲染分组视图 - var groups []av.Viewable - for _, groupView := range view.Groups { - groupViewable := sql.RenderGroupView(attrView, view, groupView) - err = renderViewableInstance(groupViewable, view, attrView, page, pageSize) - if nil != err { - return - } - groups = append(groups, groupViewable) + var groups []av.Viewable + for _, groupView := range view.Groups { + groupViewable := sql.RenderGroupView(attrView, view, groupView) + err = renderViewableInstance(groupViewable, view, attrView, page, pageSize) + if nil != err { + return + } + groups = append(groups, groupViewable) - // 将分组视图的分组字段清空,减少冗余(字段信息可以在总的视图 view 对象上获取到) - switch groupView.LayoutType { - case av.LayoutTypeTable: - groupView.Table.Columns = nil - case av.LayoutTypeGallery: - groupView.Gallery.CardFields = nil + // 将分组视图的分组字段清空,减少冗余(字段信息可以在总的视图 view 对象上获取到) + switch groupView.LayoutType { + case av.LayoutTypeTable: + groupView.Table.Columns = nil + case av.LayoutTypeGallery: + groupView.Gallery.CardFields = nil + } } + viewable.SetGroups(groups) } - viewable.SetGroups(groups) return } From c64d68c71d1933d0559c4d9de2a9d78aa8de8fce Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 14:15:50 +0800 Subject: [PATCH 10/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index d303ba23b..30cd527b6 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1566,6 +1566,9 @@ func renderAttributeView(attrView *av.AttributeView, blockID, viewID, query stri } } viewable.SetGroups(groups) + + // 将总的视图上的项目清空,减少冗余 + viewable.(av.Collection).SetItems(nil) } return } From 8dd1585adb95648e666867528e650e86a60ae101 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 29 Jul 2025 15:38:21 +0800 Subject: [PATCH 11/11] :art: Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 --- kernel/model/attribute_view.go | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 30cd527b6..d2793445d 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -273,27 +273,8 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) (err error return err } - oldHideEmpty := false - if nil != view.Group { - oldHideEmpty = view.Group.HideEmpty - } - view.Group = group - genAttrViewViewGroups(view, attrView) - - if view.Group.HideEmpty != oldHideEmpty { - for _, g := range view.Groups { - if view.Group.HideEmpty { - if 2 != g.GroupHidden && 1 > len(g.GroupItemIDs) { - g.GroupHidden = 1 - } - } else { - if 2 != g.GroupHidden { - g.GroupHidden = 0 - } - } - } - } + regenAttrViewViewGroups(attrView, "force") err = av.SaveAttributeView(attrView) ReloadAttrView(avID) @@ -3169,8 +3150,7 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a if av.KeyTypeSelect == groupKey.Type || av.KeyTypeMSelect == groupKey.Type { // 因为单选或多选只能按选项分组,并且可能存在空白分组(前面可能找不到临近项) ,所以单选或多选类型的分组字段使用分组值内容对应的选项 if opt := groupKey.GetOption(groupView.GroupValue); nil != opt && groupValueDefault != groupView.GroupValue { - newValue.MSelect[0].Content = opt.Name - newValue.MSelect[0].Color = opt.Color + newValue.MSelect = append(newValue.MSelect, &av.ValueSelect{Content: opt.Name, Color: opt.Color}) } }