173 lines
5.5 KiB
C#
173 lines
5.5 KiB
C#
using Blahblah.FlowerStory.Server.Data;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Net;
|
|
|
|
namespace Blahblah.FlowerStory.Server.Controller;
|
|
|
|
/// <summary>
|
|
/// 图片相关服务
|
|
/// </summary>
|
|
[Route("photo")]
|
|
public class ImageController(FlowerDatabase database, ILogger<ImageController>? logger = null) : BaseController<ImageController>(database, logger)
|
|
{
|
|
static byte[]? emptyAvatar;
|
|
|
|
static byte[] EmptyAvatar => emptyAvatar ??= GetEmbeddedData("image.avatar.jpg");
|
|
|
|
/// <summary>
|
|
/// 请求自己的头像
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 请求示例:
|
|
///
|
|
/// GET /photo/my_avatar
|
|
/// Authorization: authorization id
|
|
///
|
|
/// </remarks>
|
|
/// <returns>认证通过则显示自己的头像</returns>
|
|
/// <response code="200">返回头像</response>
|
|
/// <response code="401">认证失败</response>
|
|
[Route("my_avatar", Name = "getMyAvatar")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[HttpGet]
|
|
public ActionResult GetMyAvatar()
|
|
{
|
|
var (result, token) = CheckToken();
|
|
if (result != null)
|
|
{
|
|
return result;
|
|
}
|
|
if (token == null)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
var avatar = QueryUserAvatar(token.UserId);
|
|
if (avatar?.Length > 0)
|
|
{
|
|
return File(avatar, "image/jpeg");
|
|
}
|
|
return File(EmptyAvatar, "image/jpeg");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 请求用户头像
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 请求示例:
|
|
///
|
|
/// GET /photo/avatar/2.jpg
|
|
///
|
|
/// </remarks>
|
|
/// <param name="uid">用户唯一 id</param>
|
|
/// <returns>认证通过则显示用户头像</returns>
|
|
/// <response code="200">返回头像</response>
|
|
/// <response code="401">认证失败</response>
|
|
[Route("avatar/{uid}.jpg", Name = "getAvatar")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[HttpGet]
|
|
public ActionResult GetAvatar([Required] int uid)
|
|
{
|
|
//var (result, token) = CheckToken();
|
|
//if (result != null)
|
|
//{
|
|
// return result;
|
|
//}
|
|
//if (token == null)
|
|
//{
|
|
// return Unauthorized();
|
|
//}
|
|
var avatar = QueryUserAvatar(uid);
|
|
if (avatar?.Length > 0)
|
|
{
|
|
return File(avatar, "image/jpeg");
|
|
}
|
|
return File(EmptyAvatar, "image/jpeg");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 请求花草照片
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 请求示例:
|
|
///
|
|
/// GET /photo/flower/1/test.jpg
|
|
///
|
|
/// </remarks>
|
|
/// <param name="fid">花草唯一 id</param>
|
|
/// <param name="name">照片名称</param>
|
|
/// <param name="thumb">是否为缩略图</param>
|
|
/// <returns>认证通过则显示花草照片</returns>
|
|
/// <response code="200">返回花草照片</response>
|
|
/// <response code="401">认证失败</response>
|
|
/// <response code="404">未找到花草照片</response>
|
|
[Route("flower/{fid}/{name}", Name = "getFlowerPhoto")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
[HttpGet]
|
|
public async Task<ActionResult> GetFlowerPhoto([Required] int fid, [Required] string name, [FromQuery] string? thumb = null)
|
|
{
|
|
//var (result, token) = CheckToken();
|
|
//if (result != null)
|
|
//{
|
|
// return result;
|
|
//}
|
|
//if (token == null)
|
|
//{
|
|
// return Unauthorized();
|
|
//}
|
|
|
|
#if PRODUCTION
|
|
var referrer = Request.Headers.Referer.ToString();
|
|
if (string.IsNullOrEmpty(referrer))
|
|
{
|
|
return BadRequest();
|
|
}
|
|
if (!referrer.StartsWith("https://app.tsanie.org"))
|
|
{
|
|
return Forbid();
|
|
}
|
|
#endif
|
|
var filename = WebUtility.UrlEncode(name);
|
|
var directory = Path.Combine(Program.DataPath, "uploads", fid.ToString());
|
|
var original = Path.Combine(directory, filename);
|
|
var thumbnail = Path.Combine(directory, $"{filename}.thumb");
|
|
if (!string.IsNullOrEmpty(thumb))
|
|
{
|
|
if (System.IO.File.Exists(thumbnail))
|
|
{
|
|
var thumbnailData = await System.IO.File.ReadAllBytesAsync(thumbnail);
|
|
return File(thumbnailData, "image/jpeg");
|
|
}
|
|
else if (System.IO.File.Exists(original))
|
|
{
|
|
try
|
|
{
|
|
var originalData = await System.IO.File.ReadAllBytesAsync(original);
|
|
var thumbnailData = CreateThumbnail(originalData);
|
|
await System.IO.File.WriteAllBytesAsync(thumbnail, thumbnailData);
|
|
return File(thumbnailData, "image/jpeg");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogWarning(ex, "failed to create thumbnail for flower: {fid}, name: {name}, error: {message}", fid, name, ex.Message);
|
|
}
|
|
}
|
|
return NotFound();
|
|
}
|
|
if (System.IO.File.Exists(original))
|
|
{
|
|
var data = await System.IO.File.ReadAllBytesAsync(original);
|
|
return Path.GetExtension(original).ToLower() switch
|
|
{
|
|
".png" => File(data, "image/png"),
|
|
_ => File(data, "image/jpeg"),
|
|
};
|
|
}
|
|
return NotFound();
|
|
}
|
|
}
|