🎨 Update av export

This commit is contained in:
Daniel 2023-09-26 09:38:50 +08:00
parent 3cd6e0d953
commit 376384d4e3
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
5 changed files with 58 additions and 32 deletions

View file

@ -35,8 +35,7 @@ func renderAttributeView(c *gin.Context) {
} }
id := arg["id"].(string) id := arg["id"].(string)
nodeID := arg["nodeID"].(string) view, attrView, err := model.RenderAttributeView(id)
view, attrView, err := model.RenderAttributeView(id, nodeID)
if nil != err { if nil != err {
ret.Code = -1 ret.Code = -1
ret.Msg = err.Error() ret.Msg = err.Error()

View file

@ -40,7 +40,6 @@ import (
type AttributeView struct { type AttributeView struct {
Spec int `json:"spec"` // 格式版本 Spec int `json:"spec"` // 格式版本
ID string `json:"id"` // 属性视图 ID ID string `json:"id"` // 属性视图 ID
NodeID string `json:"nodeID"` // 属性视图所在节点 ID
Name string `json:"name"` // 属性视图名称 Name string `json:"name"` // 属性视图名称
KeyValues []*KeyValues `json:"keyValues"` // 属性视图属性列值 KeyValues []*KeyValues `json:"keyValues"` // 属性视图属性列值
ViewID string `json:"viewID"` // 当前视图 ID ViewID string `json:"viewID"` // 当前视图 ID
@ -386,7 +385,7 @@ type Viewable interface {
GetID() string GetID() string
} }
func NewAttributeView(id, nodeID string) (ret *AttributeView) { func NewAttributeView(id string) (ret *AttributeView) {
view := NewView() view := NewView()
key := NewKey(ast.NewNodeID(), "Block", KeyTypeBlock) key := NewKey(ast.NewNodeID(), "Block", KeyTypeBlock)
ret = &AttributeView{ ret = &AttributeView{
@ -395,7 +394,6 @@ func NewAttributeView(id, nodeID string) (ret *AttributeView) {
KeyValues: []*KeyValues{{Key: key}}, KeyValues: []*KeyValues{{Key: key}},
ViewID: view.ID, ViewID: view.ID,
Views: []*View{view}, Views: []*View{view},
NodeID: nodeID,
} }
view.Table.Columns = []*ViewTableColumn{{ID: key.ID}} view.Table.Columns = []*ViewTableColumn{{ID: key.ID}}
return return

View file

@ -86,11 +86,11 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
return return
} }
func RenderAttributeView(avID, nodeID string) (viewable av.Viewable, attrView *av.AttributeView, err error) { func RenderAttributeView(avID string) (viewable av.Viewable, attrView *av.AttributeView, err error) {
waitForSyncingStorages() waitForSyncingStorages()
if avJSONPath := av.GetAttributeViewDataPath(avID); !gulu.File.IsExist(avJSONPath) { if avJSONPath := av.GetAttributeViewDataPath(avID); !gulu.File.IsExist(avJSONPath) {
attrView = av.NewAttributeView(avID, nodeID) attrView = av.NewAttributeView(avID)
if err = av.SaveAttributeView(attrView); nil != err { if err = av.SaveAttributeView(attrView); nil != err {
logging.LogErrorf("save attribute view [%s] failed: %s", avID, err) logging.LogErrorf("save attribute view [%s] failed: %s", avID, err)
return return
@ -103,14 +103,6 @@ func RenderAttributeView(avID, nodeID string) (viewable av.Viewable, attrView *a
return return
} }
if "" == attrView.NodeID {
attrView.NodeID = nodeID
if err = av.SaveAttributeView(attrView); nil != err {
logging.LogErrorf("save attribute view [%s] failed: %s", avID, err)
return
}
}
if 1 > len(attrView.Views) { if 1 > len(attrView.Views) {
err = av.ErrViewNotFound err = av.ErrViewNotFound
return return

View file

@ -1380,7 +1380,6 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
} }
return ast.WalkContinue return ast.WalkContinue
}) })
} }
// 导出自定义排序 // 导出自定义排序

View file

@ -141,10 +141,10 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
return return
} }
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering { if !entering || "" == n.ID {
return ast.WalkContinue return ast.WalkContinue
} }
if "" != n.ID {
newNodeID := ast.NewNodeID() newNodeID := ast.NewNodeID()
blockIDs[n.ID] = newNodeID blockIDs[n.ID] = newNodeID
oldNodeID := n.ID oldNodeID := n.ID
@ -160,7 +160,6 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
avBlockIDs[oldNodeID] = newNodeID avBlockIDs[oldNodeID] = newNodeID
} }
} }
}
return ast.WalkContinue return ast.WalkContinue
}) })
tree.ID = tree.Root.ID tree.ID = tree.Root.ID
@ -201,13 +200,23 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
// 将关联的数据库文件移动到 data/storage/av/ 下 // 将关联的数据库文件移动到 data/storage/av/ 下
storage := filepath.Join(unzipRootPath, "storage") storage := filepath.Join(unzipRootPath, "storage")
storageAvDir := filepath.Join(storage, "av") storageAvDir := filepath.Join(storage, "av")
avIDs := map[string]string{}
renameAvPaths := map[string]string{}
if gulu.File.IsExist(storageAvDir) { if gulu.File.IsExist(storageAvDir) {
// 将数据库文件中的块 ID 替换为新的块 ID // 重新生成数据库数据
filepath.Walk(storageAvDir, func(path string, info fs.FileInfo, err error) error { filepath.Walk(storageAvDir, func(path string, info fs.FileInfo, err error) error {
if !strings.HasSuffix(path, ".json") || !ast.IsNodeIDPattern(strings.TrimSuffix(info.Name(), ".json")) { if !strings.HasSuffix(path, ".json") || !ast.IsNodeIDPattern(strings.TrimSuffix(info.Name(), ".json")) {
return nil return nil
} }
// 重命名数据库
newAvID := ast.NewNodeID()
oldAvID := strings.TrimSuffix(info.Name(), ".json")
newPath := filepath.Join(filepath.Dir(path), newAvID+".json")
renameAvPaths[path] = newPath
avIDs[oldAvID] = newAvID
// 将数据库文件中的块 ID 替换为新的块 ID
data, readErr := os.ReadFile(path) data, readErr := os.ReadFile(path)
if nil != readErr { if nil != readErr {
logging.LogErrorf("read av file [%s] failed: %s", path, readErr) logging.LogErrorf("read av file [%s] failed: %s", path, readErr)
@ -218,6 +227,7 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
for oldID, newID := range avBlockIDs { for oldID, newID := range avBlockIDs {
newData = bytes.ReplaceAll(newData, []byte(oldID), []byte(newID)) newData = bytes.ReplaceAll(newData, []byte(oldID), []byte(newID))
} }
newData = bytes.ReplaceAll(newData, []byte(oldAvID), []byte(newAvID))
if !bytes.Equal(data, newData) { if !bytes.Equal(data, newData) {
if writeErr := os.WriteFile(path, newData, 0644); nil != writeErr { if writeErr := os.WriteFile(path, newData, 0644); nil != writeErr {
logging.LogErrorf("write av file [%s] failed: %s", path, writeErr) logging.LogErrorf("write av file [%s] failed: %s", path, writeErr)
@ -227,10 +237,38 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
return nil return nil
}) })
// 重命名数据库文件
for oldPath, newPath := range renameAvPaths {
if err = os.Rename(oldPath, newPath); nil != err {
logging.LogErrorf("rename av file from [%s] to [%s] failed: %s", oldPath, newPath, err)
return
}
}
targetStorageAvDir := filepath.Join(util.DataDir, "storage", "av") targetStorageAvDir := filepath.Join(util.DataDir, "storage", "av")
if copyErr := filelock.Copy(storageAvDir, targetStorageAvDir); nil != copyErr { if copyErr := filelock.Copy(storageAvDir, targetStorageAvDir); nil != copyErr {
logging.LogErrorf("copy storage av dir from [%s] to [%s] failed: %s", storageAvDir, targetStorageAvDir, copyErr) logging.LogErrorf("copy storage av dir from [%s] to [%s] failed: %s", storageAvDir, targetStorageAvDir, copyErr)
} }
// 重新指向数据库属性值
for _, tree := range trees {
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || "" == n.ID {
return ast.WalkContinue
}
ial := parse.IAL2Map(n.KramdownIAL)
for k, v := range ial {
if strings.HasPrefix(k, NodeAttrNamePrefixAvKey) || strings.HasPrefix(k, NodeAttrNameAvs) {
for oldAvID, newAvID := range avIDs {
v = strings.ReplaceAll(v, oldAvID, newAvID)
n.SetIALAttr(k, v)
}
}
}
return ast.WalkContinue
})
}
} }
// storage 文件夹已在上方处理,所以这里删除源 storage 文件夹,避免后面被拷贝到导入目录下 targetDir // storage 文件夹已在上方处理,所以这里删除源 storage 文件夹,避免后面被拷贝到导入目录下 targetDir