网站首页 网站源码
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using Dpz.Core.Public.ViewModel.Request.HandlerRequest;
using Dpz.Core.Public.ViewModel.RequestEvent;
using Dpz.Core.Public.ViewModel.V4;
using Dpz.Core.Service.ObjectStorage.Services;
using Dpz.Core.Service.V4.Services;
using Dpz.Core.Web.Library.Api;
namespace Dpz.Core.Web.Controllers;
public partial class ArticleController(
IArticleService articleService,
IObjectStorageOperation objectStorageService,
IMediator mediator,
ILogger<ArticleController> logger
) : Controller
{
public async Task<IActionResult> Index(
[FromServices] IHomeCacheService cacheService,
string? tag = "",
[Range(10, 100)] int pageSize = 10,
int pageIndex = 1
)
{
if (!ModelState.IsValid)
{
return NotFound();
}
var tags = string.IsNullOrEmpty(tag) ? [] : new[] { tag };
this.SetTitle(string.IsNullOrEmpty(tag) ? "文章列表" : $"标签-{tag}-文章列表");
var list = await articleService.GetPagesAsync(pageIndex, pageSize, tags: tags);
if (Request.Headers["X-PJAX"] == "true" && Request.Query["_pjax"] == ".blog-main-left")
{
return PartialView("_ArticleListPartial", list);
}
var model = new ArticleIndexModel
{
LikeArticle = await cacheService.GetRandomArticlesAsync(),
List = list,
News = await cacheService.GetLatestArticlesAsync(),
Tags = await cacheService.GetArticleTagsAsync(),
};
return View(model);
}
public async Task<IActionResult> Read(string id = "", string text = "")
{
var article = await mediator.Send(new ArticleReadRequest { Id = id, Text = text });
if (article == null)
{
return NotFound();
}
this.SetTitle(article.Title);
var pageMetaPage = new VmPageMetadata
{
Description = ClearIntroductionRRegex().Replace(article.Introduction ?? "", ""),
Keywords = [article.Title],
Relations = ["Article", "Read", id],
};
ViewData["PageMetadata"] = pageMetaPage;
ViewData["Text"] = text;
return View(article);
}
[CheckAuthorize]
[HttpPost]
public async Task<IActionResult> Upload()
{
var file = Request.Form.Files.FirstOrDefault();
if (file is { Length: > 0 } && file.ContentType.Contains("image"))
{
//var userInfo = User.GetIdentity();
var path = new[] { "images", "article", DateTime.Now.ToString("yyyy-MM-dd") };
var fileName =
ObjectId.GenerateNewId() + file.FileName[file.FileName.LastIndexOf('.')..];
var result = await objectStorageService.UploadAsync(
file.OpenReadStream(),
path,
fileName
);
return Json(
new
{
success = 1,
message = "",
url = result.AccessUrl,
}
);
}
return Json(
new
{
success = 0,
message = "请选择一张图片!",
url = "",
}
);
}
[HttpGet, CheckAuthorize]
public async Task<IActionResult> Publish(string id = "")
{
VmArticle? model = null;
if (!string.IsNullOrEmpty(id))
{
model = await articleService.GetArticleAsync(id);
}
return View(model);
}
[HttpPost, CheckAuthorize]
public async Task<IActionResult> Publish(VmEditArticleV4 model, string newTag = "")
{
// if (string.IsNullOrEmpty(blog.BlogTitle))
// return Json(new ResultInfo("请填写标题!"));
// if (string.IsNullOrEmpty(blog.Introduction))
// return Json(new ResultInfo("请填写简介!"));
// if (string.IsNullOrEmpty(blog.BlogContents))
// return Json(new ResultInfo("请填写内容!"));
// if (string.IsNullOrEmpty(blog.Markdown))
// return Json(new ResultInfo("Markdown is null!"));
var userInfo = User.GetStrictIdentity();
// var editArticle = new VmEditArticle
// {
// Content = model.BlogContents,
// From = "用户前台",
// Introduction = model.Introduction,
// Markdown = model.Markdown,
// Tag = model.Tag,
// Title = model.BlogTitle
// };
var checkResult = ModelState.CheckModelState();
if (checkResult.IsValid)
{
return Json(new ResultInfo(string.Join("\n", checkResult.ErrorMessages)));
}
model.Tags ??= new List<string>();
if (!string.IsNullOrEmpty(newTag))
{
model.Tags.Add(newTag);
}
// 编辑
if (!string.IsNullOrEmpty(model.Id))
{
var article = await articleService.GetArticleAsync(model.Id);
if (article == null)
{
return Json(new ResultInfo("文章不存在"));
}
if (userInfo.Id != article.Author.Id)
{
return Json(new ResultInfo("不能修改别人发布的文章!"));
}
await articleService.EditArticleAsync(model, userInfo);
return Json(new ResultInfo(data: model.Id));
}
try
{
// 新增
var createdArticle = await articleService.CreateArticleAsync(model, userInfo);
return Json(new ResultInfo(data: createdArticle.Id));
}
catch (Exception ex)
{
logger.LogInformation(ex, "创建文章失败");
return Json(ResultInfo.ToFail(ex.Message));
}
}
[CheckAuthorize, HttpPost]
public async Task<IActionResult> Delete(string id)
{
var userInfo = User.GetStrictIdentity();
var article = await articleService.GetArticleAsync(id);
if (article == null)
{
return Json(new ResultInfo(false));
}
if (userInfo.Id != article.Author.Id)
{
return Json(new ResultInfo("不能删除别人发布的文章!"));
}
await articleService.DeleteAsync(id);
return Json(new ResultInfo(true));
}
public async Task<IActionResult> Preview(string id = "")
{
if (string.IsNullOrEmpty(id))
{
return NotFound();
}
var article = await articleService.GetArticleAsync(id);
if (article == null)
{
return NotFound();
}
return View(article);
}
/// <summary>
/// 获取我的文章
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="tag"></param>
/// <param name="title"></param>
/// <returns></returns>
[HttpGet, CheckAuthorize]
public async Task<IActionResult> MyArticle(
int pageIndex = 1,
int pageSize = 10,
string tag = "",
string title = ""
)
{
var userInfo = User.GetStrictIdentity();
var source = await articleService.GetPagesAsync(
pageIndex,
pageSize,
title,
userInfo.Id,
tag
);
var data = Pagination<VmArticleMini>.Create(source);
return Json(new ResultInfo(data));
}
[HttpGet]
public async Task<IActionResult> Detail(string id = "")
{
if (string.IsNullOrEmpty(id))
{
return Json(new ResultInfo("缺失参数"));
}
var article = await articleService.GetArticleAsync(id);
if (article == null)
{
return Json(new ResultInfo("该文章不存在"));
}
return Json(new ResultInfo(article));
}
[HttpGet]
public async Task<IActionResult> Tags()
{
var tags = await articleService.GetAllTagsAsync();
return Json(new ResultInfo(tags));
}
[HttpGet]
public async Task<IActionResult> Search(string? keyword = "")
{
var request = new ArticleSearchRequest { Keyword = keyword };
var searchResult = await mediator.Send(request);
ViewData["keyword"] = keyword;
this.SetTitle($"搜索 - {keyword}");
return View(searchResult);
}
[GeneratedRegex("<[^>]*>")]
private static partial Regex ClearIntroductionRRegex();
}
这段代码是一个 ASP.NET Core MVC 控制器的实现,主要用于处理与文章相关的操作。以下是对代码中各个部分功能的详细解释:
ArticleController
继承自 Controller
,并通过构造函数注入了三个服务:
IArticleService
:用于处理与文章相关的业务逻辑。IObjectStorageOperation
:用于处理对象存储(如文件上传)的操作。ILogger<ArticleController>
:用于记录日志。Index
方法)tag
:可选的标签,用于过滤文章。pageSize
:每页显示的文章数量,范围在 10 到 100 之间。pageIndex
:当前页码。articleService.GetPagesAsync
获取文章列表。Read
方法)articleService.GetArticleAsync
获取文章。Upload
方法)objectStorageService.UploadAsync
上传文件。Publish
方法)Delete
方法)articleService.DeleteAsync
删除文章,并返回操作结果。Preview
方法)MyArticle
方法)articleService.GetPagesAsync
获取用户的文章,并返回 JSON 响应。Detail
方法)Tags
方法)articleService.GetAllTagsAsync
获取标签,并返回 JSON 响应。Search
方法)articleService.SearchAsync
获取搜索结果,并返回视图。ClearIntroductionRRegex
)整体上,这个控制器提供了一个完整的文章管理功能,包括文章的创建、编辑、删除、查看、搜索和标签管理等。通过依赖注入的方式,控制器能够与服务层进行交互,处理业务逻辑,并返回相应的视图或 JSON 数据。