From 10a2ef4267ef07f8fcf683e527dd7575aa33d128 Mon Sep 17 00:00:00 2001
From: HFO4 <912394456@qq.com>
Date: Sat, 7 Dec 2019 15:54:07 +0800
Subject: [PATCH] Feat: rename file

---
 models/file.go                 |  5 +++++
 models/folder.go               |  8 ++++++++
 pkg/filesystem/file.go         |  2 +-
 pkg/filesystem/path.go         | 28 ++++++++++++++++++++++++++--
 routers/controllers/objects.go | 15 +++++++++++++++
 routers/router.go              |  2 ++
 service/explorer/objects.go    | 27 ++++++++++++++++++++++++++-
 7 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/models/file.go b/models/file.go
index 4a057c9..d6d7dfe 100644
--- a/models/file.go
+++ b/models/file.go
@@ -141,3 +141,8 @@ func GetFilesByParentIDs(ids []uint, uid uint) ([]File, error) {
 	result := DB.Where("user_id = ? and folder_id in (?)", uid, ids).Find(&files)
 	return files, result.Error
 }
+
+// Rename 重命名文件
+func (file *File) Rename(new string) error {
+	return DB.Model(&file).Update("name", new).Error
+}
diff --git a/models/folder.go b/models/folder.go
index bef777d..ced959a 100644
--- a/models/folder.go
+++ b/models/folder.go
@@ -367,3 +367,11 @@ func (folder *Folder) MoveOrCopyFolderTo(dirs []string, dstFolder *Folder, isCop
 	return newUsedStorage, nil
 
 }
+
+// Rename 重命名目录
+func (folder *Folder) Rename(new string) error {
+	if err := DB.Model(&folder).Update("name", new).Error; err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/pkg/filesystem/file.go b/pkg/filesystem/file.go
index 5b63a41..962be47 100644
--- a/pkg/filesystem/file.go
+++ b/pkg/filesystem/file.go
@@ -85,7 +85,7 @@ func (fs *FileSystem) GetContent(ctx context.Context, path string) (io.ReadSeeke
 	if !exist {
 		return nil, ErrObjectNotExist
 	}
-	fs.FileTarget = []model.File{file}
+	fs.FileTarget = []model.File{*file}
 
 	// 将当前存储策略重设为文件使用的
 	fs.Policy = file.GetPolicy()
diff --git a/pkg/filesystem/path.go b/pkg/filesystem/path.go
index d972807..583393d 100644
--- a/pkg/filesystem/path.go
+++ b/pkg/filesystem/path.go
@@ -26,6 +26,30 @@ type Object struct {
 	Date string `json:"date"`
 }
 
+// Rename 重命名对象
+func (fs *FileSystem) Rename(ctx context.Context, src, new string) (err error) {
+	// 验证新名字
+	if !fs.ValidateLegalName(ctx, new) || !fs.ValidateExtension(ctx, new) {
+		return ErrIllegalObjectName
+	}
+
+	// 如果源对象是文件
+	fileExist, file := fs.IsFileExist(src)
+	if fileExist {
+		err = file.Rename(new)
+		return err
+	}
+
+	// 源对象是目录
+	folderExist, folder := fs.IsPathExist(src)
+	if folderExist {
+		err = folder.Rename(new)
+		return err
+	}
+
+	return ErrPathNotExist
+}
+
 // Copy 复制src目录下的文件或目录到dst
 func (fs *FileSystem) Copy(ctx context.Context, dirs, files []string, src, dst string) error {
 	// 获取目的目录
@@ -323,11 +347,11 @@ func (fs *FileSystem) IsPathExist(path string) (bool, *model.Folder) {
 }
 
 // IsFileExist 返回给定路径的文件是否存在
-func (fs *FileSystem) IsFileExist(fullPath string) (bool, model.File) {
+func (fs *FileSystem) IsFileExist(fullPath string) (bool, *model.File) {
 	basePath := path.Dir(fullPath)
 	fileName := path.Base(fullPath)
 
 	file, err := model.GetFileByPathAndName(basePath, fileName, fs.User.ID)
 
-	return err == nil, file
+	return err == nil, &file
 }
diff --git a/routers/controllers/objects.go b/routers/controllers/objects.go
index 3b179cf..044a942 100644
--- a/routers/controllers/objects.go
+++ b/routers/controllers/objects.go
@@ -50,3 +50,18 @@ func Copy(c *gin.Context) {
 		c.JSON(200, ErrorResponse(err))
 	}
 }
+
+// Rename 重命名文件或目录
+func Rename(c *gin.Context) {
+	// 创建上下文
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	var service explorer.ItemRenameService
+	if err := c.ShouldBindJSON(&service); err == nil {
+		res := service.Rename(ctx, c)
+		c.JSON(200, res)
+	} else {
+		c.JSON(200, ErrorResponse(err))
+	}
+}
diff --git a/routers/router.go b/routers/router.go
index f49ec7d..b64e24e 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -87,6 +87,8 @@ func InitRouter() *gin.Engine {
 				object.PATCH("", controllers.Move)
 				// 复制对象
 				object.POST("copy", controllers.Copy)
+				// 重命名对象
+				object.POST("rename", controllers.Rename)
 			}
 
 		}
diff --git a/service/explorer/objects.go b/service/explorer/objects.go
index 549538a..e4bea8e 100644
--- a/service/explorer/objects.go
+++ b/service/explorer/objects.go
@@ -14,6 +14,12 @@ type ItemMoveService struct {
 	Dst    string      `json:"dst" binding:"required,min=1,max=65535"`
 }
 
+// ItemRenameService 处理多文件/目录重命名
+type ItemRenameService struct {
+	Src     string `json:"src" binding:"required,min=1,max=65535,ne=/"`
+	NewName string `json:"new_name" binding:"required,min=1,max=255"`
+}
+
 // ItemService 处理多文件/目录相关服务
 type ItemService struct {
 	Items []string `json:"items" binding:"exists,dive,ne=/"`
@@ -73,7 +79,7 @@ func (service *ItemMoveService) Copy(ctx context.Context, c *gin.Context) serial
 		return serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err)
 	}
 
-	// 移动对象
+	// 复制对象
 	err = fs.Copy(ctx, service.Src.Dirs, service.Src.Items, service.SrcDir, service.Dst)
 	if err != nil {
 		return serializer.Err(serializer.CodeNotSet, err.Error(), err)
@@ -84,3 +90,22 @@ func (service *ItemMoveService) Copy(ctx context.Context, c *gin.Context) serial
 	}
 
 }
+
+// Rename 重命名对象
+func (service *ItemRenameService) Rename(ctx context.Context, c *gin.Context) serializer.Response {
+	// 创建文件系统
+	fs, err := filesystem.NewFileSystemFromContext(c)
+	if err != nil {
+		return serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err)
+	}
+
+	// 重命名对象
+	err = fs.Rename(ctx, service.Src, service.NewName)
+	if err != nil {
+		return serializer.Err(serializer.CodeNotSet, err.Error(), err)
+	}
+
+	return serializer.Response{
+		Code: 0,
+	}
+}