From 4c55a240f35a1bf9614ac0f98e24d40d2d2cec6d Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 10 Jun 2025 12:23:07 +0800 Subject: [PATCH] :art: Database gallery view https://github.com/siyuan-note/siyuan/issues/10414 --- kernel/av/av.go | 33 ++---------------- kernel/av/layout_gallery.go | 21 +++++++++++- kernel/av/layout_table.go | 14 ++++++++ kernel/model/attribute_view.go | 62 ++++++++++++++++++++++++++++++++++ kernel/model/transaction.go | 2 ++ 5 files changed, 101 insertions(+), 31 deletions(-) diff --git a/kernel/av/av.go b/kernel/av/av.go index d4f5db735..762b92f23 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -207,15 +207,7 @@ func NewTableView() (ret *View) { ID: ast.NewNodeID(), Name: getI18nName("table"), LayoutType: LayoutTypeTable, - Table: &LayoutTable{ - BaseLayout: &BaseLayout{ - Spec: 0, - ID: ast.NewNodeID(), - Filters: []*ViewFilter{}, - Sorts: []*ViewSort{}, - PageSize: TableViewDefaultPageSize, - }, - }, + Table: NewLayoutTable(), } return } @@ -226,15 +218,7 @@ func NewTableViewWithBlockKey(blockKeyID string) (view *View, blockKey, selectKe ID: ast.NewNodeID(), Name: name, LayoutType: LayoutTypeTable, - Table: &LayoutTable{ - BaseLayout: &BaseLayout{ - Spec: 0, - ID: ast.NewNodeID(), - Filters: []*ViewFilter{}, - Sorts: []*ViewSort{}, - PageSize: TableViewDefaultPageSize, - }, - }, + Table: NewLayoutTable(), } blockKey = NewKey(blockKeyID, getI18nName("key"), "", KeyTypeBlock) view.Table.Columns = []*ViewTableColumn{{ID: blockKeyID}} @@ -249,18 +233,7 @@ func NewGalleryView() (ret *View) { ID: ast.NewNodeID(), Name: getI18nName("gallery"), LayoutType: LayoutTypeGallery, - Gallery: &LayoutGallery{ - BaseLayout: &BaseLayout{ - Spec: 0, - ID: ast.NewNodeID(), - Filters: []*ViewFilter{}, - Sorts: []*ViewSort{}, - PageSize: GalleryViewDefaultPageSize, - }, - CoverFrom: CoverFromContentImage, - CardSize: CardSizeMedium, - ShowIcon: true, - }, + Gallery: NewLayoutGallery(), } return } diff --git a/kernel/av/layout_gallery.go b/kernel/av/layout_gallery.go index 959b58ddf..09c255922 100644 --- a/kernel/av/layout_gallery.go +++ b/kernel/av/layout_gallery.go @@ -16,7 +16,11 @@ package av -import "sort" +import ( + "sort" + + "github.com/88250/lute/ast" +) // LayoutGallery 描述了画廊布局的结构。 type LayoutGallery struct { @@ -33,6 +37,21 @@ type LayoutGallery struct { CardIDs []string `json:"cardIds"` // 卡片 ID,用于自定义排序 } +func NewLayoutGallery() *LayoutGallery { + return &LayoutGallery{ + BaseLayout: &BaseLayout{ + Spec: 0, + ID: ast.NewNodeID(), + Filters: []*ViewFilter{}, + Sorts: []*ViewSort{}, + PageSize: GalleryViewDefaultPageSize, + }, + CoverFrom: CoverFromContentImage, + CardSize: CardSizeMedium, + ShowIcon: true, + } +} + type CardSize int const ( diff --git a/kernel/av/layout_table.go b/kernel/av/layout_table.go index 9c9bc811e..220e4f10a 100644 --- a/kernel/av/layout_table.go +++ b/kernel/av/layout_table.go @@ -18,6 +18,8 @@ package av import ( "sort" + + "github.com/88250/lute/ast" ) // LayoutTable 描述了表格布局的结构。 @@ -28,6 +30,18 @@ type LayoutTable struct { RowIDs []string `json:"rowIds"` // 行 ID,用于自定义排序 } +func NewLayoutTable() *LayoutTable { + return &LayoutTable{ + BaseLayout: &BaseLayout{ + Spec: 0, + ID: ast.NewNodeID(), + Filters: []*ViewFilter{}, + Sorts: []*ViewSort{}, + PageSize: TableViewDefaultPageSize, + }, + } +} + // ViewTableColumn 描述了表格列的结构。 type ViewTableColumn struct { ID string `json:"id"` // 列 ID diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 642992e0e..bd2a209a2 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -44,6 +44,68 @@ import ( "github.com/xrash/smetrics" ) +func (tx *Transaction) doChangeAttrViewLayout(operation *Operation) (ret *TxErr) { + err := changeAttrViewLayout(operation) + if err != nil { + return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()} + } + return +} + +func changeAttrViewLayout(operation *Operation) (err error) { + attrView, err := av.ParseAttributeView(operation.AvID) + if err != nil { + return + } + + view, err := getAttrViewViewByBlockID(attrView, operation.BlockID) + if err != nil { + return + } + + newLayout := operation.Layout + if newLayout == view.LayoutType { + return + } + + view.LayoutType = newLayout + switch newLayout { + case av.LayoutTypeTable: + if nil != view.Table { + break + } + + view.Table = av.NewLayoutTable() + switch view.LayoutType { + case av.LayoutTypeGallery: + for _, field := range view.Gallery.CardFields { + view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{ID: field.ID}) + } + for _, cardID := range view.Gallery.CardIDs { + view.Table.RowIDs = append(view.Table.RowIDs, cardID) + } + } + case av.LayoutTypeGallery: + if nil != view.Gallery { + break + } + + view.Gallery = av.NewLayoutGallery() + switch view.LayoutType { + case av.LayoutTypeTable: + for _, col := range view.Table.Columns { + view.Gallery.CardFields = append(view.Gallery.CardFields, &av.ViewGalleryCardField{ID: col.ID}) + } + for _, rowID := range view.Table.RowIDs { + view.Gallery.CardIDs = append(view.Gallery.CardIDs, rowID) + } + } + } + + err = av.SaveAttributeView(attrView) + return +} + func (tx *Transaction) doSetAttrViewWrapField(operation *Operation) (ret *TxErr) { err := setAttrViewWrapField(operation) if err != nil { diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 4ee57bc01..1f1faaf1c 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -290,6 +290,8 @@ func performTx(tx *Transaction) (ret *TxErr) { ret = tx.doSetAttrViewShowIcon(op) case "setAttrViewWrapField": ret = tx.doSetAttrViewWrapField(op) + case "changeAttrViewLayout": + ret = tx.doChangeAttrViewLayout(op) } if nil != ret {