mirror of https://github.com/abpframework/abp.git
64 changed files with 473 additions and 1216 deletions
@ -1,36 +0,0 @@ |
|||||
using System; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Application.Dtos; |
|
||||
using Volo.Abp.Application.Services; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
|
|
||||
namespace Volo.CmsKit.Admin.Menus |
|
||||
{ |
|
||||
public interface IMenuAdminAppService : IApplicationService |
|
||||
{ |
|
||||
Task<PagedResultDto<MenuWithDetailsDto>> GetListAsync(PagedAndSortedResultRequestDto input); |
|
||||
|
|
||||
Task<MenuWithDetailsDto> GetAsync(Guid id); |
|
||||
|
|
||||
Task<MenuWithDetailsDto> CreateAsync(MenuCreateInput input); |
|
||||
|
|
||||
Task<MenuWithDetailsDto> UpdateAsync(Guid menuId, MenuUpdateInput input); |
|
||||
|
|
||||
Task DeleteAsync(Guid menuId); |
|
||||
|
|
||||
Task<MenuItemDto> GetMenuItemAsync(Guid menuId, Guid menuItemId); |
|
||||
|
|
||||
Task<MenuItemDto> CreateMenuItemAsync(Guid menuId, MenuItemCreateInput input); |
|
||||
|
|
||||
Task<MenuItemDto> UpdateMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemUpdateInput input); |
|
||||
|
|
||||
Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId); |
|
||||
|
|
||||
Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input); |
|
||||
|
|
||||
Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input); |
|
||||
|
|
||||
|
|
||||
Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,25 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.CmsKit.Menus; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Menus |
||||
|
{ |
||||
|
public interface IMenuItemAdminAppService : IApplicationService |
||||
|
{ |
||||
|
Task<ListResultDto<MenuItemDto>> GetListAsync(); |
||||
|
|
||||
|
Task<MenuItemDto> GetAsync(Guid id); |
||||
|
|
||||
|
Task<MenuItemDto> CreateAsync(MenuItemCreateInput input); |
||||
|
|
||||
|
Task<MenuItemDto> UpdateAsync(Guid id, MenuItemUpdateInput input); |
||||
|
|
||||
|
Task DeleteAsync(Guid id); |
||||
|
|
||||
|
Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input); |
||||
|
|
||||
|
Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input); |
||||
|
} |
||||
|
} |
||||
@ -1,207 +0,0 @@ |
|||||
using Microsoft.AspNetCore.Authorization; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Application.Dtos; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.GlobalFeatures; |
|
||||
using Volo.CmsKit.GlobalFeatures; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
using Volo.CmsKit.Pages; |
|
||||
using Volo.CmsKit.Permissions; |
|
||||
|
|
||||
namespace Volo.CmsKit.Admin.Menus |
|
||||
{ |
|
||||
[RequiresGlobalFeature(typeof(MenuFeature))] |
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Default)] |
|
||||
public class MenuAdminAppService : CmsKitAdminAppServiceBase, IMenuAdminAppService |
|
||||
{ |
|
||||
protected MenuManager MenuManager { get; } |
|
||||
protected IMenuRepository MenuRepository { get; } |
|
||||
protected IPageRepository PageRepository { get; } |
|
||||
|
|
||||
public MenuAdminAppService( |
|
||||
MenuManager menuManager, |
|
||||
IMenuRepository menuRepository, |
|
||||
IPageRepository pageRepository) |
|
||||
{ |
|
||||
MenuManager = menuManager; |
|
||||
MenuRepository = menuRepository; |
|
||||
PageRepository = pageRepository; |
|
||||
} |
|
||||
|
|
||||
public async Task<PagedResultDto<MenuWithDetailsDto>> GetListAsync(PagedAndSortedResultRequestDto input) |
|
||||
{ |
|
||||
var menus = await MenuRepository.GetPagedListAsync(input.SkipCount, input.MaxResultCount, input.Sorting); |
|
||||
|
|
||||
return new PagedResultDto<MenuWithDetailsDto>( |
|
||||
await MenuRepository.GetCountAsync(), |
|
||||
ObjectMapper.Map<List<Menu>, List<MenuWithDetailsDto>>(menus) |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
public async Task<MenuWithDetailsDto> GetAsync(Guid id) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(id, includeDetails: true); |
|
||||
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu); |
|
||||
} |
|
||||
|
|
||||
public async Task<MenuWithDetailsDto> GetSimpleAsync(Guid id) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(id, includeDetails: false); |
|
||||
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Create)] |
|
||||
public async Task<MenuWithDetailsDto> CreateAsync(MenuCreateInput input) |
|
||||
{ |
|
||||
var menu = await MenuManager.CreateAsync(CurrentTenant.Id, input.Name); |
|
||||
|
|
||||
await MenuRepository.InsertAsync(menu); |
|
||||
|
|
||||
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
|
||||
public async Task<MenuWithDetailsDto> UpdateAsync(Guid menuId, MenuUpdateInput input) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId); |
|
||||
|
|
||||
menu.SetName(input.Name); |
|
||||
|
|
||||
await MenuRepository.UpdateAsync(menu); |
|
||||
|
|
||||
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Delete)] |
|
||||
public virtual Task DeleteAsync(Guid menuId) |
|
||||
{ |
|
||||
return MenuRepository.DeleteAsync(menuId); |
|
||||
} |
|
||||
|
|
||||
public async Task<MenuItemDto> GetMenuItemAsync(Guid menuId, Guid menuItemId) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId); |
|
||||
|
|
||||
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId) |
|
||||
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); |
|
||||
|
|
||||
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
|
||||
public virtual async Task<MenuItemDto> CreateMenuItemAsync(Guid menuId, MenuItemCreateInput input) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true); |
|
||||
|
|
||||
var menuItem = |
|
||||
new MenuItem( |
|
||||
GuidGenerator.Create(), |
|
||||
menuId, |
|
||||
input.DisplayName, |
|
||||
input.Url.IsNullOrEmpty() ? "#" : input.Url, |
|
||||
input.IsActive, |
|
||||
input.ParentId, |
|
||||
input.Icon, |
|
||||
input.Order, |
|
||||
input.Target, |
|
||||
input.ElementId, |
|
||||
input.CssClass); |
|
||||
|
|
||||
if (input.PageId.HasValue) |
|
||||
{ |
|
||||
var page = await PageRepository.GetAsync(input.PageId.Value); |
|
||||
MenuManager.SetPageUrl(menuItem, page); |
|
||||
} |
|
||||
|
|
||||
menu.Items.Add(menuItem); |
|
||||
|
|
||||
MenuManager.OrganizeTreeOrderForMenuItem(menu, menuItem); |
|
||||
|
|
||||
await MenuRepository.UpdateAsync(menu); |
|
||||
|
|
||||
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
|
||||
public virtual async Task<MenuItemDto> UpdateMenuItemAsync(Guid menuId, Guid menuItemId, |
|
||||
MenuItemUpdateInput input) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true); |
|
||||
|
|
||||
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId) |
|
||||
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); |
|
||||
|
|
||||
if (input.PageId.HasValue) |
|
||||
{ |
|
||||
MenuManager.SetPageUrl(menuItem, await PageRepository.GetAsync(input.PageId.Value)); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
menuItem.SetUrl(input.Url); |
|
||||
} |
|
||||
|
|
||||
menuItem.SetDisplayName(input.DisplayName); |
|
||||
menuItem.IsActive = input.IsActive; |
|
||||
menuItem.Icon = input.Icon; |
|
||||
menuItem.Target = input.Target; |
|
||||
menuItem.ElementId = input.ElementId; |
|
||||
menuItem.CssClass = input.CssClass; |
|
||||
|
|
||||
await MenuRepository.UpdateAsync(menu); |
|
||||
|
|
||||
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
|
||||
public virtual async Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true); |
|
||||
|
|
||||
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId) |
|
||||
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); |
|
||||
|
|
||||
menu.Items.Remove(menuItem); |
|
||||
|
|
||||
await MenuRepository.UpdateAsync(menu); |
|
||||
} |
|
||||
|
|
||||
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
|
||||
public virtual Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input) |
|
||||
{ |
|
||||
return MenuManager.MoveAsync(menuId, menuItemId, input.NewParentId, input.Position); |
|
||||
} |
|
||||
|
|
||||
public virtual async Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input) |
|
||||
{ |
|
||||
if (input.IsMainMenu) |
|
||||
{ |
|
||||
await MenuManager.SetMainMenuAsync(menuId); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
await MenuManager.UnSetMainMenuAsync(menuId); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public virtual async Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input) |
|
||||
{ |
|
||||
var count = await PageRepository.GetCountAsync(input.Filter); |
|
||||
|
|
||||
var pages = await PageRepository.GetListAsync( |
|
||||
input.Filter, |
|
||||
input.MaxResultCount, |
|
||||
input.SkipCount, |
|
||||
input.Sorting |
|
||||
); |
|
||||
|
|
||||
return new PagedResultDto<PageLookupDto>( |
|
||||
count, |
|
||||
ObjectMapper.Map<List<Page>, List<PageLookupDto>>(pages) |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,125 @@ |
|||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
using Volo.CmsKit.GlobalFeatures; |
||||
|
using Volo.CmsKit.Menus; |
||||
|
using Volo.CmsKit.Pages; |
||||
|
using Volo.CmsKit.Permissions; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Menus |
||||
|
{ |
||||
|
[RequiresGlobalFeature(typeof(MenuFeature))] |
||||
|
[Authorize(CmsKitAdminPermissions.Menus.Default)] |
||||
|
public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdminAppService |
||||
|
{ |
||||
|
protected MenuItemManager MenuManager { get; } |
||||
|
protected IMenuItemRepository MenuItemRepository { get; } |
||||
|
protected IPageRepository PageRepository { get; } |
||||
|
|
||||
|
public MenuItemAdminAppService( |
||||
|
MenuItemManager menuManager, |
||||
|
IMenuItemRepository menuRepository, |
||||
|
IPageRepository pageRepository) |
||||
|
{ |
||||
|
MenuManager = menuManager; |
||||
|
MenuItemRepository = menuRepository; |
||||
|
PageRepository = pageRepository; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<ListResultDto<MenuItemDto>> GetListAsync() |
||||
|
{ |
||||
|
var menuItems = await MenuItemRepository.GetListAsync(); |
||||
|
|
||||
|
return new ListResultDto<MenuItemDto>( |
||||
|
ObjectMapper.Map<List<MenuItem>, List<MenuItemDto>>(menuItems) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<MenuItemDto> GetAsync(Guid id) |
||||
|
{ |
||||
|
var menu = await MenuItemRepository.GetAsync(id); |
||||
|
return ObjectMapper.Map<MenuItem, MenuItemDto>(menu); |
||||
|
} |
||||
|
|
||||
|
[Authorize(CmsKitAdminPermissions.Menus.Create)] |
||||
|
public virtual async Task<MenuItemDto> CreateAsync(MenuItemCreateInput input) |
||||
|
{ |
||||
|
var menuItem = new MenuItem( |
||||
|
GuidGenerator.Create(), |
||||
|
input.DisplayName, |
||||
|
input.Url.IsNullOrEmpty() ? "#" : input.Url, |
||||
|
input.IsActive, |
||||
|
input.ParentId, |
||||
|
input.Icon, |
||||
|
input.Order, |
||||
|
input.Target, |
||||
|
input.ElementId, |
||||
|
input.CssClass |
||||
|
); |
||||
|
|
||||
|
await MenuItemRepository.InsertAsync(menuItem); |
||||
|
|
||||
|
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); |
||||
|
} |
||||
|
|
||||
|
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
||||
|
public virtual async Task<MenuItemDto> UpdateAsync(Guid id, MenuItemUpdateInput input) |
||||
|
{ |
||||
|
var menuItem = await MenuItemRepository.GetAsync(id); |
||||
|
|
||||
|
if (input.PageId.HasValue) |
||||
|
{ |
||||
|
MenuManager.SetPageUrl(menuItem, await PageRepository.GetAsync(input.PageId.Value)); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
menuItem.SetUrl(input.Url); |
||||
|
} |
||||
|
|
||||
|
menuItem.SetDisplayName(input.DisplayName); |
||||
|
menuItem.IsActive = input.IsActive; |
||||
|
menuItem.Icon = input.Icon; |
||||
|
menuItem.Target = input.Target; |
||||
|
menuItem.ElementId = input.ElementId; |
||||
|
menuItem.CssClass = input.CssClass; |
||||
|
|
||||
|
await MenuItemRepository.UpdateAsync(menuItem); |
||||
|
|
||||
|
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); |
||||
|
} |
||||
|
|
||||
|
[Authorize(CmsKitAdminPermissions.Menus.Delete)] |
||||
|
public virtual Task DeleteAsync(Guid id) |
||||
|
{ |
||||
|
return MenuItemRepository.DeleteAsync(id); |
||||
|
} |
||||
|
|
||||
|
[Authorize(CmsKitAdminPermissions.Menus.Update)] |
||||
|
public virtual Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input) |
||||
|
{ |
||||
|
return MenuManager.MoveAsync(id, input.NewParentId, input.Position); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input) |
||||
|
{ |
||||
|
var count = await PageRepository.GetCountAsync(input.Filter); |
||||
|
|
||||
|
var pages = await PageRepository.GetListAsync( |
||||
|
input.Filter, |
||||
|
input.MaxResultCount, |
||||
|
input.SkipCount, |
||||
|
input.Sorting |
||||
|
); |
||||
|
|
||||
|
return new PagedResultDto<PageLookupDto>( |
||||
|
count, |
||||
|
ObjectMapper.Map<List<Page>, List<PageLookupDto>>(pages) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,23 +0,0 @@ |
|||||
@page |
|
||||
|
|
||||
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus |
|
||||
@using Volo.CmsKit.Admin.Web.Pages |
|
||||
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
|
||||
|
|
||||
@inherits CmsKitAdminPageBase |
|
||||
|
|
||||
@model CreateModalModel |
|
||||
|
|
||||
@{ |
|
||||
Layout = null; |
|
||||
} |
|
||||
|
|
||||
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Menus/CreateModal"> |
|
||||
<abp-modal> |
|
||||
<abp-modal-header title="@L["New"].Value"></abp-modal-header> |
|
||||
<abp-modal-body> |
|
||||
<abp-form-content /> |
|
||||
</abp-modal-body> |
|
||||
<abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer> |
|
||||
</abp-modal> |
|
||||
</abp-dynamic-form> |
|
||||
@ -1,44 +0,0 @@ |
|||||
using AutoMapper; |
|
||||
using Microsoft.AspNetCore.Mvc; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.ComponentModel.DataAnnotations; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Validation; |
|
||||
using Volo.CmsKit.Admin.Menus; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
|
|
||||
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus |
|
||||
{ |
|
||||
public class CreateModalModel : CmsKitAdminPageModel |
|
||||
{ |
|
||||
protected IMenuAdminAppService MenuAdminAppService { get; } |
|
||||
|
|
||||
[BindProperty] |
|
||||
public CreateMenuViewModel ViewModel { get; set; } |
|
||||
|
|
||||
public CreateModalModel(IMenuAdminAppService menuAdminAppService) |
|
||||
{ |
|
||||
MenuAdminAppService = menuAdminAppService; |
|
||||
} |
|
||||
|
|
||||
public async Task<IActionResult> OnPostAsync() |
|
||||
{ |
|
||||
var input = ObjectMapper.Map<CreateMenuViewModel, MenuCreateInput>(ViewModel); |
|
||||
|
|
||||
await MenuAdminAppService.CreateAsync(input); |
|
||||
|
|
||||
return NoContent(); |
|
||||
} |
|
||||
|
|
||||
[AutoMap(typeof(MenuCreateInput), ReverseMap = true)] |
|
||||
public class CreateMenuViewModel |
|
||||
{ |
|
||||
[Required] |
|
||||
[DynamicMaxLength(typeof(MenuConsts), nameof(MenuConsts.MaxNameLength))] |
|
||||
public string Name { get; set; } |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,34 +0,0 @@ |
|||||
@page |
|
||||
|
|
||||
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus |
|
||||
@using Volo.CmsKit.Admin.Web.Pages |
|
||||
@using Volo.CmsKit.Admin.Web.Menus |
|
||||
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar |
|
||||
|
|
||||
@inherits CmsKitAdminPageBase |
|
||||
|
|
||||
@model IndexModel |
|
||||
|
|
||||
@{ |
|
||||
PageLayout.Content.Title = L["Menus"].Value; |
|
||||
PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); |
|
||||
PageLayout.Content.MenuItemName = CmsKitAdminMenus.Menus.MenusMenu; |
|
||||
} |
|
||||
|
|
||||
@section scripts { |
|
||||
<abp-script-bundle> |
|
||||
<abp-script src="/Pages/CmsKit/Menus/index.js" /> |
|
||||
</abp-script-bundle> |
|
||||
} |
|
||||
|
|
||||
@section content_toolbar { |
|
||||
@await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName }) |
|
||||
} |
|
||||
|
|
||||
<div id="CmsKitMenusWrapper"> |
|
||||
<abp-card> |
|
||||
<abp-card-body> |
|
||||
<abp-table striped-rows="true" id="MenusTable" class="nowrap"></abp-table> |
|
||||
</abp-card-body> |
|
||||
</abp-card> |
|
||||
</div> |
|
||||
@ -1,13 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus |
|
||||
{ |
|
||||
public class IndexModel |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
@page |
|
||||
@using Volo.CmsKit.Admin.Web.Pages |
|
||||
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus |
|
||||
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
|
||||
|
|
||||
@inherits CmsKitAdminPageBase |
|
||||
|
|
||||
@model UpdateModalModel |
|
||||
|
|
||||
@{ |
|
||||
Layout = null; |
|
||||
} |
|
||||
|
|
||||
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Menus/UpdateModal"> |
|
||||
<abp-modal> |
|
||||
<abp-modal-header title="@L["Edit"].Value"></abp-modal-header> |
|
||||
<abp-modal-body> |
|
||||
<abp-input asp-for="Id" /> |
|
||||
<abp-form-content /> |
|
||||
</abp-modal-body> |
|
||||
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> |
|
||||
</abp-modal> |
|
||||
</abp-dynamic-form> |
|
||||
@ -1,53 +0,0 @@ |
|||||
using AutoMapper; |
|
||||
using Microsoft.AspNetCore.Mvc; |
|
||||
using System; |
|
||||
using System.ComponentModel.DataAnnotations; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Validation; |
|
||||
using Volo.CmsKit.Admin.Menus; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
|
|
||||
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus |
|
||||
{ |
|
||||
public class UpdateModalModel : CmsKitAdminPageModel |
|
||||
{ |
|
||||
protected IMenuAdminAppService MenuAdminAppService { get; } |
|
||||
|
|
||||
[HiddenInput] |
|
||||
[BindProperty(SupportsGet = true)] |
|
||||
public Guid Id { get; set; } |
|
||||
|
|
||||
[BindProperty] |
|
||||
public UpdateMenuViewModel ViewModel { get; set; } |
|
||||
|
|
||||
public UpdateModalModel(IMenuAdminAppService menuAdminAppService) |
|
||||
{ |
|
||||
MenuAdminAppService = menuAdminAppService; |
|
||||
} |
|
||||
|
|
||||
public async Task OnGetAsync() |
|
||||
{ |
|
||||
var menu = await MenuAdminAppService.GetAsync(Id); |
|
||||
|
|
||||
ViewModel = ObjectMapper.Map<MenuWithDetailsDto, UpdateMenuViewModel>(menu); |
|
||||
} |
|
||||
|
|
||||
public async Task<IActionResult> OnPostAsync() |
|
||||
{ |
|
||||
var input = ObjectMapper.Map<UpdateMenuViewModel, MenuUpdateInput>(ViewModel); |
|
||||
|
|
||||
await MenuAdminAppService.UpdateAsync(Id, input); |
|
||||
|
|
||||
return NoContent(); |
|
||||
} |
|
||||
|
|
||||
[AutoMap(typeof(MenuWithDetailsDto))] |
|
||||
[AutoMap(typeof(MenuUpdateInput), ReverseMap = true)] |
|
||||
public class UpdateMenuViewModel |
|
||||
{ |
|
||||
[Required] |
|
||||
[DynamicMaxLength(typeof(MenuConsts), nameof(MenuConsts.MaxNameLength))] |
|
||||
public string Name { get; set; } |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
|
|
||||
@ -1,118 +0,0 @@ |
|||||
$(function () { |
|
||||
var l = abp.localization.getResource("CmsKit"); |
|
||||
|
|
||||
var createModal = new abp.ModalManager(abp.appPath + "CmsKit/Menus/CreateModal"); |
|
||||
var updateModal = new abp.ModalManager(abp.appPath + "CmsKit/Menus/UpdateModal"); |
|
||||
|
|
||||
var menusService = volo.cmsKit.admin.menus.menuAdmin; |
|
||||
|
|
||||
var dataTable = $("#MenusTable").DataTable(abp.libs.datatables.normalizeConfiguration({ |
|
||||
processing: true, |
|
||||
serverSide: true, |
|
||||
paging: true, |
|
||||
searching: false, |
|
||||
scrollCollapse: true, |
|
||||
scrollX: true, |
|
||||
ordering: true, |
|
||||
order: [[1, "desc"]], |
|
||||
ajax: abp.libs.datatables.createAjax(menusService.getList), |
|
||||
columnDefs: [ |
|
||||
{ |
|
||||
title: l("Details"), |
|
||||
targets: 0, |
|
||||
rowAction: { |
|
||||
items: [ |
|
||||
{ |
|
||||
text: l('MenuItems'), |
|
||||
visible: abp.auth.isGranted('CmsKit.Menus.Update'), |
|
||||
action: function (data) { |
|
||||
location.href = "/Cms/Menus/" + data.record.id + "/menu-items" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
text: l('MakeMainMenu'), |
|
||||
visible: function (data) { |
|
||||
return abp.auth.isGranted('CmsKit.Menus.Update') && !data.isMainMenu |
|
||||
}, |
|
||||
action: function (data) { |
|
||||
menusService |
|
||||
.updateMainMenu(data.record.id, {isMainMenu: true}) |
|
||||
.then(function () { |
|
||||
dataTable.ajax.reload(); |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
text: l('UnMakeMainMenu'), |
|
||||
visible: function (data) { |
|
||||
return abp.auth.isGranted('CmsKit.Menus.Update') && data.isMainMenu |
|
||||
}, |
|
||||
action: function (data) { |
|
||||
menusService |
|
||||
.updateMainMenu(data.record.id, {isMainMenu: false}) |
|
||||
.then(function () { |
|
||||
dataTable.ajax.reload(); |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
text: l('Edit'), |
|
||||
visible: abp.auth.isGranted('CmsKit.Menus.Update'), |
|
||||
action: function (data) { |
|
||||
updateModal.open({id: data.record.id}); |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
text: l('Delete'), |
|
||||
visible: abp.auth.isGranted('CmsKit.Menus.Delete'), |
|
||||
confirmMessage: function (data) { |
|
||||
return l("MenuDeletionConfirmationMessage", data.record.name) |
|
||||
}, |
|
||||
action: function (data) { |
|
||||
menusService |
|
||||
.delete(data.record.id) |
|
||||
.then(function () { |
|
||||
dataTable.ajax.reload(); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
title: l("Name"), |
|
||||
orderable: true, |
|
||||
data: "name", |
|
||||
render: function (data, val, record) { |
|
||||
|
|
||||
if (record.isMainMenu) { |
|
||||
return ( |
|
||||
data |
|
||||
+ |
|
||||
'<span class="badge badge-pill badge-info ml-1">' |
|
||||
+ |
|
||||
l("MainMenu") |
|
||||
+ |
|
||||
'</span>' |
|
||||
); |
|
||||
} else { |
|
||||
return data; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
] |
|
||||
})); |
|
||||
|
|
||||
$('#AbpContentToolbar button[name=CreateMenu]').on('click', function (e) { |
|
||||
e.preventDefault(); |
|
||||
createModal.open(); |
|
||||
}); |
|
||||
|
|
||||
createModal.onResult(function () { |
|
||||
dataTable.ajax.reload(); |
|
||||
}); |
|
||||
|
|
||||
updateModal.onResult(function () { |
|
||||
dataTable.ajax.reload(); |
|
||||
}); |
|
||||
}); |
|
||||
@ -1 +0,0 @@ |
|||||
|
|
||||
@ -1,20 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Application.Dtos; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
[Serializable] |
|
||||
public class MenuWithDetailsDto : FullAuditedEntityDto<Guid> |
|
||||
{ |
|
||||
public string Name { get; set; } |
|
||||
|
|
||||
|
|
||||
public bool IsMainMenu { get; set; } |
|
||||
|
|
||||
public List<MenuItemDto> Items { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,9 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
|
namespace Volo.CmsKit.Menus |
||||
|
{ |
||||
|
public interface IMenuItemRepository : IBasicRepository<MenuItem, Guid> |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -1,18 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Domain.Repositories; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
public interface IMenuRepository : IBasicRepository<Menu, Guid> |
|
||||
{ |
|
||||
Task<Menu> FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default); |
|
||||
|
|
||||
Task<List<Menu>> GetCurrentAndNextMainMenusAsync( |
|
||||
Guid nextMainMenuId, |
|
||||
bool includeDetails = true, |
|
||||
CancellationToken cancellationToken = default); |
|
||||
} |
|
||||
} |
|
||||
@ -1,33 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using System; |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.Domain.Entities.Auditing; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
public class Menu : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|
||||
{ |
|
||||
public string Name { get; protected set; } |
|
||||
|
|
||||
public bool IsMainMenu { get; internal set; } |
|
||||
|
|
||||
public Guid? TenantId { get; protected set; } |
|
||||
|
|
||||
public ICollection<MenuItem> Items { get; protected set; } |
|
||||
|
|
||||
internal Menu(Guid id, Guid? tenantId, [NotNull] string name) : base(id) |
|
||||
{ |
|
||||
TenantId = tenantId; |
|
||||
SetName(name); |
|
||||
Items = new HashSet<MenuItem>(); |
|
||||
} |
|
||||
|
|
||||
public void SetName([NotNull] string name) |
|
||||
{ |
|
||||
Name = Check.NotNullOrEmpty(name, nameof(name), MenuConsts.MaxNameLength); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,63 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.Uow; |
||||
|
using Volo.CmsKit.Pages; |
||||
|
|
||||
|
namespace Volo.CmsKit.Menus |
||||
|
{ |
||||
|
public class MenuItemManager : CmsKitDomainServiceBase |
||||
|
{ |
||||
|
protected IMenuItemRepository MenuItemRepository { get; } |
||||
|
|
||||
|
public MenuItemManager(IMenuItemRepository menuRepository) |
||||
|
{ |
||||
|
MenuItemRepository = menuRepository; |
||||
|
} |
||||
|
|
||||
|
public virtual void SetPageUrl(MenuItem menuItem, Page page) |
||||
|
{ |
||||
|
menuItem.SetPageId(page.Id); |
||||
|
menuItem.SetUrl(PageConsts.UrlPrefix + page.Slug); |
||||
|
} |
||||
|
|
||||
|
[UnitOfWork] |
||||
|
public virtual async Task MoveAsync(Guid menuItemId, Guid? newParentMenuItemId, int position = 0) |
||||
|
{ |
||||
|
var menuItems = await MenuItemRepository.GetListAsync(); |
||||
|
|
||||
|
var movedMenuItem = menuItems.FirstOrDefault(x => x.Id == menuItemId) |
||||
|
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); |
||||
|
|
||||
|
if (newParentMenuItemId.HasValue && !menuItems.Any(a => a.Id == newParentMenuItemId.Value)) |
||||
|
{ |
||||
|
throw new EntityNotFoundException(typeof(MenuItem), newParentMenuItemId); |
||||
|
} |
||||
|
|
||||
|
movedMenuItem.ParentId = newParentMenuItemId; |
||||
|
movedMenuItem.Order = position; |
||||
|
|
||||
|
OrganizeTreeOrderForMenuItem(menuItems, movedMenuItem); |
||||
|
|
||||
|
await MenuItemRepository.UpdateManyAsync(menuItems); |
||||
|
} |
||||
|
|
||||
|
public virtual void OrganizeTreeOrderForMenuItem(List<MenuItem> items, MenuItem menuItem) |
||||
|
{ |
||||
|
var sameTree = items.Where(x => x.ParentId == menuItem.ParentId).OrderBy(x => x.Order).ToList(); |
||||
|
|
||||
|
sameTree.Remove(menuItem); // Remove if exists to prevent misordering with same order number
|
||||
|
|
||||
|
sameTree.Insert(menuItem.Order, menuItem); |
||||
|
|
||||
|
for (int i = 0; i < sameTree.Count; i++) |
||||
|
{ |
||||
|
sameTree[i].Order = i; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,109 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using JetBrains.Annotations; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.Domain.Services; |
|
||||
using Volo.Abp.Uow; |
|
||||
using Volo.CmsKit.Pages; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
public class MenuManager : CmsKitDomainServiceBase |
|
||||
{ |
|
||||
protected IMenuRepository MenuRepository { get; } |
|
||||
|
|
||||
public MenuManager(IMenuRepository menuRepository) |
|
||||
{ |
|
||||
MenuRepository = menuRepository; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Creates a new instance of <see cref="Menu"/> without inserting into database.
|
|
||||
/// </summary>
|
|
||||
/// <param name="tenantId">Tenant Id of Menu.</param>
|
|
||||
/// <param name="name">Name of Menu.</param>
|
|
||||
/// <returns>Created instance.</returns>
|
|
||||
public virtual async Task<Menu> CreateAsync(Guid? tenantId, [NotNull] string name) |
|
||||
{ |
|
||||
var menu = new Menu( |
|
||||
GuidGenerator.Create(), |
|
||||
tenantId, |
|
||||
Check.NotNullOrEmpty(name, nameof(name), MenuConsts.MaxNameLength)); |
|
||||
|
|
||||
var existingMenuCount = await MenuRepository.GetCountAsync(); |
|
||||
|
|
||||
if (existingMenuCount == 0) |
|
||||
{ |
|
||||
menu.IsMainMenu = true; |
|
||||
} |
|
||||
|
|
||||
return menu; |
|
||||
} |
|
||||
|
|
||||
public virtual void SetPageUrl(MenuItem menuItem, Page page) |
|
||||
{ |
|
||||
menuItem.SetPageId(page.Id); |
|
||||
menuItem.SetUrl(PageConsts.UrlPrefix + page.Slug); |
|
||||
} |
|
||||
|
|
||||
[UnitOfWork] |
|
||||
public virtual async Task MoveAsync(Guid menuId, Guid menuItemId, Guid? newParentId, int position = 0) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true); |
|
||||
|
|
||||
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId) |
|
||||
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); |
|
||||
|
|
||||
if (newParentId.HasValue && !menu.Items.Any(a => a.Id == newParentId.Value)) |
|
||||
{ |
|
||||
throw new EntityNotFoundException(typeof(MenuItem), newParentId); |
|
||||
} |
|
||||
|
|
||||
menuItem.ParentId = newParentId; |
|
||||
menuItem.Order = position; |
|
||||
|
|
||||
OrganizeTreeOrderForMenuItem(menu, menuItem); |
|
||||
|
|
||||
await MenuRepository.UpdateAsync(menu); |
|
||||
} |
|
||||
|
|
||||
public virtual void OrganizeTreeOrderForMenuItem(Menu menu, MenuItem menuItem) |
|
||||
{ |
|
||||
var sameTree = menu.Items.Where(x => x.ParentId == menuItem.ParentId).OrderBy(x => x.Order).ToList(); |
|
||||
|
|
||||
sameTree.Remove(menuItem); // Remove if exists to prevent misordering with same order number
|
|
||||
|
|
||||
sameTree.Insert(menuItem.Order, menuItem); |
|
||||
|
|
||||
for (int i = 0; i < sameTree.Count; i++) |
|
||||
{ |
|
||||
sameTree[i].Order = i; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public virtual async Task SetMainMenuAsync(Guid menuId) |
|
||||
{ |
|
||||
var menus = await MenuRepository.GetCurrentAndNextMainMenusAsync(menuId ,includeDetails: false); |
|
||||
|
|
||||
foreach (var menu in menus) |
|
||||
{ |
|
||||
menu.IsMainMenu = menuId == menu.Id; |
|
||||
} |
|
||||
|
|
||||
await MenuRepository.UpdateManyAsync(menus); |
|
||||
} |
|
||||
|
|
||||
public virtual async Task UnSetMainMenuAsync(Guid menuId) |
|
||||
{ |
|
||||
var menu = await MenuRepository.GetAsync(menuId, includeDetails: false); |
|
||||
|
|
||||
menu.IsMainMenu = false; |
|
||||
|
|
||||
await MenuRepository.UpdateAsync(menu); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,13 +0,0 @@ |
|||||
using System.Linq; |
|
||||
using Microsoft.EntityFrameworkCore; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
public static class EfCoreMenuExtensions |
|
||||
{ |
|
||||
public static IQueryable<Menu> IncludeDetails(this IQueryable<Menu> source) |
|
||||
{ |
|
||||
return source.Include(i => i.Items); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
using Volo.CmsKit.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Volo.CmsKit.Menus |
||||
|
{ |
||||
|
public class EfCoreMenuItemRepository : EfCoreRepository<ICmsKitDbContext, MenuItem, Guid>, IMenuItemRepository |
||||
|
{ |
||||
|
public EfCoreMenuItemRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,40 +0,0 @@ |
|||||
using Microsoft.EntityFrameworkCore; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|
||||
using Volo.Abp.EntityFrameworkCore; |
|
||||
using Volo.CmsKit.EntityFrameworkCore; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
public class EfCoreMenuRepository : EfCoreRepository<ICmsKitDbContext, Menu, Guid>, IMenuRepository |
|
||||
{ |
|
||||
public EfCoreMenuRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public override async Task<IQueryable<Menu>> WithDetailsAsync() |
|
||||
{ |
|
||||
return (await base.WithDetailsAsync()).IncludeDetails(); |
|
||||
} |
|
||||
|
|
||||
public virtual async Task<Menu> FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default) |
|
||||
{ |
|
||||
return await (includeDetails ? await WithDetailsAsync() : await GetQueryableAsync()) |
|
||||
.FirstOrDefaultAsync(x => x.IsMainMenu, GetCancellationToken(cancellationToken)); |
|
||||
} |
|
||||
|
|
||||
public virtual async Task<List<Menu>> GetCurrentAndNextMainMenusAsync( |
|
||||
Guid nextMainMenuId, |
|
||||
bool includeDetails = true, |
|
||||
CancellationToken cancellationToken = default) |
|
||||
{ |
|
||||
return await (includeDetails ? await WithDetailsAsync() : await GetQueryableAsync()) |
|
||||
.Where(x => x.IsMainMenu || x.Id == nextMainMenuId) |
|
||||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,21 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using MongoDB.Driver; |
||||
|
using MongoDB.Driver.Linq; |
||||
|
using Volo.Abp.Domain.Repositories.MongoDB; |
||||
|
using Volo.Abp.MongoDB; |
||||
|
using Volo.CmsKit.Menus; |
||||
|
|
||||
|
namespace Volo.CmsKit.MongoDB.Menus |
||||
|
{ |
||||
|
public class MongoMenuItemRepository : MongoDbRepository<ICmsKitMongoDbContext, MenuItem, Guid>, IMenuItemRepository |
||||
|
{ |
||||
|
public MongoMenuItemRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,35 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using MongoDB.Driver; |
|
||||
using MongoDB.Driver.Linq; |
|
||||
using Volo.Abp.Domain.Repositories.MongoDB; |
|
||||
using Volo.Abp.MongoDB; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
|
|
||||
namespace Volo.CmsKit.MongoDB.Menus |
|
||||
{ |
|
||||
public class MongoMenuRepository : MongoDbRepository<ICmsKitMongoDbContext, Menu, Guid>, IMenuRepository |
|
||||
{ |
|
||||
public MongoMenuRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public virtual async Task<Menu> FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default) |
|
||||
{ |
|
||||
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) |
|
||||
.FirstOrDefaultAsync(x => x.IsMainMenu, GetCancellationToken(cancellationToken)); |
|
||||
} |
|
||||
|
|
||||
public virtual async Task<List<Menu>> GetCurrentAndNextMainMenusAsync(Guid nextMainMenuId, bool includeDetails = true, |
|
||||
CancellationToken cancellationToken = default) |
|
||||
{ |
|
||||
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) |
|
||||
.Where(x => x.IsMainMenu || x.Id == nextMainMenuId) |
|
||||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,12 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.CmsKit.Menus; |
||||
|
|
||||
|
namespace Volo.CmsKit.Public.Menus |
||||
|
{ |
||||
|
public interface IMenuItemPublicAppService : IApplicationService |
||||
|
{ |
||||
|
Task<List<MenuItemDto>> GetMenuItemsAsync(); |
||||
|
} |
||||
|
} |
||||
@ -1,11 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Application.Services; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
|
|
||||
namespace Volo.CmsKit.Public.Menus |
|
||||
{ |
|
||||
public interface IMenuPublicAppService : IApplicationService |
|
||||
{ |
|
||||
Task<MenuWithDetailsDto> GetMainMenuAsync(); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,43 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
using Volo.CmsKit.GlobalFeatures; |
||||
|
using Volo.CmsKit.Menus; |
||||
|
|
||||
|
namespace Volo.CmsKit.Public.Menus |
||||
|
{ |
||||
|
[RequiresGlobalFeature(typeof(MenuFeature))] |
||||
|
public class MenuItemPublicAppService : CmsKitPublicAppServiceBase, IMenuItemPublicAppService |
||||
|
{ |
||||
|
protected IMenuItemRepository MenuItemRepository { get; } |
||||
|
protected IDistributedCache<List<MenuItemDto>> DistributedCache { get; } |
||||
|
|
||||
|
public MenuItemPublicAppService( |
||||
|
IMenuItemRepository menuRepository, |
||||
|
IDistributedCache<List<MenuItemDto>> distributedCache) |
||||
|
{ |
||||
|
MenuItemRepository = menuRepository; |
||||
|
DistributedCache = distributedCache; |
||||
|
} |
||||
|
|
||||
|
public async Task<List<MenuItemDto>> GetMenuItemsAsync() |
||||
|
{ |
||||
|
var cachedMenu = await DistributedCache.GetOrAddAsync( |
||||
|
MenuApplicationConsts.MainMenuCacheKey, |
||||
|
async () => |
||||
|
{ |
||||
|
var menuItems = await MenuItemRepository.GetListAsync(); |
||||
|
|
||||
|
if (menuItems == null) |
||||
|
{ |
||||
|
return new(); |
||||
|
} |
||||
|
|
||||
|
return ObjectMapper.Map<List<MenuItem>, List<MenuItemDto>>(menuItems); |
||||
|
}); |
||||
|
|
||||
|
return cachedMenu; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,45 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.GlobalFeatures; |
|
||||
using Volo.CmsKit.GlobalFeatures; |
|
||||
using Volo.CmsKit.Menus; |
|
||||
|
|
||||
namespace Volo.CmsKit.Public.Menus |
|
||||
{ |
|
||||
[RequiresGlobalFeature(typeof(MenuFeature))] |
|
||||
public class MenuPublicAppService : CmsKitPublicAppServiceBase, IMenuPublicAppService |
|
||||
{ |
|
||||
protected IMenuRepository MenuRepository { get; } |
|
||||
|
|
||||
protected IDistributedCache<MenuWithDetailsDto> DistributedCache { get; } |
|
||||
|
|
||||
public MenuPublicAppService( |
|
||||
IMenuRepository menuRepository, |
|
||||
IDistributedCache<MenuWithDetailsDto> distributedCache) |
|
||||
{ |
|
||||
MenuRepository = menuRepository; |
|
||||
DistributedCache = distributedCache; |
|
||||
} |
|
||||
|
|
||||
public async Task<MenuWithDetailsDto> GetMainMenuAsync() |
|
||||
{ |
|
||||
var cachedMenu = await DistributedCache.GetOrAddAsync( |
|
||||
MenuApplicationConsts.MainMenuCacheKey, |
|
||||
async () => |
|
||||
{ |
|
||||
var menu = await MenuRepository.FindMainMenuAsync(includeDetails: true); |
|
||||
|
|
||||
if (menu == null) |
|
||||
{ |
|
||||
return new MenuWithDetailsDto(); |
|
||||
} |
|
||||
|
|
||||
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu); |
|
||||
}); |
|
||||
|
|
||||
return cachedMenu; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,21 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.CmsKit.Menus |
||||
|
{ |
||||
|
public abstract class MenuItemRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule> |
||||
|
where TStartupModule : IAbpModule |
||||
|
{ |
||||
|
|
||||
|
private readonly CmsKitTestData testData; |
||||
|
private readonly IMenuItemRepository menuItemRepository; |
||||
|
|
||||
|
public MenuItemRepository_Test() |
||||
|
{ |
||||
|
testData = GetRequiredService<CmsKitTestData>(); |
||||
|
menuItemRepository = GetRequiredService<IMenuItemRepository>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,51 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
using Shouldly; |
|
||||
using Volo.Abp.Modularity; |
|
||||
using Xunit; |
|
||||
|
|
||||
namespace Volo.CmsKit.Menus |
|
||||
{ |
|
||||
public abstract class MenuRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule> |
|
||||
where TStartupModule : IAbpModule |
|
||||
{ |
|
||||
|
|
||||
private readonly CmsKitTestData testData; |
|
||||
private readonly IMenuRepository menuRepository; |
|
||||
|
|
||||
public MenuRepository_Test() |
|
||||
{ |
|
||||
testData = GetRequiredService<CmsKitTestData>(); |
|
||||
menuRepository = GetRequiredService<IMenuRepository>(); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task GetMainMenuAsync_ShouldWorkProperly() |
|
||||
{ |
|
||||
var mainMenu = await menuRepository.FindMainMenuAsync(); |
|
||||
|
|
||||
mainMenu.ShouldNotBeNull(); |
|
||||
mainMenu.Id.ShouldBe(testData.Menu_1_Id); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task GetMainMenuAsync_ShouldWorkProperly_WithIncludeDetails() |
|
||||
{ |
|
||||
var mainMenu = await menuRepository.FindMainMenuAsync(includeDetails: true); |
|
||||
|
|
||||
mainMenu.ShouldNotBeNull(); |
|
||||
mainMenu.Id.ShouldBe(testData.Menu_1_Id); |
|
||||
mainMenu.Items.ShouldNotBeEmpty(); |
|
||||
mainMenu.Items.Count.ShouldBe(2); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public async Task GetCurrentAndNextMainMenusAsync_ShouldWorkProperly() |
|
||||
{ |
|
||||
var menus = await menuRepository.GetCurrentAndNextMainMenusAsync( |
|
||||
testData.Menu_2_Id); |
|
||||
|
|
||||
menus.ShouldNotBeEmpty(); |
|
||||
menus.Count.ShouldBe(2); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue