网站首页 网站源码
namespace Dpz.Core.WebApi.Controllers;
/// <summary>
/// 图片管理
/// </summary>
[ApiController, Route("api/[controller]"), Authorize(Policy = "System")]
public class PictureController(
IPictureRecordService pictureRecordService,
IObjectStorageOperation objectStorageService,
ILogger<PictureController> logger
) : ControllerBase
{
/// <summary>
/// 图片列表
/// </summary>
/// <returns></returns>
[HttpGet]
[ProducesResponseType<List<VmPictureRecord>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetPictures([FromQuery] PictureQueryParameterDto parameter)
{
var query = new VmPictureQuery
{
Tag = parameter.Tag,
Description = parameter.Description,
Type = parameter.Type
};
var list = await pictureRecordService.GetPagesAsync(
[parameter.Tag],
parameter.Description,
parameter.PageIndex,
parameter.PageSize
);
list.AddPaginationMetadata(Response.Headers);
return Ok(list);
}
/// <summary>
/// 上传图片
/// </summary>
/// <returns></returns>
[HttpPost]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> CreatePicture([FromForm] PictureCreateDto model)
{
if (model.Image.Length <= 0 || !model.Image.ContentType.Contains("image"))
{
return BadRequest("please select image to upload");
}
model.Tags = model
.Tags?.Select(x => x?.Trim())
.Where(x => !string.IsNullOrEmpty(x))
.ToList();
var userInfo = User.GetIdentity();
using var memoryStream = new MemoryStream();
await model.Image.CopyToAsync(memoryStream);
var bytes = memoryStream.ToArray();
var path = new[] { "images", "album", DateTime.Now.ToString("yyyy-MM") };
var filename = $"{ObjectId.GenerateNewId()}.{await GetImageFormatAsync(bytes) ?? "jpg"}";
var result = await objectStorageService.UploadAsync(
model.Image.OpenReadStream(),
path,
filename
);
var pictureRecord = new VmPictureRecord
{
Creator = userInfo,
UploadTime = DateTime.Now,
Tags = model.Tags,
Description = model.Description,
Category = PictureCategory.Album,
AccessUrl = result.AccessUrl,
Length = bytes.Length,
ObjectStorageUploadTime = DateTime.Now,
Md5 = CalculateMd5(bytes),
Width = result.Width,
Height = result.Height,
};
await pictureRecordService.CreateRecordAsync(pictureRecord);
return NoContent();
}
[NonAction]
private static string CalculateMd5(byte[] bytes)
{
using var md5 = MD5.Create();
var hash = md5.ComputeHash(bytes);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
[NonAction]
private async Task<string> GetImageFormatAsync(byte[] bytes)
{
try
{
using var stream = new MemoryStream(bytes);
using var image = await Image.LoadAsync(stream);
return image.Metadata.DecodedImageFormat?.FileExtensions.FirstOrDefault() ?? "jpg";
}
catch (Exception e)
{
logger.LogError(e, "get image format fail");
return null;
}
}
/// <summary>
/// 修改图像、图像信息
/// </summary>
/// <returns></returns>
[HttpPatch]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> EditPicture([FromBody] PictureEditDto model)
{
model.Tags = model
.Tags?.Select(x => x?.Trim())
.Where(x => !string.IsNullOrEmpty(x))
.ToList();
var recordChange = new VmPictureRecordChange
{
Category = PictureCategory.Album,
Description = model.Description,
Tags = model.Tags,
Id = model.Id
};
await pictureRecordService.ChangeInformationAsync(recordChange);
return NoContent();
}
/// <summary>
/// 获取图片信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}")]
[ProducesResponseType<VmPictureRecord>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetPicture(string id)
{
var picture = await pictureRecordService.GetPictureRecordAsync(id);
if (picture == null)
return NotFound();
return Ok(picture);
}
/// <summary>
/// 删除图像
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(string id)
{
var pictureRecord = await pictureRecordService.GetPictureRecordAsync(id);
if (pictureRecord == null)
return NotFound();
await pictureRecordService.DeleteAsync(id);
await objectStorageService.DeleteAsync(pictureRecord.AccessUrl);
return NoContent();
}
/// <summary>
/// 获取所有标签
/// </summary>
/// <returns></returns>
[HttpGet("tags")]
[ProducesResponseType<List<string>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetPictureTags()
{
var tags = await pictureRecordService.GetTagsAsync();
return Ok(tags);
}
}
上述代码是一个 ASP.NET Core Web API 控制器,名为 PictureController
,用于管理图片的上传、查询、编辑和删除等操作。以下是对代码中各个部分功能的详细解释:
[ApiController, Route("api/[controller]"), Authorize(Policy = "System")]
public class PictureController : ControllerBase
ApiController
:标记该类为 API 控制器,启用一些特性,如自动模型验证。Route("api/[controller]")
:定义路由模板,[controller]
会被替换为控制器的名称(即 Picture
)。Authorize(Policy = "System")
:要求用户必须通过授权策略 "System" 才能访问该控制器中的方法。public PictureController(IPictureRecordService pictureRecordService, IObjectStorageOperation objectStorageService, ILogger<PictureController> logger)
IPictureRecordService
:用于处理图片记录的服务。IObjectStorageOperation
:用于处理对象存储操作的服务(如上传和删除图片)。ILogger<PictureController>
:用于记录日志。[HttpGet]
public async Task<IActionResult> GetPictures([FromQuery] PictureQueryParameterDto parameter)
PictureQueryParameterDto
,用于过滤图片。pictureRecordService.GetPagesAsync
获取分页的图片记录,并返回结果。[HttpPost]
public async Task<IActionResult> CreatePicture([FromForm] PictureCreateDto model)
private static string CalculateMd5(byte[] bytes)
private async Task<string> GetImageFormatAsync(byte[] bytes)
[HttpPatch]
public async Task<IActionResult> EditPicture([FromBody] PictureEditDto model)
pictureRecordService.ChangeInformationAsync
更新记录。[HttpGet("{id}")]
public async Task<IActionResult> GetPicture(string id)
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(string id)
[HttpGet("tags")]
public async Task<IActionResult> GetPictureTags()
这个控制器提供了一整套 RESTful API 接口,用于管理图片的生命周期,包括上传、查询、编辑、删除和获取标签等功能。通过依赖注入的方式,控制器能够与服务层进行交互,处理业务逻辑。