109 lines
2.6 KiB
Go
109 lines
2.6 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"time"
|
|
|
|
"rag/file-system/internal/common"
|
|
"rag/file-system/internal/domain/model"
|
|
"rag/file-system/internal/domain/repository"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type UploadToFolderCommand struct {
|
|
FolderID string
|
|
FileName string
|
|
Data io.Reader
|
|
S3Bucket string
|
|
OwnerID string
|
|
Size int64
|
|
ContentType string
|
|
}
|
|
|
|
type MoveFileCommand struct {
|
|
FileID string
|
|
TargetFolderID string
|
|
OwnerID string
|
|
}
|
|
|
|
type UploadToFolderHandler struct {
|
|
FileMetaRepo repository.FileMetaRepository
|
|
FolderRepo repository.FolderRepository
|
|
S3Repo repository.FileRepository
|
|
}
|
|
|
|
func NewUploadToFolderHandler(
|
|
fileMetaRepo repository.FileMetaRepository,
|
|
folderRepo repository.FolderRepository,
|
|
s3Repo repository.FileRepository,
|
|
) *UploadToFolderHandler {
|
|
return &UploadToFolderHandler{
|
|
FileMetaRepo: fileMetaRepo,
|
|
FolderRepo: folderRepo,
|
|
S3Repo: s3Repo,
|
|
}
|
|
}
|
|
|
|
func (h *UploadToFolderHandler) Handle(ctx context.Context, cmd UploadToFolderCommand) (*model.FileMeta, error) {
|
|
folder, err := h.FolderRepo.GetByID(ctx, cmd.FolderID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if folder == nil || folder.OwnerID != cmd.OwnerID {
|
|
return nil, common.NewNotFoundError("目录不存在")
|
|
}
|
|
|
|
s3Key := uuid.New().String()
|
|
|
|
if err := h.S3Repo.UploadFile(ctx, cmd.S3Bucket, s3Key, cmd.Data); err != nil {
|
|
return nil, fmt.Errorf("S3 upload failed: %w", err)
|
|
}
|
|
|
|
contentType := cmd.ContentType
|
|
if contentType == "" {
|
|
contentType = "application/octet-stream"
|
|
}
|
|
|
|
now := time.Now()
|
|
fileMeta := &model.FileMeta{
|
|
ID: uuid.New().String(),
|
|
FolderID: cmd.FolderID,
|
|
Name: cmd.FileName,
|
|
S3Key: s3Key,
|
|
S3Bucket: cmd.S3Bucket,
|
|
Size: cmd.Size,
|
|
ContentType: contentType,
|
|
OwnerID: cmd.OwnerID,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
if err := h.FileMetaRepo.Create(ctx, fileMeta); err != nil {
|
|
if delErr := h.S3Repo.DeleteFile(ctx, cmd.S3Bucket, s3Key); delErr != nil {
|
|
common.Logger.Error("compensation failed: could not delete S3 object after PG write failure",
|
|
"s3_key", s3Key, "error", delErr)
|
|
}
|
|
return nil, fmt.Errorf("failed to save file metadata: %w", err)
|
|
}
|
|
|
|
return fileMeta, nil
|
|
}
|
|
|
|
type MoveFileHandler struct {
|
|
FileMetaRepo repository.FileMetaRepository
|
|
}
|
|
|
|
func NewMoveFileHandler(fileMetaRepo repository.FileMetaRepository) *MoveFileHandler {
|
|
return &MoveFileHandler{FileMetaRepo: fileMetaRepo}
|
|
}
|
|
|
|
func (h *MoveFileHandler) Handle(ctx context.Context, cmd MoveFileCommand) (string, error) {
|
|
if err := h.FileMetaRepo.Move(ctx, cmd.FileID, cmd.TargetFolderID, cmd.OwnerID); err != nil {
|
|
return "", err
|
|
}
|
|
return "文件移动成功", nil
|
|
}
|