build-flow.api/src/BuildFlow.Host/Endpoints/file/Files/GetFilePreviewEndpoint.cs
xiangning 7e8623730b style(namespace): 统一命名空间大小写格式
- 将 file 目录下的命名空间从 BuildFlow.Host.Endpoints.file 统一为 BuildFlow.Host.Endpoints.File
- 将 im 目录下的命名空间从 BuildFlow.Host.Endpoints.im 统一为 BuildFlow.Host.Endpoints.IM
- 将 rag 目录下的命名空间从 BuildFlow.Host.Endpoints.rag 统一为 BuildFlow.Host.Endpoints.Rag
- 将 workflow 目录下的命名空间从 BuildFlow.Host.Endpoints.workflow 统一为 BuildFlow.Host.Endpoints.Workflow
- 将 platform 目录下的命名空间从 BuildFlow.Host.Endpoints.rag 统一为 BuildFlow.Host.Endpoints.Platform
- 修复了多个端点类的命名空间大小写不一致的问题
2026-07-03 17:13:17 +08:00

43 lines
1.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Net.Mime;
using File.Application.Features.Files.Queries;
using MediatR;
namespace BuildFlow.Host.Endpoints.File.Files;
/// <summary>
/// 文件预览端点。GET /api/files/preview,流式返回文件内容供内联展示(非下载)。
/// 后端从 S3 拉流透传,前端永远不接触 S3 URL 和凭据。
/// 鉴权:[Authorize] + JWT 中间件从 token query 参数读 JWT(img src / window.open 无法带 header)。
/// 该路径在 ApiResponseMiddlewareOptions.PassthroughPrefixes 注册,绕过响应包裹中间件的缓冲。
/// </summary>
[Authorize]
public class GetFilePreviewEndpoint(IMediator mediator) : Endpoint<GetFilePreviewRequest>
{
public override void Configure()
{
Get("/files/preview");
}
public override async Task HandleAsync(GetFilePreviewRequest req, CancellationToken ct)
{
// 复用下载查询(返回 Stream + ContentType + FileName)
var result = await mediator.Send(new DownloadFileQuery(req.ObjectKey), ct);
// inline = 浏览器内联展示(图片/PDF 直接渲染),而非触发下载
HttpContext.Response.ContentType = result.ContentType;
var disposition = new ContentDisposition { FileName = result.FileName, Inline = true };
HttpContext.Response.Headers.ContentDisposition = disposition.ToString();
// 流式透传:S3 流 → HTTP 响应体
try
{
await result.Stream.CopyToAsync(HttpContext.Response.Body, ct);
await HttpContext.Response.Body.FlushAsync(ct);
}
finally
{
await result.Stream.DisposeAsync();
}
}
}