Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2025-08-26 10:47:21 +08:00
commit 1017610ec8
6 changed files with 36 additions and 57 deletions

View file

@ -331,6 +331,10 @@ func addAttributeViewBlocks(c *gin.Context) {
if blockIDArg := arg["blockID"]; nil != blockIDArg {
blockID = blockIDArg.(string)
}
var viewID string
if viewIDArg := arg["viewID"]; nil != viewIDArg {
viewID = viewIDArg.(string)
}
var groupID string
if groupIDArg := arg["groupID"]; nil != groupIDArg {
groupID = groupIDArg.(string)
@ -351,7 +355,7 @@ func addAttributeViewBlocks(c *gin.Context) {
ignoreDefaultFill = arg["ignoreDefaultFill"].(bool)
}
err := model.AddAttributeViewBlock(nil, srcs, avID, blockID, groupID, previousID, ignoreDefaultFill, map[string]interface{}{})
err := model.AddAttributeViewBlock(nil, srcs, avID, blockID, viewID, groupID, previousID, ignoreDefaultFill, map[string]interface{}{})
if err != nil {
ret.Code = -1
ret.Msg = err.Error()

View file

@ -138,18 +138,17 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return true
}
switch filter.Operator {
case FilterOperatorIsEmpty:
return value.IsEmpty()
case FilterOperatorIsNotEmpty:
return !value.IsEmpty()
}
if nil != value.Rollup && KeyTypeRollup == value.Type && nil != filter.Value && KeyTypeRollup == filter.Value.Type &&
nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) {
// 单独处理汇总类型的比较
// 处理为空和不为空
switch filter.Operator {
case FilterOperatorIsEmpty:
return 0 == len(value.Rollup.Contents)
case FilterOperatorIsNotEmpty:
return 0 != len(value.Rollup.Contents)
}
// 处理值比较
key, _ := attrView.GetKey(value.KeyID)
if nil == key {
@ -215,14 +214,6 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
nil != filter.Value.Relation && 0 < len(filter.Value.Relation.BlockIDs) {
// 单独处理关联类型的比较
// 处理为空和不为空
switch filter.Operator {
case FilterOperatorIsEmpty:
return 0 == len(value.Relation.Contents)
case FilterOperatorIsNotEmpty:
return 0 != len(value.Relation.Contents)
}
for _, relationValue := range value.Relation.Contents {
filterValue := &Value{Type: KeyTypeBlock, Block: &ValueBlock{Content: filter.Value.Relation.BlockIDs[0]}}
@ -256,6 +247,13 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
}
func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDate, operator FilterOperator) bool {
switch operator {
case FilterOperatorIsEmpty:
return value.IsEmpty()
case FilterOperatorIsNotEmpty:
return !value.IsEmpty()
}
switch value.Type {
case KeyTypeBlock:
if nil != value.Block && nil != other && nil != other.Block {
@ -284,10 +282,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa
return value.Number.Content < other.Number.Content
case FilterOperatorIsLessOrEqual:
return value.Number.Content <= other.Number.Content
case FilterOperatorIsEmpty:
return !value.Number.IsNotEmpty
case FilterOperatorIsNotEmpty:
return value.Number.IsNotEmpty
}
}
case KeyTypeDate:
@ -298,13 +292,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa
}
if nil != value.Date {
switch operator {
case FilterOperatorIsEmpty:
return !value.Date.IsNotEmpty
case FilterOperatorIsNotEmpty:
return value.Date.IsNotEmpty
}
if !value.Date.IsNotEmpty {
// 空值不进行比较,直接排除
// Database date filter excludes empty values https://github.com/siyuan-note/siyuan/issues/11061
@ -352,12 +339,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa
case KeyTypeSelect, KeyTypeMSelect:
if nil != value.MSelect {
if 1 > len(other.MSelect) {
switch operator {
case FilterOperatorIsEmpty:
return value.IsEmpty()
case FilterOperatorIsNotEmpty:
return !value.IsEmpty()
}
return true
}
@ -423,10 +404,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa
}
}
return !contains
case FilterOperatorIsEmpty:
return 0 == len(value.MAsset) || 1 == len(value.MAsset) && "" == value.MAsset[0].Content
case FilterOperatorIsNotEmpty:
return 0 != len(value.MAsset) && !(1 == len(value.MAsset) && "" == value.MAsset[0].Content)
}
}
case KeyTypeTemplate:
@ -482,10 +459,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa
return true
}
return strings.HasSuffix(value.Template.Content, other.Template.Content)
case FilterOperatorIsEmpty:
return "" == strings.TrimSpace(value.Template.Content)
case FilterOperatorIsNotEmpty:
return "" != strings.TrimSpace(value.Template.Content)
}
}
case KeyTypeCheckbox:
@ -498,13 +471,6 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa
}
}
}
switch operator {
case FilterOperatorIsEmpty:
return value.IsEmpty()
case FilterOperatorIsNotEmpty:
return !value.IsEmpty()
}
return false
}

View file

