Browse Source

优化置顶文章排序规则

懒得勤快 1 year ago
parent
commit
6b270e36e3
1 changed files with 288 additions and 288 deletions
  1. 288 288
      src/Masuit.MyBlogs.Core/Controllers/HomeController.cs

+ 288 - 288
src/Masuit.MyBlogs.Core/Controllers/HomeController.cs

@@ -24,315 +24,315 @@ namespace Masuit.MyBlogs.Core.Controllers;
 /// </summary>
 public sealed class HomeController : BaseController
 {
-	/// <summary>
-	/// 文章
-	/// </summary>
-	public IPostService PostService { get; set; }
+    /// <summary>
+    /// 文章
+    /// </summary>
+    public IPostService PostService { get; set; }
 
-	/// <summary>
-	/// 分类
-	/// </summary>
-	public ICategoryService CategoryService { get; set; }
+    /// <summary>
+    /// 分类
+    /// </summary>
+    public ICategoryService CategoryService { get; set; }
 
-	/// <summary>
-	/// 网站公告
-	/// </summary>
-	public INoticeService NoticeService { get; set; }
+    /// <summary>
+    /// 网站公告
+    /// </summary>
+    public INoticeService NoticeService { get; set; }
 
-	/// <summary>
-	/// 首页
-	/// </summary>
-	/// <returns></returns>
-	[ResponseCache(Duration = 600, VaryByHeader = nameof(HeaderNames.Cookie))]
-	public async Task<ActionResult> Index([FromServices] IFastShareService fastShareService)
-	{
-		var banners = AdsService.GetsByWeightedPrice(8, AdvertiseType.Banner, Request.Location()).OrderByRandom().ToPooledListScope();
-		var fastShares = fastShareService.GetAllFromCache(s => s.Sort);
-		var postsQuery = PostService.GetQuery(PostBaseWhere()); //准备文章的查询
-		var posts = await postsQuery.Where(p => !p.IsFixedTop).OrderBy(OrderBy.ModifyDate.GetDisplay() + " desc").ToPagedListAsync<Post, PostDto>(1, 15, MapperConfig);
-		posts.Data.InsertRange(0, postsQuery.Where(p => p.IsFixedTop).OrderByDescending(p => p.ModifyDate).ProjectTo<PostDto>(MapperConfig).Cacheable().ToPooledListScope());
-		var viewModel = GetIndexPageViewModel();
-		viewModel.Banner = banners;
-		viewModel.Posts = posts;
-		ViewBag.FastShare = fastShares;
-		viewModel.PageParams = new Pagination(1, 15, posts.TotalCount, OrderBy.ModifyDate);
-		viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
-		viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
-		PostService.SolvePostsCategory(posts.Data);
-		foreach (var item in posts.Data)
-		{
-			item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-		}
+    /// <summary>
+    /// 首页
+    /// </summary>
+    /// <returns></returns>
+    [ResponseCache(Duration = 600, VaryByHeader = nameof(HeaderNames.Cookie))]
+    public async Task<ActionResult> Index([FromServices] IFastShareService fastShareService)
+    {
+        var banners = AdsService.GetsByWeightedPrice(8, AdvertiseType.Banner, Request.Location()).OrderByRandom().ToPooledListScope();
+        var fastShares = fastShareService.GetAllFromCache(s => s.Sort);
+        var postsQuery = PostService.GetQuery(PostBaseWhere()); //准备文章的查询
+        var posts = await postsQuery.Where(p => !p.IsFixedTop).OrderBy(OrderBy.ModifyDate.GetDisplay() + " desc").ToPagedListAsync<Post, PostDto>(1, 15, MapperConfig);
+        posts.Data.InsertRange(0, postsQuery.Where(p => p.IsFixedTop).ProjectTo<PostDto>(MapperConfig).Cacheable().ToPooledListScope().OrderByRandom());
+        var viewModel = GetIndexPageViewModel();
+        viewModel.Banner = banners;
+        viewModel.Posts = posts;
+        ViewBag.FastShare = fastShares;
+        viewModel.PageParams = new Pagination(1, 15, posts.TotalCount, OrderBy.ModifyDate);
+        viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
+        viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+        PostService.SolvePostsCategory(posts.Data);
+        foreach (var item in posts.Data)
+        {
+            item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
+        }
 
-		return View(viewModel);
-	}
+        return View(viewModel);
+    }
 
-	/// <summary>
-	/// 文章列表页
-	/// </summary>
-	/// <param name="page"></param>
-	/// <param name="size"></param>
-	/// <param name="orderBy"></param>
-	/// <returns></returns>
-	[Route("posts"), Route("p", Order = 1), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
-	public async Task<ActionResult> Post([Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
-	{
-		page = Math.Max(1, page);
-		var viewModel = GetIndexPageViewModel();
-		var postsQuery = PostService.GetQuery(PostBaseWhere()); //准备文章的查询
-		var h24 = DateTime.Today.AddDays(-1);
-		var posts = orderBy switch
-		{
-			OrderBy.Trending => await postsQuery.Where(p => !p.IsFixedTop).OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(t => t.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
-			_ => await postsQuery.Where(p => !p.IsFixedTop).OrderBy((orderBy ?? OrderBy.ModifyDate).GetDisplay() + " desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
-		};
-		if (page == 1)
-		{
-			posts.Data.InsertRange(0, postsQuery.Where(p => p.IsFixedTop).OrderByDescending(p => p.ModifyDate).ProjectTo<PostDto>(MapperConfig));
-		}
+    /// <summary>
+    /// 文章列表页
+    /// </summary>
+    /// <param name="page"></param>
+    /// <param name="size"></param>
+    /// <param name="orderBy"></param>
+    /// <returns></returns>
+    [Route("posts"), Route("p", Order = 1), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
+    public async Task<ActionResult> Post([Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
+    {
+        page = Math.Max(1, page);
+        var viewModel = GetIndexPageViewModel();
+        var postsQuery = PostService.GetQuery(PostBaseWhere()); //准备文章的查询
+        var h24 = DateTime.Today.AddDays(-1);
+        var posts = orderBy switch
+        {
+            OrderBy.Trending => await postsQuery.Where(p => !p.IsFixedTop).OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(t => t.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
+            _ => await postsQuery.Where(p => !p.IsFixedTop).OrderBy((orderBy ?? OrderBy.ModifyDate).GetDisplay() + " desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
+        };
+        if (page == 1)
+        {
+            posts.Data.InsertRange(0, postsQuery.Where(p => p.IsFixedTop).ProjectTo<PostDto>(MapperConfig).ToPooledListScope().OrderByRandom());
+        }
 
-		viewModel.Posts = posts;
-		viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
-		viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
-		viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
-		PostService.SolvePostsCategory(posts.Data);
-		foreach (var item in posts.Data)
-		{
-			item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-		}
+        viewModel.Posts = posts;
+        viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
+        viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
+        viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+        PostService.SolvePostsCategory(posts.Data);
+        foreach (var item in posts.Data)
+        {
+            item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
+        }
 
-		return View(viewModel);
-	}
+        return View(viewModel);
+    }
 
-	/// <summary>
-	/// 标签文章页
-	/// </summary>
-	/// <param name="tag"></param>
-	/// <param name="page"></param>
-	/// <param name="size"></param>
-	/// <param name="orderBy"></param>
-	/// <returns></returns>
-	[Route("tag/{tag}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
-	public async Task<ActionResult> Tag(string tag, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
-	{
-		page = Math.Max(1, page);
-		if (string.IsNullOrWhiteSpace(tag))
-		{
-			throw new NotFoundException("");
-		}
+    /// <summary>
+    /// 标签文章页
+    /// </summary>
+    /// <param name="tag"></param>
+    /// <param name="page"></param>
+    /// <param name="size"></param>
+    /// <param name="orderBy"></param>
+    /// <returns></returns>
+    [Route("tag/{tag}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
+    public async Task<ActionResult> Tag(string tag, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
+    {
+        page = Math.Max(1, page);
+        if (string.IsNullOrWhiteSpace(tag))
+        {
+            throw new NotFoundException("");
+        }
 
-		var where = PostBaseWhere();
-		var queryable = PostService.GetQuery(tag.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(s => Regex.Escape(s.Trim())).Aggregate(where, (current, s) => current.And(p => Regex.IsMatch(p.Label, s, RegexOptions.IgnoreCase))));
-		var h24 = DateTime.Today.AddDays(-1);
-		var posts = orderBy switch
-		{
-			OrderBy.Trending => await queryable.OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
-			_ => await queryable.OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
-		};
-		var viewModel = GetIndexPageViewModel();
-		ViewBag.Tag = tag;
-		viewModel.Posts = posts;
-		viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
-		viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location(), keywords: tag);
-		viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), keywords: tag);
-		PostService.SolvePostsCategory(posts.Data);
-		foreach (var item in posts.Data)
-		{
-			item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-		}
+        var where = PostBaseWhere();
+        var queryable = PostService.GetQuery(tag.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(s => Regex.Escape(s.Trim())).Aggregate(where, (current, s) => current.And(p => Regex.IsMatch(p.Label, s, RegexOptions.IgnoreCase))));
+        var h24 = DateTime.Today.AddDays(-1);
+        var posts = orderBy switch
+        {
+            OrderBy.Trending => await queryable.OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
+            _ => await queryable.OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
+        };
+        var viewModel = GetIndexPageViewModel();
+        ViewBag.Tag = tag;
+        viewModel.Posts = posts;
+        viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
+        viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location(), keywords: tag);
+        viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), keywords: tag);
+        PostService.SolvePostsCategory(posts.Data);
+        foreach (var item in posts.Data)
+        {
+            item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
+        }
 
-		return View(viewModel);
-	}
+        return View(viewModel);
+    }
 
-	/// <summary>
-	/// 存档文章页
-	/// </summary>
-	/// <param name="yyyy"></param>
-	/// <param name="mm"></param>
-	/// <param name="dd"></param>
-	/// <param name="page"></param>
-	/// <param name="size"></param>
-	/// <param name="orderBy"></param>
-	/// <returns></returns>
-	[Route("{yyyy:int}/{mm:int}/{dd:int}/{mode}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
-	public async Task<ActionResult> Archieve([Range(2010, 2099)] int yyyy, [Range(1, 12)] int mm, [Range(1, 31)] int dd, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15, string mode = nameof(Models.Entity.Post.ModifyDate))
-	{
-		page = Math.Max(1, page);
-		if (!DateTime.TryParse(yyyy + "-" + mm + "-" + dd, out var date))
-		{
-			date = DateTime.Today;
-		}
+    /// <summary>
+    /// 存档文章页
+    /// </summary>
+    /// <param name="yyyy"></param>
+    /// <param name="mm"></param>
+    /// <param name="dd"></param>
+    /// <param name="page"></param>
+    /// <param name="size"></param>
+    /// <param name="orderBy"></param>
+    /// <returns></returns>
+    [Route("{yyyy:int}/{mm:int}/{dd:int}/{mode}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
+    public async Task<ActionResult> Archieve([Range(2010, 2099)] int yyyy, [Range(1, 12)] int mm, [Range(1, 31)] int dd, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15, string mode = nameof(Models.Entity.Post.ModifyDate))
+    {
+        page = Math.Max(1, page);
+        if (!DateTime.TryParse(yyyy + "-" + mm + "-" + dd, out var date))
+        {
+            date = DateTime.Today;
+        }
 
-		var where = mode switch
-		{
-			nameof(Models.Entity.Post.PostDate) => PostBaseWhere().And(p => p.PostDate.Date == date),
-			_ => PostBaseWhere().And(p => p.ModifyDate.Date == date),
-		};
-		var queryable = PostService.GetQuery(where);
-		var h24 = DateTime.Today.AddDays(-1);
-		var posts = orderBy switch
-		{
-			OrderBy.Trending => await queryable.OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
-			_ => await queryable.OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
-		};
-		var viewModel = GetIndexPageViewModel();
-		viewModel.Posts = posts;
-		viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
-		viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
-		viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
-		PostService.SolvePostsCategory(posts.Data);
-		foreach (var item in posts.Data)
-		{
-			item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-		}
+        var where = mode switch
+        {
+            nameof(Models.Entity.Post.PostDate) => PostBaseWhere().And(p => p.PostDate.Date == date),
+            _ => PostBaseWhere().And(p => p.ModifyDate.Date == date),
+        };
+        var queryable = PostService.GetQuery(where);
+        var h24 = DateTime.Today.AddDays(-1);
+        var posts = orderBy switch
+        {
+            OrderBy.Trending => await queryable.OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
+            _ => await queryable.OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
+        };
+        var viewModel = GetIndexPageViewModel();
+        viewModel.Posts = posts;
+        viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
+        viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
+        viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+        PostService.SolvePostsCategory(posts.Data);
+        foreach (var item in posts.Data)
+        {
+            item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
+        }
 
-		return View(viewModel);
-	}
+        return View(viewModel);
+    }
 
-	/// <summary>
-	/// 作者文章页
-	/// </summary>
-	/// <param name="author"></param>
-	/// <param name="page"></param>
-	/// <param name="size"></param>
-	/// <param name="orderBy"></param>
-	/// <returns></returns>
-	[Route("author/{author}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
-	public async Task<ActionResult> Author(string author, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
-	{
-		page = Math.Max(1, page);
-		Expression<Func<Post, bool>> where = PostBaseWhere().And(p => p.Author.Equals(author) || p.Modifier.Equals(author) || p.Email.Equals(author) || p.PostHistoryVersion.Any(v => v.Modifier.Equals(author) || v.ModifierEmail.Equals(author)));
-		var h24 = DateTime.Today.AddDays(-1);
-		var posts = orderBy switch
-		{
-			OrderBy.Trending => await PostService.GetQuery(where).OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
-			_ => await PostService.GetQuery(where).OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
-		};
-		var viewModel = GetIndexPageViewModel();
-		ViewBag.Author = author;
-		viewModel.Posts = posts;
-		viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
-		viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
-		viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
-		PostService.SolvePostsCategory(posts.Data);
-		foreach (var item in posts.Data)
-		{
-			item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-		}
+    /// <summary>
+    /// 作者文章页
+    /// </summary>
+    /// <param name="author"></param>
+    /// <param name="page"></param>
+    /// <param name="size"></param>
+    /// <param name="orderBy"></param>
+    /// <returns></returns>
+    [Route("author/{author}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
+    public async Task<ActionResult> Author(string author, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
+    {
+        page = Math.Max(1, page);
+        Expression<Func<Post, bool>> where = PostBaseWhere().And(p => p.Author.Equals(author) || p.Modifier.Equals(author) || p.Email.Equals(author) || p.PostHistoryVersion.Any(v => v.Modifier.Equals(author) || v.ModifierEmail.Equals(author)));
+        var h24 = DateTime.Today.AddDays(-1);
+        var posts = orderBy switch
+        {
+            OrderBy.Trending => await PostService.GetQuery(where).OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
+            _ => await PostService.GetQuery(where).OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
+        };
+        var viewModel = GetIndexPageViewModel();
+        ViewBag.Author = author;
+        viewModel.Posts = posts;
+        viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
+        viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
+        viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+        PostService.SolvePostsCategory(posts.Data);
+        foreach (var item in posts.Data)
+        {
+            item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
+        }
 
-		return View(viewModel);
-	}
+        return View(viewModel);
+    }
 
-	/// <summary>
-	/// 分类文章页
-	/// </summary>
-	/// <param name="id"></param>
-	/// <param name="page"></param>
-	/// <param name="size"></param>
-	/// <param name="orderBy"></param>
-	/// <returns></returns>
-	[Route("cat/{id:int}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
-	public async Task<ActionResult> Category(int id, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
-	{
-		page = Math.Max(1, page);
-		var cat = await CategoryService.GetByIdAsync(id) ?? throw new NotFoundException("文章分类未找到");
-		var cids = cat.Flatten().Select(c => c.Id).ToArray();
-		var h24 = DateTime.Today.AddDays(-1);
-		var posts = orderBy switch
-		{
-			OrderBy.Trending => await PostService.GetQuery(PostBaseWhere().And(p => cids.Contains(p.CategoryId))).OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
-			_ => await PostService.GetQuery(PostBaseWhere().And(p => cids.Contains(p.CategoryId))).OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
-		};
-		var viewModel = GetIndexPageViewModel();
-		viewModel.Posts = posts;
-		ViewBag.Category = cat;
-		viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
-		viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location(), id);
-		viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), id);
-		PostService.SolvePostsCategory(posts.Data);
-		foreach (var item in posts.Data)
-		{
-			item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-		}
+    /// <summary>
+    /// 分类文章页
+    /// </summary>
+    /// <param name="id"></param>
+    /// <param name="page"></param>
+    /// <param name="size"></param>
+    /// <param name="orderBy"></param>
+    /// <returns></returns>
+    [Route("cat/{id:int}"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "page", "size", "orderBy" }, VaryByHeader = nameof(HeaderNames.Cookie))]
+    public async Task<ActionResult> Category(int id, [Optional] OrderBy? orderBy, int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
+    {
+        page = Math.Max(1, page);
+        var cat = await CategoryService.GetByIdAsync(id) ?? throw new NotFoundException("文章分类未找到");
+        var cids = cat.Flatten().Select(c => c.Id).ToArray();
+        var h24 = DateTime.Today.AddDays(-1);
+        var posts = orderBy switch
+        {
+            OrderBy.Trending => await PostService.GetQuery(PostBaseWhere().And(p => cids.Contains(p.CategoryId))).OrderByDescending(p => p.PostVisitRecordStats.Where(e => e.Date >= h24).Sum(e => e.Count)).ToPagedListAsync<Post, PostDto>(page, size, MapperConfig),
+            _ => await PostService.GetQuery(PostBaseWhere().And(p => cids.Contains(p.CategoryId))).OrderBy($"{nameof(PostDto.IsFixedTop)} desc,{(orderBy ?? OrderBy.ModifyDate).GetDisplay()} desc").ToPagedListAsync<Post, PostDto>(page, size, MapperConfig)
+        };
+        var viewModel = GetIndexPageViewModel();
+        viewModel.Posts = posts;
+        ViewBag.Category = cat;
+        viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
+        viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location(), id);
+        viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), id);
+        PostService.SolvePostsCategory(posts.Data);
+        foreach (var item in posts.Data)
+        {
+            item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
+        }
 
-		return View(viewModel);
-	}
+        return View(viewModel);
+    }
 
-	/// <summary>
-	/// 切换语言
-	/// </summary>
-	/// <param name="lang"></param>
-	/// <returns></returns>
-	[Route("lang/{lang}")]
-	public ActionResult SetLang(string lang)
-	{
-		Response.Cookies.Append("lang", lang, new CookieOptions()
-		{
-			Expires = DateTime.Now.AddYears(1),
-		});
-		var referer = Request.Headers[HeaderNames.Referer].ToString();
-		return Redirect(string.IsNullOrEmpty(referer) ? "/" : referer);
-	}
+    /// <summary>
+    /// 切换语言
+    /// </summary>
+    /// <param name="lang"></param>
+    /// <returns></returns>
+    [Route("lang/{lang}")]
+    public ActionResult SetLang(string lang)
+    {
+        Response.Cookies.Append("lang", lang, new CookieOptions()
+        {
+            Expires = DateTime.Now.AddYears(1),
+        });
+        var referer = Request.Headers[HeaderNames.Referer].ToString();
+        return Redirect(string.IsNullOrEmpty(referer) ? "/" : referer);
+    }
 
-	/// <summary>
-	/// 站点地图
-	/// </summary>
-	/// <param name="env"></param>
-	/// <param name="ext"></param>
-	/// <returns></returns>
-	[HttpGet("/sitemaps.{ext}")]
-	public async Task<ActionResult> Sitemap([FromServices] IWebHostEnvironment env, string ext)
-	{
-		var sitemap = Path.Combine(env.WebRootPath, "sitemap." + ext);
-		if (System.IO.File.Exists(sitemap))
-		{
-			var fs = new FileInfo(sitemap).ShareReadWrite();
-			switch (ext)
-			{
-				case "txt":
-					return Content((await fs.ReadAllLinesAsync(Encoding.UTF8)).Select(s => Request.Scheme + "://" + Request.Host.Host + new Uri(s).GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped)).Join("\r\n"), ContentType.Txt);
+    /// <summary>
+    /// 站点地图
+    /// </summary>
+    /// <param name="env"></param>
+    /// <param name="ext"></param>
+    /// <returns></returns>
+    [HttpGet("/sitemaps.{ext}")]
+    public async Task<ActionResult> Sitemap([FromServices] IWebHostEnvironment env, string ext)
+    {
+        var sitemap = Path.Combine(env.WebRootPath, "sitemap." + ext);
+        if (System.IO.File.Exists(sitemap))
+        {
+            var fs = new FileInfo(sitemap).ShareReadWrite();
+            switch (ext)
+            {
+                case "txt":
+                    return Content((await fs.ReadAllLinesAsync(Encoding.UTF8)).Select(s => Request.Scheme + "://" + Request.Host.Host + new Uri(s).GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped)).Join("\r\n"), ContentType.Txt);
 
-				case "html":
-					var context = BrowsingContext.New(Configuration.Default);
-					var doc = await context.OpenAsync(req => req.Content(fs.ReadAllText(Encoding.UTF8)));
-					foreach (var e in doc.Body.QuerySelectorAll("li a"))
-					{
-						e.SetAttribute("href", Request.Scheme + "://" + Request.Host.Host + new Uri(e.GetAttribute("href")).GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped));
-					}
+                case "html":
+                    var context = BrowsingContext.New(Configuration.Default);
+                    var doc = await context.OpenAsync(req => req.Content(fs.ReadAllText(Encoding.UTF8)));
+                    foreach (var e in doc.Body.QuerySelectorAll("li a"))
+                    {
+                        e.SetAttribute("href", Request.Scheme + "://" + Request.Host.Host + new Uri(e.GetAttribute("href")).GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped));
+                    }
 
-					return Content(doc.DocumentElement.OuterHtml, ContentType.Html);
-			}
-			return File("/sitemap." + ext, new MimeMapper().GetMimeFromExtension("." + ext));
-		}
+                    return Content(doc.DocumentElement.OuterHtml, ContentType.Html);
+            }
+            return File("/sitemap." + ext, new MimeMapper().GetMimeFromExtension("." + ext));
+        }
 
-		return NotFound();
-	}
+        return NotFound();
+    }
 
-	/// <summary>
-	/// 获取页面视图模型
-	/// </summary>
-	/// <returns></returns>
-	private HomePageViewModel GetIndexPageViewModel()
-	{
-		var postsQuery = PostService.GetQuery<PostDto>(PostBaseWhere()); //准备文章的查询
-		var notices = NoticeService.GetPagesFromCache<DateTime, NoticeDto>(1, 5, n => n.NoticeStatus == NoticeStatus.Normal, n => n.ModifyDate, false); //加载前5条公告
-		var cats = CategoryService.GetQuery(c => c.Status == Status.Available && c.Post.Count > 0).Include(c => c.Parent).OrderBy(c => c.Name).ThenBy(c => c.Path).AsNoTracking().Cacheable().ToPooledListScope(); //加载分类目录
-		var hotSearches = RedisHelper.Get<List<KeywordsRank>>("SearchRank:Week").AsNotNull().Take(10).ToPooledListScope(); //热词统计
-		var hot5Post = postsQuery.OrderBy((new Random().Next() % 3) switch
-		{
-			1 => nameof(OrderBy.VoteUpCount),
-			2 => nameof(OrderBy.AverageViewCount),
-			_ => nameof(OrderBy.TotalViewCount)
-		} + " desc").Skip(0).Take(5).Cacheable().ToPooledListScope(); //热门文章
-		var tagdic = PostService.GetTags().OrderByRandom().Take(20).ToDictionary(x => x.Key, x => Math.Min(x.Value + 12, 32)); //统计标签
-		return new HomePageViewModel
-		{
-			Categories = Mapper.Map<List<CategoryDto_P>>(cats.ToTree(c => c.Id, c => c.ParentId).Flatten()),
-			HotSearch = hotSearches,
-			Notices = notices.Data,
-			Tags = tagdic,
-			Top5Post = hot5Post,
-			PostsQueryable = postsQuery
-		};
-	}
+    /// <summary>
+    /// 获取页面视图模型
+    /// </summary>
+    /// <returns></returns>
+    private HomePageViewModel GetIndexPageViewModel()
+    {
+        var postsQuery = PostService.GetQuery<PostDto>(PostBaseWhere()); //准备文章的查询
+        var notices = NoticeService.GetPagesFromCache<DateTime, NoticeDto>(1, 5, n => n.NoticeStatus == NoticeStatus.Normal, n => n.ModifyDate, false); //加载前5条公告
+        var cats = CategoryService.GetQuery(c => c.Status == Status.Available && c.Post.Count > 0).Include(c => c.Parent).OrderBy(c => c.Name).ThenBy(c => c.Path).AsNoTracking().Cacheable().ToPooledListScope(); //加载分类目录
+        var hotSearches = RedisHelper.Get<List<KeywordsRank>>("SearchRank:Week").AsNotNull().Take(10).ToPooledListScope(); //热词统计
+        var hot5Post = postsQuery.OrderBy((new Random().Next() % 3) switch
+        {
+            1 => nameof(OrderBy.VoteUpCount),
+            2 => nameof(OrderBy.AverageViewCount),
+            _ => nameof(OrderBy.TotalViewCount)
+        } + " desc").Skip(0).Take(5).Cacheable().ToPooledListScope(); //热门文章
+        var tagdic = PostService.GetTags().OrderByRandom().Take(20).ToDictionary(x => x.Key, x => Math.Min(x.Value + 12, 32)); //统计标签
+        return new HomePageViewModel
+        {
+            Categories = Mapper.Map<List<CategoryDto_P>>(cats.ToTree(c => c.Id, c => c.ParentId).Flatten()),
+            HotSearch = hotSearches,
+            Notices = notices.Data,
+            Tags = tagdic,
+            Top5Post = hot5Post,
+            PostsQueryable = postsQuery
+        };
+    }
 }