mirror of https://github.com/abpframework/abp.git
committed by
GitHub
88 changed files with 6013 additions and 17 deletions
File diff suppressed because it is too large
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace Volo.CmsKit.Migrations |
|||
{ |
|||
public partial class Added_Page : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "CmsPages", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|||
Title = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|||
Url = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false), |
|||
Description = table.Column<string>(type: "nvarchar(515)", maxLength: 515, nullable: true), |
|||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
|||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|||
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false), |
|||
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|||
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_CmsPages", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_CmsPages_TenantId_Url", |
|||
table: "CmsPages", |
|||
columns: new[] { "TenantId", "Url" }); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "CmsPages"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,24 @@ |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace Volo.CmsKit.Migrations |
|||
{ |
|||
public partial class Updated_Tag_Removed_HexColor : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "HexColor", |
|||
table: "CmsTags"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<string>( |
|||
name: "HexColor", |
|||
table: "CmsTags", |
|||
type: "nvarchar(6)", |
|||
maxLength: 6, |
|||
nullable: true); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
.jq-stars { |
|||
display: inline-block; |
|||
} |
|||
|
|||
.jq-rating-label { |
|||
font-size: 22px; |
|||
display: inline-block; |
|||
position: relative; |
|||
vertical-align: top; |
|||
font-family: helvetica, arial, verdana; |
|||
} |
|||
|
|||
.jq-star { |
|||
width: 100px; |
|||
height: 100px; |
|||
display: inline-block; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.jq-star-svg { |
|||
width: 100%; |
|||
height: 100% ; |
|||
} |
|||
|
|||
.jq-star:hover .fs-star-svg polygon { |
|||
} |
|||
|
|||
.jq-star-svg polygon { |
|||
stroke: #000; |
|||
stroke-linejoin: round; |
|||
} |
|||
|
|||
/* un-used */ |
|||
.jq-shadow { |
|||
-webkit-filter: drop-shadow( -2px -2px 2px #888 ); |
|||
filter: drop-shadow( -2px -2px 2px #888 ); |
|||
} |
|||
@ -0,0 +1 @@ |
|||
!function(a){"use strict";var b="starRating",c=function(){},d={totalStars:5,useFullStars:!1,emptyColor:"lightgray",hoverColor:"orange",activeColor:"gold",useGradient:!0,readOnly:!1,disableAfterRate:!0,starGradient:{start:"#FEF7CD",end:"#FF9511"},strokeWidth:0,strokeColor:"black",initialRating:0,starSize:40,callback:c,onHover:c,onLeave:c},e=function(c,e){var f;this.element=c,this.$el=a(c),this.settings=a.extend({},d,e),f=this.$el.data("rating")||this.settings.initialRating,this._state={rating:(Math.round(2*f)/2).toFixed(1)},this._uid=Math.floor(999*Math.random()),e.starGradient||this.settings.useGradient||(this.settings.starGradient.start=this.settings.starGradient.end=this.settings.activeColor),this._defaults=d,this._name=b,this.init()},f={init:function(){this.renderMarkup(),this.addListeners(),this.initRating()},addListeners:function(){this.settings.readOnly||(this.$stars.on("mouseover",this.hoverRating.bind(this)),this.$stars.on("mouseout",this.restoreState.bind(this)),this.$stars.on("click",this.handleRating.bind(this)))},hoverRating:function(a){var b=this.getIndex(a);this.paintStars(b,"hovered"),this.settings.onHover(b+1,this._state.rating,this.$el)},handleRating:function(a){var b=this.getIndex(a),c=b+1;this.applyRating(c,this.$el),this.executeCallback(c,this.$el),this.settings.disableAfterRate&&this.$stars.off()},applyRating:function(a){var b=a-1;this.paintStars(b,"active"),this._state.rating=b+1},restoreState:function(a){var b=this.getIndex(a),c=this._state.rating||-1;this.paintStars(c-1,"active"),this.settings.onLeave(b+1,this._state.rating,this.$el)},getIndex:function(b){var c=a(b.currentTarget),d=c.width(),e=a(b.target).attr("data-side");e=e?e:this.getOffsetByPixel(b,c,d),e=this.settings.useFullStars?"right":e;var f=c.index()-("left"===e?.5:0);return f=.5>f&&b.offsetX<d/4?-1:f},getOffsetByPixel:function(a,b,c){var d=a.pageX-b.offset().left;return c/2>=d&&!this.settings.useFullStars?"left":"right"},initRating:function(){this.paintStars(this._state.rating-1,"active")},paintStars:function(b,c){var d,e,f,g;a.each(this.$stars,function(h,i){d=a(i).find('polygon[data-side="left"]'),e=a(i).find('polygon[data-side="right"]'),f=g=b>=h?c:"empty",f=h-b===.5?c:f,d.attr("class","svg-"+f+"-"+this._uid),e.attr("class","svg-"+g+"-"+this._uid)}.bind(this))},renderMarkup:function(){for(var a='<div class="jq-star" style="width:'+this.settings.starSize+"px; height:"+this.settings.starSize+'px;"><svg version="1.0" class="jq-star-svg" shape-rendering="geometricPrecision" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="305px" height="305px" viewBox="60 -62 309 309" style="enable-background:new 64 -59 305 305; stroke-width:'+this.settings.strokeWidth+'px;" xml:space="preserve"><style type="text/css">.svg-empty-'+this._uid+"{fill:url(#"+this._uid+"_SVGID_1_);}.svg-hovered-"+this._uid+"{fill:url(#"+this._uid+"_SVGID_2_);}.svg-active-"+this._uid+"{fill:url(#"+this._uid+"_SVGID_3_);}</style>"+this.getLinearGradient(this._uid+"_SVGID_1_",this.settings.emptyColor,this.settings.emptyColor)+this.getLinearGradient(this._uid+"_SVGID_2_",this.settings.hoverColor,this.settings.hoverColor)+this.getLinearGradient(this._uid+"_SVGID_3_",this.settings.starGradient.start,this.settings.starGradient.end)+'<polygon data-side="left" class="svg-empty-'+this._uid+'" points="281.1,129.8 364,55.7 255.5,46.8 214,-59 172.5,46.8 64,55.4 146.8,129.7 121.1,241 213.9,181.1 213.9,181 306.5,241 " style="stroke: '+this.settings.strokeColor+'"/><polygon data-side="right" class="svg-empty-'+this._uid+'" points="364,55.7 255.5,46.8 214,-59 213.9,181 306.5,241 281.1,129.8 " style="stroke-dasharray: 230 232 210 0; stroke: '+this.settings.strokeColor+'"/></svg></div>',b="",c=0;c<this.settings.totalStars;c++)b+=a;this.$el.append(b),this.$stars=this.$el.find(".jq-star")},getLinearGradient:function(a,b,c){return'<linearGradient id="'+a+'" gradientUnits="userSpaceOnUse" x1="121.1501" y1="-70.35" x2="121.15" y2="125.0045"><stop offset="0" style="stop-color:'+b+'"/><stop offset="1" style="stop-color:'+c+'"/> </linearGradient>'},executeCallback:function(a,b){var c=this.settings.callback;c(a,b)}},g={unload:function(){var c="plugin_"+b,d=a(this),e=d.data(c).$stars;e.off(),d.removeData(c).remove()},setRating:function(c,d){var e="plugin_"+b,f=a(this),g=f.data(e);c>g.settings.totalStars||0>c||(d&&(c=Math.round(c)),g.applyRating(c))},getRating:function(){var c="plugin_"+b,d=a(this),e=d.data(c);return e._state.rating}};a.extend(e.prototype,f),a.fn[b]=function(c){if(!a.isPlainObject(c)){if(g.hasOwnProperty(c))return g[c].apply(this,Array.prototype.slice.call(arguments,1));a.error("Method "+c+" does not exist on "+b+".js")}return this.each(function(){a.data(this,"plugin_"+b)||a.data(this,"plugin_"+b,new e(this,c))})}}(jQuery,window,document); |
|||
@ -0,0 +1,7 @@ |
|||
namespace Volo.CmsKit |
|||
{ |
|||
public class CmsKitCommonRemoteServiceConsts |
|||
{ |
|||
public const string RemoteServiceName = "CmsKitCommon"; |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public class ContentDto : EntityDto<Guid> |
|||
{ |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public class GetContentInput |
|||
{ |
|||
public string EntityType { get; set; } |
|||
public string EntityId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public interface IContentAppService |
|||
{ |
|||
Task<ContentDto> GetAsync(GetContentInput input); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class CheckUrlInputDto |
|||
{ |
|||
[Required] |
|||
public string Url { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class CreatePageInputDto |
|||
{ |
|||
[Required] |
|||
public string Title { get; set; } |
|||
|
|||
[Required] |
|||
public string Url { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class CreatePageWithContentInputDto |
|||
{ |
|||
[Required] |
|||
public string Title { get; set; } |
|||
|
|||
[Required] |
|||
public string Url { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
[Required] |
|||
public string Content { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public interface IPageAppService |
|||
{ |
|||
Task<PageDto> GetAsync(Guid id); |
|||
|
|||
Task<PageDto> GetByUrlAsync([NotNull] string url); |
|||
|
|||
Task<PageDto> CreatePageAsync(CreatePageInputDto input); |
|||
|
|||
Task<PageDto> CreatePageWithContentAsync(CreatePageWithContentInputDto input); |
|||
|
|||
Task<PageDto> UpdatePageAsync(Guid id, UpdatePageInputDto input); |
|||
|
|||
Task<bool> DoesUrlExistAsync(CheckUrlInputDto input); |
|||
|
|||
Task UpdatePageContentAsync(Guid id, UpdatePageContentInputDto input); |
|||
|
|||
Task DeleteAsync(Guid id); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class PageDto : EntityDto<Guid> |
|||
{ |
|||
public string Title { get; set; } |
|||
|
|||
public string Url { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class PageWithContentDto : EntityDto<Guid> |
|||
{ |
|||
public string Title { get; set; } |
|||
|
|||
public string Url { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public ContentDto Content { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class UpdatePageContentInputDto |
|||
{ |
|||
[Required] |
|||
public string Content { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class UpdatePageInputDto |
|||
{ |
|||
[Required] |
|||
public string Title { get; set; } |
|||
|
|||
[Required] |
|||
public string Url { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class GetRelatedTagsInput |
|||
{ |
|||
[Required] |
|||
public string EntityType { get; set; } |
|||
|
|||
[Required] |
|||
public string EntityId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public interface ITagAppService : IApplicationService |
|||
{ |
|||
Task<List<TagDto>> GetAllRelatedTagsAsync(GetRelatedTagsInput input); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class TagDto : EntityDto<Guid> |
|||
{ |
|||
public string EntityType { get; set; } |
|||
|
|||
public string Name { get; protected set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using AutoMapper; |
|||
using Volo.CmsKit.Contents; |
|||
using Volo.CmsKit.Pages; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit |
|||
{ |
|||
public class CmsKitCommonApplicationAutoMapperProfile : Profile |
|||
{ |
|||
public CmsKitCommonApplicationAutoMapperProfile() |
|||
{ |
|||
CreateMap<Content, ContentDto>(); |
|||
|
|||
CreateMap<Tag, TagDto>(); |
|||
|
|||
CreateMap<Page, PageDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public class ContentAppService : CmsKitAppServiceBase, IContentAppService |
|||
{ |
|||
protected readonly IContentRepository ContentRepository; |
|||
|
|||
public ContentAppService(IContentRepository contentRepository) |
|||
{ |
|||
ContentRepository = contentRepository; |
|||
} |
|||
|
|||
public virtual async Task<ContentDto> GetAsync(GetContentInput input) |
|||
{ |
|||
var entity = await ContentRepository.GetAsync( |
|||
input.EntityType, |
|||
input.EntityId, |
|||
CurrentTenant.Id); |
|||
|
|||
return ObjectMapper.Map<Content, ContentDto>(entity); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class PageAppService : CmsKitAppServiceBase, IPageAppService |
|||
{ |
|||
protected readonly IPageRepository PageRepository; |
|||
protected readonly IContentRepository ContentRepository; |
|||
|
|||
public PageAppService(IPageRepository pageRepository, IContentRepository contentRepository) |
|||
{ |
|||
PageRepository = pageRepository; |
|||
ContentRepository = contentRepository; |
|||
} |
|||
|
|||
public virtual async Task<PageDto> GetAsync(Guid id) |
|||
{ |
|||
var page = await PageRepository.GetAsync(id); |
|||
|
|||
return ObjectMapper.Map<Page, PageDto>(page); |
|||
} |
|||
|
|||
public virtual async Task<PageDto> GetByUrlAsync(string url) |
|||
{ |
|||
var page = await PageRepository.GetByUrlAsync(url); |
|||
|
|||
return ObjectMapper.Map<Page, PageDto>(page); |
|||
} |
|||
|
|||
public virtual async Task<PageDto> CreatePageAsync(CreatePageInputDto input) |
|||
{ |
|||
var page = await CreatePageAsync(input.Title, input.Url, input.Description); |
|||
|
|||
await PageRepository.InsertAsync(page); |
|||
|
|||
return ObjectMapper.Map<Page, PageDto>(page); |
|||
} |
|||
|
|||
public virtual async Task<PageDto> CreatePageWithContentAsync(CreatePageWithContentInputDto input) |
|||
{ |
|||
var page = await CreatePageAsync(input.Title, input.Url, input.Description); |
|||
|
|||
await PageRepository.InsertAsync(page); |
|||
|
|||
var content = new Content( |
|||
GuidGenerator.Create(), |
|||
nameof(Page), |
|||
page.Id.ToString(), |
|||
input.Content, |
|||
page.TenantId); |
|||
|
|||
await ContentRepository.InsertAsync(content); |
|||
|
|||
return ObjectMapper.Map<Page, PageDto>(page); |
|||
} |
|||
|
|||
public virtual async Task<PageDto> UpdatePageAsync(Guid id, UpdatePageInputDto input) |
|||
{ |
|||
var page = await PageRepository.GetAsync(id); |
|||
|
|||
if (page.Url != input.Url) |
|||
{ |
|||
await CheckPageUrlAsync(input.Url); |
|||
} |
|||
|
|||
page.Title = input.Title; |
|||
page.Url = input.Url; |
|||
page.Description = input.Description; |
|||
|
|||
await PageRepository.UpdateAsync(page); |
|||
|
|||
return ObjectMapper.Map<Page, PageDto>(page); |
|||
} |
|||
|
|||
public virtual Task<bool> DoesUrlExistAsync(CheckUrlInputDto input) |
|||
{ |
|||
return PageRepository.DoesExistAsync(input.Url); |
|||
} |
|||
|
|||
public virtual async Task UpdatePageContentAsync(Guid id, UpdatePageContentInputDto input) |
|||
{ |
|||
var pageContent = await ContentRepository.GetAsync(nameof(Page), id.ToString()); |
|||
|
|||
pageContent.SetValue(input.Content); |
|||
|
|||
await ContentRepository.UpdateAsync(pageContent); |
|||
} |
|||
|
|||
public virtual async Task DeleteAsync(Guid id) |
|||
{ |
|||
await ContentRepository.DeleteAsync(nameof(Page), id.ToString(), CurrentTenant?.Id, CancellationToken.None); |
|||
await PageRepository.DeleteAsync(id, cancellationToken: CancellationToken.None); |
|||
} |
|||
|
|||
protected virtual async Task<Page> CreatePageAsync(string title, string url, string description) |
|||
{ |
|||
await CheckPageUrlAsync(url); |
|||
|
|||
return new Page(GuidGenerator.Create(), title, url, description, CurrentTenant?.Id); |
|||
} |
|||
|
|||
protected virtual async Task CheckPageUrlAsync(string url) |
|||
{ |
|||
if (await PageRepository.DoesExistAsync(url)) |
|||
{ |
|||
throw new UserFriendlyException("Url exist"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class TagAppService : CmsKitAppServiceBase, ITagAppService |
|||
{ |
|||
protected readonly ITagManager TagManager; |
|||
protected readonly ITagRepository TagRepository; |
|||
protected readonly IEntityTagRepository EntityTagRepository; |
|||
|
|||
public TagAppService( |
|||
ITagManager tagManager, |
|||
ITagRepository tagRepository, |
|||
IEntityTagRepository entityTagRepository) |
|||
{ |
|||
TagManager = tagManager; |
|||
TagRepository = tagRepository; |
|||
EntityTagRepository = entityTagRepository; |
|||
} |
|||
|
|||
public virtual async Task<List<TagDto>> GetAllRelatedTagsAsync(GetRelatedTagsInput input) |
|||
{ |
|||
var entities = await TagRepository.GetAllRelatedTagsAsync( |
|||
input.EntityType, |
|||
input.EntityId, |
|||
CurrentTenant.Id); |
|||
|
|||
return ObjectMapper.Map<List<Tag>, List<TagDto>>(entities); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp; |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.Controllers.Contents |
|||
{ |
|||
|
|||
[RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("cms-kit")] |
|||
[Route("api/cms-kit/contents")] |
|||
public class ContentController : CmsKitControllerBase, IContentAppService |
|||
{ |
|||
protected readonly IContentAppService _contentAppService; |
|||
|
|||
public ContentController(IContentAppService contentAppService) |
|||
{ |
|||
_contentAppService = contentAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual Task<ContentDto> GetAsync(GetContentInput input) |
|||
{ |
|||
return _contentAppService.GetAsync(input); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp; |
|||
using Volo.CmsKit.Pages; |
|||
|
|||
namespace Volo.CmsKit.Controllers.Pages |
|||
{ |
|||
[RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("cms-kit")] |
|||
[Route("api/cms-kit/pages")] |
|||
public class PageController : CmsKitControllerBase, IPageAppService |
|||
{ |
|||
protected readonly IPageAppService PageAppService; |
|||
|
|||
public PageController(IPageAppService pageAppService) |
|||
{ |
|||
PageAppService = pageAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public virtual Task<PageDto> GetAsync(Guid id) |
|||
{ |
|||
return PageAppService.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("url/{url}")] |
|||
public Task<PageDto> GetByUrlAsync(string url) |
|||
{ |
|||
return PageAppService.GetByUrlAsync(url); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("create")] |
|||
public virtual Task<PageDto> CreatePageAsync(CreatePageInputDto input) |
|||
{ |
|||
return PageAppService.CreatePageAsync(input); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("create-with-content")] |
|||
public virtual Task<PageDto> CreatePageWithContentAsync(CreatePageWithContentInputDto input) |
|||
{ |
|||
return PageAppService.CreatePageWithContentAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
public virtual Task<PageDto> UpdatePageAsync(Guid id, UpdatePageInputDto input) |
|||
{ |
|||
return PageAppService.UpdatePageAsync(id, input); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("does-url-exist")] |
|||
public virtual Task<bool> DoesUrlExistAsync(CheckUrlInputDto input) |
|||
{ |
|||
return PageAppService.DoesUrlExistAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("update-content/{id}")] |
|||
public virtual Task UpdatePageContentAsync(Guid id, UpdatePageContentInputDto input) |
|||
{ |
|||
return PageAppService.UpdatePageContentAsync(id, input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return PageAppService.DeleteAsync(id); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.Controllers.Tags |
|||
{ |
|||
[RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("cms-kit")] |
|||
[Route("api/cms-kit/tags")] |
|||
public class TagController : CmsKitControllerBase, ITagAppService |
|||
{ |
|||
protected readonly ITagAppService TagAppService; |
|||
|
|||
public TagController(ITagAppService tagAppService) |
|||
{ |
|||
TagAppService = tagAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
public Task<List<TagDto>> GetAllRelatedTagsAsync(GetRelatedTagsInput input) |
|||
{ |
|||
return TagAppService.GetAllRelatedTagsAsync(input); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.CmsKit.Web.Contents |
|||
{ |
|||
public interface IContentRenderer |
|||
{ |
|||
Task<string> RenderAsync(string value); |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.CmsKit.Web.Contents |
|||
{ |
|||
public class PlainTextContentRenderer : IContentRenderer, ITransientDependency |
|||
{ |
|||
public Task<string> RenderAsync(string value) |
|||
{ |
|||
return Task.FromResult(value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
@page "{pageUrl}" |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.CmsKit.Localization |
|||
@using Volo.CmsKit.Web.Pages.CmsKit.Pages |
|||
@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Pages |
|||
@model IndexModel |
|||
@inject IHtmlLocalizer<CmsKitResource> L |
|||
|
|||
@await Component.InvokeAsync(typeof(DefaultPageViewComponent), |
|||
new |
|||
{ |
|||
pageId = Model.Page.Id, |
|||
title = Model.Page.Title, |
|||
description = Model.Page.Description |
|||
}) |
|||
@ -0,0 +1,26 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.CmsKit.Pages; |
|||
|
|||
namespace Volo.CmsKit.Web.Pages.CmsKit.Pages |
|||
{ |
|||
public class IndexModel : CommonPageModel |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string PageUrl { get; set; } |
|||
|
|||
protected readonly IPageAppService PageAppService; |
|||
|
|||
public PageDto Page; |
|||
|
|||
public IndexModel(IPageAppService pageAppService) |
|||
{ |
|||
PageAppService = pageAppService; |
|||
} |
|||
|
|||
public async Task OnGetAsync() |
|||
{ |
|||
Page = await PageAppService.GetByUrlAsync(PageUrl); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.CmsKit.Contents; |
|||
using Volo.CmsKit.Web.Contents; |
|||
|
|||
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Contents |
|||
{ |
|||
[ViewComponent(Name = "CmsContent")] |
|||
public class ContentViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IContentRenderer contentRenderer; |
|||
private readonly IContentAppService contentAppService; |
|||
|
|||
public ContentViewComponent( |
|||
IContentRenderer contentRenderer, |
|||
IContentAppService contentAppService) |
|||
{ |
|||
this.contentRenderer = contentRenderer; |
|||
this.contentAppService = contentAppService; |
|||
} |
|||
|
|||
public virtual async Task<IViewComponentResult> InvokeAsync( |
|||
string entityType, |
|||
string entityId) |
|||
{ |
|||
var content = await contentAppService.GetAsync(new GetContentInput |
|||
{ |
|||
EntityId = entityId, |
|||
EntityType = entityType |
|||
}); |
|||
|
|||
var viewModel = new ContentViewModel |
|||
{ |
|||
EntityId = entityId, |
|||
EntityType = entityType, |
|||
ContentId = content.Id, |
|||
Rendered = await contentRenderer.RenderAsync(content.Value) |
|||
}; |
|||
|
|||
return View("~/Pages/CmsKit/Shared/Components/Contents/Default.cshtml", viewModel); |
|||
} |
|||
|
|||
public class ContentViewModel |
|||
{ |
|||
public Guid ContentId { get; set; } |
|||
public string EntityType { get; set; } |
|||
|
|||
public string EntityId { get; set; } |
|||
|
|||
public string Rendered { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.CmsKit.Localization |
|||
@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Contents.ContentViewComponent.ContentViewModel |
|||
|
|||
<div> |
|||
@Html.Raw(Model.Rendered) |
|||
</div> |
|||
@ -0,0 +1,21 @@ |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
|
|||
@using Microsoft.AspNetCore.Mvc.RazorPages |
|||
@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Contents |
|||
@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Pages.PageViewModel |
|||
|
|||
<abp-card> |
|||
<abp-card-header> |
|||
<h3> |
|||
@Model.Title |
|||
</h3> |
|||
</abp-card-header> |
|||
|
|||
<abp-card-body> |
|||
<p> |
|||
@Model.Description |
|||
</p> |
|||
|
|||
@await Component.InvokeAsync(typeof(ContentViewComponent), new { entityType = nameof(Page), entityId = Model.Id.ToString() }) |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.CmsKit.Pages; |
|||
|
|||
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Pages |
|||
{ |
|||
[ViewComponent(Name = "CmsDefaultPage")] |
|||
public class DefaultPageViewComponent : AbpViewComponent |
|||
{ |
|||
protected readonly IPageAppService PageAppService; |
|||
|
|||
public DefaultPageViewComponent(IPageAppService pageAppService) |
|||
{ |
|||
PageAppService = pageAppService; |
|||
} |
|||
|
|||
public virtual async Task<IViewComponentResult> InvokeAsync(Guid pageId, string title, string description) |
|||
{ |
|||
var model = new PageViewModel |
|||
{ |
|||
Id = pageId, |
|||
Title = title, |
|||
Description = description |
|||
}; |
|||
|
|||
return View("~/Pages/CmsKit/Shared/Components/Pages/Default.cshtml", model); |
|||
} |
|||
} |
|||
|
|||
public class PageViewModel |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string Title { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Tags |
|||
|
|||
@model TagViewComponent.TagViewModel |
|||
|
|||
@if (Model.Tags != null) |
|||
{ |
|||
foreach (var tag in Model.Tags) |
|||
{ |
|||
<span class="cmskit-tag"> |
|||
@tag.Name |
|||
</span> |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Tags |
|||
{ |
|||
[ViewComponent(Name = "CmsTags")] |
|||
public class TagViewComponent : AbpViewComponent |
|||
{ |
|||
protected readonly ITagAppService TagAppService; |
|||
|
|||
public TagViewComponent(ITagAppService tagAppService) |
|||
{ |
|||
TagAppService = tagAppService; |
|||
} |
|||
|
|||
public virtual async Task<IViewComponentResult> InvokeAsync( |
|||
string entityType, |
|||
string entityId) |
|||
{ |
|||
var tagDtos = await TagAppService.GetAllRelatedTagsAsync(new GetRelatedTagsInput |
|||
{ |
|||
EntityId = entityId, |
|||
EntityType = entityType |
|||
}); |
|||
|
|||
var viewModel = new TagViewModel |
|||
{ |
|||
EntityId = entityId, |
|||
EntityType = entityType, |
|||
Tags = tagDtos |
|||
}; |
|||
|
|||
return View("~/Pages/CmsKit/Shared/Components/Tags/Default.cshtml", viewModel); |
|||
} |
|||
|
|||
public class TagViewModel |
|||
{ |
|||
public List<TagDto> Tags { get; set; } |
|||
public string EntityId { get; set; } |
|||
public string EntityType { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
using Volo.CmsKit.Localization; |
|||
|
|||
namespace Volo.CmsKit.Web.Pages |
|||
{ |
|||
public abstract class CommonPageModel : AbpPageModel |
|||
{ |
|||
protected CommonPageModel() |
|||
{ |
|||
LocalizationResourceType = typeof(CmsKitResource); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using Volo.CmsKit.Entities; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public static class ContentConsts |
|||
{ |
|||
public static int MaxEntityTypeLength { get; set; } = CmsEntityConsts.MaxEntityTypeLength; |
|||
|
|||
public static int MaxEntityIdLength { get; set; } = CmsEntityConsts.MaxEntityIdLength; |
|||
|
|||
// TODO: consider
|
|||
public static int MaxValueLength = int.MaxValue; |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.GlobalFeatures; |
|||
|
|||
namespace Volo.CmsKit.GlobalFeatures |
|||
{ |
|||
[GlobalFeatureName(Name)] |
|||
public class ContentsFeature : GlobalFeature |
|||
{ |
|||
public const string Name = "CmsKit.Contents"; |
|||
|
|||
internal ContentsFeature( |
|||
[NotNull] GlobalCmsKitFeatures cmsKit |
|||
) : base(cmsKit) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.GlobalFeatures; |
|||
|
|||
namespace Volo.CmsKit.GlobalFeatures |
|||
{ |
|||
[GlobalFeatureName(Name)] |
|||
public class TagsFeature : GlobalFeature |
|||
{ |
|||
public const string Name = "CmsKit.Tags"; |
|||
|
|||
internal TagsFeature( |
|||
[NotNull] GlobalCmsKitFeatures cmsKit |
|||
) : base(cmsKit) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class PageConsts |
|||
{ |
|||
public static int MaxTitleLength = 256; |
|||
|
|||
public static int MaxUrlLength = 256; |
|||
|
|||
public static int MaxDescriptionLength = 515; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.CmsKit.Entities; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public static class TagConsts |
|||
{ |
|||
public static int MaxEntityTypeLength { get; set; } = CmsEntityConsts.MaxEntityTypeLength; |
|||
|
|||
public static int MaxNameLength { get; set; } = 32; |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public class Content : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; set; } |
|||
|
|||
public virtual string EntityType { get; set; } |
|||
|
|||
public virtual string EntityId { get; set; } |
|||
|
|||
public virtual string Value { get; protected set; } |
|||
|
|||
protected Content() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public Content(Guid id, [NotNull] string entityType, [NotNull] string entityId, [NotNull] string value, Guid? tenantId = null) : base(id) |
|||
{ |
|||
EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType), ContentConsts.MaxEntityTypeLength); |
|||
EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId), ContentConsts.MaxEntityIdLength); |
|||
SetValue(value); |
|||
|
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
public void SetValue([NotNull] string value) |
|||
{ |
|||
Value = Check.NotNullOrWhiteSpace(value, nameof(value), ContentConsts.MaxValueLength); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public interface IContentRepository : IBasicRepository<Content, Guid> |
|||
{ |
|||
Task<Content> GetAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Content> FindAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task DeleteAsync([NotNull] string entityType, [NotNull] string entityId, Guid? tenantId = null, CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public interface IPageRepository : IBasicRepository<Page, Guid> |
|||
{ |
|||
Task<Page> GetByUrlAsync(string url); |
|||
|
|||
Task<Page> FindByUrlAsync(string url); |
|||
|
|||
Task<bool> DoesExistAsync(string url); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class Page : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
|
|||
public virtual string Title { get; set; } |
|||
|
|||
public virtual string Url { get; set; } |
|||
|
|||
public virtual string Description { get; set; } |
|||
|
|||
protected Page() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public Page(Guid id, [NotNull] string title, [NotNull] string url, [CanBeNull] string description, Guid? tenantId = null) : base(id) |
|||
{ |
|||
Title = Check.NotNullOrWhiteSpace(title, nameof(title), PageConsts.MaxTitleLength); |
|||
Url = Check.NotNullOrWhiteSpace(url, nameof(url), PageConsts.MaxUrlLength); |
|||
Description = Check.Length(description, nameof(description), PageConsts.MaxDescriptionLength); |
|||
|
|||
TenantId = tenantId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class EntityTag : Entity, IMultiTenant |
|||
{ |
|||
public virtual Guid TagId { get; set; } |
|||
|
|||
public virtual string EntityId { get; set; } |
|||
|
|||
public virtual Guid? TenantId { get; set; } |
|||
|
|||
protected EntityTag() |
|||
{ |
|||
} |
|||
|
|||
public EntityTag(Guid tagId, string entityId, Guid? tenantId = null) |
|||
{ |
|||
TagId = tagId; |
|||
EntityId = entityId; |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
public override object[] GetKeys() |
|||
{ |
|||
return new object[] { TagId, EntityId }; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public interface IEntityTagRepository : IBasicRepository<EntityTag> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public interface ITagManager : IDomainService |
|||
{ |
|||
Task<Tag> InsertAsync( |
|||
Guid id, |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Tag> UpdateAsync( |
|||
Guid id, |
|||
[NotNull] string name, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Tag> GetOrAddAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public interface ITagRepository : IBasicRepository<Tag, Guid> |
|||
{ |
|||
Task<Tag> GetAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<bool> AnyAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Tag> FindAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<Tag>> GetAllRelatedTagsAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class Tag : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
public string EntityType { get; set; } |
|||
|
|||
public string Name { get; protected set; } |
|||
|
|||
public Guid? TenantId { get; set; } |
|||
|
|||
protected Tag() |
|||
{ |
|||
} |
|||
|
|||
public Tag( |
|||
Guid id, |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null) : base(id) |
|||
{ |
|||
EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType), TagConsts.MaxEntityTypeLength); |
|||
SetName(name); |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
public void SetName(string name) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name), TagConsts.MaxNameLength); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class TagManager : DomainService, ITagManager |
|||
{ |
|||
private readonly ITagRepository _tagRepository; |
|||
|
|||
public TagManager(ITagRepository tagRepository) |
|||
{ |
|||
_tagRepository = tagRepository; |
|||
} |
|||
|
|||
public async Task<Tag> GetOrAddAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var entity = await _tagRepository.FindAsync(entityType, name, tenantId, cancellationToken); |
|||
|
|||
if (entity == null) |
|||
{ |
|||
entity = await InsertAsync(GuidGenerator.Create(), entityType, name, tenantId, cancellationToken); |
|||
} |
|||
|
|||
return entity; |
|||
} |
|||
|
|||
public async Task<Tag> InsertAsync( |
|||
Guid id, |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
if (await _tagRepository.AnyAsync(entityType, name, tenantId, cancellationToken)) |
|||
{ |
|||
throw new BusinessException(message: "Tag already exist!"); // Already Exist
|
|||
} |
|||
|
|||
return await _tagRepository.InsertAsync( |
|||
new Tag( |
|||
id, |
|||
entityType, |
|||
name, |
|||
tenantId), |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
public async Task<Tag> UpdateAsync( |
|||
Guid id, |
|||
[NotNull] string name, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var entity = await _tagRepository.GetAsync(id, cancellationToken: cancellationToken); |
|||
|
|||
if (name != entity.Name && await _tagRepository.AnyAsync(entity.EntityType, name, entity.TenantId, cancellationToken)) |
|||
{ |
|||
throw new BusinessException(message: "Tag already exist!"); // Already Exist
|
|||
} |
|||
|
|||
entity.SetName(name); |
|||
|
|||
return await _tagRepository.UpdateAsync(entity); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.CmsKit.EntityFrameworkCore; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public class EfCoreContentRepository : EfCoreRepository<ICmsKitDbContext, Content, Guid>, IContentRepository |
|||
{ |
|||
public EfCoreContentRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public Task<Content> GetAsync( |
|||
string entityType, |
|||
string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return GetAsync(x => |
|||
!x.IsDeleted && |
|||
x.EntityType == entityType && |
|||
x.EntityId == entityId && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken |
|||
); |
|||
} |
|||
|
|||
public Task<Content> FindAsync( |
|||
string entityType, |
|||
string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return FindAsync(x => |
|||
!x.IsDeleted && |
|||
x.EntityType == entityType && |
|||
x.EntityId == entityId && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken |
|||
); |
|||
} |
|||
|
|||
public Task DeleteAsync(string entityType, string entityId, Guid? tenantId = null, CancellationToken cancellationToken = default) |
|||
{ |
|||
return DeleteAsync(x => |
|||
x.EntityType == entityType && |
|||
x.EntityId == entityId && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.CmsKit.EntityFrameworkCore; |
|||
|
|||
namespace Volo.CmsKit.Pages |
|||
{ |
|||
public class EfCorePageRepository : EfCoreRepository<ICmsKitDbContext, Page, Guid>, IPageRepository |
|||
{ |
|||
public EfCorePageRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public Task<Page> GetByUrlAsync(string url) |
|||
{ |
|||
return GetAsync(x => x.Url == url); |
|||
} |
|||
|
|||
public Task<Page> FindByUrlAsync(string url) |
|||
{ |
|||
return FindAsync(x => x.Url == url); |
|||
} |
|||
|
|||
public Task<bool> DoesExistAsync(string url) |
|||
{ |
|||
return DbSet.AnyAsync(x => x.Url == url); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.CmsKit.EntityFrameworkCore; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class EfCoreEntityTagRepository: EfCoreRepository<ICmsKitDbContext, EntityTag>, IEntityTagRepository |
|||
{ |
|||
public EfCoreEntityTagRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
using JetBrains.Annotations; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
using Volo.CmsKit.EntityFrameworkCore; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class EfCoreTagRepository : EfCoreRepository<ICmsKitDbContext, Tag, Guid>, ITagRepository |
|||
{ |
|||
public EfCoreTagRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public virtual Task<bool> AnyAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return DbSet.AnyAsync(x => |
|||
x.EntityType == entityType && |
|||
x.Name == name && |
|||
x.TenantId == tenantId, |
|||
cancellationToken); |
|||
} |
|||
|
|||
public virtual Task<Tag> GetAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return GetAsync(x => |
|||
x.EntityType == entityType && |
|||
x.Name == name && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
public virtual Task<Tag> FindAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return FindAsync(x => |
|||
x.EntityType == entityType && |
|||
x.Name == name && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
public virtual async Task<List<Tag>> GetAllRelatedTagsAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var entityTagIds = await DbContext.Set<EntityTag>() |
|||
.Where(q => q.EntityId == entityId && q.TenantId == tenantId) |
|||
.Select(q => q.TagId) |
|||
.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); |
|||
|
|||
var query = DbSet |
|||
.Where(x => x.EntityType == entityType && |
|||
x.TenantId == tenantId && |
|||
entityTagIds.Contains(x.Id)); |
|||
|
|||
return await query.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Contents |
|||
{ |
|||
public class MongoContentRepository : MongoDbRepository<ICmsKitMongoDbContext, Content, Guid>, IContentRepository |
|||
{ |
|||
public MongoContentRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public Task<Content> GetAsync( |
|||
string entityType, |
|||
string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return GetAsync(x => |
|||
!x.IsDeleted && |
|||
x.EntityType == entityType && |
|||
x.EntityId == entityId && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken |
|||
); |
|||
} |
|||
|
|||
public Task<Content> FindAsync( |
|||
string entityType, |
|||
string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return FindAsync(x => |
|||
!x.IsDeleted && |
|||
x.EntityType == entityType && |
|||
x.EntityId == entityId && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken |
|||
); |
|||
} |
|||
|
|||
public Task DeleteAsync(string entityType, string entityId, Guid? tenantId = null, CancellationToken cancellationToken = default) |
|||
{ |
|||
return DeleteAsync(x => |
|||
x.EntityType == entityType && |
|||
x.EntityId == entityId && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using MongoDB.Driver.Linq; |
|||
using Volo.Abp.Domain.Repositories.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
using Volo.CmsKit.Pages; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Pages |
|||
{ |
|||
public class MongoPageRepository : MongoDbRepository<ICmsKitMongoDbContext, Page, Guid>, IPageRepository |
|||
{ |
|||
public MongoPageRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public Task<Page> GetByUrlAsync(string url) |
|||
{ |
|||
return GetAsync(x => x.Url == url); |
|||
} |
|||
|
|||
public Task<Page> FindByUrlAsync(string url) |
|||
{ |
|||
return FindAsync(x => x.Url == url); |
|||
} |
|||
|
|||
public Task<bool> DoesExistAsync(string url) |
|||
{ |
|||
return GetMongoQueryable().AnyAsync(x => x.Url == url); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.Domain.Repositories.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Tags |
|||
{ |
|||
public class MongoEntityTagRepository: MongoDbRepository<ICmsKitMongoDbContext, EntityTag>, IEntityTagRepository |
|||
{ |
|||
public MongoEntityTagRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
using JetBrains.Annotations; |
|||
using MongoDB.Driver; |
|||
using MongoDB.Driver.Linq; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
using Volo.CmsKit.Tags; |
|||
using Tag = Volo.CmsKit.Tags.Tag; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Tags |
|||
{ |
|||
public class MongoTagRepository : MongoDbRepository<ICmsKitMongoDbContext, Volo.CmsKit.Tags.Tag, Guid>, ITagRepository |
|||
{ |
|||
public MongoTagRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public Task<bool> AnyAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return GetMongoQueryable() |
|||
.AnyAsync(x => |
|||
x.EntityType == entityType && |
|||
x.Name == name && |
|||
x.TenantId == tenantId, |
|||
cancellationToken); |
|||
} |
|||
|
|||
public Task<Tag> GetAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return GetAsync(x => |
|||
x.EntityType == entityType && |
|||
x.Name == name && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
public Task<Tag> FindAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return FindAsync(x => |
|||
x.EntityType == entityType && |
|||
x.Name == name && |
|||
x.TenantId == tenantId, |
|||
cancellationToken: cancellationToken); |
|||
} |
|||
|
|||
public virtual async Task<List<Tag>> GetAllRelatedTagsAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var entityTagIds = await DbContext.EntityTags.AsQueryable() |
|||
.Where(q => q.EntityId == entityId && q.TenantId == tenantId) |
|||
.Select(q => q.TagId) |
|||
.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); |
|||
|
|||
var query = await Collection.FindAsync(Builders<Tag>.Filter.And(new[] |
|||
{ |
|||
Builders<Tag>.Filter.Eq(x =>x.EntityType, entityType), |
|||
Builders<Tag>.Filter.Eq(x =>x.TenantId, tenantId), |
|||
Builders<Tag>.Filter.In(x => x.Id, entityTagIds), |
|||
})); |
|||
|
|||
var result = await query.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); |
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class TagManager_Tests : CmsKitDomainTestBase |
|||
{ |
|||
private readonly CmsKitTestData _cmsKitTestData; |
|||
private readonly TagManager _tagManager; |
|||
|
|||
private readonly ITagRepository _tagRepository; |
|||
|
|||
public TagManager_Tests() |
|||
{ |
|||
_cmsKitTestData = GetRequiredService<CmsKitTestData>(); |
|||
_tagManager = GetRequiredService<TagManager>(); |
|||
_tagRepository = GetRequiredService<ITagRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldAddWhenGettingAsync() |
|||
{ |
|||
var newTagEntityType = "testEntity"; |
|||
var newTagName = "test_tag_2123"; |
|||
|
|||
var doesExist = await _tagRepository.AnyAsync(newTagEntityType, newTagName); |
|||
|
|||
doesExist.ShouldBeFalse(); |
|||
|
|||
var newTag = await _tagManager.GetOrAddAsync(newTagEntityType, newTagName); |
|||
|
|||
newTag.ShouldNotBeNull(); |
|||
|
|||
var doesExistAgain = await _tagRepository.AnyAsync(newTagEntityType, newTagName); |
|||
|
|||
doesExistAgain.ShouldBeTrue(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotAddWhenGettingAsync() |
|||
{ |
|||
var tagName = _cmsKitTestData.Content_1_Tags[0]; |
|||
|
|||
var tag = await _tagRepository.GetAsync(_cmsKitTestData.Content_1_EntityType, tagName); |
|||
|
|||
var newTag = await _tagManager.GetOrAddAsync(_cmsKitTestData.Content_1_EntityType, tag.Name); |
|||
|
|||
newTag.ShouldNotBeNull(); |
|||
|
|||
newTag.Id.ShouldBe(tag.Id); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldInsert() |
|||
{ |
|||
var tag = await _tagManager.InsertAsync(Guid.NewGuid(), "test", "test"); |
|||
|
|||
tag.ShouldNotBeNull(); |
|||
|
|||
var doesExist = await _tagRepository.AnyAsync("test", "test"); |
|||
|
|||
doesExist.ShouldBeTrue(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotInsert() |
|||
{ |
|||
var type = _cmsKitTestData.Content_1_EntityType; |
|||
var name = _cmsKitTestData.Content_1_Tags[0]; |
|||
|
|||
Should.Throw<Exception>(async () => await _tagManager.InsertAsync(Guid.NewGuid(), type, name)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldUpdate() |
|||
{ |
|||
var type = _cmsKitTestData.Content_1_EntityType; |
|||
var name = _cmsKitTestData.Content_1_Tags[0]; |
|||
var newName = name + "-updated"; |
|||
|
|||
var tag = await _tagRepository.GetAsync(type, name); |
|||
|
|||
await _tagManager.UpdateAsync(tag.Id, newName); |
|||
|
|||
var updatedTag = await _tagRepository.GetAsync(type, newName); |
|||
|
|||
updatedTag.Id.ShouldBe(tag.Id); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotUpdate() |
|||
{ |
|||
var type = _cmsKitTestData.Content_1_EntityType; |
|||
var name = _cmsKitTestData.Content_1_Tags[0]; |
|||
var newName = _cmsKitTestData.Content_1_Tags[1]; |
|||
|
|||
var tag = await _tagRepository.GetAsync(type, name); |
|||
|
|||
Should.Throw<Exception>(async () => await _tagManager.UpdateAsync(tag.Id, newName)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.CmsKit.Contents; |
|||
|
|||
namespace Volo.CmsKit.EntityFrameworkCore.Contents |
|||
{ |
|||
public class ContentRepository_Test : ContentRepository_Tests<CmsKitEntityFrameworkCoreTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.EntityFrameworkCore.Tags |
|||
{ |
|||
public class TagRepository_Test : TagRepository_Test<CmsKitEntityFrameworkCoreTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.CmsKit.Contents; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Contents |
|||
{ |
|||
[Collection(MongoTestCollection.Name)] |
|||
public class ContentRepository_Test : ContentRepository_Tests<CmsKitMongoDbTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.CmsKit.Tags; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Tags |
|||
{ |
|||
[Collection(MongoTestCollection.Name)] |
|||
public class TagRepository_Test : TagRepository_Test<CmsKitMongoDbTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Contents |
|||
{ |
|||
public abstract class ContentRepository_Tests<TStartupModule> : CmsKitTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
private readonly CmsKitTestData _cmsKitTestData; |
|||
private readonly IContentRepository _contentRepository; |
|||
|
|||
protected ContentRepository_Tests() |
|||
{ |
|||
_cmsKitTestData = GetRequiredService<CmsKitTestData>(); |
|||
_contentRepository = GetRequiredService<IContentRepository>(); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData("Lyrics", "1", "First things first")] |
|||
[InlineData("LyricsAlso", "2", "Second thing second")] |
|||
public async Task ShouldGetAsync(string entityType, string entityId, string contentStartsWith = null) |
|||
{ |
|||
var content = await _contentRepository.GetAsync(entityType, entityId); |
|||
|
|||
content.ShouldNotBeNull(); |
|||
|
|||
if (contentStartsWith != null) |
|||
{ |
|||
content.Value.ShouldStartWith(contentStartsWith); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotGetAsync() |
|||
{ |
|||
Should.Throw<EntityNotFoundException>( |
|||
async () |
|||
=> |
|||
await _contentRepository.GetAsync("not_exist_entity", Guid.NewGuid().ToString())); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldFindAsync() |
|||
{ |
|||
var content = |
|||
await _contentRepository.FindAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.Content_1_Id); |
|||
|
|||
content.ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotFindAsync() |
|||
{ |
|||
var content = await _contentRepository.FindAsync("not_exist_entity", Guid.NewGuid().ToString()); |
|||
|
|||
content.ShouldBeNull(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,116 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public abstract class TagRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
private readonly CmsKitTestData _cmsKitTestData; |
|||
private readonly ITagRepository _tagRepository; |
|||
|
|||
protected TagRepository_Test() |
|||
{ |
|||
_cmsKitTestData = GetRequiredService<CmsKitTestData>(); |
|||
_tagRepository = GetRequiredService<ITagRepository>(); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData("Lyrics", "Imagine Dragons")] |
|||
[InlineData("Lyrics", "Music")] |
|||
[InlineData("LyricsAlso", "Imagine Dragons")] |
|||
[InlineData("LyricsAlso", "Music")] |
|||
[InlineData("LyricsAlso", "Most Loved Part")] |
|||
public async Task ShouldGetAsync(string entityType, string name) |
|||
{ |
|||
var tag = await _tagRepository.GetAsync(entityType, name); |
|||
|
|||
tag.ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotGetAsync() |
|||
{ |
|||
Should.Throw<EntityNotFoundException>( |
|||
async () => await _tagRepository.GetAsync("not_exist_entity", Guid.NewGuid().ToString()) |
|||
); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData("Lyrics", "Imagine Dragons")] |
|||
[InlineData("Lyrics", "Music")] |
|||
[InlineData("LyricsAlso", "Imagine Dragons")] |
|||
[InlineData("LyricsAlso", "Music")] |
|||
[InlineData("LyricsAlso", "Most Loved Part")] |
|||
public async Task ShouldExistAsync(string entityType, string name) |
|||
{ |
|||
var tag = await _tagRepository.AnyAsync(entityType, name); |
|||
|
|||
tag.ShouldBeTrue(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotExistAsync() |
|||
{ |
|||
var tag = await _tagRepository.AnyAsync("not_exist_entity", Guid.NewGuid().ToString()); |
|||
|
|||
tag.ShouldBeFalse(); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData("Lyrics", "Imagine Dragons")] |
|||
[InlineData("Lyrics", "Music")] |
|||
[InlineData("LyricsAlso", "Imagine Dragons")] |
|||
[InlineData("LyricsAlso", "Music")] |
|||
[InlineData("LyricsAlso", "Most Loved Part")] |
|||
public async Task ShouldFindAsync(string entityType, string name) |
|||
{ |
|||
var tag = await _tagRepository.FindAsync(entityType, name); |
|||
|
|||
tag.ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ShouldNotFindAsync() |
|||
{ |
|||
var tag = await _tagRepository.FindAsync("not_exist_entity", Guid.NewGuid().ToString()); |
|||
|
|||
tag.ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Get_Related_Tags() |
|||
{ |
|||
var content_1_tags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.EntityId1); |
|||
|
|||
content_1_tags.Count.ShouldBe(_cmsKitTestData.Content_1_Tags.Length); |
|||
|
|||
foreach (var tag in content_1_tags) |
|||
{ |
|||
_cmsKitTestData.Content_1_Tags.Contains(tag.Name).ShouldBeTrue(); |
|||
} |
|||
|
|||
var content_2_tags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.Content_2_EntityType, _cmsKitTestData.EntityId2); |
|||
|
|||
content_2_tags.Count.ShouldBe(_cmsKitTestData.Content_2_Tags.Length); |
|||
|
|||
foreach (var tag in content_2_tags) |
|||
{ |
|||
_cmsKitTestData.Content_2_Tags.Contains(tag.Name).ShouldBeTrue(); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Not_Get_Related_Tags() |
|||
{ |
|||
var tags = await _tagRepository.GetAllRelatedTagsAsync("not_exist_entity", Guid.NewGuid().ToString()); |
|||
|
|||
tags.Count.ShouldBe(0); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue