mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 23:20:13 +01:00
🎨 The database rollup field supports using the updated/created field https://github.com/siyuan-note/siyuan/issues/15662
This commit is contained in:
parent
ee95f9bf6f
commit
9bb6f4d134
6 changed files with 54 additions and 44 deletions
|
|
@ -35,6 +35,8 @@ const genAVRollupHTML = (value: IAVCellValue) => {
|
||||||
html = value.number.formattedContent || value.number.content.toString();
|
html = value.number.formattedContent || value.number.content.toString();
|
||||||
break;
|
break;
|
||||||
case "date":
|
case "date":
|
||||||
|
case "updated":
|
||||||
|
case "created":
|
||||||
if (value[value.type] && value[value.type].isNotEmpty) {
|
if (value[value.type] && value[value.type].isNotEmpty) {
|
||||||
html = dayjs(value[value.type].content).format(value[value.type].isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
|
html = dayjs(value[value.type].content).format(value[value.type].isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,20 @@ func GetKeyBlockValue(blockKeyValues []*KeyValues) (ret *Value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetValue(keyValues []*KeyValues, keyID, itemID string) (ret *Value) {
|
||||||
|
for _, kv := range keyValues {
|
||||||
|
if kv.Key.ID == keyID {
|
||||||
|
for _, v := range kv.Values {
|
||||||
|
if v.BlockID == itemID {
|
||||||
|
ret = v
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// KeyType 描述了属性视图属性字段的类型。
|
// KeyType 描述了属性视图属性字段的类型。
|
||||||
type KeyType string
|
type KeyType string
|
||||||
|
|
||||||
|
|
@ -565,15 +579,6 @@ func (av *AttributeView) GetCurrentView(viewID string) (ret *View, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (av *AttributeView) ExistItem(itemID string) bool {
|
|
||||||
for _, blockVal := range av.GetBlockKeyValues().Values {
|
|
||||||
if blockVal.BlockID == itemID {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (av *AttributeView) ExistBoundBlock(nodeID string) bool {
|
func (av *AttributeView) ExistBoundBlock(nodeID string) bool {
|
||||||
for _, blockVal := range av.GetBlockKeyValues().Values {
|
for _, blockVal := range av.GetBlockKeyValues().Values {
|
||||||
if blockVal.Block.ID == nodeID {
|
if blockVal.Block.ID == nodeID {
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
value.Rollup.BuildContents(destAv, destKey, relVal, key.Rollup.Calc, nil)
|
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, nil)
|
||||||
for _, content := range value.Rollup.Contents {
|
for _, content := range value.Rollup.Contents {
|
||||||
switch filter.Operator {
|
switch filter.Operator {
|
||||||
case FilterOperatorContains:
|
case FilterOperatorContains:
|
||||||
|
|
|
||||||
|
|
@ -796,21 +796,16 @@ type ValueRollup struct {
|
||||||
Contents []*Value `json:"contents"`
|
Contents []*Value `json:"contents"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ValueRollup) BuildContents(destAv *AttributeView, destKey *Key, relationVal *Value, calc *RollupCalc, furtherCollection Collection) {
|
func (r *ValueRollup) BuildContents(keyValues []*KeyValues, destKey *Key, relationVal *Value, calc *RollupCalc, furtherCollection Collection) {
|
||||||
r.Contents = nil
|
r.Contents = nil
|
||||||
for _, blockID := range relationVal.Relation.BlockIDs {
|
for _, blockID := range relationVal.Relation.BlockIDs {
|
||||||
destVal := destAv.GetValue(destKey.ID, blockID)
|
destVal := GetValue(keyValues, destKey.ID, blockID)
|
||||||
if nil != furtherCollection && KeyTypeTemplate == destKey.Type {
|
if nil != furtherCollection && KeyTypeTemplate == destKey.Type {
|
||||||
destVal = furtherCollection.GetValue(blockID, destKey.ID)
|
destVal = furtherCollection.GetValue(blockID, destKey.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if nil == destVal {
|
if nil == destVal {
|
||||||
if destAv.ExistItem(blockID) { // 数据库中存在项目但是字段值不存在是数据未初始化,这里补一个默认值
|
continue
|
||||||
destVal = GetAttributeViewDefaultValue(ast.NewNodeID(), destKey.ID, blockID, destKey.Type)
|
|
||||||
}
|
|
||||||
if nil == destVal {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if KeyTypeNumber == destKey.Type {
|
if KeyTypeNumber == destKey.Type {
|
||||||
destVal.Number.Format = destKey.NumberFormat
|
destVal.Number.Format = destKey.NumberFormat
|
||||||
|
|
|
||||||
|
|
@ -1491,8 +1491,7 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染自动生成的字段值,比如模板字段、关联字段、汇总字段、创建时间字段和更新时间字段
|
// 先渲染主键、创建时间、更新时间
|
||||||
// 先处理关联字段、汇总字段、创建时间字段和更新时间字段
|
|
||||||
for _, kv := range keyValues {
|
for _, kv := range keyValues {
|
||||||
switch kv.Key.Type {
|
switch kv.Key.Type {
|
||||||
case av.KeyTypeBlock: // 对于主键可能需要填充静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049
|
case av.KeyTypeBlock: // 对于主键可能需要填充静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049
|
||||||
|
|
@ -1502,6 +1501,33 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
||||||
kv.Values[0].Block.Content = v
|
kv.Values[0].Block.Content = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case av.KeyTypeCreated:
|
||||||
|
createdStr := nodeID[:len("20060102150405")]
|
||||||
|
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
||||||
|
if nil == parseErr {
|
||||||
|
kv.Values[0].Created = av.NewFormattedValueCreated(created.UnixMilli(), 0, av.CreatedFormatNone)
|
||||||
|
kv.Values[0].Created.IsNotEmpty = true
|
||||||
|
} else {
|
||||||
|
logging.LogWarnf("parse created [%s] failed: %s", createdStr, parseErr)
|
||||||
|
kv.Values[0].Created = av.NewFormattedValueCreated(time.Now().UnixMilli(), 0, av.CreatedFormatNone)
|
||||||
|
}
|
||||||
|
case av.KeyTypeUpdated:
|
||||||
|
ial := sql.GetBlockAttrs(nodeID)
|
||||||
|
updatedStr := ial["updated"]
|
||||||
|
updated, parseErr := time.ParseInLocation("20060102150405", updatedStr, time.Local)
|
||||||
|
if nil == parseErr {
|
||||||
|
kv.Values[0].Updated = av.NewFormattedValueUpdated(updated.UnixMilli(), 0, av.UpdatedFormatNone)
|
||||||
|
kv.Values[0].Updated.IsNotEmpty = true
|
||||||
|
} else {
|
||||||
|
logging.LogWarnf("parse updated [%s] failed: %s", updatedStr, parseErr)
|
||||||
|
kv.Values[0].Updated = av.NewFormattedValueUpdated(time.Now().UnixMilli(), 0, av.UpdatedFormatNone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 再渲染汇总和关联
|
||||||
|
for _, kv := range keyValues {
|
||||||
|
switch kv.Key.Type {
|
||||||
case av.KeyTypeRollup:
|
case av.KeyTypeRollup:
|
||||||
if nil == kv.Key.Rollup {
|
if nil == kv.Key.Rollup {
|
||||||
break
|
break
|
||||||
|
|
@ -1534,7 +1560,7 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kv.Values[0].Rollup.BuildContents(destAv, destKey, relVal, kv.Key.Rollup.Calc, furtherCollection)
|
kv.Values[0].Rollup.BuildContents(keyValues, destKey, relVal, kv.Key.Rollup.Calc, furtherCollection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case av.KeyTypeRelation:
|
case av.KeyTypeRelation:
|
||||||
|
|
@ -1560,31 +1586,10 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
||||||
for _, bID := range kv.Values[0].Relation.BlockIDs {
|
for _, bID := range kv.Values[0].Relation.BlockIDs {
|
||||||
kv.Values[0].Relation.Contents = append(kv.Values[0].Relation.Contents, blocks[bID])
|
kv.Values[0].Relation.Contents = append(kv.Values[0].Relation.Contents, blocks[bID])
|
||||||
}
|
}
|
||||||
case av.KeyTypeCreated:
|
|
||||||
createdStr := nodeID[:len("20060102150405")]
|
|
||||||
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
|
||||||
if nil == parseErr {
|
|
||||||
kv.Values[0].Created = av.NewFormattedValueCreated(created.UnixMilli(), 0, av.CreatedFormatNone)
|
|
||||||
kv.Values[0].Created.IsNotEmpty = true
|
|
||||||
} else {
|
|
||||||
logging.LogWarnf("parse created [%s] failed: %s", createdStr, parseErr)
|
|
||||||
kv.Values[0].Created = av.NewFormattedValueCreated(time.Now().UnixMilli(), 0, av.CreatedFormatNone)
|
|
||||||
}
|
|
||||||
case av.KeyTypeUpdated:
|
|
||||||
ial := sql.GetBlockAttrs(nodeID)
|
|
||||||
updatedStr := ial["updated"]
|
|
||||||
updated, parseErr := time.ParseInLocation("20060102150405", updatedStr, time.Local)
|
|
||||||
if nil == parseErr {
|
|
||||||
kv.Values[0].Updated = av.NewFormattedValueUpdated(updated.UnixMilli(), 0, av.UpdatedFormatNone)
|
|
||||||
kv.Values[0].Updated.IsNotEmpty = true
|
|
||||||
} else {
|
|
||||||
logging.LogWarnf("parse updated [%s] failed: %s", updatedStr, parseErr)
|
|
||||||
kv.Values[0].Updated = av.NewFormattedValueUpdated(time.Now().UnixMilli(), 0, av.UpdatedFormatNone)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 再处理模板字段
|
// 最后渲染模板
|
||||||
templateKeys, _ := sql.GetTemplateKeysByResolutionOrder(attrView)
|
templateKeys, _ := sql.GetTemplateKeysByResolutionOrder(attrView)
|
||||||
var renderTemplateErr error
|
var renderTemplateErr error
|
||||||
for _, templateKey := range templateKeys {
|
for _, templateKey := range templateKeys {
|
||||||
|
|
|
||||||
|
|
@ -336,6 +336,8 @@ func fillAttributeViewBaseValue(baseValue *av.BaseValue, fieldID, itemID string,
|
||||||
|
|
||||||
func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection av.Collection, ials map[string]map[string]string,
|
func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection av.Collection, ials map[string]map[string]string,
|
||||||
depth *int, renderedAttrViews map[string]*av.AttributeView) {
|
depth *int, renderedAttrViews map[string]*av.AttributeView) {
|
||||||
|
|
||||||
|
// 先渲染主键、创建时间、更新时间
|
||||||
for _, item := range collection.GetItems() {
|
for _, item := range collection.GetItems() {
|
||||||
for _, value := range item.GetValues() {
|
for _, value := range item.GetValues() {
|
||||||
itemID := item.GetID()
|
itemID := item.GetID()
|
||||||
|
|
@ -397,6 +399,7 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 再渲染汇总和关联
|
||||||
for _, item := range collection.GetItems() {
|
for _, item := range collection.GetItems() {
|
||||||
for _, value := range item.GetValues() {
|
for _, value := range item.GetValues() {
|
||||||
itemID := item.GetID()
|
itemID := item.GetID()
|
||||||
|
|
@ -446,7 +449,7 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value.Rollup.BuildContents(destAv, destKey, relVal, rollupKey.Rollup.Calc, furtherCollection)
|
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, rollupKey.Rollup.Calc, furtherCollection)
|
||||||
case av.KeyTypeRelation: // 渲染关联
|
case av.KeyTypeRelation: // 渲染关联
|
||||||
value.Relation.Contents = nil
|
value.Relation.Contents = nil
|
||||||
relKey, _ := attrView.GetKey(value.KeyID)
|
relKey, _ := attrView.GetKey(value.KeyID)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue