2026-05-22 17:01:49 +08:00
|
|
|
using FileShare_EFCore.Database;
|
|
|
|
|
using FileShare_Services.Core;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
|
|
|
|
|
namespace FileShare_Services.Services.FileLibrary
|
|
|
|
|
{
|
2026-05-22 17:11:11 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 缩略图流服务接口,根据缩略图 ID 返回文件流响应。
|
|
|
|
|
/// </summary>
|
2026-05-22 17:01:49 +08:00
|
|
|
public interface IThumbnailStreamService
|
|
|
|
|
{
|
2026-05-22 17:11:11 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 根据缩略图记录 ID 获取缩略图文件流响应。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">缩略图记录 ID。</param>
|
|
|
|
|
/// <param name="cancellationToken">取消令牌。</param>
|
|
|
|
|
/// <returns>文件流响应,不存在或文件丢失时返回 null。</returns>
|
2026-05-22 17:01:49 +08:00
|
|
|
Task<FileStreamResponse?> GetThumbnailAsync(int id, CancellationToken cancellationToken = default);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-22 17:11:11 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 缩略图流服务实现,从数据库查找缩略图映射并返回对应的物理文件流。
|
|
|
|
|
/// </summary>
|
2026-05-22 17:01:49 +08:00
|
|
|
public sealed class ThumbnailStreamService(AppDataContext db, IVideoThumbnailService thumbnails) : IThumbnailStreamService
|
|
|
|
|
{
|
2026-05-22 17:11:11 +08:00
|
|
|
/// <inheritdoc />
|
2026-05-22 17:01:49 +08:00
|
|
|
public async Task<FileStreamResponse?> GetThumbnailAsync(int id, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
var thumbnail = await db.ManagedThumbnailMaps
|
|
|
|
|
.AsNoTracking()
|
|
|
|
|
.FirstOrDefaultAsync(item => item.Id == id, cancellationToken);
|
|
|
|
|
|
|
|
|
|
if (thumbnail is null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var absolutePath = thumbnails.GetAbsolutePath(thumbnail.RelativePath);
|
|
|
|
|
if (!File.Exists(absolutePath))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new FileStreamResponse(
|
|
|
|
|
absolutePath,
|
|
|
|
|
Path.GetFileName(absolutePath),
|
|
|
|
|
thumbnail.ContentType,
|
|
|
|
|
File.GetLastWriteTimeUtc(absolutePath));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|