using YD_Event.Application.Auth; using YD_Event.Application.Client.Dtos; using Furion.UnifyResult; namespace YD_Event.Application.Client; /// /// 博客文章 /// [ApiDescriptionSettings("博客前端接口")] [AllowAnonymous] public class ArticleController : IDynamicApiController { private readonly ISqlSugarRepository _tagsRepository; private readonly ISqlSugarRepository
_articleRepository; private readonly AuthManager _authManager; private readonly ISqlSugarRepository _categoryRepository; private readonly ISqlSugarRepository _authAccountRepository; private readonly ISqlSugarRepository _friendLinkRepository; public ArticleController(ISqlSugarRepository tagsRepository, ISqlSugarRepository
articleRepository, AuthManager authManager, ISqlSugarRepository categoryRepository, ISqlSugarRepository authAccountRepository, ISqlSugarRepository friendLinkRepository) { _tagsRepository = tagsRepository; _articleRepository = articleRepository; _authManager = authManager; _categoryRepository = categoryRepository; _authAccountRepository = authAccountRepository; _friendLinkRepository = friendLinkRepository; } /// /// 文章表查询 /// /// /// [HttpGet] public async Task> Get([FromQuery] ArticleListQueryInput dto) { if (dto.TagId.HasValue) { var tag = await _tagsRepository.AsQueryable().Where(x => x.Id == dto.TagId && x.Status == AvailabilityStatus.Enable).Select(x => new { x.Name, x.Cover }).FirstAsync(); UnifyContext.Fill(new { tag.Name, tag.Cover }); } if (dto.CategoryId.HasValue) { var category = await _categoryRepository.AsQueryable().Where(x => x.Id == dto.CategoryId && x.Status == AvailabilityStatus.Enable).Select(x => new { x.Name, x.Cover }).FirstAsync(); UnifyContext.Fill(new { category.Name, category.Cover }); } return await _articleRepository.AsQueryable().LeftJoin((article, ac) => article.Id == ac.ArticleId) .InnerJoin((article, ac, c) => ac.CategoryId == c.Id && c.Status == AvailabilityStatus.Enable) .Where(article => article.Status == AvailabilityStatus.Enable && article.PublishTime <= DateTime.Now) .Where(article => article.ExpiredTime == null || DateTime.Now < article.ExpiredTime) .WhereIF(dto.CategoryId.HasValue, (article, ac) => ac.CategoryId == dto.CategoryId) .WhereIF(!string.IsNullOrWhiteSpace(dto.Keyword), article => article.Title.Contains(dto.Keyword) || article.Summary.Contains(dto.Keyword) || article.Content.Contains(dto.Keyword)) .WhereIF(dto.TagId.HasValue, article => SqlFunc.Subqueryable().InnerJoin((tags, at) => tags.Id == at.TagId) .Where((tags, at) => tags.Status == AvailabilityStatus.Enable && at.ArticleId == article.Id && tags.Id == dto.TagId).Any()) .OrderByDescending(article => article.IsTop) .OrderBy(article => article.Sort) .OrderByDescending(article => article.PublishTime) .Select((article, ac, c) => new ArticleOutput { Id = article.Id, Title = article.Title, CategoryId = c.Id, CategoryName = c.Name, IsTop = article.IsTop, CreationType = article.CreationType, Summary = article.Summary, Cover = article.Cover, PublishTime = article.PublishTime, Tags = SqlFunc.Subqueryable().InnerJoin((tags, at) => tags.Id == at.TagId) .Where((tags, at) => tags.Status == AvailabilityStatus.Enable && at.ArticleId == article.Id) .ToList(tags => new TagsOutput { Id = tags.Id, Name = tags.Name, Color = tags.Color, Icon = tags.Icon }) }).ToPagedListAsync(dto); } /// /// 标签列表 /// /// [HttpGet] public async Task> Tags() { return await _tagsRepository.AsQueryable().Where(x => x.Status == AvailabilityStatus.Enable) .OrderBy(x => x.Sort) .Select(x => new TagsOutput { Id = x.Id, Icon = x.Icon, Name = x.Name, Color = x.Color }).ToListAsync(); } /// /// 文章栏目分类 /// /// [HttpGet] public async Task> Categories() { var queryable = _articleRepository.AsQueryable().Where(a => a.Status == AvailabilityStatus.Enable && a.PublishTime <= DateTime.Now && (a.ExpiredTime == null || DateTime.Now < a.ExpiredTime)); return await _categoryRepository.AsQueryable().LeftJoin((c, ac) => c.Id == ac.CategoryId) .LeftJoin(queryable, (c, ac, a) => ac.ArticleId == a.Id) .Where(c => c.Status == AvailabilityStatus.Enable) .WithCache() .GroupBy(c => new { c.Id, c.ParentId, c.Name, c.Sort }) .Select((c, ac, a) => new CategoryOutput { Id = c.Id, ParentId = c.ParentId, Sort = c.Sort, Name = c.Name, Total = SqlFunc.AggregateCount(a.Id) }) .MergeTable() .OrderBy(x => x.Sort) .OrderBy(x => x.ParentId) .OrderBy(x => x.Id) .ToListAsync(); } /// /// 文章信息统计 /// /// [HttpGet] public async Task Report() { //统计文章数量 int articleCount = await _articleRepository.AsQueryable() .Where(x => x.Status == AvailabilityStatus.Enable && (x.ExpiredTime == null || DateTime.Now < x.ExpiredTime)) .Where(x => x.PublishTime <= DateTime.Now) .CountAsync(); //标签统计 int tagCount = await _tagsRepository.AsQueryable().Where(x => x.Status == AvailabilityStatus.Enable).CountAsync(); //栏目统计 int categoryCount = await _categoryRepository.AsQueryable().Where(x => x.Status == AvailabilityStatus.Enable).CountAsync(); int userCount = await _authAccountRepository.AsQueryable().CountAsync(); int linkCount = await _friendLinkRepository.AsQueryable().CountAsync(x => x.Status == AvailabilityStatus.Enable); return new ArticleReportOutput { ArticleCount = articleCount, CategoryCount = categoryCount, TagCount = tagCount, LinkCount = linkCount, UserCount = userCount }; } /// /// 文章详情 /// /// 文章ID /// [HttpGet] public async Task Info([FromQuery] long id) { long userId = _authManager.UserId; var article = await _articleRepository.AsQueryable() .LeftJoin((x, ac) => x.Id == ac.ArticleId) .InnerJoin((x, ac, c) => ac.CategoryId == c.Id && c.Status == AvailabilityStatus.Enable) .Where(x => x.Id == id && x.PublishTime <= DateTime.Now && x.Status == AvailabilityStatus.Enable) .Where(x => x.ExpiredTime == null || x.ExpiredTime > DateTime.Now) .Select((x, ac, c) => new ArticleInfoOutput { Id = x.Id, Title = x.Title, Content = x.Content, Summary = x.Summary, Cover = x.Cover, PublishTime = x.PublishTime, Author = x.Author, Views = x.Views, CreationType = x.CreationType, IsAllowComments = x.IsAllowComments, IsHtml = x.IsHtml, IsTop = x.IsTop, Link = x.Link, UpdatedTime = x.UpdatedTime, CategoryId = c.Id, PraiseTotal = SqlFunc.Subqueryable().Where(p => p.ObjectId == x.Id).Count(), IsPraise = SqlFunc.Subqueryable().Where(p => p.ObjectId == x.Id && p.AccountId == userId).Any(), CategoryName = c.Name, Tags = SqlFunc.Subqueryable().InnerJoin((tags, at) => tags.Id == at.TagId) .Where((tags, at) => tags.Status == AvailabilityStatus.Enable && at.ArticleId == x.Id) .ToList(tags => new TagsOutput { Id = tags.Id, Name = tags.Name, Color = tags.Color, Icon = tags.Icon }) }).FirstAsync(); if (article == null) throw Oops.Bah("糟糕,您访问的信息丢失了...").StatusCode(404); await _articleRepository.UpdateAsync(x => new Article() { Views = x.Views + 1 }, x => x.Id == article.Id); //上一篇 var prevQuery = _articleRepository.AsQueryable().Where(x => x.PublishTime < article.PublishTime && x.PublishTime <= DateTime.Now && x.Status == AvailabilityStatus.Enable) .Where(x => x.ExpiredTime == null || x.ExpiredTime > DateTime.Now) .OrderByDescending(x => x.PublishTime) .Select(x => new ArticleBasicsOutput { Id = x.Id, Cover = x.Cover, Title = x.Title, PublishTime = null, Type = 0 }).Take(1).MergeTable(); //下一篇 var nextQuery = _articleRepository.AsQueryable().Where(x => x.PublishTime > article.PublishTime && x.PublishTime <= DateTime.Now && x.Status == AvailabilityStatus.Enable) .Where(x => x.ExpiredTime == null || x.ExpiredTime > DateTime.Now) .OrderBy(x => x.PublishTime) .Select(x => new ArticleBasicsOutput { Id = x.Id, Cover = x.Cover, Title = x.Title, PublishTime = null, Type = 1 }).Take(1).MergeTable(); //随机6条 var randomQuery = _articleRepository.AsQueryable().Where(x => x.Id != id) .Where(x => x.PublishTime <= DateTime.Now && x.Status == AvailabilityStatus.Enable) .Where(x => x.ExpiredTime == null || x.ExpiredTime > DateTime.Now) .OrderBy(x => SqlFunc.GetRandom()) .Select(x => new ArticleBasicsOutput { Id = x.Id, Cover = x.Cover, Title = x.Title, PublishTime = x.PublishTime, Type = 2 }) .Take(6).MergeTable(); //相关文章 var relevant = await _articleRepository.AsSugarClient().Union(prevQuery, nextQuery, randomQuery) .OrderBy(x => x.PublishTime).ToListAsync(); article.Prev = relevant.FirstOrDefault(x => x.Type == 0); article.Next = relevant.FirstOrDefault(x => x.Type == 1); article.Random = relevant.Where(x => x.Type == 2).ToList(); article.Views++; return article; } /// /// 最新文章 /// /// [HttpGet] public async Task> Latest() { return await _articleRepository.AsQueryable() .Where(x => x.Status == AvailabilityStatus.Enable && x.PublishTime <= DateTime.Now) .Where(x => x.ExpiredTime == null || x.ExpiredTime > DateTime.Now) .Take(5) .OrderByDescending(x => x.Id) .Select() .ToListAsync(); } }