diff --git a/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs b/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs new file mode 100644 index 0000000..cf19b6a --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs @@ -0,0 +1,169 @@ +using Infrastructure; +using Infrastructure.Attribute; +using Infrastructure.Enums; +using Infrastructure.Model; +using Mapster; +using Microsoft.AspNetCore.Mvc; +using ZR.Model.Dto; +using ZR.Admin.WebApi.Extensions; +using ZR.Admin.WebApi.Filters; +using ZR.Common; +using ZR.Service.System.IService; +using ZR.Model.System; + +namespace ZR.Admin.WebApi.Controllers +{ + /// + /// 文章目录Controller + /// + /// @tableName articleCategory + /// @author zr + /// @date 2022-05-13 + /// + [Verify] + [Route("article/ArticleCategory")] + public class ArticleCategoryController : BaseController + { + /// + /// 文章目录接口 + /// + private readonly IArticleCategoryService _ArticleCategoryService; + + public ArticleCategoryController(IArticleCategoryService ArticleCategoryService) + { + _ArticleCategoryService = ArticleCategoryService; + } + + /// + /// 查询文章目录列表 + /// + /// + /// + [HttpGet("list")] + [ActionPermissionFilter(Permission = "articlecategory:list")] + public IActionResult QueryArticleCategory([FromQuery] ArticleCategoryQueryDto parm) + { + var response = _ArticleCategoryService.GetList(parm); + return SUCCESS(response); + } + + /// + /// 查询文章目录列表树 + /// + /// + /// + [HttpGet("treeList")] + [ActionPermissionFilter(Permission = "articlecategory:list")] + public IActionResult QueryTreeArticleCategory([FromQuery] ArticleCategoryQueryDto parm) + { + var response = _ArticleCategoryService.GetTreeList(parm); + return SUCCESS(response); + } + + /// + /// 查询文章目录详情 + /// + /// + /// + [HttpGet("{CategoryId}")] + [ActionPermissionFilter(Permission = "articlecategory:query")] + public IActionResult GetArticleCategory(int CategoryId) + { + var response = _ArticleCategoryService.GetFirst(x => x.CategoryId == CategoryId); + + return SUCCESS(response); + } + + /// + /// 添加文章目录 + /// + /// + [HttpPost] + [ActionPermissionFilter(Permission = "articlecategory:add")] + [Log(Title = "文章目录", BusinessType = BusinessType.INSERT)] + public IActionResult AddArticleCategory([FromBody] ArticleCategoryDto parm) + { + if (parm == null) + { + throw new CustomException("请求参数错误"); + } + //从 Dto 映射到 实体 + var modal = parm.Adapt().ToCreate(HttpContext); + + var response = _ArticleCategoryService.AddArticleCategory(modal); + + return ToResponse(response); + } + + /// + /// 更新文章目录 + /// + /// + [HttpPut] + [ActionPermissionFilter(Permission = "articlecategory:edit")] + [Log(Title = "文章目录", BusinessType = BusinessType.UPDATE)] + public IActionResult UpdateArticleCategory([FromBody] ArticleCategoryDto parm) + { + if (parm == null) + { + throw new CustomException("请求实体不能为空"); + } + //从 Dto 映射到 实体 + var modal = parm.Adapt().ToUpdate(HttpContext); + + var response = _ArticleCategoryService.Update(w => w.CategoryId == modal.CategoryId, it => new ArticleCategory() + { + //Update 字段映射 + Name = modal.Name, + ParentId = modal.ParentId, + }); + + return ToResponse(response); + } + + /// + /// 删除文章目录 + /// + /// + [HttpDelete("{ids}")] + [ActionPermissionFilter(Permission = "articlecategory:delete")] + [Log(Title = "文章目录", BusinessType = BusinessType.DELETE)] + public IActionResult DeleteArticleCategory(string ids) + { + int[] idsArr = Tools.SpitIntArrary(ids); + if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); } + + var response = _ArticleCategoryService.Delete(idsArr); + + return ToResponse(response); + } + + /// + /// 导出文章目录 + /// + /// + [Log(Title = "文章目录", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)] + [HttpGet("export")] + [ActionPermissionFilter(Permission = "articlecategory:export")] + public IActionResult Export([FromQuery] ArticleCategoryQueryDto parm) + { + parm.PageSize = 10000; + var list = _ArticleCategoryService.GetList(parm).Result; + + string sFileName = ExportExcel(list, "ArticleCategory", "文章目录"); + return SUCCESS(new { path = "/export/" + sFileName, fileName = sFileName }); + } + + /// + /// 获取文章目录,前端没用到 + /// + /// + [HttpGet("CategoryList")] + public IActionResult CategoryList() + { + var response = _ArticleCategoryService.GetAll(); + return SUCCESS(response); + } + + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Controllers/System/ArticleController.cs b/ZR.Admin.WebApi/Controllers/System/ArticleController.cs index 3b1e340..e6a542e 100644 --- a/ZR.Admin.WebApi/Controllers/System/ArticleController.cs +++ b/ZR.Admin.WebApi/Controllers/System/ArticleController.cs @@ -1,17 +1,15 @@ -using Infrastructure.Attribute; +using Infrastructure; +using Infrastructure.Attribute; +using Infrastructure.Enums; +using Infrastructure.Model; +using Mapster; using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using ZR.Admin.WebApi.Extensions; using ZR.Admin.WebApi.Filters; using ZR.Model.System; -using ZR.Service.System.IService; -using Infrastructure.Model; -using SqlSugar; -using Mapster; using ZR.Model.System.Dto; -using Infrastructure.Enums; -using Infrastructure; -using ZR.Admin.WebApi.Extensions; -using System.Reflection; -using System; +using ZR.Service.System.IService; namespace ZR.Admin.WebApi.Controllers { @@ -75,28 +73,6 @@ namespace ZR.Admin.WebApi.Controllers return SUCCESS(response); } - /// - /// 获取文章目录,前端没用到 - /// - /// - [HttpGet("CategoryList")] - public IActionResult CategoryList() - { - var response = _ArticleCategoryService.GetAll(); - return SUCCESS(response); - } - - /// - /// 获取文章目录树 - /// - /// - [HttpGet("CategoryTreeList")] - public IActionResult CategoryTreeList() - { - var response = _ArticleCategoryService.BuildCategoryTree(_ArticleCategoryService.GetAll()); - return SUCCESS(response); - } - /// /// 查询文章详情 /// @@ -125,7 +101,7 @@ namespace ZR.Admin.WebApi.Controllers } //从 Dto 映射到 实体 var addModel = parm.Adapt
().ToCreate(context: HttpContext); - addModel.AuthorName = User.Identity.Name; + addModel.AuthorName = HttpContext.GetName(); return SUCCESS(_ArticleService.Add(addModel)); } diff --git a/ZR.Model/Dto/Article/ArticleCategoryDto.cs b/ZR.Model/Dto/Article/ArticleCategoryDto.cs new file mode 100644 index 0000000..39ae5c4 --- /dev/null +++ b/ZR.Model/Dto/Article/ArticleCategoryDto.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using ZR.Model.Dto; +using ZR.Model.Models; + +namespace ZR.Model.Dto +{ + /// + /// 文章目录输入对象 + /// + public class ArticleCategoryDto + { + [Required(ErrorMessage = "目录id不能为空")] + public int CategoryId { get; set; } + [Required(ErrorMessage = "目录名不能为空")] + public string Name { get; set; } + public DateTime? CreateTime { get; set; } + public int? ParentId { get; set; } + } + + /// + /// 文章目录查询对象 + /// + public class ArticleCategoryQueryDto : PagerInfo + { + } +} diff --git a/ZR.Model/System/ArticleCategory.cs b/ZR.Model/System/ArticleCategory.cs index 48c9d6d..cdd134c 100644 --- a/ZR.Model/System/ArticleCategory.cs +++ b/ZR.Model/System/ArticleCategory.cs @@ -13,9 +13,15 @@ namespace ZR.Model.System [Tenant("0")] public class ArticleCategory { - public int Category_Id { get; set; } + /// + /// 目录id + /// + [SugarColumn(IsPrimaryKey = true, ColumnName = "Category_id")] + public int CategoryId { get; set; } public string Name { get; set; } public int ParentId { get; set; } + [SugarColumn(ColumnName = "create_time")] + public DateTime CreateTime { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [SugarColumn(IsIgnore = true)] diff --git a/ZR.Service/System/ArticleCategoryService.cs b/ZR.Service/System/ArticleCategoryService.cs index 9f9a11d..3070624 100644 --- a/ZR.Service/System/ArticleCategoryService.cs +++ b/ZR.Service/System/ArticleCategoryService.cs @@ -3,72 +3,78 @@ using SqlSugar; using SqlSugar.IOC; using System.Collections.Generic; using System.Linq; +using ZR.Model; +using ZR.Model.Dto; using ZR.Model.System; +using ZR.Repository; using ZR.Repository.System; using ZR.Service.System.IService; namespace ZR.Service.System { /// - /// 文章目录 + /// 文章目录Service业务层处理 /// [AppService(ServiceType = typeof(IArticleCategoryService), ServiceLifetime = LifeTime.Transient)] public class ArticleCategoryService : BaseService, IArticleCategoryService { - /// - /// 构建前端所需要树结构 - /// - /// 目录列表 - /// - public List BuildCategoryTree(List categories) + private readonly ArticleCategoryRepository _ArticleCategoryRepository; + public ArticleCategoryService(ArticleCategoryRepository repository) { - List returnList = new List(); - List tempList = categories.Select(f => f.Category_Id).ToList(); - foreach (var dept in categories) - { - // 如果是顶级节点, 遍历该父节点的所有子节点 - if (!tempList.Contains(dept.ParentId)) - { - RecursionFn(categories, dept); - returnList.Add(dept); - } - } - - if (!returnList.Any()) - { - returnList = categories; - } - return returnList; + _ArticleCategoryRepository = repository; } /// - /// 递归列表 + /// 查询文章目录列表 /// - /// - /// - private void RecursionFn(List list, ArticleCategory t) + /// + /// + public PagedInfo GetList(ArticleCategoryQueryDto parm) { - //得到子节点列表 - List childList = GetChildList(list, t); - t.Children = childList; - foreach (var item in childList) - { - if (GetChildList(list, item).Count() > 0) - { - RecursionFn(list, item); - } - } + //开始拼装查询条件 + var predicate = Expressionable.Create(); + + //搜索条件查询语法参考Sqlsugar + var response = _ArticleCategoryRepository + .Queryable() + .Where(predicate.ToExpression()) + .ToPage(parm); + + return response; } /// - /// 递归获取子菜单 + /// 查询文章目录树列表 /// - /// 所有菜单 - /// + /// /// - private List GetChildList(List list, ArticleCategory t) + public List GetTreeList(ArticleCategoryQueryDto parm) { - return list.Where(p => p.ParentId == t.Category_Id).ToList(); + //开始拼装查询条件 + var predicate = Expressionable.Create(); + + //搜索条件查询语法参考Sqlsugar + + var response = _ArticleCategoryRepository.Queryable().Where(predicate.ToExpression()) + .ToTree(it => it.Children, it => it.ParentId, 0); + + return response; + } + + /// + /// 添加文章目录 + /// + /// + /// + public int AddArticleCategory(ArticleCategory parm) + { + var response = _ArticleCategoryRepository.Insert(parm, it => new + { + it.Name, + it.CreateTime, + it.ParentId, + }); + return response; } } } diff --git a/ZR.Service/System/IService/IArticleCategoryService.cs b/ZR.Service/System/IService/IArticleCategoryService.cs index 602b228..9ee2bc5 100644 --- a/ZR.Service/System/IService/IArticleCategoryService.cs +++ b/ZR.Service/System/IService/IArticleCategoryService.cs @@ -1,14 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; +using ZR.Model; +using ZR.Model.Dto; using ZR.Model.System; namespace ZR.Service.System.IService { public interface IArticleCategoryService : IBaseService { - List BuildCategoryTree(List categories); + PagedInfo GetList(ArticleCategoryQueryDto parm); + List GetTreeList(ArticleCategoryQueryDto parm); + int AddArticleCategory(ArticleCategory parm); } } diff --git a/ZRAdmin-vue/src/api/article/articlecategory.js b/ZRAdmin-vue/src/api/article/articlecategory.js new file mode 100644 index 0000000..d9fe8b3 --- /dev/null +++ b/ZRAdmin-vue/src/api/article/articlecategory.js @@ -0,0 +1,70 @@ +import request from '@/utils/request' + +/** +* 文章目录分页查询 +* @param {查询条件} data +*/ +export function listArticleCategory(query) { + return request({ + url: 'article/ArticleCategory/list', + method: 'get', + params: query, + }) +} + + +/** +* 新增文章目录 +* @param data +*/ +export function addArticleCategory(data) { + return request({ + url: 'article/ArticleCategory', + method: 'post', + data: data, + }) +} + +/** +* 修改文章目录 +* @param data +*/ +export function updateArticleCategory(data) { + return request({ + url: 'article/ArticleCategory', + method: 'PUT', + data: data, + }) +} + +/** +* 获取文章目录详情 +* @param {Id} +*/ +export function getArticleCategory(id) { + return request({ + url: 'article/ArticleCategory/' + id, + method: 'get' + }) +} + +/** +* 删除文章目录 +* @param {主键} pid +*/ +export function delArticleCategory(pid) { + return request({ + url: 'article/ArticleCategory/' + pid, + method: 'delete' + }) +} + +// 导出文章目录 +export function exportArticleCategory(query) { + return request({ + url: 'article/ArticleCategory/export', + method: 'get', + params: query + }) +} + diff --git a/ZRAdmin-vue/src/views/article/ArticleCategory.vue b/ZRAdmin-vue/src/views/article/ArticleCategory.vue new file mode 100644 index 0000000..5e2b5f8 --- /dev/null +++ b/ZRAdmin-vue/src/views/article/ArticleCategory.vue @@ -0,0 +1,286 @@ + + + + + \ No newline at end of file diff --git a/document/admin-mysql.sql b/document/admin-mysql.sql index 0d9f2d4..e3df594 100644 --- a/document/admin-mysql.sql +++ b/document/admin-mysql.sql @@ -404,6 +404,25 @@ VALUES ('删除', @langMenuId, 3, '#', NULL, 0, 0, 'F', '0', '0', 'system:lang:d INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) VALUES ('修改', @langMenuId, 4, '#', NULL, 0, 0, 'F', '0', '0', 'system:lang:edit', '', 'system', sysdate()); + +-- 文章目录菜单 +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) +VALUES ('文章目录', 118, 999, 'ArticleCategory', 'system/article/articleCategory', 0, 0, 'C', '0', '0', 'articlecategory:list', 'tree-table', 'system', sysdate()); +-- 按钮父菜单id +SELECT @cmenuId := LAST_INSERT_ID(); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) +VALUES ('查询', @cmenuId, 1, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:query', '', 'system', sysdate()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) +VALUES ('新增', @cmenuId, 2, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:add', '', 'system', sysdate()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) +VALUES ('删除', @cmenuId, 3, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:delete', '', 'system', sysdate()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) +VALUES ('修改', @cmenuId, 4, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:edit', '', 'system', sysdate()); + -- ---------------------------- -- Table structure for sys_oper_log -- ---------------------------- diff --git a/document/admin-sqlserver.sql b/document/admin-sqlserver.sql index 038eba1..8f16873 100644 --- a/document/admin-sqlserver.sql +++ b/document/admin-sqlserver.sql @@ -386,8 +386,29 @@ VALUES ('修改', @menuId, 4, '#', NULL, 0, 0, 'F', '0', '0', 'system:lang:edit' INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by,create_time) VALUES ('导出', @menuId, 5, '#', NULL, 0, 0, 'F', '0', '0', 'system:lang:export', '', 'system', GETDATE()); - GO + +-- 文章目录菜单 +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by, create_time) +VALUES ('文章目录', 118, 999, 'ArticleCategory', 'system/article/articleCategory', 0, 0, 'C', '0', '0', 'articlecategory:list', 'tree-table', 'system', GETDATE()); +-- 按钮父菜单id +DECLARE @cmenuId int = @@identity +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by,create_time) +VALUES ('查询', @cmenuId, 1, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:query', '', 'system', GETDATE()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by,create_time) +VALUES ('新增', @cmenuId, 2, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:add', '', 'system', GETDATE()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by,create_time) +VALUES ('删除', @cmenuId, 3, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:delete', '', 'system', GETDATE()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by,create_time) +VALUES ('修改', @cmenuId, 4, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:edit', '', 'system', GETDATE()); + +INSERT INTO sys_menu(menuName, parentId, orderNum, path, component, isFrame, isCache, menuType, visible, status, perms, icon, create_by,create_time) +VALUES ('导出', @cmenuId, 5, '#', NULL, 0, 0, 'F', '0', '0', 'articlecategory:export', '', 'system', GETDATE()); +GO + -- ---------------------------- -- = '操作日志记录' -- Table structure for sys_oper_log @@ -653,7 +674,7 @@ CREATE TABLE articleCategory ( create_time datetime NULL DEFAULT NULL , -- '创建时间', parentId int NULL DEFAULT 0 , -- '父级ID', ) - +GO -- ---------------------------- -- Records of articleCategory -- ----------------------------