diff --git a/kernel/api/attr.go b/kernel/api/attr.go index fba22c944..1afe6274d 100644 --- a/kernel/api/attr.go +++ b/kernel/api/attr.go @@ -88,6 +88,48 @@ func setBlockAttrs(c *gin.Context) { } } +func batchSetBlockAttrs(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + blockAttrsArg := arg["blockAttrs"].([]interface{}) + var blockAttrs []map[string]interface{} + for _, blockAttrArg := range blockAttrsArg { + blockAttr := blockAttrArg.(map[string]interface{}) + id := blockAttr["id"].(string) + if util.InvalidIDPattern(id, ret) { + return + } + + attrs := blockAttr["attrs"].(map[string]interface{}) + nameValues := map[string]string{} + for name, value := range attrs { + if nil == value { + nameValues[name] = "" + } else { + nameValues[name] = value.(string) + } + } + + blockAttrs = append(blockAttrs, map[string]interface{}{ + "id": id, + "attrs": nameValues, + }) + } + + err := model.BatchSetBlockAttrs(blockAttrs) + if nil != err { + ret.Code = -1 + ret.Msg = err.Error() + return + } +} + func resetBlockAttrs(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/router.go b/kernel/api/router.go index 271f30306..b999c71c2 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -211,6 +211,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/attr/getBookmarkLabels", model.CheckAuth, getBookmarkLabels) ginServer.Handle("POST", "/api/attr/resetBlockAttrs", model.CheckAuth, model.CheckReadonly, resetBlockAttrs) ginServer.Handle("POST", "/api/attr/setBlockAttrs", model.CheckAuth, model.CheckReadonly, setBlockAttrs) + ginServer.Handle("POST", "/api/attr/batchSetBlockAttrs", model.CheckAuth, model.CheckReadonly, batchSetBlockAttrs) ginServer.Handle("POST", "/api/attr/getBlockAttrs", model.CheckAuth, getBlockAttrs) ginServer.Handle("POST", "/api/cloud/getCloudSpace", model.CheckAuth, getCloudSpace) diff --git a/kernel/model/blockial.go b/kernel/model/blockial.go index 6a8e315fd..49f98b609 100644 --- a/kernel/model/blockial.go +++ b/kernel/model/blockial.go @@ -95,6 +95,49 @@ func SetBlockReminder(id string, timed string) (err error) { return } +func BatchSetBlockAttrs(blockAttrs []map[string]interface{}) (err error) { + if util.ReadOnly { + return + } + + WaitForWritingFiles() + trees := map[string]*parse.Tree{} + for _, blockAttr := range blockAttrs { + id := blockAttr["id"].(string) + if nil == trees[id] { + tree, e := loadTreeByBlockID(id) + if nil != e { + return e + } + trees[id] = tree + } + } + + var nodes []*ast.Node + for _, blockAttr := range blockAttrs { + id := blockAttr["id"].(string) + attrs := blockAttr["attrs"].(map[string]string) + tree := trees[id] + node := treenode.GetNodeInTree(tree, id) + if nil == node { + return errors.New(fmt.Sprintf(Conf.Language(15), id)) + } + + oldAttrs, e := setNodeAttrs0(node, attrs) + if nil != e { + return e + } + + cache.PutBlockIAL(node.ID, parse.IAL2Map(node.KramdownIAL)) + pushBroadcastAttrTransactions(oldAttrs, node) + nodes = append(nodes, node) + } + + IncSync() + // 不做锚文本刷新 + return +} + func SetBlockAttrs(id string, nameValues map[string]string) (err error) { if util.ReadOnly { return