102 lines
2.9 KiB
Go
102 lines
2.9 KiB
Go
package example
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"kra/internal/biz/example"
|
|
"kra/internal/data/model"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type breakpointContinueRepo struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewBreakpointContinueRepo 创建断点续传仓储
|
|
func NewBreakpointContinueRepo(db *gorm.DB) example.BreakpointContinueRepo {
|
|
return &breakpointContinueRepo{db: db}
|
|
}
|
|
|
|
// FindOrCreateFile 查找或创建文件记录
|
|
func (r *breakpointContinueRepo) FindOrCreateFile(ctx context.Context, fileMd5, fileName string, chunkTotal int) (*example.ExaFile, error) {
|
|
var file model.ExaFile
|
|
cfile := model.ExaFile{
|
|
FileMd5: fileMd5,
|
|
FileName: fileName,
|
|
ChunkTotal: int64(chunkTotal),
|
|
}
|
|
|
|
// 检查是否已有完成的文件
|
|
if errors.Is(r.db.WithContext(ctx).Where("file_md5 = ? AND is_finish = ?", fileMd5, true).First(&file).Error, gorm.ErrRecordNotFound) {
|
|
// 没有完成的文件,查找或创建
|
|
err := r.db.WithContext(ctx).Where("file_md5 = ? AND file_name = ?", fileMd5, fileName).
|
|
FirstOrCreate(&file, cfile).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 加载切片
|
|
var chunks []model.ExaFileChunk
|
|
r.db.WithContext(ctx).Where("exa_file_id = ?", file.ID).Find(&chunks)
|
|
return toBizExaFileWithChunks(&file, chunks), nil
|
|
}
|
|
|
|
// 已有完成的文件,创建新记录
|
|
cfile.IsFinish = true
|
|
cfile.FilePath = file.FilePath
|
|
if err := r.db.WithContext(ctx).Create(&cfile).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return toBizExaFileWithChunks(&cfile, nil), nil
|
|
}
|
|
|
|
// CreateFileChunk 创建文件切片记录
|
|
func (r *breakpointContinueRepo) CreateFileChunk(ctx context.Context, fileID uint, fileChunkPath string, fileChunkNumber int) error {
|
|
chunk := model.ExaFileChunk{
|
|
ExaFileID: int64(fileID),
|
|
FileChunkPath: fileChunkPath,
|
|
FileChunkNumber: int64(fileChunkNumber),
|
|
}
|
|
return r.db.WithContext(ctx).Create(&chunk).Error
|
|
}
|
|
|
|
// DeleteFileChunk 删除文件切片记录
|
|
func (r *breakpointContinueRepo) DeleteFileChunk(ctx context.Context, fileMd5, filePath string) error {
|
|
var file model.ExaFile
|
|
err := r.db.WithContext(ctx).Where("file_md5 = ?", fileMd5).First(&file).
|
|
Updates(map[string]interface{}{
|
|
"is_finish": true,
|
|
"file_path": filePath,
|
|
}).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return r.db.WithContext(ctx).Where("exa_file_id = ?", file.ID).Delete(&model.ExaFileChunk{}).Unscoped().Error
|
|
}
|
|
|
|
// 转换函数
|
|
func toBizExaFileWithChunks(m *model.ExaFile, chunks []model.ExaFileChunk) *example.ExaFile {
|
|
file := &example.ExaFile{
|
|
ID: uint(m.ID),
|
|
FileName: m.FileName,
|
|
FileMd5: m.FileMd5,
|
|
FilePath: m.FilePath,
|
|
ChunkTotal: int(m.ChunkTotal),
|
|
IsFinish: m.IsFinish,
|
|
}
|
|
if len(chunks) > 0 {
|
|
file.ExaFileChunk = make([]example.ExaFileChunk, len(chunks))
|
|
for i, chunk := range chunks {
|
|
file.ExaFileChunk[i] = example.ExaFileChunk{
|
|
ID: uint(chunk.ID),
|
|
ExaFileID: uint(chunk.ExaFileID),
|
|
FileChunkNumber: int(chunk.FileChunkNumber),
|
|
FileChunkPath: chunk.FileChunkPath,
|
|
}
|
|
}
|
|
}
|
|
return file
|
|
}
|