diff --git a/kernel/av/av.go b/kernel/av/av.go index 555ebce93..9b534fc5e 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -190,6 +190,7 @@ type View struct { LayoutType LayoutType `json:"type"` // 当前布局类型 Table *LayoutTable `json:"table,omitempty"` // 表格布局 Gallery *LayoutGallery `json:"gallery,omitempty"` // 画廊布局 + ItemIDs []string `json:"itemIds,omitempty"` // 项目 ID 列表,用于维护所有项目 Groups []*View `json:"groups,omitempty"` // 分组视图列表 GroupItemIDs []string `json:"groupItemIds,omitempty"` // 分组项目 ID 列表,用于维护分组中的所有项目 @@ -276,7 +277,7 @@ type Viewable interface { func NewAttributeView(id string) (ret *AttributeView) { view, blockKey, selectKey := NewTableViewWithBlockKey(ast.NewNodeID()) ret = &AttributeView{ - Spec: 2, + Spec: 3, ID: id, KeyValues: []*KeyValues{{Key: blockKey}, {Key: selectKey}}, ViewID: view.ID, @@ -418,14 +419,8 @@ func SaveAttributeView(av *AttributeView) (err error) { // 视图值去重 for _, view := range av.Views { - if nil != view.Table { - // 行去重 - view.Table.RowIDs = gulu.Str.RemoveDuplicatedElem(view.Table.RowIDs) - } - if nil != view.Gallery { - // 行去重 - view.Gallery.CardIDs = gulu.Str.RemoveDuplicatedElem(view.Gallery.CardIDs) - } + // 项目自定义排序去重 + view.ItemIDs = gulu.Str.RemoveDuplicatedElem(view.ItemIDs) // 分页大小 if 1 > view.PageSize { @@ -614,14 +609,13 @@ func (av *AttributeView) Clone() (ret *AttributeView) { for _, column := range view.Table.Columns { column.ID = keyIDMap[column.ID] } - view.Table.RowIDs = []string{} case LayoutTypeGallery: view.Gallery.ID = ast.NewNodeID() for _, cardField := range view.Gallery.CardFields { cardField.ID = keyIDMap[cardField.ID] } - view.Gallery.CardIDs = []string{} } + view.ItemIDs = []string{} } ret.ViewID = ret.Views[0].ID diff --git a/kernel/av/av_fix.go b/kernel/av/av_fix.go index 013e60962..c85bc5cbe 100644 --- a/kernel/av/av_fix.go +++ b/kernel/av/av_fix.go @@ -27,6 +27,33 @@ import ( func UpgradeSpec(av *AttributeView) { upgradeSpec1(av) upgradeSpec2(av) + upgradeSpec3(av) +} + +func upgradeSpec3(av *AttributeView) { + if 3 <= av.Spec { + return + } + + // 将 view.table.rowIds 或 view.gallery.cardIds 复制到 view.itemIds + for _, view := range av.Views { + if 0 < len(view.ItemIDs) { + continue + } + + switch view.LayoutType { + case LayoutTypeTable: + if nil != view.Table { + view.ItemIDs = view.Table.RowIDs + } + case LayoutTypeGallery: + if nil != view.Gallery { + view.ItemIDs = view.Gallery.CardIDs + } + } + } + + av.Spec = 3 } func upgradeSpec2(av *AttributeView) { @@ -78,7 +105,6 @@ func upgradeSpec2(av *AttributeView) { } av.Spec = 2 - logging.LogInfof("av [%s] upgraded to spec [%d]", av.ID, av.Spec) } func upgradeSpec1(av *AttributeView) { @@ -211,5 +237,4 @@ func upgradeSpec1(av *AttributeView) { } av.Spec = 1 - logging.LogInfof("av [%s] upgraded to spec [%d]", av.ID, av.Spec) } diff --git a/kernel/av/layout.go b/kernel/av/layout.go index 09de79d7d..b719f9e7f 100644 --- a/kernel/av/layout.go +++ b/kernel/av/layout.go @@ -110,13 +110,6 @@ func (baseInstanceField *BaseInstanceField) GetID() string { return baseInstanceField.ID } -// CollectionLayout 描述了集合布局的接口。 -type CollectionLayout interface { - - // GetItemIDs 返回集合中所有项目的 ID。 - GetItemIDs() []string -} - // Collection 描述了一个集合的接口。 // 集合可以是表格、画廊等,包含多个项目。 type Collection interface { diff --git a/kernel/av/layout_gallery.go b/kernel/av/layout_gallery.go index bfa978bae..1fc42ab37 100644 --- a/kernel/av/layout_gallery.go +++ b/kernel/av/layout_gallery.go @@ -30,12 +30,11 @@ type LayoutGallery struct { CardSize CardSize `json:"cardSize"` // 卡片大小,0:小卡片,1:中卡片,2:大卡片 FitImage bool `json:"fitImage"` // 是否适应封面图片大小 - CardFields []*ViewGalleryCardField `json:"fields"` // 画廊卡片字段 - CardIDs []string `json:"cardIds"` // 卡片 ID,用于自定义排序 -} + CardFields []*ViewGalleryCardField `json:"fields"` // 画廊卡片字段 -func (layoutGallery *LayoutGallery) GetItemIDs() (ret []string) { - return layoutGallery.CardIDs + // TODO CardIDs 字段已经废弃,计划于 2026 年 6 月 30 日后删除 https://github.com/siyuan-note/siyuan/issues/15194 + //Deprecated + CardIDs []string `json:"cardIds"` // 卡片 ID,用于自定义排序 } func NewLayoutGallery() *LayoutGallery { diff --git a/kernel/av/layout_table.go b/kernel/av/layout_table.go index dfb2a1459..e46e10b69 100644 --- a/kernel/av/layout_table.go +++ b/kernel/av/layout_table.go @@ -25,11 +25,10 @@ type LayoutTable struct { *BaseLayout Columns []*ViewTableColumn `json:"columns"` // 表格列 - RowIDs []string `json:"rowIds"` // 行 ID,用于自定义排序 -} -func (layoutTable *LayoutTable) GetItemIDs() (ret []string) { - return layoutTable.RowIDs + // TODO RowIDs 字段已经废弃,计划于 2026 年 6 月 30 日后删除 https://github.com/siyuan-note/siyuan/issues/15194 + //Deprecated + RowIDs []string `json:"rowIds"` // 行 ID,用于自定义排序 } func NewLayoutTable() *LayoutTable { diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index b592ce258..b74d745f4 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -175,9 +175,6 @@ func ChangeAttrViewLayout(blockID, avID string, layout av.LayoutType) (err error for _, field := range view.Gallery.CardFields { view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{BaseField: &av.BaseField{ID: field.ID}}) } - for _, cardID := range view.Gallery.CardIDs { - view.Table.RowIDs = append(view.Table.RowIDs, cardID) - } } case av.LayoutTypeGallery: if view.Name == av.GetAttributeViewI18n("table") { @@ -194,9 +191,6 @@ func ChangeAttrViewLayout(blockID, avID string, layout av.LayoutType) (err error for _, col := range view.Table.Columns { view.Gallery.CardFields = append(view.Gallery.CardFields, &av.ViewGalleryCardField{BaseField: &av.BaseField{ID: col.ID}}) } - for _, rowID := range view.Table.RowIDs { - view.Gallery.CardIDs = append(view.Gallery.CardIDs, rowID) - } } } @@ -469,15 +463,8 @@ func AppendAttributeViewDetachedBlocksWithValues(avID string, blocksValues [][]* } for _, v := range attrView.Views { - switch v.LayoutType { - case av.LayoutTypeTable: - for _, addingBlockID := range blockIDs { - v.Table.RowIDs = append(v.Table.RowIDs, addingBlockID) - } - case av.LayoutTypeGallery: - for _, addingBlockID := range blockIDs { - v.Gallery.CardIDs = append(v.Gallery.CardIDs, addingBlockID) - } + for _, addingBlockID := range blockIDs { + v.ItemIDs = append(v.ItemIDs, addingBlockID) } } @@ -1441,31 +1428,16 @@ func unbindAttributeViewBlock(operation *Operation, tx *Transaction) (err error) replacedRowID := false for _, v := range attrView.Views { - switch v.LayoutType { - case av.LayoutTypeTable: - for i, rowID := range v.Table.RowIDs { - if rowID == operation.ID { - v.Table.RowIDs[i] = operation.NextID - replacedRowID = true - break - } + for i, itemID := range v.ItemIDs { + if itemID == operation.ID { + v.ItemIDs[i] = operation.NextID + replacedRowID = true + break } + } - if !replacedRowID { - v.Table.RowIDs = append(v.Table.RowIDs, operation.NextID) - } - case av.LayoutTypeGallery: - for i, cardID := range v.Gallery.CardIDs { - if cardID == operation.ID { - v.Gallery.CardIDs[i] = operation.NextID - replacedRowID = true - break - } - } - - if !replacedRowID { - v.Gallery.CardIDs = append(v.Gallery.CardIDs, operation.NextID) - } + if !replacedRowID { + v.ItemIDs = append(v.ItemIDs, operation.NextID) } } @@ -1977,7 +1949,6 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr }) } - view.Table.RowIDs = masterView.Table.RowIDs view.Table.ShowIcon = masterView.Table.ShowIcon view.Table.WrapField = masterView.Table.WrapField case av.LayoutTypeGallery: @@ -1992,7 +1963,6 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr }) } - view.Gallery.CardIDs = masterView.Gallery.CardIDs view.Gallery.CoverFrom = masterView.Gallery.CoverFrom view.Gallery.CoverFromAssetKeyID = masterView.Gallery.CoverFromAssetKeyID view.Gallery.CardSize = masterView.Gallery.CardSize @@ -2001,6 +1971,8 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr view.Gallery.WrapField = masterView.Gallery.WrapField } + view.ItemIDs = masterView.ItemIDs + if err = av.SaveAttributeView(attrView); err != nil { logging.LogErrorf("save attribute view [%s] failed: %s", avID, err) return &TxErr{code: TxErrWriteAttributeView, msg: err.Error(), id: avID} @@ -2047,16 +2019,10 @@ func addAttrViewView(avID, viewID, blockID string, layout av.LayoutType) (err er for _, col := range firstView.Table.Columns { view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{BaseField: &av.BaseField{ID: col.ID}}) } - for _, rowID := range firstView.Table.RowIDs { - view.Table.RowIDs = append(view.Table.RowIDs, rowID) - } case av.LayoutTypeGallery: for _, field := range firstView.Gallery.CardFields { view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{BaseField: &av.BaseField{ID: field.ID}}) } - for _, cardID := range firstView.Gallery.CardIDs { - view.Table.RowIDs = append(view.Table.RowIDs, cardID) - } } case av.LayoutTypeGallery: view = av.NewGalleryView() @@ -2065,16 +2031,10 @@ func addAttrViewView(avID, viewID, blockID string, layout av.LayoutType) (err er for _, col := range firstView.Table.Columns { view.Gallery.CardFields = append(view.Gallery.CardFields, &av.ViewGalleryCardField{BaseField: &av.BaseField{ID: col.ID}}) } - for _, rowID := range firstView.Table.RowIDs { - view.Gallery.CardIDs = append(view.Gallery.CardIDs, rowID) - } case av.LayoutTypeGallery: for _, field := range firstView.Gallery.CardFields { view.Gallery.CardFields = append(view.Gallery.CardFields, &av.ViewGalleryCardField{BaseField: &av.BaseField{ID: field.ID}}) } - for _, cardID := range firstView.Gallery.CardIDs { - view.Gallery.CardIDs = append(view.Gallery.CardIDs, cardID) - } } default: err = av.ErrWrongLayoutType @@ -2082,6 +2042,7 @@ func addAttrViewView(avID, viewID, blockID string, layout av.LayoutType) (err er return } + view.ItemIDs = firstView.ItemIDs attrView.ViewID = viewID view.ID = viewID attrView.Views = append(attrView.Views, view) @@ -2599,39 +2560,20 @@ func addAttributeViewBlock(now int64, avID, blockID, previousBlockID, addingBloc } for _, v := range attrView.Views { - switch v.LayoutType { - case av.LayoutTypeTable: - if "" != previousBlockID { - changed := false - for i, id := range v.Table.RowIDs { - if id == previousBlockID { - v.Table.RowIDs = append(v.Table.RowIDs[:i+1], append([]string{addingBlockID}, v.Table.RowIDs[i+1:]...)...) - changed = true - break - } + if "" != previousBlockID { + changed := false + for i, id := range v.ItemIDs { + if id == previousBlockID { + v.ItemIDs = append(v.ItemIDs[:i+1], append([]string{addingBlockID}, v.ItemIDs[i+1:]...)...) + changed = true + break } - if !changed { - v.Table.RowIDs = append(v.Table.RowIDs, addingBlockID) - } - } else { - v.Table.RowIDs = append([]string{addingBlockID}, v.Table.RowIDs...) } - case av.LayoutTypeGallery: - if "" != previousBlockID { - changed := false - for i, id := range v.Gallery.CardIDs { - if id == previousBlockID { - v.Gallery.CardIDs = append(v.Gallery.CardIDs[:i+1], append([]string{addingBlockID}, v.Gallery.CardIDs[i+1:]...)...) - changed = true - break - } - } - if !changed { - v.Gallery.CardIDs = append(v.Gallery.CardIDs, addingBlockID) - } - } else { - v.Gallery.CardIDs = append([]string{addingBlockID}, v.Gallery.CardIDs...) + if !changed { + v.ItemIDs = append(v.ItemIDs, addingBlockID) } + } else { + v.ItemIDs = append([]string{addingBlockID}, v.ItemIDs...) } } @@ -2688,12 +2630,7 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er for _, view := range attrView.Views { for _, blockID := range srcIDs { - switch view.LayoutType { - case av.LayoutTypeTable: - view.Table.RowIDs = gulu.Str.RemoveElem(view.Table.RowIDs, blockID) - case av.LayoutTypeGallery: - view.Gallery.CardIDs = gulu.Str.RemoveElem(view.Gallery.CardIDs, blockID) - } + view.ItemIDs = gulu.Str.RemoveElem(view.ItemIDs, blockID) } } @@ -3082,51 +3019,27 @@ func sortAttributeViewRow(operation *Operation) (err error) { var itemID string var idx, previousIndex int - switch view.LayoutType { - case av.LayoutTypeTable: - for i, r := range view.Table.RowIDs { - if r == operation.ID { - itemID = r - idx = i - break - } + for i, id := range view.ItemIDs { + if id == operation.ID { + itemID = id + idx = i + break } - if "" == itemID { - itemID = operation.ID - view.Table.RowIDs = append(view.Table.RowIDs, itemID) - idx = len(view.Table.RowIDs) - 1 - } - - view.Table.RowIDs = append(view.Table.RowIDs[:idx], view.Table.RowIDs[idx+1:]...) - for i, r := range view.Table.RowIDs { - if r == operation.PreviousID { - previousIndex = i + 1 - break - } - } - view.Table.RowIDs = util.InsertElem(view.Table.RowIDs, previousIndex, itemID) - case av.LayoutTypeGallery: - for i, c := range view.Gallery.CardIDs { - if c == operation.ID { - itemID = c - idx = i - break - } - } - if "" == itemID { - itemID = operation.ID - view.Gallery.CardIDs = append(view.Gallery.CardIDs, itemID) - idx = len(view.Gallery.CardIDs) - 1 - } - view.Gallery.CardIDs = append(view.Gallery.CardIDs[:idx], view.Gallery.CardIDs[idx+1:]...) - for i, c := range view.Gallery.CardIDs { - if c == operation.PreviousID { - previousIndex = i + 1 - break - } - } - view.Gallery.CardIDs = util.InsertElem(view.Gallery.CardIDs, previousIndex, itemID) } + if "" == itemID { + itemID = operation.ID + view.ItemIDs = append(view.ItemIDs, itemID) + idx = len(view.ItemIDs) - 1 + } + + view.ItemIDs = append(view.ItemIDs[:idx], view.ItemIDs[idx+1:]...) + for i, r := range view.ItemIDs { + if r == operation.PreviousID { + previousIndex = i + 1 + break + } + } + view.ItemIDs = util.InsertElem(view.ItemIDs, previousIndex, itemID) err = av.SaveAttributeView(attrView) return @@ -3664,27 +3577,16 @@ func replaceAttributeViewBlock(operation *Operation, tx *Transaction) (err error replacedRowID := false for _, v := range attrView.Views { - switch v.LayoutType { - case av.LayoutTypeTable: - for i, rowID := range v.Table.RowIDs { - if rowID == operation.PreviousID { - v.Table.RowIDs[i] = operation.NextID - replacedRowID = true - break - } + for i, itemID := range v.ItemIDs { + if itemID == operation.PreviousID { + v.ItemIDs[i] = operation.NextID + replacedRowID = true + break } + } - if !replacedRowID { - v.Table.RowIDs = append(v.Table.RowIDs, operation.NextID) - } - case av.LayoutTypeGallery: - for i, cardID := range v.Gallery.CardIDs { - if cardID == operation.PreviousID { - v.Gallery.CardIDs[i] = operation.NextID - replacedRowID = true - break - } - } + if !replacedRowID { + v.ItemIDs = append(v.ItemIDs, operation.NextID) } } diff --git a/kernel/model/export.go b/kernel/model/export.go index a77a88d5e..4ba5065c9 100644 --- a/kernel/model/export.go +++ b/kernel/model/export.go @@ -3405,9 +3405,6 @@ func getAttrViewTable(attrView *av.AttributeView, view *av.View, query string) ( for _, field := range view.Gallery.CardFields { view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{BaseField: &av.BaseField{ID: field.ID}}) } - for _, cardID := range view.Gallery.CardIDs { - view.Table.RowIDs = append(view.Table.RowIDs, cardID) - } } ret = sql.RenderAttributeViewTable(attrView, view, query) return diff --git a/kernel/sql/av.go b/kernel/sql/av.go index fedc7133d..7e946d2b0 100644 --- a/kernel/sql/av.go +++ b/kernel/sql/av.go @@ -619,16 +619,16 @@ func filterByQuery(query string, collection av.Collection) { } // manualSort 处理用户手动排序。 -func manualSort(collectionLayout av.CollectionLayout, collection av.Collection) { - sortRowIDs := map[string]int{} - for i, itemID := range collectionLayout.GetItemIDs() { - sortRowIDs[itemID] = i +func manualSort(view *av.View, collection av.Collection) { + sortItemIDs := map[string]int{} + for i, itemID := range view.ItemIDs { + sortItemIDs[itemID] = i } items := collection.GetItems() sort.Slice(items, func(i, j int) bool { - iv := sortRowIDs[items[i].GetID()] - jv := sortRowIDs[items[j].GetID()] + iv := sortItemIDs[items[i].GetID()] + jv := sortItemIDs[items[j].GetID()] if iv == jv { return items[i].GetID() < items[j].GetID() } diff --git a/kernel/sql/av_gallery.go b/kernel/sql/av_gallery.go index 852ffeba4..51bd4229f 100644 --- a/kernel/sql/av_gallery.go +++ b/kernel/sql/av_gallery.go @@ -143,7 +143,7 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query } filterByQuery(query, ret) - manualSort(view.Gallery, ret) + manualSort(view, ret) return } diff --git a/kernel/sql/av_table.go b/kernel/sql/av_table.go index e301cf6d0..c6a77456a 100644 --- a/kernel/sql/av_table.go +++ b/kernel/sql/av_table.go @@ -142,6 +142,6 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s } filterByQuery(query, ret) - manualSort(view.Table, ret) + manualSort(view, ret) return }