Browse Source

Finish some code refine work.

master
zicla 7 years ago
parent
commit
f2bed9ac33
  1. 4
      rest/alien_controller.go
  2. 3
      rest/dav_service.go
  3. 8
      rest/matter_controller.go
  4. 30
      rest/matter_dao.go
  5. 3
      rest/matter_model.go
  6. 322
      rest/matter_service.go

4
rest/alien_controller.go

@ -279,7 +279,9 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re
panic("文件大小不正确")
}
matter := this.matterService.Upload(file, user, uploadToken.FolderUuid, uploadToken.Filename, uploadToken.Privacy, true)
dirMatter := this.matterDao.CheckDirByUuid(uploadToken.FolderUuid, user)
matter := this.matterService.Upload(file, user, dirMatter, uploadToken.Filename, uploadToken.Privacy)
//更新这个uploadToken的信息.
uploadToken.ExpireTime = time.Now()

3
rest/dav_service.go

@ -252,7 +252,8 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ
this.matterService.Delete(srcMatter)
}
this.matterService.Upload(request.Body, user, matter.Uuid, filename, true, false)
this.matterService.Upload(request.Body, user, matter, filename, true)
}

8
rest/matter_controller.go

@ -170,7 +170,6 @@ func (this *MatterController) Page(writer http.ResponseWriter, request *http.Req
return this.Success(pager)
}
//创建一个文件夹。
func (this *MatterController) CreateDirectory(writer http.ResponseWriter, request *http.Request) *result.WebResult {
@ -178,7 +177,6 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques
name := request.FormValue("name")
userUuid := request.FormValue("userUuid")
//管理员可以指定给某个用户创建文件夹。
user := this.checkUser(writer, request)
if user.Role != USER_ROLE_ADMINISTRATOR {
@ -198,8 +196,6 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques
return this.Success(matter)
}
//上传文件
func (this *MatterController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
@ -236,7 +232,9 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R
fileName = fileName[pos+1:]
}
matter := this.matterService.Upload(file, user, puuid, fileName, privacy, false)
dirMatter := this.matterDao.CheckDirByUuid(puuid, user)
matter := this.matterService.Upload(file, user, dirMatter, fileName, privacy)
return this.Success(matter)
}

30
rest/matter_dao.go

@ -31,21 +31,39 @@ func (this *MatterDao) FindByUuid(uuid string) *Matter {
var matter Matter
db := CONTEXT.DB.Where(&Matter{Base: Base{Uuid: uuid}}).First(&matter)
if db.Error != nil {
return nil
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
return nil
} else {
this.PanicError(db.Error)
}
}
return &matter
}
//按照Id查询文件
func (this *MatterDao) CheckByUuid(uuid string) *Matter {
matter := this.FindByUuid(uuid)
if matter == nil {
this.PanicNotFound("%s 对应的matter不存在", uuid)
}
return matter
}
// Read
var matter Matter
db := CONTEXT.DB.Where(&Matter{Base: Base{Uuid: uuid}}).First(&matter)
this.PanicError(db.Error)
return &matter
//按照uuid查找一个文件夹,可能返回root对应的matter.
func (this *MatterDao) CheckDirByUuid(uuid string, user *User) *Matter {
var matter *Matter
if uuid == MATTER_ROOT {
if user == nil {
this.PanicBadRequest("user cannot be nil.")
}
matter = NewRootMatter(user)
} else {
matter = this.CheckByUuid(uuid)
}
return matter
}
//按照名字查询文件夹

3
rest/matter_model.go

