feat: 数据看板视频封面接口 + Cookie 编辑弹窗全屏化
- Controllers/VideoController.cs:补回 upstream merge 时丢失的 GetVideoCover 接口(/api/video/cover/{id}),修复数据看板作者视频列表封面加载失败
- app/src/App.vue:.full-modal 改成 flex + height:100vh 全屏抽屉式布局,footer 常驻底部,body flex:1 承担滚动,解决大视口下 modal 底部大片空白
- app/src/pages/cok/CookieTable.vue:删除 .modal-scroll-body 的双层滚动 hack(max-height + overflow:scroll),让 .ant-modal-body 独家承担滚动,修复小屏下 Cookie 编辑弹窗内容滑不动
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -223,6 +223,75 @@ namespace dy.net.Controllers
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取视频封面图片
|
||||
/// </summary>
|
||||
/// <param name="id">视频ID</param>
|
||||
[Authorize]
|
||||
[HttpGet("cover/{id}")]
|
||||
public async Task<IActionResult> GetVideoCover([FromRoute] string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var video = await douyinVideoService.GetById(id);
|
||||
if (video == null)
|
||||
{
|
||||
return GetDefaultCoverImage();
|
||||
}
|
||||
|
||||
// 优先使用本地保存的封面
|
||||
if (!string.IsNullOrWhiteSpace(video.VideoCoverSavePath) && System.IO.File.Exists(video.VideoCoverSavePath))
|
||||
{
|
||||
var contentType = GetImageContentType(video.VideoCoverSavePath);
|
||||
var fileStream = System.IO.File.OpenRead(video.VideoCoverSavePath);
|
||||
return File(fileStream, contentType);
|
||||
}
|
||||
|
||||
// 本地封面缺失时回落到默认占位图
|
||||
return GetDefaultCoverImage();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Serilog.Log.Error(ex, $"获取视频封面失败: {id}");
|
||||
return GetDefaultCoverImage();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 默认封面占位图(SVG)
|
||||
/// </summary>
|
||||
private IActionResult GetDefaultCoverImage()
|
||||
{
|
||||
var svgContent = @"<svg width=""400"" height=""225"" xmlns=""http://www.w3.org/2000/svg"">
|
||||
<rect width=""400"" height=""225"" fill=""#f0f0f0""/>
|
||||
<text x=""50%"" y=""50%"" font-family=""Arial, sans-serif"" font-size=""16"" fill=""#999"" text-anchor=""middle"" dy="".3em"">暂无封面</text>
|
||||
</svg>";
|
||||
var svgBytes = System.Text.Encoding.UTF8.GetBytes(svgContent);
|
||||
return File(svgBytes, "image/svg+xml");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文件扩展名获取图片 Content-Type
|
||||
/// </summary>
|
||||
private string GetImageContentType(string fileName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
return "image/jpeg";
|
||||
}
|
||||
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||
return extension switch
|
||||
{
|
||||
".jpg" or ".jpeg" => "image/jpeg",
|
||||
".png" => "image/png",
|
||||
".gif" => "image/gif",
|
||||
".webp" => "image/webp",
|
||||
".svg" => "image/svg+xml",
|
||||
".bmp" => "image/bmp",
|
||||
_ => "image/jpeg"
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放视频
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user