diff --git a/kernel/av/av.go b/kernel/av/av.go index e1d6c0c37..555ebce93 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -191,12 +191,13 @@ type View struct { Table *LayoutTable `json:"table,omitempty"` // 表格布局 Gallery *LayoutGallery `json:"gallery,omitempty"` // 画廊布局 - Groups []*View `json:"groups,omitempty"` // 分组视图列表 - GroupCalcSum bool `json:"groupCalcSum,omitempty"` // 分组是否计算总和 - GroupName string `json:"groupName,omitempty"` // 分组名称 - GroupFolded bool `json:"groupFolded,omitempty"` // 分组是否折叠 - GroupHidden bool `json:"groupHidden,omitempty"` // 分组是否隐藏 - GroupDefault bool `json:"groupDefault,omitempty"` // 是否为默认分组 + Groups []*View `json:"groups,omitempty"` // 分组视图列表 + GroupItemIDs []string `json:"groupItemIds,omitempty"` // 分组项目 ID 列表,用于维护分组中的所有项目 + GroupCalcSum bool `json:"groupCalcSum,omitempty"` // 分组是否计算总和 + GroupName string `json:"groupName,omitempty"` // 分组名称 + GroupFolded bool `json:"groupFolded,omitempty"` // 分组是否折叠 + GroupHidden bool `json:"groupHidden,omitempty"` // 分组是否隐藏 + GroupDefault bool `json:"groupDefault,omitempty"` // 是否为默认分组 } // LayoutType 描述了视图布局类型。 @@ -252,12 +253,24 @@ func NewGalleryView() (ret *View) { // Viewable 描述了视图的接口。 type Viewable interface { - Filterable - Sortable - Calculable + // Filter 根据视图中设置的过滤器进行过滤。 + Filter(attrView *AttributeView) + + // Sort 根据视图中设置的排序规则进行排序。 + Sort(attrView *AttributeView) + + // Calc 根据视图中设置的计算规则进行计算。 + Calc() + + // GetType 获取视图的布局类型。 GetType() LayoutType + + // GetID 获取视图的 ID。 GetID() string + + // SetGroups 设置视图分组列表。 + SetGroups(viewables []Viewable) } func NewAttributeView(id string) (ret *AttributeView) { diff --git a/kernel/av/calc.go b/kernel/av/calc.go index 0a35e3438..c20989e0a 100644 --- a/kernel/av/calc.go +++ b/kernel/av/calc.go @@ -16,13 +16,6 @@ package av -// Calculable 接口定义了可计算的视图类型。 -type Calculable interface { - - // Calc 根据视图中设置的计算规则进行计算。 - Calc() -} - // ColumnCalc 描述了列(字段)计算操作和结果的结构。 type ColumnCalc struct { Operator CalcOperator `json:"operator"` // 计算操作符 diff --git a/kernel/av/filter.go b/kernel/av/filter.go index 8503c5479..5545f548d 100644 --- a/kernel/av/filter.go +++ b/kernel/av/filter.go @@ -24,13 +24,6 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) -// Filterable 接口定义了可过滤的视图类型。 -type Filterable interface { - - // Filter 根据视图中设置的过滤器进行过滤。 - Filter(attrView *AttributeView) -} - // ViewFilter 描述了视图过滤器的结构。 type ViewFilter struct { Column string `json:"column"` // 列(字段)ID diff --git a/kernel/av/layout.go b/kernel/av/layout.go index 5610af3c5..09de79d7d 100644 --- a/kernel/av/layout.go +++ b/kernel/av/layout.go @@ -66,6 +66,8 @@ type BaseInstance struct { WrapField bool `json:"wrapField"` // 是否换行字段内容 Folded bool `json:"folded,omitempty"` // 是否折叠 Hidden bool `json:"hidden,omitempty"` // 是否隐藏 + + Groups []Viewable `json:"groups,omitempty"` // 分组实例列表 } func (baseInstance *BaseInstance) GetSorts() []*ViewSort { @@ -76,6 +78,14 @@ func (baseInstance *BaseInstance) GetFilters() []*ViewFilter { return baseInstance.Filters } +func (baseInstance *BaseInstance) SetGroups(viewables []Viewable) { + baseInstance.Groups = viewables +} + +func (baseInstance *BaseInstance) GetID() string { + return baseInstance.ID +} + // BaseInstanceField 描述了实例字段的基础结构。 type BaseInstanceField struct { ID string `json:"id"` // ID diff --git a/kernel/av/layout_gallery.go b/kernel/av/layout_gallery.go index 231404597..bfa978bae 100644 --- a/kernel/av/layout_gallery.go +++ b/kernel/av/layout_gallery.go @@ -97,8 +97,6 @@ type Gallery struct { Fields []*GalleryField `json:"fields"` // 画廊字段 Cards []*GalleryCard `json:"cards"` // 画廊卡片 CardCount int `json:"cardCount"` // 画廊总卡片数 - - Groups []*Gallery `json:"groups,omitempty"` // 分组实例列表 } // GalleryCard 描述了画廊实例卡片的结构。 @@ -179,10 +177,6 @@ func (gallery *Gallery) GetType() LayoutType { return LayoutTypeGallery } -func (gallery *Gallery) GetID() string { - return gallery.ID -} - func (gallery *Gallery) Sort(attrView *AttributeView) { sort0(gallery, attrView) } diff --git a/kernel/av/layout_table.go b/kernel/av/layout_table.go index e7dcf2105..dfb2a1459 100644 --- a/kernel/av/layout_table.go +++ b/kernel/av/layout_table.go @@ -58,8 +58,6 @@ type Table struct { Columns []*TableColumn `json:"columns"` // 表格列 Rows []*TableRow `json:"rows"` // 表格行 RowCount int `json:"rowCount"` // 表格总行数 - - Groups []*Table `json:"groups,omitempty"` // 分组实例列表 } // TableColumn 描述了表格实例列的结构。 diff --git a/kernel/av/sort.go b/kernel/av/sort.go index 6cd3c13df..5cef4f83f 100644 --- a/kernel/av/sort.go +++ b/kernel/av/sort.go @@ -24,13 +24,6 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) -// Sortable 接口定义了可排序的视图类型。 -type Sortable interface { - - // Sort 根据视图中设置的排序规则进行排序。 - Sort(attrView *AttributeView) -} - // ViewSort 描述了视图排序规则的结构。 type ViewSort struct { Column string `json:"column"` // 列(字段)ID diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 3fb48f4c6..59ed1a0ff 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -85,7 +85,7 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) error { v := av.NewTableView() v.Table = av.NewLayoutTable() for _, row := range rows { - v.Table.RowIDs = append(v.Table.RowIDs, row.ID) + v.GroupItemIDs = append(v.GroupItemIDs, row.ID) } view.Groups = append(view.Groups, v) } @@ -1285,34 +1285,24 @@ func renderAttributeView(attrView *av.AttributeView, viewID, query string, page, checkAttrView(attrView, view) upgradeAttributeViewSpec(attrView) - if nil != view.Group && 0 < len(view.Groups) { - var instances []av.Viewable - for _, groupView := range view.Groups { - groupView.Table.Columns = view.Table.Columns - groupViewable := sql.RenderView(groupView, attrView, query) - err = renderViewableInstance(groupViewable, view, attrView, page, pageSize) - if nil != err { - return - } - instances = append(instances, groupViewable) - } - - viewable = instances[0] - switch view.LayoutType { - case av.LayoutTypeTable: - for i := 1; i < len(instances); i++ { - viewable.(*av.Table).Groups = append(viewable.(*av.Table).Groups, instances[i].(*av.Table)) - } - case av.LayoutTypeGallery: - for i := 1; i < len(instances); i++ { - viewable.(*av.Gallery).Groups = append(viewable.(*av.Gallery).Groups, instances[i].(*av.Gallery)) - } - } + viewable = sql.RenderView(view, attrView, query) + err = renderViewableInstance(viewable, view, attrView, page, pageSize) + if nil != err { return } - viewable = sql.RenderView(view, attrView, query) - err = renderViewableInstance(viewable, view, attrView, page, pageSize) + var groups []av.Viewable + for _, groupView := range view.Groups { + groupView.Table.Columns = view.Table.Columns + groupViewable := sql.RenderView(groupView, attrView, query) + err = renderViewableInstance(groupViewable, view, attrView, page, pageSize) + if nil != err { + return + } + + groups = append(groups, groupViewable) + } + viewable.SetGroups(groups) return } diff --git a/kernel/sql/av.go b/kernel/sql/av.go index e2cc45d6d..fedc7133d 100644 --- a/kernel/sql/av.go +++ b/kernel/sql/av.go @@ -187,7 +187,7 @@ func RenderTemplateField(ial map[string]string, keyValues []*av.KeyValues, tplCo return } -func generateAttrViewItems(attrView *av.AttributeView) (ret map[string][]*av.KeyValues) { +func generateAttrViewItems(attrView *av.AttributeView, view *av.View) (ret map[string][]*av.KeyValues) { ret = map[string][]*av.KeyValues{} for _, keyValues := range attrView.KeyValues { for _, val := range keyValues.Values { @@ -200,6 +200,17 @@ func generateAttrViewItems(attrView *av.AttributeView) (ret map[string][]*av.Key ret[val.BlockID] = values } } + + // 如果是分组视图,则需要过滤掉不在分组中的项目 + if 0 < len(view.GroupItemIDs) { + tmp := map[string][]*av.KeyValues{} + for _, groupItemID := range view.GroupItemIDs { + if _, ok := ret[groupItemID]; ok { + tmp[groupItemID] = ret[groupItemID] + } + } + ret = tmp + } return } diff --git a/kernel/sql/av_gallery.go b/kernel/sql/av_gallery.go index 0f225de32..852ffeba4 100644 --- a/kernel/sql/av_gallery.go +++ b/kernel/sql/av_gallery.go @@ -66,8 +66,8 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query }) } - cardsValues := generateAttrViewItems(attrView) // 生成卡片 - filterNotFoundAttrViewItems(&cardsValues) // 过滤掉不存在的卡片 + cardsValues := generateAttrViewItems(attrView, view) // 生成卡片 + filterNotFoundAttrViewItems(&cardsValues) // 过滤掉不存在的卡片 // 批量加载绑定块对应的树 var ialIDs []string diff --git a/kernel/sql/av_table.go b/kernel/sql/av_table.go index 5049cbded..e301cf6d0 100644 --- a/kernel/sql/av_table.go +++ b/kernel/sql/av_table.go @@ -71,8 +71,8 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s }) } - rowsValues := generateAttrViewItems(attrView) // 生成行 - filterNotFoundAttrViewItems(&rowsValues) // 过滤掉不存在的行 + rowsValues := generateAttrViewItems(attrView, view) // 生成行 + filterNotFoundAttrViewItems(&rowsValues) // 过滤掉不存在的行 // 生成行单元格 for rowID, rowValues := range rowsValues {