Merge branch 'master' of https://gitea.nxsir.cn/nanxun/IM_NEW
This commit is contained in:
@@ -14,6 +14,7 @@ namespace FileService.Infrastructure
|
||||
services.AddScoped<IUploadFileReposity, UploadFileReposity>();
|
||||
services.AddScoped<IUploadTaskReposity, UploadTaskReposity>();
|
||||
services.AddScoped<IObjectStoragePort, LocalStorageAdapter>();
|
||||
services.AddScoped<IRedisService, RedisCacheService>();
|
||||
services.AddScoped<IObjectStorageRouter, ObjectStorageRouter>();
|
||||
services.AddScoped<IStorageRedisCache,StorageCacheService>();
|
||||
}
|
||||
|
||||
@@ -3,27 +3,73 @@ using FileService.Application.StorageContracts;
|
||||
using FileService.Domain.ValueObjects;
|
||||
using IM.Commons;
|
||||
using IM.InitCommon;
|
||||
using MassTransit;
|
||||
using MassTransit.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace FileService.Infrastructure.Storage
|
||||
{
|
||||
public class LocalStorageAdapter(IRedisService redis, IOptions<StorageOptions> options) : IObjectStoragePort
|
||||
public class LocalStorageAdapter(IStorageRedisCache redis, IOptions<StorageOptions> options) : IObjectStoragePort
|
||||
{
|
||||
private readonly IRedisService redis = redis;
|
||||
private readonly IStorageRedisCache redis = redis;
|
||||
private readonly IOptions<StorageOptions> options = options;
|
||||
|
||||
public string ProviderCode => "Local";
|
||||
|
||||
public Task<CompleteUploadResult> CompleteUploadAsync(CompleteUploadCommand command, CancellationToken token)
|
||||
public async Task<CompleteUploadResult> CompleteUploadAsync(CompleteUploadCommand command, CancellationToken token)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var res = await MergeAsync(command.UploadSessionId, command.ObjectKey, command.Parts);
|
||||
return new CompleteUploadResult(new StorageLocation(
|
||||
storageProvider: command.ProviderCode,
|
||||
bucket: command.Bucket,
|
||||
objectKey: command.ObjectKey,
|
||||
region: command.Region
|
||||
), null, command.Parts.Sum(x => x.Size).Value);
|
||||
}
|
||||
public async Task<Result<object>> MergeAsync(string sessionId, string objectKey, IReadOnlyList<UploadPart> parts)
|
||||
{
|
||||
var rootPath = options.Value.Providers[options.Value.DefaultProviderCode].LocalRootPath;
|
||||
var tempPath = Path.Combine(rootPath, "temp"); // 项目根目录下 uploads // 最终文件存储路径(这里可以用你之前 ObjectNameGenerator 生成的名字)
|
||||
var finalPath = Path.Combine(rootPath, objectKey);
|
||||
var finalDir = Path.GetDirectoryName(finalPath);
|
||||
Directory.CreateDirectory(finalDir);
|
||||
|
||||
var storageCache = await redis.GetAsync(sessionId);
|
||||
var totalChunks = storageCache.TotalPartCount;
|
||||
try
|
||||
{
|
||||
using (var finalStream = new FileStream(finalPath, FileMode.Create))
|
||||
{
|
||||
for (var i = 1; i <= totalChunks; i++)
|
||||
{
|
||||
var progress = (i * 100.0 / totalChunks);
|
||||
if (i % 5 == 0 || i == totalChunks)
|
||||
{
|
||||
//await _redis.HashSetAsync(RedisKeys.MergeStatus(taskId), new HashEntry[]
|
||||
//{
|
||||
// new("status", "processing"),
|
||||
// new("progress", progress.ToString("F2"))
|
||||
//});
|
||||
}
|
||||
var chunkPath = Path.Combine(tempPath, $"{i}.part.tmp");
|
||||
if (!File.Exists(chunkPath))
|
||||
return Result.Fail(ResultCode.CHUNK_NOT_FOUND);
|
||||
using (var chunkStream = new FileStream(chunkPath, FileMode.Open))
|
||||
{
|
||||
await chunkStream.CopyToAsync(finalStream);
|
||||
}
|
||||
}
|
||||
Directory.Delete(tempPath, true);
|
||||
await redis.DeleteAsync(sessionId);
|
||||
}
|
||||
|
||||
return Result.Success();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//_logger.LogError(e, e.Message);
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<PresignedUrl> GenerateUploadUrlAsync(GenerateUploadUrlCommand command, CancellationToken token)
|
||||
|
||||
Reference in New Issue
Block a user