Skip to content

Commit eab7e7e

Browse files
committed
feat(blog): 支持按分类及其子分类筛选文章
在文章查询参数中新增 IncludeSubCategory 选项,当指定分类ID且启用该选项时,会同时查询该分类及其所有子分类下的文章。这使博客分类筛选功能更灵活,便于组织层级分类结构。 - 在 PostQueryParameters 中添加 IncludeSubCategory 属性 - 在 BlogController 的查询中默认启用包含子分类 - 在 PostService 的查询逻辑中实现子分类包含功能 - 调整部分代码格式以提升可读性
1 parent 84d7b2e commit eab7e7e

3 files changed

Lines changed: 44 additions & 28 deletions

File tree

src/StarBlog.Web/Controllers/BlogController.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public async Task<IActionResult> List(int categoryId = 0, int page = 1, int page
5656

5757
var posts = await _postService.GetPagedList(new PostQueryParameters {
5858
CategoryId = categoryId,
59+
IncludeSubCategory = true,
5960
Page = page,
6061
PageSize = pageSize,
6162
SortBy = sortType == "desc" ? $"-{sortBy}" : sortBy

src/StarBlog.Web/Criteria/PostQueryParameters.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public class PostQueryParameters : QueryParameters {
1919
/// </summary>
2020
public int CategoryId { get; set; } = 0;
2121

22+
/// <summary>
23+
/// 是否包含子分类
24+
/// </summary>
25+
public bool IncludeSubCategory { get; set; } = false;
26+
2227
/// <summary>
2328
/// 排序字段
2429
/// </summary>

src/StarBlog.Web/Services/PostService.cs

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ public class PostService {
2929

3030
private string Host => _conf["host"];
3131

32-
public PostService(IBaseRepository<Post> postRepo,
32+
public PostService(
33+
IBaseRepository<Post> postRepo,
3334
IBaseRepository<Category> categoryRepo,
3435
IWebHostEnvironment environment,
3536
IHttpContextAccessor accessor,
@@ -129,7 +130,7 @@ public async Task<string> UploadImage(Post post, IFormFile file) {
129130

130131
// 直接生成唯一文件名,不保留原始文件名了。——2023-6-5 21:21:46
131132
var filename = GuidUtils.GuidTo16String() + Path.GetExtension(file.FileName);
132-
var fileRelativePath = Path.Combine("media", "blog", post.Id, filename);
133+
var fileRelativePath = Path.Combine("media", "blog", post.Id, filename);
133134
var savePath = Path.Combine(_environment.WebRootPath, fileRelativePath);
134135

135136
await using (var fs = new FileStream(savePath, FileMode.Create)) {
@@ -171,8 +172,17 @@ public async Task<IPagedList<Post>> GetPagedList(PostQueryParameters param, bool
171172
}
172173

173174
// 分类过滤
175+
// 支持包含子分类过滤
174176
if (param.CategoryId != 0) {
175-
querySet = querySet.Where(a => a.CategoryId == param.CategoryId);
177+
if (param.IncludeSubCategory) {
178+
var subCategories = await _categoryRepo.Select.Where(e => e.ParentId == param.CategoryId).ToListAsync();
179+
var targetCategoryIds = subCategories.Select(a => a.Id).ToList();
180+
targetCategoryIds.Insert(0, param.CategoryId);
181+
querySet = querySet.Where(e => targetCategoryIds.Contains(e.CategoryId));
182+
}
183+
else {
184+
querySet = querySet.Where(a => a.CategoryId == param.CategoryId);
185+
}
176186
}
177187

178188
// 关键词过滤
@@ -248,9 +258,9 @@ public static string GetContentHtml(Post post) {
248258
// - 关于前端渲染 MarkDown 样式:https://blog.csdn.net/sprintline/article/details/122849907
249259
// - https://github.com/showdownjs/showdown
250260
var pipeline = new MarkdownPipelineBuilder()
251-
.UseAdvancedExtensions()
252-
.UseBootstrap5()
253-
.Build();
261+
.UseAdvancedExtensions()
262+
.UseBootstrap5()
263+
.Build();
254264
return Markdown.ToHtml(post.Content ?? "", pipeline);
255265
}
256266

@@ -280,7 +290,7 @@ private string MdImageLinkConvert(Post post, bool isAddPrefix = true) {
280290
var document = Markdown.Parse(post.Content);
281291

282292
foreach (var node in document.AsEnumerable()) {
283-
if (node is not ParagraphBlock { Inline: { } } paragraphBlock) continue;
293+
if (node is not ParagraphBlock { Inline: {} } paragraphBlock) continue;
284294
foreach (var inline in paragraphBlock.Inline) {
285295
if (inline is not LinkInline { IsImage: true } linkInline) continue;
286296

@@ -315,7 +325,7 @@ private bool ContainsExternalImages(Post post) {
315325

316326
var document = Markdown.Parse(post.Content);
317327
foreach (var node in document.AsEnumerable()) {
318-
if (node is not ParagraphBlock { Inline: { } } paragraphBlock) continue;
328+
if (node is not ParagraphBlock { Inline: {} } paragraphBlock) continue;
319329
foreach (var inline in paragraphBlock.Inline) {
320330
if (inline is not LinkInline { IsImage: true } linkInline) continue;
321331

@@ -346,7 +356,7 @@ private async Task<string> MdExternalUrlDownloadAsync(Post post) {
346356

347357
var document = Markdown.Parse(post.Content);
348358
foreach (var node in document.AsEnumerable()) {
349-
if (node is not ParagraphBlock { Inline: { } } paragraphBlock) continue;
359+
if (node is not ParagraphBlock { Inline: {} } paragraphBlock) continue;
350360
foreach (var inline in paragraphBlock.Inline) {
351361
if (inline is not LinkInline { IsImage: true } linkInline) continue;
352362

@@ -383,14 +393,14 @@ public async Task<List<Post>> GetRelatedPosts(Post currentPost, int count = 5) {
383393
// 1. 优先推荐同分类的文章(随机顺序)
384394
if (currentPost.CategoryId > 0) {
385395
var sameCategoryPosts = await _postRepo
386-
.Where(p => p.IsPublish && p.Id != currentPost.Id && p.CategoryId == currentPost.CategoryId)
387-
.ToListAsync();
396+
.Where(p => p.IsPublish && p.Id != currentPost.Id && p.CategoryId == currentPost.CategoryId)
397+
.ToListAsync();
388398

389399
// 随机打乱同分类文章
390400
var randomSameCategoryPosts = sameCategoryPosts
391-
.OrderBy(x => Random.Shared.Next())
392-
.Take(count)
393-
.ToList();
401+
.OrderBy(x => Random.Shared.Next())
402+
.Take(count)
403+
.ToList();
394404
relatedPosts.AddRange(randomSameCategoryPosts);
395405
}
396406

@@ -401,14 +411,14 @@ public async Task<List<Post>> GetRelatedPosts(Post currentPost, int count = 5) {
401411
excludeIds.Add(currentPost.Id); // 排除当前文章
402412

403413
var otherPosts = await _postRepo
404-
.Where(p => p.IsPublish && !excludeIds.Contains(p.Id))
405-
.ToListAsync();
414+
.Where(p => p.IsPublish && !excludeIds.Contains(p.Id))
415+
.ToListAsync();
406416

407417
// 随机打乱其他文章
408418
var randomOtherPosts = otherPosts
409-
.OrderBy(x => Random.Shared.Next())
410-
.Take(remainingCount)
411-
.ToList();
419+
.OrderBy(x => Random.Shared.Next())
420+
.Take(remainingCount)
421+
.ToList();
412422
relatedPosts.AddRange(randomOtherPosts);
413423
}
414424

@@ -420,20 +430,20 @@ public async Task<List<Post>> GetRelatedPosts(Post currentPost, int count = 5) {
420430
/// </summary>
421431
public async Task<List<Post>> GetPopularPosts(int count = 10) {
422432
return await _postRepo
423-
.Where(p => p.IsPublish)
424-
.OrderByDescending(p => p.LastUpdateTime)
425-
.Take(count)
426-
.ToListAsync();
433+
.Where(p => p.IsPublish)
434+
.OrderByDescending(p => p.LastUpdateTime)
435+
.Take(count)
436+
.ToListAsync();
427437
}
428438

429439
/// <summary>
430440
/// 获取最新文章
431441
/// </summary>
432442
public async Task<List<Post>> GetLatestPosts(int count = 10) {
433443
return await _postRepo
434-
.Where(p => p.IsPublish)
435-
.OrderByDescending(p => p.CreationTime)
436-
.Take(count)
437-
.ToListAsync();
444+
.Where(p => p.IsPublish)
445+
.OrderByDescending(p => p.CreationTime)
446+
.Take(count)
447+
.ToListAsync();
438448
}
439-
}
449+
}

0 commit comments

Comments
 (0)