@ -15,7 +15,7 @@ const (
)
/**
* 文件alien表示是否是应用内使用的文件比如说蓝眼云盘的头像alien = true 这种文件在上传时不需要指定存放目录会统一放在同一个文件夹下
* 文件
*/
type Matter struct {
Base
@ -23,7 +23,6 @@ type Matter struct {
UserUuid string `json:"userUuid" gorm:"type:char(36);index:idx_uu"`
Username string `json:"username" gorm:"type:varchar(45) not null"`
Dir bool `json:"dir" gorm:"type:tinyint(1) not null;default:0"`
Alien bool `json:"alien" gorm:"type:tinyint(1) not null;default:0"`
Name string `json:"name" gorm:"type:varchar(255) not null"`
Md5 string `json:"md5" gorm:"type:varchar(45)"`
Size int64 `json:"size" gorm:"type:bigint(20) not null;default:0"`

322
rest/matter_service.go

@ -71,53 +71,43 @@ func (this *MatterService) Delete(matter *Matter) {
panic(result.BadRequest("matter不能为nil"))
}
//操作锁
this.userService.MatterLock(matter.UserUuid)
defer this.userService.MatterUnlock(matter.UserUuid)
this.matterDao.Delete(matter)
}
//开始上传文件
//上传文件. alien表明文件是否是应用使用的文件。
func (this *MatterService) Upload(file io.Reader, user *User, puuid string, filename string, privacy bool, alien bool) *Matter {
func (this *MatterService) Upload(file io.Reader, user *User, dirMatter *Matter, filename string, privacy bool) *Matter {
//文件名不能太长。
if len(filename) > 200 {
panic("文件名不能超过200")
if user == nil {
panic(result.BadRequest("user cannot be nil."))
}
//文件夹路径
var dirAbsolutePath string
var dirRelativePath string
if puuid == "" {
this.PanicBadRequest("puuid必填")
} else {
//操作锁
this.userService.MatterLock(user.Uuid)
defer this.userService.MatterUnlock(user.Uuid)
if puuid == MATTER_ROOT {
dirAbsolutePath = GetUserFileRootDir(user.Username)
dirRelativePath = ""
} else {
//验证puuid是否存在
dirMatter := this.matterDao.CheckByUuidAndUserUuid(puuid, user.Uuid)
dirAbsolutePath = GetUserFileRootDir(user.Username) + dirMatter.Path
dirRelativePath = dirMatter.Path
//验证dirMatter
if dirMatter == nil {
panic(result.BadRequest("dirMatter cannot be nil."))
}
}
//文件名不能太长。
if len(filename) > MATTER_NAME_MAX_LENGTH {
panic(result.BadRequest("文件名不能超过%s", MATTER_NAME_MAX_LENGTH))
}
//查找文件夹下面是否有同名文件。
matters := this.matterDao.ListByUserUuidAndPuuidAndDirAndName(user.Uuid, puuid, false, filename)
//如果有同名的文件,那么我们直接覆盖同名文件。
for _, dbFile := range matters {
this.PanicBadRequest("该目录下%s已经存在了", dbFile.Name)
//文件夹路径
dirAbsolutePath := dirMatter.AbsolutePath()
dirRelativePath := dirMatter.Path
count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, false, filename)
if count > 0 {
panic(result.BadRequest("该目录下%s已经存在了", filename))
}
//获取文件应该存放在的物理路径的绝对路径和相对路径。
@ -136,112 +126,51 @@ func (this *MatterService) Upload(file io.Reader, user *User, puuid string, file
this.PanicError(removeError)
}
distFile, err := os.OpenFile(fileAbsolutePath, os.O_WRONLY|os.O_CREATE, 0777)
destFile, err := os.OpenFile(fileAbsolutePath, os.O_WRONLY|os.O_CREATE, 0777)
this.PanicError(err)
defer func() {
err := distFile.Close()
err := destFile.Close()
this.PanicError(err)
}()
written, err := io.Copy(distFile, file)
fileSize, err := io.Copy(destFile, file)
this.PanicError(err)
this.logger.Info("上传文件%s大小为%v", filename, HumanFileSize(written))
this.logger.Info("上传文件 %s 大小为 %v ", filename, HumanFileSize(fileSize))
//判断用户自身上传大小的限制。
if user.SizeLimit >= 0 {
if written > user.SizeLimit {
this.PanicBadRequest("文件大小超出限制 " + HumanFileSize(user.SizeLimit) + ">" + HumanFileSize(written))
if fileSize > user.SizeLimit {
//删除上传过来的内容
err = os.Remove(fileAbsolutePath)
this.PanicError(err)
panic(result.BadRequest("文件大小超出限制 %s > %s ", HumanFileSize(user.SizeLimit), HumanFileSize(fileSize)))
}
}
//将文件信息存入数据库中。
matter := &Matter{
Puuid: puuid,
Puuid: dirMatter.Uuid,
UserUuid: user.Uuid,
Username: user.Username,
Dir: false,
Alien: alien,
Name: filename,
Md5: "",
Size: written,
Size: fileSize,
Privacy: privacy,
Path: fileRelativePath,
}
matter = this.matterDao.Create(matter)
return matter
}
//根据一个文件夹路径,找到最后一个文件夹的uuid,如果中途出错,返回err.
func (this *MatterService) GetDirUuid(user *User, dir string) (puuid string, dirRelativePath string) {
if dir == "" {
panic(`文件夹不能为空`)
} else if dir[0:1] != "/" {
panic(`文件夹必须以/开头`)
} else if strings.Index(dir, "//") != -1 {
panic(`文件夹不能出现连续的//`)
} else if m, _ := regexp.MatchString(`[<>|*?\\]`, dir); m {
panic(`文件夹中不能包含以下特殊符号:< > | * ? \`)
}
if dir == "/" {
return MATTER_ROOT, ""
}
if dir[len(dir)-1] == '/' {
dir = dir[:len(dir)-1]
}
//递归找寻文件的上级目录uuid.
folders := strings.Split(dir, "/")
if len(folders) > 32 {
panic("文件夹最多32层。")
}
puuid = MATTER_ROOT
parentRelativePath := "/"
for k, name := range folders {
if len(name) > 200 {
panic("每级文件夹的最大长度为200")
}
if k == 0 {
continue
}
matter := this.matterDao.FindByUserUuidAndPuuidAndNameAndDirTrue(user.Uuid, puuid, name)
if matter == nil {
//创建一个文件夹。这里一般都是通过alien接口来创建的文件夹。
matter = &Matter{
Puuid: puuid,
UserUuid: user.Uuid,
Username: user.Username,
Dir: true,
Alien: true,
Name: name,
Path: parentRelativePath + "/" + name,
}
matter = this.matterDao.Create(matter)
}
puuid = matter.Uuid
parentRelativePath = matter.Path
}
return puuid, parentRelativePath
}
//在dirMatter中创建文件夹 返回刚刚创建的这个文件夹
func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user *User) *Matter {
//操作锁
this.userService.MatterLock(user.Uuid)
defer this.userService.MatterUnlock(user.Uuid)
@ -273,7 +202,6 @@ func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user
}
if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m {
panic(result.BadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`))
}
@ -317,6 +245,129 @@ func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user
return matter
}
//将一个srcMatter复制到另一个destMatter(必须为文件夹)下,名字叫做name
func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name string) {
if !destDirMatter.Dir {
this.PanicBadRequest("目标必须为文件夹")
}
if srcMatter.Dir {
//如果源是文件夹
//在目标地址创建新文件夹。
newMatter := &Matter{
Puuid: destDirMatter.Uuid,
UserUuid: srcMatter.UserUuid,
Username: srcMatter.Username,
Dir: srcMatter.Dir,
Name: name,
Md5: "",
Size: srcMatter.Size,
Privacy: srcMatter.Privacy,
Path: destDirMatter.Path + "/" + name,
}
newMatter = this.matterDao.Create(newMatter)
//复制子文件或文件夹
matters := this.matterDao.List(srcMatter.Uuid, srcMatter.UserUuid, nil)
for _, m := range matters {
this.Copy(m, newMatter, m.Name)
}
} else {
//如果源是普通文件
destAbsolutePath := destDirMatter.AbsolutePath() + "/" + name
srcAbsolutePath := srcMatter.AbsolutePath()
//物理文件进行复制
CopyFile(srcAbsolutePath, destAbsolutePath)
//创建新文件的数据库信息。
newMatter := &Matter{
Puuid: destDirMatter.Uuid,
UserUuid: srcMatter.UserUuid,
Username: srcMatter.Username,
Dir: srcMatter.Dir,
Name: name,
Md5: "",
Size: srcMatter.Size,
Privacy: srcMatter.Privacy,
Path: destDirMatter.Path + "/" + name,
}
newMatter = this.matterDao.Create(newMatter)
}
}
//根据一个文件夹路径,找到最后一个文件夹的uuid,如果中途出错,返回err.
func (this *MatterService) GetDirUuid(user *User, dir string) (puuid string, dirRelativePath string) {
if dir == "" {
panic(`文件夹不能为空`)
} else if dir[0:1] != "/" {
panic(`文件夹必须以/开头`)
} else if strings.Index(dir, "//") != -1 {
panic(`文件夹不能出现连续的//`)
} else if m, _ := regexp.MatchString(`[<>|*?\\]`, dir); m {
panic(`文件夹中不能包含以下特殊符号:< > | * ? \`)
}
if dir == "/" {
return MATTER_ROOT, ""
}
if dir[len(dir)-1] == '/' {
dir = dir[:len(dir)-1]
}
//递归找寻文件的上级目录uuid.
folders := strings.Split(dir, "/")
if len(folders) > 32 {
panic("文件夹最多32层。")
}
puuid = MATTER_ROOT
parentRelativePath := "/"
for k, name := range folders {
if len(name) > 200 {
panic("每级文件夹的最大长度为200")
}
if k == 0 {
continue
}
matter := this.matterDao.FindByUserUuidAndPuuidAndNameAndDirTrue(user.Uuid, puuid, name)
if matter == nil {
//创建一个文件夹。这里一般都是通过alien接口来创建的文件夹。
matter = &Matter{
Puuid: puuid,
UserUuid: user.Uuid,
Username: user.Username,
Dir: true,
Name: name,
Path: parentRelativePath + "/" + name,
}
matter = this.matterDao.Create(matter)
}
puuid = matter.Uuid
parentRelativePath = matter.Path
}
return puuid, parentRelativePath
}
//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。
func (this *MatterService) Detail(uuid string) *Matter {
@ -404,7 +455,6 @@ func (this *MatterService) Crawl(url string, filename string, user *User, puuid
UserUuid: user.Uuid,
Username: user.Username,
Dir: false,
Alien: false,
Name: filename,
Md5: "",
Size: size,
@ -496,66 +546,6 @@ func (this *MatterService) Move(srcMatter *Matter, destMatter *Matter) {
return
}
//将一个srcMatter复制到另一个destMatter(必须为文件夹)下,名字叫做name
func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name string) {
if !destDirMatter.Dir {
this.PanicBadRequest("目标必须为文件夹")
}
if srcMatter.Dir {
//如果源是文件夹
//在目标地址创建新文件夹。
newMatter := &Matter{
Puuid: destDirMatter.Uuid,
UserUuid: srcMatter.UserUuid,
Username: srcMatter.Username,
Dir: srcMatter.Dir,
Alien: srcMatter.Alien,
Name: name,
Md5: "",
Size: srcMatter.Size,
Privacy: srcMatter.Privacy,
Path: destDirMatter.Path + "/" + name,
}
newMatter = this.matterDao.Create(newMatter)
//复制子文件或文件夹
matters := this.matterDao.List(srcMatter.Uuid, srcMatter.UserUuid, nil)
for _, m := range matters {
this.Copy(m, newMatter, m.Name)
}
} else {
//如果源是普通文件
destAbsolutePath := destDirMatter.AbsolutePath() + "/" + name
srcAbsolutePath := srcMatter.AbsolutePath()
//物理文件进行复制
CopyFile(srcAbsolutePath, destAbsolutePath)
//创建新文件的数据库信息。
newMatter := &Matter{
Puuid: destDirMatter.Uuid,
UserUuid: srcMatter.UserUuid,
Username: srcMatter.Username,
Dir: srcMatter.Dir,
Alien: srcMatter.Alien,
Name: name,
Md5: "",
Size: srcMatter.Size,
Privacy: srcMatter.Privacy,
Path: destDirMatter.Path + "/" + name,
}
newMatter = this.matterDao.Create(newMatter)
}
}
//将一个matter 重命名为 name
func (this *MatterService) Rename(matter *Matter, name string, user *User) {

Loading…
Cancel
Save