@ -355,7 +355,7 @@ func (value *Value) IsEmpty() bool {
if nil == value.Template {
return true
}
return "" == value.Template.Content
return "" == strings.TrimSpace(value.Template.Content)
case KeyTypeCreated:
if nil == value.Created {
return true

View file

@ -2964,14 +2964,14 @@ func (tx *Transaction) doInsertAttrViewBlock(operation *Operation) (ret *TxErr)
operation.Context = map[string]interface{}{}
}
err := AddAttributeViewBlock(tx, operation.Srcs, operation.AvID, operation.BlockID, operation.GroupID, operation.PreviousID, operation.IgnoreDefaultFill, operation.Context)
err := AddAttributeViewBlock(tx, operation.Srcs, operation.AvID, operation.BlockID, operation.ViewID, operation.GroupID, operation.PreviousID, operation.IgnoreDefaultFill, operation.Context)
if err != nil {
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func AddAttributeViewBlock(tx *Transaction, srcs []map[string]interface{}, avID, dbBlockID, groupID, previousItemID string, ignoreDefaultFill bool, context map[string]interface{}) (err error) {
func AddAttributeViewBlock(tx *Transaction, srcs []map[string]interface{}, avID, dbBlockID, viewID, groupID, previousItemID string, ignoreDefaultFill bool, context map[string]interface{}) (err error) {
slices.Reverse(srcs) // https://github.com/siyuan-note/siyuan/issues/11286
now := time.Now().UnixMilli()
@ -3006,14 +3006,14 @@ func AddAttributeViewBlock(tx *Transaction, srcs []map[string]interface{}, avID,
if nil != src["content"] {
srcContent = src["content"].(string)
}
if avErr := addAttributeViewBlock(now, avID, dbBlockID, groupID, previousItemID, srcItemID, boundBlockID, srcContent, isDetached, ignoreDefaultFill, tree, tx, context); nil != avErr {
if avErr := addAttributeViewBlock(now, avID, dbBlockID, viewID, groupID, previousItemID, srcItemID, boundBlockID, srcContent, isDetached, ignoreDefaultFill, tree, tx, context); nil != avErr {
return avErr
}
}
return
}
func addAttributeViewBlock(now int64, avID, dbBlockID, groupID, previousItemID, addingItemID, addingBoundBlockID, addingBlockContent string, isDetached, ignoreDefaultFill bool, tree *parse.Tree, tx *Transaction, context map[string]interface{}) (err error) {
func addAttributeViewBlock(now int64, avID, dbBlockID, viewID, groupID, previousItemID, addingItemID, addingBoundBlockID, addingBlockContent string, isDetached, ignoreDefaultFill bool, tree *parse.Tree, tx *Transaction, context map[string]interface{}) (err error) {
var node *ast.Node
if !isDetached {
node = treenode.GetNodeInTree(tree, addingBoundBlockID)
@ -3085,6 +3085,14 @@ func addAttributeViewBlock(now int64, avID, dbBlockID, groupID, previousItemID,
return
}
if "" != viewID {
view = attrView.GetView(viewID)
if nil == view {
logging.LogErrorf("get view by view ID [%s] failed", viewID)
return av.ErrViewNotFound
}
}
groupView := view
if "" != groupID {
groupView = view.GetGroupByID(groupID)

View file

@ -991,7 +991,7 @@ func DuplicateDoc(tree *parse.Tree) {
AddAttributeViewBlock(nil, []map[string]interface{}{{
"id": n.ID,
"isDetached": false,
}}, avID, "", "", "", false, map[string]interface{}{})
}}, avID, "", "", "", "", false, map[string]interface{}{})
ReloadAttrView(avID)
}
return ast.WalkContinue

View file

@ -1099,7 +1099,7 @@ func (tx *Transaction) doLargeInsert(previousID string) (ret *TxErr) {
AddAttributeViewBlock(tx, []map[string]interface{}{{
"id": insertedNode.ID,
"isDetached": false,
}}, avID, "", "", previousID, false, map[string]interface{}{})
}}, avID, "", "", "", previousID, false, map[string]interface{}{})
ReloadAttrView(avID)
}
@ -1284,7 +1284,7 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
AddAttributeViewBlock(tx, []map[string]interface{}{{
"id": insertedNode.ID,
"isDetached": false,
}}, avID, "", "", previousID, false, map[string]interface{}{})
}}, avID, "", "", "", previousID, false, map[string]interface{}{})
ReloadAttrView(avID)
}
@ -1727,6 +1727,7 @@ type Operation struct {
Layout av.LayoutType `json:"layout"` // 属性视图布局类型
GroupID string `json:"groupID"` // 属性视图分组视图 ID
TargetGroupID string `json:"targetGroupID"` // 属性视图目标分组视图 ID
ViewID string `json:"viewID"` // 属性视图视图 ID
IgnoreDefaultFill bool `json:"ignoreDefaultFill"` // 是否忽略默认填充
Context map[string]interface{} `json:"context"` // 上下文信息