fix: align admin behavior and Kratos integrations
This commit is contained in:
@@ -15,33 +15,6 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type UploadSession struct {
|
||||
ID uint
|
||||
UserID uint
|
||||
FileName, FileHash string
|
||||
FileSize, ChunkSize int64
|
||||
ChunkTotal int
|
||||
Status, StorageKey string
|
||||
MediaID uint
|
||||
}
|
||||
type UploadChunk struct {
|
||||
Index int
|
||||
Hash string
|
||||
Size int64
|
||||
}
|
||||
type UploadRepo interface {
|
||||
FindUploadingSession(context.Context, uint, string) (*UploadSession, error)
|
||||
CreateUploadSession(context.Context, *UploadSession) error
|
||||
FindUploadSession(context.Context, uint) (*UploadSession, error)
|
||||
CompleteUploadSession(context.Context, uint, string, uint) error
|
||||
DeleteUploadSession(context.Context, uint) error
|
||||
UpsertChunk(context.Context, uint, *UploadChunk) error
|
||||
ListChunks(context.Context, uint) ([]*UploadChunk, error)
|
||||
DeleteChunks(context.Context, uint) error
|
||||
StaleUploadSessionIDs(context.Context, time.Time) ([]uint, error)
|
||||
DeleteUploadData(context.Context, uint) error
|
||||
}
|
||||
|
||||
func (uc *MediaUsecase) InitUpload(ctx context.Context, userID uint, name, hash string, size, chunkSize int64, total int) (*UploadSession, *MediaFile, []int, error) {
|
||||
if err := validateMediaName(name); err != nil {
|
||||
return nil, nil, nil, err
|
||||
@@ -49,22 +22,22 @@ func (uc *MediaUsecase) InitUpload(ctx context.Context, userID uint, name, hash
|
||||
if size <= 0 || chunkSize <= 0 || total <= 0 {
|
||||
return nil, nil, nil, errors.New("上传参数不合法")
|
||||
}
|
||||
if media, err := uc.repo.FindMediaByHash(ctx, userID, hash); err == nil {
|
||||
if media, err := uc.FindMediaByHash(ctx, userID, hash); err == nil {
|
||||
copy := *media
|
||||
copy.ID = 0
|
||||
copy.Name = name
|
||||
if err = uc.repo.CreateMedia(ctx, ©); err == nil {
|
||||
if err = uc.CreateMedia(ctx, ©); err == nil {
|
||||
return nil, ©, nil, nil
|
||||
}
|
||||
}
|
||||
session, err := uc.repo.FindUploadingSession(ctx, userID, hash)
|
||||
session, err := uc.FindUploadingSession(ctx, userID, hash)
|
||||
if err != nil {
|
||||
session = &UploadSession{UserID: userID, FileName: name, FileHash: hash, FileSize: size, ChunkSize: chunkSize, ChunkTotal: total, Status: "uploading"}
|
||||
if err = uc.repo.CreateUploadSession(ctx, session); err != nil {
|
||||
if err = uc.CreateUploadSession(ctx, session); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
chunks, err := uc.repo.ListChunks(ctx, session.ID)
|
||||
chunks, err := uc.ListChunks(ctx, session.ID)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -76,7 +49,7 @@ func (uc *MediaUsecase) InitUpload(ctx context.Context, userID uint, name, hash
|
||||
return session, nil, indices, nil
|
||||
}
|
||||
func (uc *MediaUsecase) SaveChunk(ctx context.Context, userID, uploadID uint, index int, expected string, reader io.Reader) error {
|
||||
session, err := uc.repo.FindUploadSession(ctx, uploadID)
|
||||
session, err := uc.FindUploadSession(ctx, uploadID)
|
||||
if err != nil || session.UserID != userID {
|
||||
return errors.New("上传会话不存在或无权操作")
|
||||
}
|
||||
@@ -94,14 +67,14 @@ func (uc *MediaUsecase) SaveChunk(ctx context.Context, userID, uploadID uint, in
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return errors.New("分片校验失败")
|
||||
}
|
||||
return uc.repo.UpsertChunk(ctx, uploadID, &UploadChunk{Index: index, Hash: actual, Size: stored.Size})
|
||||
return uc.UpsertChunk(ctx, uploadID, &UploadChunk{Index: index, Hash: actual, Size: stored.Size})
|
||||
}
|
||||
func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uint, mime string) (*MediaFile, error) {
|
||||
session, err := uc.repo.FindUploadSession(ctx, uploadID)
|
||||
session, err := uc.FindUploadSession(ctx, uploadID)
|
||||
if err != nil || session.UserID != userID {
|
||||
return nil, errors.New("上传会话不存在或无权操作")
|
||||
}
|
||||
chunks, err := uc.repo.ListChunks(ctx, uploadID)
|
||||
chunks, err := uc.ListChunks(ctx, uploadID)
|
||||
if err != nil || len(chunks) != session.ChunkTotal {
|
||||
return nil, errors.New("分片不完整")
|
||||
}
|
||||
@@ -124,34 +97,34 @@ func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uin
|
||||
return nil, errors.New("整文件校验失败")
|
||||
}
|
||||
media := &MediaFile{Name: session.FileName, URL: stored.URL, Tag: strings.TrimPrefix(ext, "."), Key: key, Size: stored.Size, Mime: mime, MD5: hash, UserID: userID}
|
||||
if err = uc.repo.CreateMedia(ctx, media); err != nil {
|
||||
if err = uc.CreateMedia(ctx, media); err != nil {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return nil, err
|
||||
}
|
||||
_ = uc.repo.CompleteUploadSession(ctx, uploadID, key, media.ID)
|
||||
_ = uc.repo.DeleteChunks(ctx, uploadID)
|
||||
_ = uc.CompleteUploadSession(ctx, uploadID, key, media.ID)
|
||||
_ = uc.DeleteChunks(ctx, uploadID)
|
||||
_ = uc.files.DeletePrefix(ctx, fmt.Sprintf(".chunks/%d", uploadID))
|
||||
return media, nil
|
||||
}
|
||||
func (uc *MediaUsecase) CancelUpload(ctx context.Context, userID, uploadID uint) error {
|
||||
session, err := uc.repo.FindUploadSession(ctx, uploadID)
|
||||
session, err := uc.FindUploadSession(ctx, uploadID)
|
||||
if err != nil || session.UserID != userID {
|
||||
return errors.New("上传会话不存在或无权操作")
|
||||
}
|
||||
_ = uc.repo.DeleteChunks(ctx, uploadID)
|
||||
_ = uc.DeleteChunks(ctx, uploadID)
|
||||
_ = uc.files.DeletePrefix(ctx, fmt.Sprintf(".chunks/%d", uploadID))
|
||||
return uc.repo.DeleteUploadSession(ctx, uploadID)
|
||||
return uc.DeleteUploadSession(ctx, uploadID)
|
||||
}
|
||||
func (uc *MediaUsecase) CleanupStale(ctx context.Context, ttlHours int) error {
|
||||
if ttlHours <= 0 {
|
||||
ttlHours = 24
|
||||
}
|
||||
ids, err := uc.repo.StaleUploadSessionIDs(ctx, time.Now().Add(-time.Duration(ttlHours)*time.Hour))
|
||||
ids, err := uc.StaleUploadSessionIDs(ctx, time.Now().Add(-time.Duration(ttlHours)*time.Hour))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range ids {
|
||||
if err = uc.repo.DeleteUploadData(ctx, id); err != nil {
|
||||
if err = uc.DeleteUploadData(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = uc.files.DeletePrefix(ctx, fmt.Sprintf(".chunks/%d", id)); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user