diff --git a/kernel/av/av.go b/kernel/av/av.go index e52880c68fc..e689a8db7db 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -169,6 +169,8 @@ func (value *Value) ToJSONString() string { type ValueBlock struct { ID string `json:"id"` Content string `json:"content"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` } type ValueText struct { @@ -510,6 +512,28 @@ func ParseAttributeView(avID string) (ret *AttributeView, err error) { } func SaveAttributeView(av *AttributeView) (err error) { + // 做一些数据兼容处理 + now := util.CurrentTimeMillis() + for _, kv := range av.KeyValues { + if KeyTypeBlock == kv.Key.Type { + // 补全 block 的创建时间和更新时间 + for _, v := range kv.Values { + if 0 == v.Block.Created { + createdStr := v.Block.ID[:len("20060102150405")] + created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local) + if nil == parseErr { + v.Block.Created = created.UnixMilli() + } else { + v.Block.Created = now + } + } + if 0 == v.Block.Updated { + v.Block.Updated = now + } + } + } + } + data, err := gulu.JSON.MarshalIndentJSON(av, "", "\t") // TODO: single-line for production if nil != err { logging.LogErrorf("marshal attribute view [%s] failed: %s", av.ID, err) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 6f4261b198e..099c67ba79f 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -40,6 +40,15 @@ type BlockAttributeViewKeys struct { } func renderTemplateCol(ial map[string]string, tplContent string, rowValues []*av.KeyValues) string { + if "" == ial["id"] { + block := getRowBlockValue(rowValues) + ial["id"] = block.Block.ID + } + if "" == ial["updated"] { + block := getRowBlockValue(rowValues) + ial["updated"] = time.UnixMilli(block.Block.Updated).Format("20060102150405") + } + funcMap := sprig.TxtFuncMap() goTpl := template.New("").Delims(".action{", "}") tplContent = strings.ReplaceAll(tplContent, ".custom-", ".custom_") // 模板中的属性名不允许包含 - 字符,因此这里需要替换 @@ -71,7 +80,6 @@ func renderTemplateCol(ial map[string]string, tplContent string, rowValues []*av if nil == parseErr { dataModel["updated"] = updated } else { - logging.LogWarnf("parse updated [%s] failed: %s", updatedStr, parseErr) dataModel["updated"] = time.Now() } } @@ -142,13 +150,9 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) { } // 渲染自动生成的列值,比如模板列、创建时间列和更新时间列 + // 先处理创建时间和更新时间 for _, kv := range keyValues { switch kv.Key.Type { - case av.KeyTypeTemplate: - if 0 < len(kv.Values) { - ial := GetBlockAttrs(blockID) - kv.Values[0].Template.Content = renderTemplateCol(ial, kv.Key.Template, keyValues) - } case av.KeyTypeCreated: createdStr := blockID[:len("20060102150405")] created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local) @@ -172,6 +176,16 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) { } } } + // 再处理模板列 + for _, kv := range keyValues { + switch kv.Key.Type { + case av.KeyTypeTemplate: + if 0 < len(kv.Values) { + ial := GetBlockAttrs(blockID) + kv.Values[0].Template.Content = renderTemplateCol(ial, kv.Key.Template, keyValues) + } + } + } // Attribute Panel - Database sort attributes by view column order https://github.com/siyuan-note/siyuan/issues/9319 view, _ := attrView.GetView() @@ -229,6 +243,28 @@ func RenderAttributeView(avID string) (viewable av.Viewable, attrView *av.Attrib view = attrView.Views[0] } + // 做一些数据兼容处理,保存的时候也会做 av.SaveAttributeView() + now := util.CurrentTimeMillis() + for _, kv := range attrView.KeyValues { + switch kv.Key.Type { + case av.KeyTypeBlock: // 补全 block 的创建时间和更新时间 + for _, v := range kv.Values { + if 0 == v.Block.Created { + createdStr := v.Block.ID[:len("20060102150405")] + created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local) + if nil == parseErr { + v.Block.Created = created.UnixMilli() + } else { + v.Block.Created = now + } + } + if 0 == v.Block.Updated { + v.Block.Updated = now + } + } + } + } + switch view.LayoutType { case av.LayoutTypeTable: // 列删除以后需要删除设置的过滤和排序 @@ -393,12 +429,18 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a case av.KeyTypeUpdated: // 渲染更新时间 ial := GetBlockAttrs(row.ID) updatedStr := ial["updated"] - updated, parseErr := time.ParseInLocation("20060102150405", updatedStr, time.Local) - if nil == parseErr { - cell.Value.Updated = av.NewFormattedValueUpdated(updated.UnixMilli(), 0, av.UpdatedFormatNone) + if "" == updatedStr { + block := getTableRowBlockValue(row) + cell.Value.Updated = av.NewFormattedValueUpdated(block.Block.Updated, 0, av.UpdatedFormatNone) cell.Value.Updated.IsNotEmpty = true } else { - cell.Value.Updated = av.NewFormattedValueUpdated(time.Now().UnixMilli(), 0, av.UpdatedFormatNone) + updated, parseErr := time.ParseInLocation("20060102150405", updatedStr, time.Local) + if nil == parseErr { + cell.Value.Updated = av.NewFormattedValueUpdated(updated.UnixMilli(), 0, av.UpdatedFormatNone) + cell.Value.Updated.IsNotEmpty = true + } else { + cell.Value.Updated = av.NewFormattedValueUpdated(time.Now().UnixMilli(), 0, av.UpdatedFormatNone) + } } } } @@ -433,6 +475,16 @@ func getRowBlockValue(keyValues []*av.KeyValues) (ret *av.Value) { return } +func getTableRowBlockValue(row *av.TableRow) (ret *av.Value) { + for _, cell := range row.Cells { + if av.KeyTypeBlock == cell.ValueType { + ret = cell.Value + break + } + } + return +} + func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) { err := setAttributeViewName(operation) if nil != err { @@ -640,7 +692,8 @@ func addAttributeViewBlock(blockID string, operation *Operation, tree *parse.Tre if !operation.IsDetached { content = getNodeRefText(node) } - value := &av.Value{ID: ast.NewNodeID(), KeyID: blockValues.Key.ID, BlockID: blockID, Type: av.KeyTypeBlock, IsDetached: operation.IsDetached, Block: &av.ValueBlock{ID: blockID, Content: content}} + now := time.Now().UnixMilli() + value := &av.Value{ID: ast.NewNodeID(), KeyID: blockValues.Key.ID, BlockID: blockID, Type: av.KeyTypeBlock, IsDetached: operation.IsDetached, Block: &av.ValueBlock{ID: blockID, Content: content, Created: now, Updated: now}} blockValues.Values = append(blockValues.Values, value) if !operation.IsDetached { @@ -1243,6 +1296,10 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID, cellID string, bindBlockAv(tx, avID, rowID) } + if nil != val.Block { + val.Block.Updated = time.Now().UnixMilli() + } + if err = av.SaveAttributeView(attrView); nil != err { return }