Add the MatterLock strategy.

This commit is contained in:
zicla 2019-04-24 20:48:59 +08:00
parent daa5847859
commit d0fb55318f
5 changed files with 99 additions and 63 deletions

View File

@ -282,15 +282,15 @@ func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Re
dirPath := GetDirOfPath(subPath) dirPath := GetDirOfPath(subPath)
//寻找符合条件的matter. //寻找符合条件的matter.
var matter *Matter var dirMatter *Matter
//如果是空或者/就是请求根目录 //如果是空或者/就是请求根目录
if dirPath == "" || dirPath == "/" { if dirPath == "" || dirPath == "/" {
matter = NewRootMatter(user) dirMatter = NewRootMatter(user)
} else { } else {
matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, dirPath) dirMatter = this.matterDao.checkByUserUuidAndPath(user.Uuid, dirPath)
} }
this.matterService.CreateDirectory(matter.Uuid, thisDirName, user) this.matterService.CreateDirectory(dirMatter, thisDirName, user)
} }

View File

@ -89,25 +89,6 @@ func (this *MatterController) Detail(writer http.ResponseWriter, request *http.R
} }
//创建一个文件夹。
func (this *MatterController) CreateDirectory(writer http.ResponseWriter, request *http.Request) *result.WebResult {
puuid := request.FormValue("puuid")
name := request.FormValue("name")
//管理员可以指定给某个用户创建文件夹。
userUuid := request.FormValue("userUuid")
user := this.checkUser(writer, request)
if user.Role != USER_ROLE_ADMINISTRATOR {
userUuid = user.Uuid
}
user = this.userDao.CheckByUuid(userUuid)
matter := this.matterService.CreateDirectory(puuid, name, user);
return this.Success(matter)
}
//按照分页的方式获取某个文件夹下文件和子文件夹的列表,通常情况下只有一页。 //按照分页的方式获取某个文件夹下文件和子文件夹的列表,通常情况下只有一页。
func (this *MatterController) Page(writer http.ResponseWriter, request *http.Request) *result.WebResult { func (this *MatterController) Page(writer http.ResponseWriter, request *http.Request) *result.WebResult {
@ -189,6 +170,36 @@ func (this *MatterController) Page(writer http.ResponseWriter, request *http.Req
return this.Success(pager) return this.Success(pager)
} }
//创建一个文件夹。
func (this *MatterController) CreateDirectory(writer http.ResponseWriter, request *http.Request) *result.WebResult {
puuid := request.FormValue("puuid")
name := request.FormValue("name")
userUuid := request.FormValue("userUuid")
//管理员可以指定给某个用户创建文件夹。
user := this.checkUser(writer, request)
if user.Role != USER_ROLE_ADMINISTRATOR {
userUuid = user.Uuid
}
user = this.userDao.CheckByUuid(userUuid)
//找到父级matter
var dirMatter *Matter
if puuid == MATTER_ROOT {
dirMatter = NewRootMatter(user)
} else {
dirMatter = this.matterDao.CheckByUuid(puuid)
}
matter := this.matterService.CreateDirectory(dirMatter, name, user);
return this.Success(matter)
}
//上传文件 //上传文件
func (this *MatterController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult { func (this *MatterController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
@ -334,7 +345,6 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h
return this.Success("删除成功!") return this.Success("删除成功!")
} }
//重命名一个文件或一个文件夹 //重命名一个文件或一个文件夹
func (this *MatterController) Rename(writer http.ResponseWriter, request *http.Request) *result.WebResult { func (this *MatterController) Rename(writer http.ResponseWriter, request *http.Request) *result.WebResult {
@ -350,7 +360,6 @@ func (this *MatterController) Rename(writer http.ResponseWriter, request *http.R
this.PanicUnauthorized("没有权限") this.PanicUnauthorized("没有权限")
} }
this.matterService.Rename(matter, name, user) this.matterService.Rename(matter, name, user)
return this.Success(matter) return this.Success(matter)

View File

@ -3,8 +3,15 @@ package rest
import "tank/rest/util" import "tank/rest/util"
const ( const (
//根目录的uuid
MATTER_ROOT = "root" MATTER_ROOT = "root"
//cache文件夹名称
MATTER_CACHE = "cache" MATTER_CACHE = "cache"
//matter名称最大长度
MATTER_NAME_MAX_LENGTH = 200
//matter文件夹最大深度
MATTER_NAME_MAX_DEPTH = 32
) )
/** /**

View File

@ -8,6 +8,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"tank/rest/download" "tank/rest/download"
"tank/rest/result"
) )
//@Service //@Service
@ -132,69 +133,80 @@ func (this *MatterService) Detail(uuid string) *Matter {
return matter return matter
} }
//创建文件夹 返回刚刚创建的这个文件夹
func (this *MatterService) CreateDirectory(puuid string, name string, user *User) *Matter { //在dirMatter中创建文件夹 返回刚刚创建的这个文件夹
func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user *User) *Matter {
this.userService.MatterLock(user.Uuid)
defer this.userService.MatterUnlock(user.Uuid)
//父级matter必须存在
if dirMatter == nil {
panic(result.BadRequest("dirMatter必须指定"))
}
//必须是文件夹
if !dirMatter.Dir {
panic(result.BadRequest("dirMatter必须是文件夹"))
}
if dirMatter.UserUuid != user.Uuid {
panic(result.BadRequest("dirMatter的userUuid和user不一致"))
}
name = strings.TrimSpace(name) name = strings.TrimSpace(name)
//验证参数。 //验证参数。
if name == "" { if name == "" {
this.PanicBadRequest("name参数必填并且不能全是空格") panic(result.BadRequest("name参数必填并且不能全是空格"))
} }
if len(name) > 200 {
panic("name长度不能超过200") if len(name) > MATTER_NAME_MAX_LENGTH {
panic(result.BadRequest("name长度不能超过%d", MATTER_NAME_MAX_LENGTH))
} }
if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m {
this.PanicBadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`)
panic(result.BadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`))
} }
if puuid == "" { //判断同级文件夹中是否有同名的文件夹
panic("puuid必填") count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, true, name)
}
//判断同级文件夹中是否有同名的文件。
count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, puuid, true, name)
if count > 0 { if count > 0 {
this.PanicBadRequest("【" + name + "】已经存在了,请使用其他名称。")
panic(result.BadRequest("%s 已经存在了,请使用其他名称。", name))
} }
path := fmt.Sprintf("/%s", name) parts := strings.Split(dirMatter.Path,"/")
if puuid != MATTER_ROOT { this.logger.Info("%s的层数%d",dirMatter.Name,len(parts))
//验证目标文件夹存在。
this.matterDao.CheckByUuidAndUserUuid(puuid, user.Uuid)
//获取上级的详情 if len(parts) >= 32{
pMatter := this.Detail(puuid) panic(result.BadRequest("文件夹最多%d层", MATTER_NAME_MAX_DEPTH))
//根据父目录拼接处子目录
path = fmt.Sprintf("%s/%s", pMatter.Path, name)
//文件夹最多只能有32层。
count := 1
tmpMatter := pMatter
for tmpMatter != nil {
count++
tmpMatter = tmpMatter.Parent
}
if count >= 32 {
panic("文件夹最多32层")
}
} }
//绝对路径
absolutePath := GetUserFileRootDir(user.Username) + dirMatter.Path + "/" + name
//相对路径
relativePath := dirMatter.Path + "/" + name
//磁盘中创建文件夹。 //磁盘中创建文件夹。
dirPath := MakeDirAll(GetUserFileRootDir(user.Username) + path) dirPath := MakeDirAll(absolutePath)
this.logger.Info("Create Directory: %s", dirPath) this.logger.Info("Create Directory: %s", dirPath)
//数据库中创建文件夹。 //数据库中创建文件夹。
matter := &Matter{ matter := &Matter{
Puuid: puuid, Puuid: dirMatter.Uuid,
UserUuid: user.Uuid, UserUuid: user.Uuid,
Username: user.Username, Username: user.Username,
Dir: true, Dir: true,
Name: name, Name: name,
Path: path, Path: relativePath,
} }
matter = this.matterDao.Create(matter) matter = this.matterDao.Create(matter)
return matter return matter

View File

@ -1,6 +1,9 @@
package result package result
import "net/http" import (
"fmt"
"net/http"
)
type WebResult struct { type WebResult struct {
Code string `json:"code"` Code string `json:"code"`
@ -89,10 +92,15 @@ func CustomWebResult(codeWrapper *CodeWrapper, description string) *WebResult {
return wr return wr
} }
//请求参数有问题
func BadRequest(format string, v ...interface{}) *WebResult {
return CustomWebResult(CODE_WRAPPER_BAD_REQUEST, fmt.Sprintf(format, v...))
}
//所有的数据库错误情况 //所有的数据库错误情况
var ( var (
DB_ERROR_DUPLICATE_KEY = "Error 1062: Duplicate entry" DB_ERROR_DUPLICATE_KEY = "Error 1062: Duplicate entry"
DB_ERROR_NOT_FOUND = "record not found" DB_ERROR_NOT_FOUND = "record not found"
DB_TOO_MANY_CONNECTIONS = "Error 1040: Too many connections" DB_TOO_MANY_CONNECTIONS = "Error 1040: Too many connections"
DB_BAD_CONNECTION = "driver: bad connection" DB_BAD_CONNECTION = "driver: bad connection"
) )