This commit is contained in:
2026-08-31 14:42:22 +08:00
72 changed files with 2479 additions and 168 deletions
@@ -1,6 +1,10 @@
using Microsoft.AspNetCore.Authorization;
using FileService.Application.UploadFile;
using FileService.Infrastructure;
using IM.ASPNETCore;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace FileService.WebApi.Controllers.File
{
@@ -9,7 +13,63 @@ namespace FileService.WebApi.Controllers.File
[ApiController]
public class FileController : ControllerBase
{
//[HttpGet]
//public async
private readonly UploadFileService service;
public FileController(UploadFileService service)
{
this.service = service;
}
/// <summary>
/// 单次直传(小文件:头像/封面等)。isPublic=true 落公开桶,返回直链。
/// 支持秒传:若相同 checksum 的文件已存在,直接返回已有记录,跳过上传。
/// </summary>
[HttpPost("simple-upload")]
[UnitOfWork(typeof(FileDbContext))]
public async Task<IActionResult> SimpleUpload([FromForm] IFormFile file, [FromForm] bool isPublic)
{
if (file == null || file.Length == 0)
{
return BadRequest();
}
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
await using var stream = file.OpenReadStream();
var res = await service.SimpleUploadAsync(new SimpleUploadCommand(
OwnerId: Guid.Parse(userId),
FileName: file.FileName,
ContentType: file.ContentType,
FileSize: file.Length,
Content: stream,
IsPublic: isPublic));
return Ok(res);
}
/// <summary>
/// 获取文件信息(含直链 Url;私有文件 Url 为 null)。
/// </summary>
[HttpGet("{id}")]
public async Task<IActionResult> Get(Guid id)
{
var res = await service.GetFileInfoAsync(id);
return Ok(res);
}
/// <summary>
/// 鉴权下载文件内容(私有文件预览/下载走这里)。
/// </summary>
[HttpGet("{id}/content")]
public async Task<IActionResult> GetContent(Guid id)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var res = await service.OpenDownloadAsync(id, Guid.Parse(userId));
if (res.Data == null)
{
return NotFound(res);
}
Response.Headers["Cache-Control"] = "private,max-age=86400";
return File(res.Data.Content, res.Data.ContentType);
}
}
}
@@ -36,6 +36,14 @@ namespace FileService.WebApi.Controllers.FileTask
return Ok(res);
}
[HttpGet("progress")]
public async Task<IActionResult> Progress(string sessionId)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var res = await service.GetProgressAsync(sessionId, Guid.Parse(userId));
return Ok(res);
}
[HttpGet("Getuploadurl")]
public async Task<IActionResult> GetUploadUrl(string sessionId, int partNum)
{
+23
View File
@@ -0,0 +1,23 @@
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
# 清除本地 Windows obj 中的 NuGet fallback 路径引用,让 publish 在 Linux 下重新 restore
RUN find . -type d \( -name obj -o -name bin \) -prune -exec rm -rf {} + 2>/dev/null || true
RUN dotnet publish FileService.WebApi/FileService.WebApi.csproj \
-c Release \
-o /app/publish
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "FileService.WebApi.dll"]
+29
View File
@@ -1,5 +1,6 @@
using IM.InitCommon;
using Microsoft.Extensions.FileProviders;
namespace FileService.WebApi
{
@@ -29,10 +30,38 @@ namespace FileService.WebApi
app.UseAppDefault();
// 仅 FileService 暴露公开桶目录为静态直链,不动共享 UseAppDefault
UsePublicStaticFiles(app);
app.MapControllers();
app.Run();
}
private static void UsePublicStaticFiles(WebApplication app)
{
var storage = app.Configuration.GetSection("StorageOptions").Get<StorageOptions>();
if (storage?.Providers == null ||
!storage.Providers.TryGetValue(storage.DefaultProviderCode, out var provider))
{
return;
}
if (string.IsNullOrEmpty(provider.LocalRootPath) || string.IsNullOrEmpty(provider.PublicBucket))
{
return;
}
var publicPath = Path.Combine(provider.LocalRootPath, provider.PublicBucket);
Directory.CreateDirectory(publicPath);
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(publicPath),
RequestPath = "/static",
OnPrepareResponse = ctx =>
ctx.Context.Response.Headers["Cache-Control"] = "public,max-age=2592000"
});
}
}
}