基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(五)
阿新 • • 發佈:2020-06-08
## 系列文章
1. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 使用 abp cli 搭建專案](https://www.cnblogs.com/meowv/p/12896177.html)**
2. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 給專案瘦身,讓它跑起來](https://www.cnblogs.com/meowv/p/12896898.html)**
3. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 完善與美化,Swagger登場](https://www.cnblogs.com/meowv/p/12909558.html)**
4. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 資料訪問和程式碼優先](https://www.cnblogs.com/meowv/p/12913676.html)**
5. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 自定義倉儲之增刪改查](https://www.cnblogs.com/meowv/p/12916613.html)**
6. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 統一規範API,包裝返回模型](https://www.cnblogs.com/meowv/p/12924409.html)**
7. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 再說Swagger,分組、描述、小綠鎖](https://www.cnblogs.com/meowv/p/12924859.html)**
8. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 接入GitHub,用JWT保護你的API](https://www.cnblogs.com/meowv/p/12935693.html)**
9. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 異常處理和日誌記錄](https://www.cnblogs.com/meowv/p/12943699.html)**
10. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 使用Redis快取資料](https://www.cnblogs.com/meowv/p/12956696.html)**
11. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 整合Hangfire實現定時任務處理](https://www.cnblogs.com/meowv/p/12961014.html)**
12. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 用AutoMapper搞定物件對映](https://www.cnblogs.com/meowv/p/12966092.html)**
13. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 定時任務最佳實戰(一)](https://www.cnblogs.com/meowv/p/12971041.html)**
14. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 定時任務最佳實戰(二)](https://www.cnblogs.com/meowv/p/12974439.html)**
15. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 定時任務最佳實戰(三)](https://www.cnblogs.com/meowv/p/12980301.html)**
16. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(一)](https://www.cnblogs.com/meowv/p/12987623.html)**
17. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(二)](https://www.cnblogs.com/meowv/p/12994914.html)**
18. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(三)](https://www.cnblogs.com/meowv/p/13039883.html)**
19. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(四)](https://www.cnblogs.com/meowv/p/13043084.html)**
---
[上篇文章](https://www.cnblogs.com/meowv/p/13043084.html)完成了文章詳情頁資料查詢和清除快取的功能。
本篇繼續完成分類、標籤、友情連結的後臺操作介面,還是那句話,這些純CRUD的內容,建議還是自己動手完成比較好,本篇將不再囉嗦,直接貼程式碼,以供參考。
## 分類
新增介面:查詢分類列表`QueryCategoriesForAdminAsync()`、新增分類`InsertCategoryAsync(...)`、更新分類`UpdateCategoryAsync(...)`、刪除分類`DeleteCategoryAsync(...)`
```CSharp
#region Categories
///
/// 查詢分類列表
///
///
Task>> QueryCategoriesForAdminAsync();
///
/// 新增分類
///
///
///
Task InsertCategoryAsync(EditCategoryInput input);
///
/// 更新分類
///
///
///
///
Task UpdateCategoryAsync(int id, EditCategoryInput input);
///
/// 刪除分類
///
///
///
Task DeleteCategoryAsync(int id);
#endregion Categories
```
查詢分類列表需要返回的模型類`QueryCategoryForAdminDto.cs`。
```CSharp
//QueryCategoryForAdminDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class QueryCategoryForAdminDto : QueryCategoryDto
{
///
/// 主鍵
///
public int Id { get; set; }
}
}
```
新增分類和更新分類需要的輸入引數`EditCategoryInput.cs`,直接繼承`CategoryDto`即可。
```CSharp
//EditCategoryInput.cs
namespace Meowv.Blog.Application.Contracts.Blog.Params
{
public class EditCategoryInput : CategoryDto
{
}
}
```
分別實現這幾個介面。
```CSharp
///
/// 查詢分類列表
///
///
public async Task>> QueryCategoriesForAdminAsync()
{
var result = new ServiceResult>();
var posts = await _postRepository.GetListAsync();
var categories = _categoryRepository.GetListAsync().Result.Select(x => new QueryCategoryForAdminDto
{
Id = x.Id,
CategoryName = x.CategoryName,
DisplayName = x.DisplayName,
Count = posts.Count(p => p.CategoryId == x.Id)
});
result.IsSuccess(categories);
return result;
}
```
```CSharp
///
/// 新增分類
///
///
///
public async Task InsertCategoryAsync(EditCategoryInput input)
{
var result = new ServiceResult();
var category = ObjectMapper.Map(input);
await _categoryRepository.InsertAsync(category);
result.IsSuccess(ResponseText.INSERT_SUCCESS);
return result;
}
```
這裡需要一條AutoMapper配置,將`EditCategoryInput`轉換為`Category`,忽略Id欄位。
```CSharp
CreateMap().ForMember(x => x.Id, opt => opt.Ignore());
```
```CSharp
///
/// 更新分類
///
///
///
///
public async Task UpdateCategoryAsync(int id, EditCategoryInput input)
{
var result = new ServiceResult();
var category = await _categoryRepository.GetAsync(id);
category.CategoryName = input.CategoryName;
category.DisplayName = input.DisplayName;
await _categoryRepository.UpdateAsync(category);
result.IsSuccess(ResponseText.UPDATE_SUCCESS);
return result;
}
```
```CSharp
///
/// 刪除分類
///
///
///
public async Task DeleteCategoryAsync(int id)
{
var result = new ServiceResult();
var category = await _categoryRepository.FindAsync(id);
if (null == category)
{
result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("Id", id));
return result;
}
await _categoryRepository.DeleteAsync(id);
result.IsSuccess(ResponseText.DELETE_SUCCESS);
return result;
}
```
在`BlogController.Admin.cs`中新增介面。
```CSharp
#region Categories
///
/// 查詢分類列表
///
///
[HttpGet]
[Authorize]
[Route("admin/categories")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task>> QueryCategoriesForAdminAsync()
{
return await _blogService.QueryCategoriesForAdminAsync();
}
///
/// 新增分類
///
///
///
[HttpPost]
[Authorize]
[Route("category")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task InsertCategoryAsync([FromBody] EditCategoryInput input)
{
return await _blogService.InsertCategoryAsync(input);
}
///
/// 更新分類
///
///
///
///
[HttpPut]
[Authorize]
[Route("category")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task UpdateCategoryAsync([Required] int id, [FromBody] EditCategoryInput input)
{
return await _blogService.UpdateCategoryAsync(id, input);
}
///
/// 刪除分類
///
///
///
[HttpDelete]
[Authorize]
[Route("category")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task DeleteCategoryAsync([Required] int id)
{
return await _blogService.DeleteCategoryAsync(id);
}
#endregion Categories
```
![0](https://img2020.cnblogs.com/blog/891843/202006/891843-20200605101020914-137049974.png)
## 標籤
新增介面:查詢標籤列表`QueryTagsForAdminAsync()`、新增標籤`InsertTagAsync(...)`、更新標籤`UpdateTagAsync(...)`、刪除標籤`DeleteTagAsync(...)`
```CSharp
#region Tags
///
/// 查詢標籤列表
///
///
Task>> QueryTagsForAdminAsync();
///
/// 新增標籤
///
///
///
Task InsertTagAsync(EditTagInput input);
///
/// 更新標籤
///
///
///
///
Task UpdateTagAsync(int id, EditTagInput input);
///
/// 刪除標籤
///
///
///
Task DeleteTagAsync(int id);
#endregion Tags
```
查詢標籤列表需要返回的模型類`QueryTagForAdminDto.cs`。
```CSharp
//QueryTagForAdminDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class QueryTagForAdminDto : QueryTagDto
{
///
/// 主鍵
///
public int Id { get; set; }
}
}
```
新增標籤和更新標籤需要的輸入引數`EditTagInput.cs`,直接繼承`TagDto`即可。
```CSharp
//EditTagInput.cs
namespace Meowv.Blog.Application.Contracts.Blog.Params
{
public class EditTagInput : TagDto
{
}
}
```
分別實現這幾個介面。
```CSharp
///
/// 查詢標籤列表
///
///
public async Task>> QueryTagsForAdminAsync()
{
var result = new ServiceResult>();
var post_tags = await _postTagRepository.GetListAsync();
var tags = _tagRepository.GetListAsync().Result.Select(x => new QueryTagForAdminDto
{
Id = x.Id,
TagName = x.TagName,
DisplayName = x.DisplayName,
Count = post_tags.Count(p => p.TagId == x.Id)
});
result.IsSuccess(tags);
return result;
}
```
```CSharp
///
/// 新增標籤
///
///
///
public async Task InsertTagAsync(EditTagInput input)
{
var result = new ServiceResult();
var tag = ObjectMapper.Map(input);
await _tagRepository.InsertAsync(tag);
result.IsSuccess(ResponseText.INSERT_SUCCESS);
return result;
}
```
這裡需要一條AutoMapper配置,將`EditCategoryInput`轉換為`Tag`,忽略Id欄位。
```CSharp
CreateMap().ForMember(x => x.Id, opt => opt.Ignore());
```
```CSharp
///
/// 更新標籤
///
///
///
///
public async Task UpdateTagAsync(int id, EditTagInput input)
{
var result = new ServiceResult();
var tag = await _tagRepository.GetAsync(id);
tag.TagName = input.TagName;
tag.DisplayName = input.DisplayName;
await _tagRepository.UpdateAsync(tag);
result.IsSuccess(ResponseText.UPDATE_SUCCESS);
return result;
}
```
```CSharp
///
/// 刪除標籤
///
///
///
public async Task DeleteTagAsync(int id)
{
var result = new ServiceResult();
var tag = await _tagRepository.FindAsync(id);
if (null == tag)
{
result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("Id", id));
return result;
}
await _tagRepository.DeleteAsync(id);
await _postTagRepository.DeleteAsync(x => x.TagId == id);
result.IsSuccess(ResponseText.DELETE_SUCCESS);
return result;
}
```
在`BlogController.Admin.cs`中新增介面。
```CSharp
#region Tags
///
/// 查詢標籤列表
///
///
[HttpGet]
[Authorize]
[Route("admin/tags")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task>> QueryTagsForAdminAsync()
{
return await _blogService.QueryTagsForAdminAsync();
}
///
/// 新增標籤
///
///
///
[HttpPost]
[Authorize]
[Route("tag")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task InsertTagAsync([FromBody] EditTagInput input)
{
return await _blogService.InsertTagAsync(input);
}
///
/// 更新標籤
///
///
///
///
[HttpPut]
[Authorize]
[Route("tag")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task UpdateTagAsync([Required] int id, [FromBody] EditTagInput input)
{
return await _blogService.UpdateTagAsync(id, input);
}
///
/// 刪除標籤
///
///
///
[HttpDelete]
[Authorize]
[Route("tag")]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task DeleteTagAsync([Required] int id)
{
return await _blogService.DeleteTagAsync(id);
}
#endregion Tags
```
![1](https://img2020.cnblogs.com/blog/891843/202006/891843-20200605101101841-106276175.png)
## 友鏈
新增介面:查詢友鏈列表`QueryFriendLinksForAdminAsync()`、新增友鏈`InsertFriendLinkAsync(...)`、更新友鏈`UpdateFriendLinkAsync(...)`、刪除友鏈`DeleteFriendLinkAsync(...)`
```CSharp
#region FriendLinks
///
/// 查詢友鏈列表
///
///
Task>> QueryFriendLinksForAdminAsync();
///
/// 新增友鏈
///
///
///
Task InsertFriendLinkAsync(EditFriendLinkInput input);
///
/// 更新友鏈
///
///
///
///
Task UpdateFriendLinkAsync(int id, EditFriendLinkInput input);
///
/// 刪除友鏈
///
///
///
Task DeleteFriendLinkAsync(int id);
#endregion FriendLinks
```
查詢友鏈列表需要返回的模型類`QueryFriendLinkForAdminDto.cs`。
```CSharp
//QueryFriendLinkForAdminDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class QueryFriendLinkForAdminDto : FriendLinkDto
{
///
/// 主鍵
///
public int Id { get; set; }
}
}
```
新增友鏈和更新友鏈需要的輸入引數`EditFriendLinkInput.cs`,直接繼承`FriendLinkDto`即可。
```CSharp
//EditFriendLinkInput .cs
namespace Meowv.Blog.Application.Contracts.Blog.Params
{
public class EditFriendLinkInput : FriendLinkDto
{
}
}
```
分別實現這幾個介面。
```CSharp
///
/// 查詢友鏈列表
///
///
public async Task>> QueryFriendLinksForAdminAsync()
{
var result = new ServiceResult>();
var friendLinks = await _friendLinksRepository.GetListAsync();
var dto = ObjectMapper.Map
- , IEnumerable