网站首页 网站源码
using Dpz.Core.Hangfire;
using Hangfire;
namespace Dpz.Core.WebApi.Controllers;
/// <summary>
/// 评论
/// </summary>
[ApiController, Route("api/[controller]")]
public class CommentController(ICommentService commentService, ILogger<CommentController> logger)
: ControllerBase
{
/// <summary>
/// 获取评论
/// </summary>
/// <returns></returns>
[HttpGet, Authorize(Policy = "System")]
[ProducesResponseType<List<VmCommentFlat>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetComments([FromQuery] CommentQueryDto query)
{
var list = await commentService.GetPageAsync(
query.Node,
query.Relation,
query.PageIndex,
query.PageSize
);
list.AddPaginationMetadata(Response.Headers);
return Ok(list);
}
/// <summary>
/// 评论分页信息
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
[HttpGet("page")]
[ProducesResponseType<List<CommentViewModel>>(StatusCodes.Status200OK)]
public async Task<IActionResult> GetCommentPage([FromQuery] CommentPageQuery query)
{
var list = await commentService.GetCommentsAsync(
query.Node,
query.Relation,
query.PageIndex,
query.PageSize
);
list.AddPaginationMetadata(Response.Headers);
list.ForEach(ClearEmail);
return Ok(list);
}
private static void ClearEmail(CommentViewModel viewModel)
{
void SetEmail(VmCommenter commenter)
{
if (commenter is VmGuestCommenter guest)
{
guest.GenerateEmailMd5();
}
}
SetEmail(viewModel.Commenter);
if (viewModel.Children?.Count > 0)
{
viewModel.Children.ForEach(x =>
{
SetEmail(x.Commenter);
});
}
}
/// <summary>
/// 匿名发送评论
/// </summary>
/// <param name="comment"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
[HttpPost]
[ProducesResponseType<List<CommentViewModel>>(StatusCodes.Status200OK)]
public async Task<IActionResult> SendComment(
[FromBody] VmPublishComment comment,
[FromQuery] int pageSize = 5
)
{
if (pageSize > 100)
pageSize = 100;
await commentService.PublishCommentAsync(comment);
try
{
BackgroundJob.Enqueue<EmailSenderActivator>(x => x.SendMasterAsync(comment));
if (!string.IsNullOrEmpty(comment.ReplyId))
{
BackgroundJob.Enqueue<EmailSenderActivator>(x => x.SendCommenterAsync(comment));
}
}
catch (Exception e)
{
logger.LogError(e, "comment send email fail");
}
var list = await commentService.GetCommentsAsync(
comment.Node,
comment.Relation,
1,
pageSize
);
list.AddPaginationMetadata(Response.Headers);
list.ForEach(ClearEmail);
return Ok(list);
}
/// <summary>
/// 文章关联
/// </summary>
/// <returns></returns>
[HttpGet("relation/article"), Authorize(Policy = "System")]
[ProducesResponseType<Dictionary<string, string>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetArticleRelationTitle()
{
var dic = await commentService.HasCommentForArticleAsync();
return Ok(dic);
}
/// <summary>
/// 源码关联
/// </summary>
/// <returns></returns>
[HttpGet("relation/code"), Authorize(Policy = "System")]
[ProducesResponseType<Dictionary<string, string>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> CodeRelation()
{
var dic = await commentService.CodeRelationAsync();
return Ok(dic);
}
/// <summary>
/// 其他关联
/// </summary>
/// <returns></returns>
[HttpGet("relation/other"), Authorize(Policy = "System")]
[ProducesResponseType<Dictionary<string, string>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> OtherRelation()
{
var dic = await commentService.OtherRelationAsync();
return Ok(dic);
}
/// <summary>
/// 逻辑删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}"), Authorize(Policy = "System")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Delete(string id)
{
await commentService.ClearAsync(id);
return NoContent();
}
/// <summary>
/// 物理删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}/physical"), Authorize(Policy = "System")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> PhysicalDelete(string id)
{
await commentService.DeleteAsync(id);
return NoContent();
}
}
上述代码是一个 ASP.NET Core Web API 控制器,名为 CommentController
,用于处理与评论相关的操作。以下是对代码中各个部分的详细解释:
CommentController
继承自 ControllerBase
,并使用了 ApiController
特性,表示这是一个 API 控制器。[Route("api/[controller]")]
指定了控制器的基本路由为 api/comment
。ICommentService
和 ILogger<CommentController>
的实例,分别用于处理评论的业务逻辑和记录日志。GetComments
方法处理 GET 请求,返回指定节点和关系的评论列表。它使用 commentService.GetPageAsync
方法获取评论,并将分页元数据添加到响应头中。GetCommentPage
方法处理 GET 请求,返回评论的分页信息。它调用 commentService.GetCommentsAsync
获取评论,并清除评论者的电子邮件信息(通过 ClearEmail
方法)。ClearEmail
方法用于清除评论者的电子邮件信息,特别是对于匿名评论者(VmGuestCommenter
),通过生成其 MD5 哈希值来隐藏真实电子邮件。SendComment
方法处理 POST 请求,允许用户发送评论。它会调用 commentService.PublishCommentAsync
方法发布评论,并使用 Hangfire 的后台任务功能发送电子邮件通知(如发送给管理员或评论者)。pageSize
超过 100,则将其限制为 100。GetArticleRelationTitle
方法处理 GET 请求,返回与文章相关的评论信息。它调用 commentService.HasCommentForArticleAsync
方法获取相关数据。CodeRelation
方法处理 GET 请求,返回与代码相关的评论信息,调用 commentService.CodeRelationAsync
。OtherRelation
方法处理 GET 请求,返回与其他内容相关的评论信息,调用 commentService.OtherRelationAsync
。Delete
方法处理 DELETE 请求,允许用户逻辑删除指定 ID 的评论。它调用 commentService.ClearAsync
方法。PhysicalDelete
方法处理 DELETE 请求,允许用户物理删除指定 ID 的评论。它调用 commentService.DeleteAsync
方法。这个控制器提供了一系列与评论相关的 API 接口,包括获取评论、发送评论、获取评论的分页信息、处理评论的关联、以及删除评论的功能。它使用了依赖注入、异步编程和后台任务处理等现代开发技术,确保了代码的可维护性和扩展性。