diff --git a/models/file.go b/models/file.go index 2645662..f40bf13 100644 --- a/models/file.go +++ b/models/file.go @@ -11,10 +11,10 @@ type File struct { gorm.Model Name string SourceName string - UserID uint + UserID uint `gorm:"index:user_id"` Size uint64 PicInfo string - FolderID uint + FolderID uint `gorm:"index:folder_id"` PolicyID uint Dir string `gorm:"size:65536"` } diff --git a/models/folder.go b/models/folder.go index 4b5e0fa..7f40352 100644 --- a/models/folder.go +++ b/models/folder.go @@ -1,19 +1,28 @@ package model -import "github.com/jinzhu/gorm" +import ( + "github.com/HFO4/cloudreve/pkg/util" + "github.com/jinzhu/gorm" +) // Folder 目录 type Folder struct { // 表字段 gorm.Model Name string - ParentID uint + ParentID uint `gorm:"index:parent_id"` Position string `gorm:"size:65536"` - OwnerID uint + OwnerID uint `gorm:"index:owner_id"` PositionAbsolute string `gorm:"size:65536"` +} - // 关联模型 - OptionsSerialized PolicyOption `gorm:"-"` +// Create 创建目录 +func (folder *Folder) Create() (uint, error) { + if err := DB.Create(folder).Error; err != nil { + util.Log().Warning("无法插入目录记录, %s", err) + return 0, err + } + return folder.ID, nil } // GetFolderByPath 根据绝对路径和UID查找目录 diff --git a/pkg/filesystem/path.go b/pkg/filesystem/path.go index a2f5e88..1a80dfe 100644 --- a/pkg/filesystem/path.go +++ b/pkg/filesystem/path.go @@ -1,6 +1,7 @@ package filesystem import ( + "context" model "github.com/HFO4/cloudreve/models" "path" ) @@ -10,6 +11,42 @@ import ( ================= */ +// CreateDirectory 在`base`路径下创建名为`dir`的目录 +func (fs *FileSystem) CreateDirectory(ctx context.Context, fullPath string) error { + // 获取要创建目录的父路径和目录名 + fullPath = path.Clean(fullPath) + base := path.Dir(fullPath) + dir := path.Base(fullPath) + + // 检查目录名是否合法 + if !fs.ValidateLegalName(ctx, dir) { + return ErrIllegalObjectName + } + + // 父目录是否存在 + isExist, parent := fs.IsPathExist(base) + if !isExist { + return ErrPathNotExist + } + + // 是否有同名文件 + if fs.IsFileExist(path.Join(base, dir)) { + return ErrFileExisted + } + + // 创建目录 + newFolder := model.Folder{ + Name: dir, + ParentID: parent.ID, + Position: base, + OwnerID: fs.User.ID, + PositionAbsolute: fullPath, + } + _, err := newFolder.Create() + + return err +} + // IsPathExist 返回给定目录是否存在 // 如果存在就返回目录 func (fs *FileSystem) IsPathExist(path string) (bool, *model.Folder) { diff --git a/pkg/serializer/common.go b/pkg/serializer/common.go index e3d156f..b415260 100644 --- a/pkg/serializer/common.go +++ b/pkg/serializer/common.go @@ -21,6 +21,8 @@ const ( CodeNoRightErr = 403 // CodeUploadFailed 上传出错 CodeUploadFailed = 4001 + // CodeCreateFolderFailed 目录创建失败 + CodeCreateFolderFailed = 4002 // CodeDBError 数据库操作失败 CodeDBError = 50001 // CodeEncryptError 加密失败 diff --git a/routers/controllers/directory.go b/routers/controllers/directory.go index 2d32936..523c5a6 100644 --- a/routers/controllers/directory.go +++ b/routers/controllers/directory.go @@ -1 +1,17 @@ package controllers + +import ( + "github.com/HFO4/cloudreve/service/explorer" + "github.com/gin-gonic/gin" +) + +// CreateDirectory 创建目录 +func CreateDirectory(c *gin.Context) { + var service explorer.DirectoryCreateService + if err := c.ShouldBindJSON(&service); err == nil { + res := service.CreateDirectory(c) + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} diff --git a/routers/router.go b/routers/router.go index c4e3321..207908b 100644 --- a/routers/router.go +++ b/routers/router.go @@ -67,8 +67,8 @@ func InitRouter() *gin.Engine { // 目录 directory := auth.Group("directory") { - // 文件上传 - directory.PUT("", controllers.Ping) + // 创建目录 + directory.PUT("", controllers.CreateDirectory) } } diff --git a/service/explorer/directory.go b/service/explorer/directory.go new file mode 100644 index 0000000..4363c26 --- /dev/null +++ b/service/explorer/directory.go @@ -0,0 +1,39 @@ +package explorer + +import ( + "context" + model "github.com/HFO4/cloudreve/models" + "github.com/HFO4/cloudreve/pkg/filesystem" + "github.com/HFO4/cloudreve/pkg/serializer" + "github.com/gin-gonic/gin" +) + +// DirectoryCreateService 创建新目录服务 +type DirectoryCreateService struct { + Path string `form:"newPath" json:"newPath" binding:"required,min=1,max=65535"` +} + +// CreateDirectory 创建目录 +func (service *DirectoryCreateService) CreateDirectory(c *gin.Context) serializer.Response { + // 创建文件系统 + user, _ := c.Get("user") + fs, err := filesystem.NewFileSystem(user.(*model.User)) + if err != nil { + return serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err) + } + + // 上下文 + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // 创建目录 + err = fs.CreateDirectory(ctx, service.Path) + if err != nil { + return serializer.Err(serializer.CodeCreateFolderFailed, err.Error(), err) + } + + return serializer.Response{ + Code: 0, + } + +}