소스 검색

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

Vanessa 1 년 전
부모
커밋
318156f25d
4개의 변경된 파일160개의 추가작업 그리고 14개의 파일을 삭제
  1. 32 1
      kernel/av/av.go
  2. 102 13
      kernel/model/attribute_view.go
  3. 2 0
      kernel/model/transaction.go
  4. 24 0
      kernel/treenode/node.go

+ 32 - 1
kernel/av/av.go

@@ -49,6 +49,16 @@ type KeyValues struct {
 	Values []*Value `json:"values,omitempty"` // 属性视图属性列值
 	Values []*Value `json:"values,omitempty"` // 属性视图属性列值
 }
 }
 
 
+func (kValues *KeyValues) GetValue(blockID string) (ret *Value) {
+	for _, v := range kValues.Values {
+		if v.BlockID == blockID {
+			ret = v
+			return
+		}
+	}
+	return
+}
+
 type KeyType string
 type KeyType string
 
 
 const (
 const (
@@ -105,7 +115,14 @@ func NewKey(id, name, icon string, keyType KeyType) *Key {
 }
 }
 
 
 type Rollup struct {
 type Rollup struct {
-	KeyID string `json:"keyID"` // 汇总列 ID
+	RelationKeyID string      `json:"relationKeyID"` // 关联列 ID
+	KeyID         string      `json:"keyID"`         // 目标列 ID
+	Calc          *RollupCalc `json:"calc"`          // 计算方式
+}
+
+type RollupCalc struct {
+	Operator CalcOperator `json:"operator"`
+	Result   *Value       `json:"result"`
 }
 }
 
 
 type Relation struct {
 type Relation struct {
@@ -299,6 +316,20 @@ func (av *AttributeView) GetCurrentView() (ret *View, err error) {
 	return
 	return
 }
 }
 
 
+func (av *AttributeView) GetValue(keyID, blockID string) (ret *Value) {
+	for _, kv := range av.KeyValues {
+		if kv.Key.ID == keyID {
+			for _, v := range kv.Values {
+				if v.BlockID == blockID {
+					ret = v
+					return
+				}
+			}
+		}
+	}
+	return
+}
+
 func (av *AttributeView) GetKey(keyID string) (ret *Key, err error) {
 func (av *AttributeView) GetKey(keyID string) (ret *Key, err error) {
 	for _, kv := range av.KeyValues {
 	for _, kv := range av.KeyValues {
 		if kv.Key.ID == keyID {
 		if kv.Key.ID == keyID {

+ 102 - 13
kernel/model/attribute_view.go

@@ -180,23 +180,48 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
 		}
 		}
 
 
 		// 渲染自动生成的列值,比如模板列、关联列、汇总列、创建时间列和更新时间列
 		// 渲染自动生成的列值,比如模板列、关联列、汇总列、创建时间列和更新时间列
-		// 先处理创建时间和更新时间
+		// 先处理关联列、汇总列、创建时间和更新时间
 		for _, kv := range keyValues {
 		for _, kv := range keyValues {
 			switch kv.Key.Type {
 			switch kv.Key.Type {
-			case av.KeyTypeRelation:
-				relKey, _ := attrView.GetKey(kv.Values[0].KeyID)
-				if nil != relKey && nil != relKey.Relation {
-					destAv, _ := av.ParseAttributeView(relKey.Relation.AvID)
-					if nil != destAv {
-						blocks := map[string]string{}
-						for _, blockValue := range destAv.GetBlockKeyValues().Values {
-							blocks[blockValue.BlockID] = blockValue.Block.Content
-						}
-						for _, blockID := range kv.Values[0].Relation.BlockIDs {
-							kv.Values[0].Relation.Contents = append(kv.Values[0].Relation.Contents, blocks[blockID])
-						}
+			case av.KeyTypeRollup:
+				if nil == kv.Key.Rollup {
+					break
+				}
+
+				relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
+				if nil == relKey {
+					break
+				}
+
+				var blockIDs []string
+				relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID)
+				if nil != relVal && nil != relVal.Relation {
+					blockIDs = relVal.Relation.BlockIDs
+				}
+
+				destAv, _ := av.ParseAttributeView(relKey.Relation.AvID)
+				if nil != destAv {
+					for _, bID := range blockIDs {
+						kv.Values[0].Rollup.Contents = append(kv.Values[0].Rollup.Contents, destAv.GetValue(kv.Key.Rollup.KeyID, bID).String())
 					}
 					}
 				}
 				}
+			case av.KeyTypeRelation:
+				if nil == kv.Key.Relation {
+					break
+				}
+
+				destAv, _ := av.ParseAttributeView(kv.Key.Relation.AvID)
+				if nil == destAv {
+					break
+				}
+
+				blocks := map[string]string{}
+				for _, blockValue := range destAv.GetBlockKeyValues().Values {
+					blocks[blockValue.BlockID] = blockValue.Block.Content
+				}
+				for _, bID := range kv.Values[0].Relation.BlockIDs {
+					kv.Values[0].Relation.Contents = append(kv.Values[0].Relation.Contents, blocks[bID])
+				}
 			case av.KeyTypeCreated:
 			case av.KeyTypeCreated:
 				createdStr := blockID[:len("20060102150405")]
 				createdStr := blockID[:len("20060102150405")]
 				created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
 				created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
@@ -699,6 +724,30 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
 				}
 				}
 				content := renderTemplateCol(ial, cell.Value.Template.Content, keyValues)
 				content := renderTemplateCol(ial, cell.Value.Template.Content, keyValues)
 				cell.Value.Template.Content = content
 				cell.Value.Template.Content = content
+			case av.KeyTypeRollup: // 渲染汇总列
+				rollupKey, _ := attrView.GetKey(cell.Value.KeyID)
+				if nil == rollupKey || nil == rollupKey.Rollup {
+					break
+				}
+
+				relKey, _ := attrView.GetKey(rollupKey.Rollup.RelationKeyID)
+				if nil == relKey || nil == relKey.Relation {
+					break
+				}
+
+				relVal := attrView.GetValue(relKey.ID, row.ID)
+				if nil == relVal || nil == relVal.Relation {
+					break
+				}
+
+				destAv, _ := av.ParseAttributeView(relKey.Relation.AvID)
+				if nil == destAv {
+					break
+				}
+
+				for _, blockID := range relVal.Relation.BlockIDs {
+					cell.Value.Rollup.Contents = append(cell.Value.Rollup.Contents, destAv.GetValue(rollupKey.Rollup.KeyID, blockID).String())
+				}
 			case av.KeyTypeRelation: // 渲染关联列
 			case av.KeyTypeRelation: // 渲染关联列
 				relKey, _ := attrView.GetKey(cell.Value.KeyID)
 				relKey, _ := attrView.GetKey(cell.Value.KeyID)
 				if nil != relKey && nil != relKey.Relation {
 				if nil != relKey && nil != relKey.Relation {
@@ -774,6 +823,46 @@ func getRowBlockValue(keyValues []*av.KeyValues) (ret *av.Value) {
 	return
 	return
 }
 }
 
 
+func (tx *Transaction) doUpdateAttrViewColRollup(operation *Operation) (ret *TxErr) {
+	err := updateAttributeViewColRollup(operation)
+	if nil != err {
+		return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
+	}
+	return
+}
+
+func updateAttributeViewColRollup(operation *Operation) (err error) {
+	// operation.AvID 汇总列所在 av
+	// operation.ID 汇总列 ID
+	// operation.ParentID 汇总列基于的关联列 ID
+	// operation.KeyID 目标列 ID
+	// operation.Data 计算方式
+
+	attrView, err := av.ParseAttributeView(operation.AvID)
+	if nil != err {
+		return
+	}
+
+	rollUpKey, _ := attrView.GetKey(operation.ID)
+	if nil == rollUpKey {
+		return
+	}
+
+	rollUpKey.Rollup = &av.Rollup{
+		RelationKeyID: operation.ParentID,
+		KeyID:         operation.KeyID,
+	}
+
+	if "" != operation.Data {
+		if err = gulu.JSON.UnmarshalJSON([]byte(operation.Data.(string)), &rollUpKey.Rollup.Calc); nil != err {
+			return
+		}
+	}
+
+	err = av.SaveAttributeView(attrView)
+	return
+}
+
 func (tx *Transaction) doUpdateAttrViewColRelation(operation *Operation) (ret *TxErr) {
 func (tx *Transaction) doUpdateAttrViewColRelation(operation *Operation) (ret *TxErr) {
 	err := updateAttributeViewColRelation(operation)
 	err := updateAttributeViewColRelation(operation)
 	if nil != err {
 	if nil != err {

+ 2 - 0
kernel/model/transaction.go

@@ -274,6 +274,8 @@ func performTx(tx *Transaction) (ret *TxErr) {
 			ret = tx.doSortAttrViewView(op)
 			ret = tx.doSortAttrViewView(op)
 		case "updateAttrViewColRelation":
 		case "updateAttrViewColRelation":
 			ret = tx.doUpdateAttrViewColRelation(op)
 			ret = tx.doUpdateAttrViewColRelation(op)
+		case "updateAttrViewColRollup":
+			ret = tx.doUpdateAttrViewColRollup(op)
 		}
 		}
 
 
 		if nil != ret {
 		if nil != ret {

+ 24 - 0
kernel/treenode/node.go

@@ -723,6 +723,30 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
 				}
 				}
 				content := renderTemplateCol(ial, cell.Value.Template.Content, keyValues)
 				content := renderTemplateCol(ial, cell.Value.Template.Content, keyValues)
 				cell.Value.Template.Content = content
 				cell.Value.Template.Content = content
+			case av.KeyTypeRollup: // 渲染汇总列
+				rollupKey, _ := attrView.GetKey(cell.Value.KeyID)
+				if nil == rollupKey || nil == rollupKey.Rollup {
+					break
+				}
+
+				relKey, _ := attrView.GetKey(rollupKey.Rollup.RelationKeyID)
+				if nil == relKey || nil == relKey.Relation {
+					break
+				}
+
+				relVal := attrView.GetValue(relKey.ID, row.ID)
+				if nil == relVal || nil == relVal.Relation {
+					break
+				}
+
+				destAv, _ := av.ParseAttributeView(relKey.Relation.AvID)
+				if nil == destAv {
+					break
+				}
+
+				for _, blockID := range relVal.Relation.BlockIDs {
+					cell.Value.Rollup.Contents = append(cell.Value.Rollup.Contents, destAv.GetValue(rollupKey.Rollup.KeyID, blockID).String())
+				}
 			case av.KeyTypeRelation: // 渲染关联列
 			case av.KeyTypeRelation: // 渲染关联列
 				relKey, _ := attrView.GetKey(cell.Value.KeyID)
 				relKey, _ := attrView.GetKey(cell.Value.KeyID)
 				if nil != relKey && nil != relKey.Relation {
 				if nil != relKey && nil != relKey.Relation {