refactor: reorganize modules and add Linux build tooling
This commit is contained in:
83
module/base/cloud/internal/logic/disk/copy_file.go
Normal file
83
module/base/cloud/internal/logic/disk/copy_file.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/engine/types"
|
||||
)
|
||||
|
||||
// 复制文件
|
||||
func CopyFile(ctx context.Context, in *pb.CopyFileRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request
|
||||
if in.Id == 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.NewName) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var file models.CloudDiskFile
|
||||
if err := impl.DBService.Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_files.id = ? AND cloud_disk_dirs.passport_id = ?", in.Id, auth.ID).
|
||||
First(&file).Error; err != nil {
|
||||
printer.Error("File not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查目标目录是否存在且属于当前用户
|
||||
var targetDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ? AND passport_id = ?", in.TargetDirectoryId, auth.ID).First(&targetDir).Error; err != nil {
|
||||
printer.Error("Target directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查目标目录下是否已存在同名文件
|
||||
var existingFile models.CloudDiskFile
|
||||
if err := impl.DBService.Where("name = ? AND directory_id = ?", in.NewName, in.TargetDirectoryId).First(&existingFile).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
// 创建文件副本
|
||||
newFile := models.CloudDiskFile{
|
||||
Std_IICUDS: types.Std_IICUDS{
|
||||
Identity: utils.UUID(),
|
||||
},
|
||||
CloudBase: models.CloudBase{
|
||||
CloudID: file.CloudID,
|
||||
CloudIdentity: file.CloudIdentity,
|
||||
},
|
||||
DirectoryID: func() *uint { id := uint(in.TargetDirectoryId); return &id }(),
|
||||
Name: in.NewName,
|
||||
OriginalName: in.NewName,
|
||||
Size: file.Size,
|
||||
MimeType: file.MimeType,
|
||||
StoragePath: file.StoragePath, // 注意:实际存储中可能需要复制文件内容
|
||||
Hash: file.Hash,
|
||||
}
|
||||
|
||||
if err := impl.DBService.Create(&newFile).Error; err != nil {
|
||||
printer.Error("Copy file error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: newFile.Identity,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
85
module/base/cloud/internal/logic/disk/create_dir.go
Normal file
85
module/base/cloud/internal/logic/disk/create_dir.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/engine/types"
|
||||
)
|
||||
|
||||
// 创建目录
|
||||
func CreateDir(ctx context.Context, in *pb.CreateDirRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// valid code
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.CloudIdentity) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
// 构建完整路径
|
||||
var fullPath string
|
||||
if in.ParentId > 0 {
|
||||
var parentDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ? AND passport_id = ?", in.ParentId, auth.ID).First(&parentDir).Error; err != nil {
|
||||
printer.Error("Parent directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
fullPath = filepath.Join(parentDir.Path, in.Name)
|
||||
} else {
|
||||
fullPath = "/" + in.Name
|
||||
}
|
||||
|
||||
// 检查目录是否已存在
|
||||
var existingDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path = ? AND passport_id = ?", fullPath, auth.ID).First(&existingDir).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
record := models.CloudDiskDir{
|
||||
Std_IICUDS: types.Std_IICUDS{
|
||||
Identity: utils.UUID(),
|
||||
},
|
||||
Std_Passport: types.Std_Passport{
|
||||
PassportID: auth.ID,
|
||||
PassportIdentity: auth.Identity,
|
||||
},
|
||||
CloudBase: models.CloudBase{
|
||||
CloudID: uint(in.CloudId),
|
||||
CloudIdentity: in.CloudIdentity,
|
||||
},
|
||||
Name: in.Name,
|
||||
Path: fullPath,
|
||||
}
|
||||
|
||||
if in.ParentId > 0 {
|
||||
parentId := uint(in.ParentId)
|
||||
record.ParentID = &parentId
|
||||
}
|
||||
|
||||
if err := impl.DBService.Create(&record).Error; err != nil {
|
||||
printer.Error("Create directory error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: record.Identity,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
74
module/base/cloud/internal/logic/disk/delete_dir.go
Normal file
74
module/base/cloud/internal/logic/disk/delete_dir.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 删除目录
|
||||
func DeleteDir(ctx context.Context, in *pb.IdentRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var dir models.CloudDiskDir
|
||||
query := impl.DBService.Where("passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.First(&dir).Error; err != nil {
|
||||
printer.Error("Directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查是否有子目录
|
||||
var subdirCount int64
|
||||
if err := impl.DBService.Model(&models.CloudDiskDir{}).Where("parent_id = ?", dir.ID).Count(&subdirCount).Error; err != nil {
|
||||
printer.Error("Check subdirectories error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
if subdirCount > 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查是否有文件
|
||||
var fileCount int64
|
||||
if err := impl.DBService.Model(&models.CloudDiskFile{}).Where("directory_id = ?", dir.ID).Count(&fileCount).Error; err != nil {
|
||||
printer.Error("Check files error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
if fileCount > 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 删除目录
|
||||
if err := impl.DBService.Delete(&dir).Error; err != nil {
|
||||
printer.Error("Delete directory error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
55
module/base/cloud/internal/logic/disk/delete_file.go
Normal file
55
module/base/cloud/internal/logic/disk/delete_file.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 删除文件
|
||||
func DeleteFile(ctx context.Context, in *pb.IdentRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var file models.CloudDiskFile
|
||||
query := impl.DBService.Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_dirs.passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("cloud_disk_files.id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("cloud_disk_files.identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.First(&file).Error; err != nil {
|
||||
printer.Error("File not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 删除文件
|
||||
if err := impl.DBService.Delete(&file).Error; err != nil {
|
||||
printer.Error("Delete file error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
102
module/base/cloud/internal/logic/disk/get_dir.go
Normal file
102
module/base/cloud/internal/logic/disk/get_dir.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取目录详情
|
||||
func GetDir(ctx context.Context, in *pb.IdentRequest) (reply *pb.CloudDiskDirItem, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var dir models.CloudDiskDir
|
||||
query := impl.DBService.Where("passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.Preload("Parent").Preload("Subdirectories").Preload("Files").First(&dir).Error; err != nil {
|
||||
printer.Error("Directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 转换子目录数据
|
||||
var subdirs []*pb.CloudDiskDirItem
|
||||
for _, subdir := range dir.Subdirectories {
|
||||
subdirs = append(subdirs, &pb.CloudDiskDirItem{
|
||||
Id: uint64(subdir.ID),
|
||||
Identity: subdir.Identity,
|
||||
ParentId: uint64(*subdir.ParentID),
|
||||
Name: subdir.Name,
|
||||
Path: subdir.Path,
|
||||
CreatedAt: subdir.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: subdir.UpdatedAt.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
|
||||
// 转换文件数据
|
||||
var files []*pb.CloudDiskFileItem
|
||||
for _, file := range dir.Files {
|
||||
files = append(files, &pb.CloudDiskFileItem{
|
||||
Id: uint64(file.ID),
|
||||
Identity: file.Identity,
|
||||
DirectoryId: uint64(*file.DirectoryID),
|
||||
Name: file.Name,
|
||||
OriginalName: file.OriginalName,
|
||||
Size: file.Size,
|
||||
MimeType: file.MimeType,
|
||||
StoragePath: file.StoragePath,
|
||||
Hash: file.Hash,
|
||||
CreatedAt: file.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.UpdatedAt.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
|
||||
// 构建父目录信息
|
||||
var parent *pb.CloudDiskDirItem
|
||||
if dir.Parent != nil {
|
||||
parent = &pb.CloudDiskDirItem{
|
||||
Id: uint64(dir.Parent.ID),
|
||||
Identity: dir.Parent.Identity,
|
||||
Name: dir.Parent.Name,
|
||||
Path: dir.Parent.Path,
|
||||
CreatedAt: dir.Parent.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: dir.Parent.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
reply = &pb.CloudDiskDirItem{
|
||||
Id: uint64(dir.ID),
|
||||
Identity: dir.Identity,
|
||||
ParentId: uint64(*dir.ParentID),
|
||||
Name: dir.Name,
|
||||
Path: dir.Path,
|
||||
CreatedAt: dir.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: dir.UpdatedAt.Format(time.RFC3339),
|
||||
Parent: parent,
|
||||
Subdirectories: subdirs,
|
||||
Files: files,
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
108
module/base/cloud/internal/logic/disk/get_dir_tree.go
Normal file
108
module/base/cloud/internal/logic/disk/get_dir_tree.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取目录树
|
||||
func GetDirTree(ctx context.Context, in *pb.IdentRequest) (reply *pb.CloudDiskDirItem, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var dir models.CloudDiskDir
|
||||
query := impl.DBService.Where("passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.Preload("Parent").Preload("Subdirectories").Preload("Files").First(&dir).Error; err != nil {
|
||||
printer.Error("Directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 递归加载子目录树
|
||||
var loadSubdirs func(*models.CloudDiskDir) []*pb.CloudDiskDirItem
|
||||
loadSubdirs = func(d *models.CloudDiskDir) []*pb.CloudDiskDirItem {
|
||||
var subdirs []*pb.CloudDiskDirItem
|
||||
for _, subdir := range d.Subdirectories {
|
||||
subdirItem := &pb.CloudDiskDirItem{
|
||||
Id: uint64(subdir.ID),
|
||||
Identity: subdir.Identity,
|
||||
ParentId: uint64(*subdir.ParentID),
|
||||
Name: subdir.Name,
|
||||
Path: subdir.Path,
|
||||
CreatedAt: subdir.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: subdir.UpdatedAt.Format(time.RFC3339),
|
||||
Subdirectories: loadSubdirs(&subdir),
|
||||
}
|
||||
subdirs = append(subdirs, subdirItem)
|
||||
}
|
||||
return subdirs
|
||||
}
|
||||
|
||||
// 转换文件数据
|
||||
var files []*pb.CloudDiskFileItem
|
||||
for _, file := range dir.Files {
|
||||
files = append(files, &pb.CloudDiskFileItem{
|
||||
Id: uint64(file.ID),
|
||||
Identity: file.Identity,
|
||||
DirectoryId: uint64(*file.DirectoryID),
|
||||
Name: file.Name,
|
||||
OriginalName: file.OriginalName,
|
||||
Size: file.Size,
|
||||
MimeType: file.MimeType,
|
||||
StoragePath: file.StoragePath,
|
||||
Hash: file.Hash,
|
||||
CreatedAt: file.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.UpdatedAt.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
|
||||
// 构建父目录信息
|
||||
var parent *pb.CloudDiskDirItem
|
||||
if dir.Parent != nil {
|
||||
parent = &pb.CloudDiskDirItem{
|
||||
Id: uint64(dir.Parent.ID),
|
||||
Identity: dir.Parent.Identity,
|
||||
Name: dir.Parent.Name,
|
||||
Path: dir.Parent.Path,
|
||||
CreatedAt: dir.Parent.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: dir.Parent.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
reply = &pb.CloudDiskDirItem{
|
||||
Id: uint64(dir.ID),
|
||||
Identity: dir.Identity,
|
||||
ParentId: uint64(*dir.ParentID),
|
||||
Name: dir.Name,
|
||||
Path: dir.Path,
|
||||
CreatedAt: dir.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: dir.UpdatedAt.Format(time.RFC3339),
|
||||
Parent: parent,
|
||||
Subdirectories: loadSubdirs(&dir),
|
||||
Files: files,
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
73
module/base/cloud/internal/logic/disk/get_file.go
Normal file
73
module/base/cloud/internal/logic/disk/get_file.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取文件详情
|
||||
func GetFile(ctx context.Context, in *pb.IdentRequest) (reply *pb.CloudDiskFileItem, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var file models.CloudDiskFile
|
||||
query := impl.DBService.Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_dirs.passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("cloud_disk_files.id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("cloud_disk_files.identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.Preload("Directory").First(&file).Error; err != nil {
|
||||
printer.Error("File not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 构建目录信息
|
||||
var directory *pb.CloudDiskDirItem
|
||||
if file.Directory != nil {
|
||||
directory = &pb.CloudDiskDirItem{
|
||||
Id: uint64(file.Directory.ID),
|
||||
Identity: file.Directory.Identity,
|
||||
Name: file.Directory.Name,
|
||||
Path: file.Directory.Path,
|
||||
CreatedAt: file.Directory.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.Directory.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
reply = &pb.CloudDiskFileItem{
|
||||
Id: uint64(file.ID),
|
||||
Identity: file.Identity,
|
||||
DirectoryId: uint64(*file.DirectoryID),
|
||||
Name: file.Name,
|
||||
OriginalName: file.OriginalName,
|
||||
Size: file.Size,
|
||||
MimeType: file.MimeType,
|
||||
StoragePath: file.StoragePath,
|
||||
Hash: file.Hash,
|
||||
CreatedAt: file.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.UpdatedAt.Format(time.RFC3339),
|
||||
Directory: directory,
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
87
module/base/cloud/internal/logic/disk/list_dirs.go
Normal file
87
module/base/cloud/internal/logic/disk/list_dirs.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取目录列表
|
||||
func ListDirs(ctx context.Context, in *pb.FetchRequest) (reply *pb.ListDirsResponse, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request page_no,page_size.
|
||||
if in.GetPageNo() < 1 {
|
||||
in.PageNo = 1
|
||||
}
|
||||
if in.GetPageSize() < 10 {
|
||||
in.PageSize = 50
|
||||
}
|
||||
|
||||
// logic code
|
||||
var dirs []models.CloudDiskDir
|
||||
var total int64
|
||||
|
||||
// 获取总数
|
||||
if err := impl.DBService.Model(&models.CloudDiskDir{}).Where("passport_id = ?", auth.ID).Count(&total).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (in.PageNo - 1) * in.PageSize
|
||||
if err := impl.DBService.Where("passport_id = ?", auth.ID).
|
||||
Preload("Parent").
|
||||
Order("created_at DESC").
|
||||
Offset(int(offset)).
|
||||
Limit(int(in.PageSize)).
|
||||
Find(&dirs).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 转换数据
|
||||
var dirItems []*pb.CloudDiskDirItem
|
||||
for _, dir := range dirs {
|
||||
var parentId uint64
|
||||
if dir.ParentID != nil {
|
||||
parentId = uint64(*dir.ParentID)
|
||||
}
|
||||
|
||||
var parent *pb.CloudDiskDirItem
|
||||
if dir.Parent != nil {
|
||||
parent = &pb.CloudDiskDirItem{
|
||||
Id: uint64(dir.Parent.ID),
|
||||
Identity: dir.Parent.Identity,
|
||||
Name: dir.Parent.Name,
|
||||
Path: dir.Parent.Path,
|
||||
CreatedAt: dir.Parent.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: dir.Parent.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
dirItems = append(dirItems, &pb.CloudDiskDirItem{
|
||||
Id: uint64(dir.ID),
|
||||
Identity: dir.Identity,
|
||||
ParentId: parentId,
|
||||
Name: dir.Name,
|
||||
Path: dir.Path,
|
||||
CreatedAt: dir.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: dir.UpdatedAt.Format(time.RFC3339),
|
||||
Parent: parent,
|
||||
})
|
||||
}
|
||||
|
||||
reply = &pb.ListDirsResponse{
|
||||
Dirs: dirItems,
|
||||
Total: total,
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
91
module/base/cloud/internal/logic/disk/list_files.go
Normal file
91
module/base/cloud/internal/logic/disk/list_files.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取文件列表
|
||||
func ListFiles(ctx context.Context, in *pb.FetchRequest) (reply *pb.ListFilesResponse, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request page_no,page_size.
|
||||
if in.GetPageNo() < 1 {
|
||||
in.PageNo = 1
|
||||
}
|
||||
if in.GetPageSize() < 10 {
|
||||
in.PageSize = 50
|
||||
}
|
||||
|
||||
// logic code
|
||||
var files []models.CloudDiskFile
|
||||
var total int64
|
||||
|
||||
// 获取总数
|
||||
if err := impl.DBService.Model(&models.CloudDiskFile{}).
|
||||
Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_dirs.passport_id = ?", auth.ID).
|
||||
Count(&total).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (in.PageNo - 1) * in.PageSize
|
||||
if err := impl.DBService.
|
||||
Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_dirs.passport_id = ?", auth.ID).
|
||||
Preload("Directory").
|
||||
Order("cloud_disk_files.created_at DESC").
|
||||
Offset(int(offset)).
|
||||
Limit(int(in.PageSize)).
|
||||
Find(&files).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 转换数据
|
||||
var fileItems []*pb.CloudDiskFileItem
|
||||
for _, file := range files {
|
||||
var directory *pb.CloudDiskDirItem
|
||||
if file.Directory != nil {
|
||||
directory = &pb.CloudDiskDirItem{
|
||||
Id: uint64(file.Directory.ID),
|
||||
Identity: file.Directory.Identity,
|
||||
Name: file.Directory.Name,
|
||||
Path: file.Directory.Path,
|
||||
CreatedAt: file.Directory.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.Directory.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
fileItems = append(fileItems, &pb.CloudDiskFileItem{
|
||||
Id: uint64(file.ID),
|
||||
Identity: file.Identity,
|
||||
DirectoryId: uint64(*file.DirectoryID),
|
||||
Name: file.Name,
|
||||
OriginalName: file.OriginalName,
|
||||
Size: file.Size,
|
||||
MimeType: file.MimeType,
|
||||
StoragePath: file.StoragePath,
|
||||
Hash: file.Hash,
|
||||
CreatedAt: file.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.UpdatedAt.Format(time.RFC3339),
|
||||
Directory: directory,
|
||||
})
|
||||
}
|
||||
|
||||
reply = &pb.ListFilesResponse{
|
||||
Files: fileItems,
|
||||
Total: total,
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
108
module/base/cloud/internal/logic/disk/move_dir.go
Normal file
108
module/base/cloud/internal/logic/disk/move_dir.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 移动目录
|
||||
func MoveDir(ctx context.Context, in *pb.MoveDirRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request
|
||||
if in.Id == 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var dir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ? AND passport_id = ?", in.Id, auth.ID).First(&dir).Error; err != nil {
|
||||
printer.Error("Directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查目标父目录是否存在
|
||||
if in.NewParentId > 0 {
|
||||
var parentDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ? AND passport_id = ?", in.NewParentId, auth.ID).First(&parentDir).Error; err != nil {
|
||||
printer.Error("Parent directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查是否会形成循环引用
|
||||
if dir.ID == parentDir.ID {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查目标路径是否已存在
|
||||
newPath := filepath.Join(parentDir.Path, dir.Name)
|
||||
var existingDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path = ? AND passport_id = ? AND id != ?", newPath, auth.ID, dir.ID).First(&existingDir).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
// 更新目录
|
||||
oldPath := dir.Path
|
||||
newParentId := uint(in.NewParentId)
|
||||
dir.ParentID = &newParentId
|
||||
dir.Path = newPath
|
||||
|
||||
if err := impl.DBService.Save(&dir).Error; err != nil {
|
||||
printer.Error("Move directory error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 更新所有子目录的路径
|
||||
var subdirs []models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path LIKE ? AND passport_id = ?", oldPath+"%", auth.ID).Find(&subdirs).Error; err == nil {
|
||||
for _, subdir := range subdirs {
|
||||
newSubPath := strings.Replace(subdir.Path, oldPath, newPath, 1)
|
||||
impl.DBService.Model(&subdir).Update("path", newSubPath)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 移动到根目录
|
||||
oldPath := dir.Path
|
||||
dir.ParentID = nil
|
||||
dir.Path = "/" + dir.Name
|
||||
|
||||
// 检查根目录下是否已存在同名目录
|
||||
var existingDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path = ? AND passport_id = ? AND id != ?", dir.Path, auth.ID, dir.ID).First(&existingDir).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
if err := impl.DBService.Save(&dir).Error; err != nil {
|
||||
printer.Error("Move directory error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 更新所有子目录的路径
|
||||
var subdirs []models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path LIKE ? AND passport_id = ?", oldPath+"%", auth.ID).Find(&subdirs).Error; err == nil {
|
||||
for _, subdir := range subdirs {
|
||||
newSubPath := strings.Replace(subdir.Path, oldPath, dir.Path, 1)
|
||||
impl.DBService.Model(&subdir).Update("path", newSubPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
64
module/base/cloud/internal/logic/disk/move_file.go
Normal file
64
module/base/cloud/internal/logic/disk/move_file.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 移动文件
|
||||
func MoveFile(ctx context.Context, in *pb.MoveFileRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request
|
||||
if in.Id == 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var file models.CloudDiskFile
|
||||
if err := impl.DBService.Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_files.id = ? AND cloud_disk_dirs.passport_id = ?", in.Id, auth.ID).
|
||||
First(&file).Error; err != nil {
|
||||
printer.Error("File not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查目标目录是否存在且属于当前用户
|
||||
var targetDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ? AND passport_id = ?", in.NewDirectoryId, auth.ID).First(&targetDir).Error; err != nil {
|
||||
printer.Error("Target directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查目标目录下是否已存在同名文件
|
||||
var existingFile models.CloudDiskFile
|
||||
if err := impl.DBService.Where("name = ? AND directory_id = ? AND id != ?", file.Name, in.NewDirectoryId, file.ID).First(&existingFile).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
// 更新文件目录
|
||||
newDirectoryId := uint(in.NewDirectoryId)
|
||||
file.DirectoryID = &newDirectoryId
|
||||
|
||||
if err := impl.DBService.Save(&file).Error; err != nil {
|
||||
printer.Error("Move file error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
98
module/base/cloud/internal/logic/disk/search_files.go
Normal file
98
module/base/cloud/internal/logic/disk/search_files.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 搜索文件
|
||||
func SearchFiles(ctx context.Context, in *pb.FetchRequest) (reply *pb.ListFilesResponse, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request page_no,page_size.
|
||||
if in.GetPageNo() < 1 {
|
||||
in.PageNo = 1
|
||||
}
|
||||
if in.GetPageSize() < 10 {
|
||||
in.PageSize = 50
|
||||
}
|
||||
|
||||
// logic code
|
||||
var files []models.CloudDiskFile
|
||||
var total int64
|
||||
|
||||
// 构建搜索查询
|
||||
query := impl.DBService.Model(&models.CloudDiskFile{}).
|
||||
Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_dirs.passport_id = ?", auth.ID)
|
||||
|
||||
// 添加搜索条件
|
||||
if keyword, exists := in.Params["keyword"]; exists && keyword != "" {
|
||||
searchKeyword := "%" + strings.ToLower(keyword) + "%"
|
||||
query = query.Where("LOWER(cloud_disk_files.name) LIKE ? OR LOWER(cloud_disk_files.original_name) LIKE ?", searchKeyword, searchKeyword)
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (in.PageNo - 1) * in.PageSize
|
||||
if err := query.
|
||||
Preload("Directory").
|
||||
Order("cloud_disk_files.created_at DESC").
|
||||
Offset(int(offset)).
|
||||
Limit(int(in.PageSize)).
|
||||
Find(&files).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 转换数据
|
||||
var fileItems []*pb.CloudDiskFileItem
|
||||
for _, file := range files {
|
||||
var directory *pb.CloudDiskDirItem
|
||||
if file.Directory != nil {
|
||||
directory = &pb.CloudDiskDirItem{
|
||||
Id: uint64(file.Directory.ID),
|
||||
Identity: file.Directory.Identity,
|
||||
Name: file.Directory.Name,
|
||||
Path: file.Directory.Path,
|
||||
CreatedAt: file.Directory.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.Directory.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
fileItems = append(fileItems, &pb.CloudDiskFileItem{
|
||||
Id: uint64(file.ID),
|
||||
Identity: file.Identity,
|
||||
DirectoryId: uint64(*file.DirectoryID),
|
||||
Name: file.Name,
|
||||
OriginalName: file.OriginalName,
|
||||
Size: file.Size,
|
||||
MimeType: file.MimeType,
|
||||
StoragePath: file.StoragePath,
|
||||
Hash: file.Hash,
|
||||
CreatedAt: file.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: file.UpdatedAt.Format(time.RFC3339),
|
||||
Directory: directory,
|
||||
})
|
||||
}
|
||||
|
||||
reply = &pb.ListFilesResponse{
|
||||
Files: fileItems,
|
||||
Total: total,
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
89
module/base/cloud/internal/logic/disk/update_dir.go
Normal file
89
module/base/cloud/internal/logic/disk/update_dir.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 更新目录
|
||||
func UpdateDir(ctx context.Context, in *pb.CloudDiskDirItem) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var dir models.CloudDiskDir
|
||||
query := impl.DBService.Where("passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.First(&dir).Error; err != nil {
|
||||
printer.Error("Directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 更新目录名称和路径
|
||||
oldPath := dir.Path
|
||||
dir.Name = in.Name
|
||||
|
||||
// 重新构建路径
|
||||
if dir.ParentID != nil {
|
||||
var parentDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ?", *dir.ParentID).First(&parentDir).Error; err == nil {
|
||||
dir.Path = filepath.Join(parentDir.Path, in.Name)
|
||||
}
|
||||
} else {
|
||||
dir.Path = "/" + in.Name
|
||||
}
|
||||
|
||||
// 检查新路径是否已存在
|
||||
var existingDir models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path = ? AND passport_id = ? AND id != ?", dir.Path, auth.ID, dir.ID).First(&existingDir).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
if err := impl.DBService.Save(&dir).Error; err != nil {
|
||||
printer.Error("Update directory error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 更新所有子目录的路径
|
||||
if oldPath != dir.Path {
|
||||
var subdirs []models.CloudDiskDir
|
||||
if err := impl.DBService.Where("path LIKE ? AND passport_id = ?", oldPath+"%", auth.ID).Find(&subdirs).Error; err == nil {
|
||||
for _, subdir := range subdirs {
|
||||
newSubPath := strings.Replace(subdir.Path, oldPath, dir.Path, 1)
|
||||
impl.DBService.Model(&subdir).Update("path", newSubPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
73
module/base/cloud/internal/logic/disk/update_file.go
Normal file
73
module/base/cloud/internal/logic/disk/update_file.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 更新文件
|
||||
func UpdateFile(ctx context.Context, in *pb.CloudDiskFileItem) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
var file models.CloudDiskFile
|
||||
query := impl.DBService.Joins("JOIN cloud_disk_dirs ON cloud_disk_files.directory_id = cloud_disk_dirs.id").
|
||||
Where("cloud_disk_dirs.passport_id = ?", auth.ID)
|
||||
|
||||
if in.Id > 0 {
|
||||
query = query.Where("cloud_disk_files.id = ?", in.Id)
|
||||
} else {
|
||||
query = query.Where("cloud_disk_files.identity = ?", in.Identity)
|
||||
}
|
||||
|
||||
if err := query.First(&file).Error; err != nil {
|
||||
printer.Error("File not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查新文件名是否已存在(在同一目录下)
|
||||
if file.Name != in.Name {
|
||||
var existingFile models.CloudDiskFile
|
||||
if err := impl.DBService.Where("name = ? AND directory_id = ? AND id != ?", in.Name, file.DirectoryID, file.ID).First(&existingFile).Error; err == nil {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
file.Name = in.Name
|
||||
file.OriginalName = in.OriginalName
|
||||
file.MimeType = in.MimeType
|
||||
file.StoragePath = in.StoragePath
|
||||
file.Hash = in.Hash
|
||||
|
||||
if err := impl.DBService.Save(&file).Error; err != nil {
|
||||
printer.Error("Update file error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
87
module/base/cloud/internal/logic/disk/upload_file.go
Normal file
87
module/base/cloud/internal/logic/disk/upload_file.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/base/cloud/internal/impl"
|
||||
"bsm/full/module/base/cloud/internal/models"
|
||||
pb "bsm/full/module/base/cloud/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/engine/types"
|
||||
)
|
||||
|
||||
// 上传文件
|
||||
func UploadFile(ctx context.Context, in *pb.CloudDiskFileRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate request
|
||||
if in.DirectoryId == 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.StoragePath) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if strings.TrimSpace(in.CloudIdentity) == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// logic code
|
||||
// 验证目录是否存在且属于当前用户
|
||||
var directory models.CloudDiskDir
|
||||
if err := impl.DBService.Where("id = ? AND passport_id = ?", in.DirectoryId, auth.ID).First(&directory).Error; err != nil {
|
||||
printer.Error("Directory not found: %v", err)
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 检查文件是否已存在(基于文件名和目录)
|
||||
var existingFile models.CloudDiskFile
|
||||
if err := impl.DBService.Where("name = ? AND directory_id = ?", in.Name, in.DirectoryId).First(&existingFile).Error; err == nil {
|
||||
// 文件已存在,可以选择覆盖或返回错误
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
|
||||
// 生成文件哈希(如果未提供)
|
||||
fileHash := in.Hash
|
||||
if fileHash == "" {
|
||||
fileHash = utils.UUID() // 使用UUID作为默认哈希
|
||||
}
|
||||
|
||||
record := models.CloudDiskFile{
|
||||
Std_IICUDS: types.Std_IICUDS{
|
||||
Identity: utils.UUID(),
|
||||
},
|
||||
CloudBase: models.CloudBase{
|
||||
CloudID: uint(in.CloudId),
|
||||
CloudIdentity: in.CloudIdentity,
|
||||
},
|
||||
DirectoryID: func() *uint { id := uint(in.DirectoryId); return &id }(),
|
||||
Name: in.Name,
|
||||
OriginalName: in.OriginalName,
|
||||
Size: in.Size,
|
||||
MimeType: in.MimeType,
|
||||
StoragePath: in.StoragePath,
|
||||
Hash: fileHash,
|
||||
}
|
||||
|
||||
if err := impl.DBService.Create(&record).Error; err != nil {
|
||||
printer.Error("Upload file error: %v", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: record.Identity,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user