基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
基于 abp vNext 和 .NET Core 開發(fā)博客項(xiàng)目 - 博客接口實(shí)戰(zhàn)篇(二)
轉(zhuǎn)載于:https://github.com/Meowv/Blog
上篇文章完成了兩個(gè)接口:文章列表頁、文章詳情頁,本篇繼續(xù)。
分類列表
圖片
分析:這里多了一個(gè)統(tǒng)計(jì)文章數(shù)量的字段,可以直接新建一個(gè)模型QueryCategoryDto.cs繼承CategoryDto。
//QueryCategoryDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class QueryCategoryDto : CategoryDto
{
///
/// 總數(shù)
///
public int Count { get; set; }
}
}
添加查詢分類列表接口和緩存接口。
//IBlogService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog
{
public partial interface IBlogService
{
///
/// 查詢分類列表
///
///
Task<ServiceResult<IEnumerable>> QueryCategoriesAsync();
}
}
//IBlogCacheService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Caching.Blog
{
public partial interface IBlogCacheService
{
///
/// 查詢分類列表
///
///
///
Task<ServiceResult<IEnumerable>> QueryCategoriesAsync(Func<Task<ServiceResult<IEnumerable>>> factory);
}
}
分別實(shí)現(xiàn)這兩個(gè)接口。
//BlogCacheService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static Meowv.Blog.Domain.Shared.MeowvBlogConsts;
namespace Meowv.Blog.Application.Caching.Blog.Impl
{
public partial class BlogCacheService
{
private const string KEY_QueryCategories = “Blog:Category:QueryCategories”;
}
//BlogService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog.Impl
{
public partial class BlogService
{
///
/// 查詢分類列表
///
///
public async Task<ServiceResult<IEnumerable>> QueryCategoriesAsync()
{
return await _blogCacheService.QueryCategoriesAsync(async () =>
{
var result = new ServiceResult<IEnumerable>();
}
緩存就不說了,查詢分類列表,聯(lián)合查詢文章和分類兩張表,關(guān)聯(lián)字段為CategoryId,然后分組,計(jì)算出對(duì)應(yīng)的數(shù)量,在BlogController中添加API。
///
/// 查詢分類列表
///
///
[HttpGet]
[Route(“categories”)]
public async Task<ServiceResult<IEnumerable>> QueryCategoriesAsync()
{
return await _blogService.QueryCategoriesAsync();
}
圖片
標(biāo)簽列表
圖片
分析:和分類列表差不多,新建模型QueryTagDto.cs繼承TagDto。
//QueryTagDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class QueryTagDto : TagDto
{
///
/// 總數(shù)
///
public int Count { get; set; }
}
}
添加查詢標(biāo)簽列表接口和緩存接口。
//IBlogCacheService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Caching.Blog
{
public partial interface IBlogCacheService
{
///
/// 查詢標(biāo)簽列表
///
///
///
Task<ServiceResult<IEnumerable>> QueryTagsAsync(Func<Task<ServiceResult<IEnumerable>>> factory);
}
}
//IBlogService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog
{
public partial interface IBlogService
{
///
/// 查詢標(biāo)簽列表
///
///
Task<ServiceResult<IEnumerable>> QueryTagsAsync();
}
}
分別實(shí)現(xiàn)這兩個(gè)接口。
//BlogCacheService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static Meowv.Blog.Domain.Shared.MeowvBlogConsts;
namespace Meowv.Blog.Application.Caching.Blog.Impl
{
public partial class BlogCacheService
{
private const string KEY_QueryTags = “Blog:Tag:QueryTags”;
}
//BlogService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog.Impl
{
public partial class BlogService
{
///
/// 查詢標(biāo)簽列表
///
///
public async Task<ServiceResult<IEnumerable>> QueryTagsAsync()
{
return await _blogCacheService.QueryTagsAsync(async () =>
{
var result = new ServiceResult<IEnumerable>();
}
查詢標(biāo)簽列表需要聯(lián)合查詢tags和post_tags,根據(jù)TagId進(jìn)行關(guān)聯(lián),然后分組從而獲取標(biāo)簽下文章的總數(shù),在BlogController中添加API。
///
/// 查詢標(biāo)簽列表
///
///
[HttpGet]
[Route(“tags”)]
public async Task<ServiceResult<IEnumerable>> QueryTagsAsync()
{
return await _blogService.QueryTagsAsync();
}
圖片
分類名稱&文章列表
圖片
分析:此頁面下包含兩個(gè)接口,查詢分類的名稱和當(dāng)前分類下的文章列表,和文章列表不同的是,它不帶分頁。分類包含兩個(gè)字段,分類名稱和展示名稱,我們要把真正的名稱查詢出來展示在頁面上。
分類名稱
不需要給他添加返回模型,直接返回一個(gè)string類型即可,同時(shí)給一個(gè)查詢參數(shù)name,添加獲取分類名稱接口和緩存接口。
//IBlogService.Category.cs
///
/// 獲取分類名稱
///
///
///
Task<ServiceResult> GetCategoryAsync(string name);
//IBlogCacheService.Category.cs
///
/// 獲取分類名稱
///
///
///
///
Task<ServiceResult> GetCategoryAsync(string name, Func<Task<ServiceResult>> factory);
實(shí)現(xiàn)這兩個(gè)接口。
//BlogCacheService.Category.cs
…
public partial class BlogCacheService
{
private const string KEY_GetCategory = “Blog:Category:GetCategory-{0}”;
…
//BlogService.Category.cs
///
/// 獲取分類名稱
///
///
///
public async Task<ServiceResult> GetCategoryAsync(string name)
{
return await _blogCacheService.GetCategoryAsync(name, async () =>
{
var result = new ServiceResult();
}
FormatWith()是擴(kuò)展方法,ResponseText.WHAT_NOT_EXIST是之前說過的常量,直接查詢是否存在當(dāng)前name的分類,如果不存在給出錯(cuò)誤提示,存在的話,則只返回分類名稱,在BlogController中添加API。
///
/// 獲取分類名稱
///
///
///
[HttpGet]
[Route(“category”)]
public async Task<ServiceResult> GetCategoryAsync(([Required] string name)
{
return await _blogService.GetCategoryAsync(name);
}
[Required]Attribute 指定參數(shù)name必填。
圖片
圖片
文章列表
通過分類名稱查詢文章列表和分頁查詢文章列表返回模型是一樣的,只是不用分頁,所以直接返回一個(gè)列表就可以了,添加通過分類名稱查詢文章列表和緩存的接口。
//IBlogService.Post.cs
///
/// 通過分類名稱查詢文章列表
///
///
///
Task<ServiceResult<IEnumerable>> QueryPostsByCategoryAsync(string name);
//IBlogCacheService.Post.cs
///
/// 通過分類名稱查詢文章列表
///
///
///
///
Task<ServiceResult<IEnumerable>> QueryPostsByCategoryAsync(string name, Func<Task<ServiceResult<IEnumerable>>> factory);
分別實(shí)現(xiàn)這兩個(gè)接口。
//BlogCacheService.Post.cs
…
public partial class BlogCacheService
{
private const string KEY_QueryPostsByCategory = “Blog:Post:QueryPostsByCategory-{0}”;
…
//BlogService.Post.cs
///
/// 通過分類名稱查詢文章列表
///
///
///
public async Task<ServiceResult<IEnumerable>> QueryPostsByCategoryAsync(string name)
{
return await _blogCacheService.QueryPostsByCategoryAsync(name, async () =>
{
var result = new ServiceResult<IEnumerable>();
}
這個(gè)邏輯和分頁查詢文章列表是差不多的,聯(lián)合查詢文章表和分類表,關(guān)聯(lián)字段為CategoryId,指定查詢條件categories.DisplayName==name,以CreationTime倒序排序,年份分組,篩選出所需字段返回,在BlogController中添加API。
///
/// 通過分類名稱查詢文章列表
///
///
///
[HttpGet]
[Route(“posts/category”)]
public async Task<ServiceResult<IEnumerable>> QueryPostsByCategoryAsync([Required] string name)
{
return await _blogService.QueryPostsByCategoryAsync(name);
}
圖片
標(biāo)簽名稱&文章列表
圖片
分析:此頁面和分類頁一樣,包含兩個(gè)接口,查詢標(biāo)簽的名稱和當(dāng)前標(biāo)簽下的文章列表。
標(biāo)簽名稱
添加獲取標(biāo)簽名稱接口和緩存接口,GetTagAsync()。
//IBlogService.Tag.cs
///
/// 獲取標(biāo)簽名稱
///
///
///
Task<ServiceResult> GetTagAsync(string name);
//IBlogCacheService.Tag.cs
///
/// 獲取標(biāo)簽名稱
///
///
///
///
Task<ServiceResult> GetTagAsync(string name, Func<Task<ServiceResult>> factory);
實(shí)現(xiàn)這兩個(gè)接口。
//BlogCacheService.Tag.cs
…
public partial class BlogCacheService
{
private const string KEY_GetTag = “Blog:Tag:GetTag-{0}”;
…
//BlogService.Tag.cs
///
/// 獲取標(biāo)簽名稱
///
///
///
public async Task<ServiceResult> GetTagAsync(string name)
{
return await _blogCacheService.GetTagAsync(name, async () =>
{
var result = new ServiceResult();
}
FormatWith()是擴(kuò)展方法,ResponseText.WHAT_NOT_EXIST是之前說過的常量,直接查詢是否存在當(dāng)前name的分類,如果不存在給出錯(cuò)誤提示,存在的話,則只返回分類名稱,在BlogController中添加API。
///
/// 獲取標(biāo)簽名稱
///
///
///
[HttpGet]
[Route(“tag”)]
public async Task<ServiceResult> GetTagAsync(string name)
{
return await _blogService.GetTagAsync(name);
}
[Required]Attribute 指定參數(shù)name必填。
圖片
圖片
文章列表
和上面一模一樣的,添加通過標(biāo)簽名稱查詢文章列表接口和緩存接口。
//IBlogService.Post.cs
///
/// 通過標(biāo)簽名稱查詢文章列表
///
///
///
Task<ServiceResult<IEnumerable>> QueryPostsByTagAsync(string name);
//IBlogCacheService.Post.cs
///
/// 通過標(biāo)簽名稱查詢文章列表
///
///
///
///
Task<ServiceResult<IEnumerable>> QueryPostsByTagAsync(string name, Func<Task<ServiceResult<IEnumerable>>> factory);
分別實(shí)現(xiàn)這兩個(gè)接口。
//BlogCacheService.Post.cs
…
public partial class BlogCacheService
{
private const string KEY_QueryPostsByTag = “Blog:Post:QueryPostsByTag-{0}”;
…
//BlogService.Post.cs
///
/// 通過標(biāo)簽名稱查詢文章列表
///
///
///
public async Task<ServiceResult<IEnumerable>> QueryPostsByTagAsync(string name)
{
return await _blogCacheService.QueryPostsByTagAsync(name, async () =>
{
var result = new ServiceResult<IEnumerable>();
}
這個(gè)查詢有點(diǎn)特殊,聯(lián)合查詢了3張表,先查post_tags和tags,關(guān)聯(lián)字段TagId,再根據(jù)PostId查詢posts,指定查詢條件tags.DisplayName==name,以CreationTime倒序排序,年份分組,篩選出所需字段返回,在BlogController中添加API。
///
/// 通過標(biāo)簽名稱查詢文章列表
///
///
///
[HttpGet]
[Route(“posts/tag”)]
public async Task<ServiceResult<IEnumerable>> QueryPostsByTagAsync(string name)
{
return await _blogService.QueryPostsByTagAsync(name);
}
圖片
至此,基本上完成了博客前端所需的所有查詢接口,就還剩下友鏈的查詢,大家可以自己完成,后面如果需要什么新的接口再回頭來寫就好了。
開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
總結(jié)
以上是生活随笔為你收集整理的基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于 abp vNext 和 .NET
- 下一篇: 基于 abp vNext 和 .NET