version 0.27.33.54 , fix blog update issue , fix sitemap , fix page creation
parent
5a38eda328
commit
c152f06e08
|
@ -82,6 +82,8 @@ public class BlogCategoryController : ICarterModule
|
|||
if (dto.ParentId != default)
|
||||
ent.SetParent(dto.ParentId);
|
||||
newEnt.Id = ent.Id;
|
||||
newEnt.CreatedAt = ent.CreatedAt;
|
||||
newEnt.CreatedBy = ent.CreatedBy;
|
||||
repositoryWrapper.SetRepository<BlogCategory>().Update(newEnt);
|
||||
await repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
return TypedResults.Ok();
|
||||
|
|
|
@ -74,6 +74,8 @@ public class BlogController : ICarterModule
|
|||
throw new AppException("Blog not found");
|
||||
var newEnt = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested, dto.CategoryId);
|
||||
newEnt.Id = ent.Id;
|
||||
newEnt.CreatedAt = ent.CreatedAt;
|
||||
newEnt.CreatedBy = ent.CreatedBy;
|
||||
repositoryWrapper.SetRepository<Blog>().Update(newEnt);
|
||||
await repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
return TypedResults.Ok();
|
||||
|
|
|
@ -31,8 +31,19 @@ public class PageController : ICarterModule
|
|||
.WithDisplayName("Post Page")
|
||||
.HasApiVersion(1.0)
|
||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages));
|
||||
|
||||
|
||||
group.MapDelete("{id}", DeletePageByIdAsync)
|
||||
.WithDisplayName("Delete Page")
|
||||
.HasApiVersion(1.0)
|
||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPages, ApplicationPermission.ManagePages));
|
||||
|
||||
}
|
||||
public async Task<IResult> GetPagesAsync(Guid id, [FromServices] IPageService pageService, CancellationToken cancellationToken)
|
||||
|
||||
private async Task<IResult> DeletePageByIdAsync([FromRoute]Guid id,[FromServices]IPageService pageService,CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await pageService.DeletePageAsync(id, cancellationToken));
|
||||
|
||||
public async Task<IResult> GetPagesAsync([FromServices] IPageService pageService, CancellationToken cancellationToken)
|
||||
{
|
||||
return TypedResults.Ok(await pageService.GetPagesAsync(cancellationToken));
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<AssemblyVersion>0.27.31.52</AssemblyVersion>
|
||||
<FileVersion>0.27.31.52</FileVersion>
|
||||
<AssemblyVersion>0.27.33.54</AssemblyVersion>
|
||||
<FileVersion>0.27.33.54</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -8,7 +8,7 @@ string env = builder.Environment.IsDevelopment() == true ? "Development" : "Prod
|
|||
builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
string projectName = "Hamyan";
|
||||
string projectName = "Vesmeh";
|
||||
builder.Configuration.AddJsonFile($"AppSettings/appsettings.json").AddJsonFile($"AppSettings/appsettings.{env}{projectName}.json");
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,17 @@ public class SiteMapService : ISiteMapService
|
|||
{
|
||||
private readonly IUploadFileService _uploadFileService;
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
private readonly IPageService _pageService;
|
||||
private readonly SiteSettings _siteSetting;
|
||||
|
||||
public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot, IUploadFileService uploadFileService, IRepositoryWrapper repositoryWrapper)
|
||||
public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot,
|
||||
IUploadFileService uploadFileService,
|
||||
IRepositoryWrapper repositoryWrapper,
|
||||
IPageService pageService)
|
||||
{
|
||||
_uploadFileService = uploadFileService;
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
_pageService = pageService;
|
||||
_siteSetting = snapshot.Value;
|
||||
}
|
||||
public async Task CreateSiteMapAsync()
|
||||
|
@ -106,10 +111,77 @@ public class SiteMapService : ISiteMapService
|
|||
await CreateBlogsSiteMapsAsync();
|
||||
await CreateBrandsSiteMapsAsync();
|
||||
await CreateBlogCategoriesSiteMapsAsync();
|
||||
await CreatePagesSiteMapsAsync();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async Task CreatePagesSiteMapsAsync()
|
||||
{
|
||||
var siteMapsUId = SiteMapUIds.Pages;
|
||||
|
||||
var pages = await _pageService.GetPagesAsync();
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
|
||||
doc.AppendChild(documentType);
|
||||
|
||||
//XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
|
||||
//doc.AppendChild(declaration);
|
||||
|
||||
XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
|
||||
root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
|
||||
doc.AppendChild(root);
|
||||
|
||||
foreach (var page in pages)
|
||||
{
|
||||
var productUrl = $"{_siteSetting.WebSiteUrl}/{page.Slug}";
|
||||
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
|
||||
root.AppendChild(urlElement);
|
||||
|
||||
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
|
||||
loc.InnerText = Path.Combine(productUrl);
|
||||
urlElement.AppendChild(loc);
|
||||
|
||||
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
|
||||
lastmod.InnerText = page.ModifiedAt == DateTime.MinValue ? page.CreatedAt.ToString("yyyy-MM-dd") : page.ModifiedAt.ToString("yyyy-MM-dd");
|
||||
urlElement.AppendChild(lastmod);
|
||||
|
||||
|
||||
XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
|
||||
changeFeq.InnerText = "weekly";
|
||||
urlElement.AppendChild(changeFeq);
|
||||
|
||||
|
||||
XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
|
||||
priority.InnerText = "0.8";
|
||||
urlElement.AppendChild(priority);
|
||||
|
||||
}
|
||||
|
||||
using var siteMapStream = new MemoryStream();
|
||||
await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
|
||||
doc.WriteTo(siteMapWriter);
|
||||
siteMapWriter.Flush();
|
||||
byte[] unZipBytes = siteMapStream.ToArray();
|
||||
|
||||
using (var compressedStream = new MemoryStream())
|
||||
await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
|
||||
{
|
||||
zipStream.Write(unZipBytes, 0, unZipBytes.Length);
|
||||
zipStream.Close();
|
||||
var siteMapArray = compressedStream.ToArray();
|
||||
|
||||
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
|
||||
{
|
||||
FileBytes = siteMapArray,
|
||||
ContentType = "text/plain",
|
||||
FileName = $"{siteMapsUId}.gz",
|
||||
FileUploadType = FileUploadType.SiteMap,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateBrandsSiteMapsAsync()
|
||||
{
|
||||
var siteMapsUId = SiteMapUIds.Brands;
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
using Netina.Common.Models;
|
||||
using Netina.Domain.Dtos.RequestDtos;
|
||||
using Netina.Domain.Dtos.SmallDtos;
|
||||
|
||||
namespace Netina.Core.CoreServices.Abstracts;
|
||||
namespace Netina.Core.CoreServices.Abstracts;
|
||||
|
||||
public interface IPageService : IScopedDependency
|
||||
{
|
||||
Task<BasePageSDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null,string? type = null, CancellationToken cancellationToken=default);
|
||||
Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default);
|
||||
Task<bool> CreatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default);
|
||||
Task<bool> DeletePageAsync(Guid id,CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -1,21 +1,16 @@
|
|||
using Netina.Common.Models.Api;
|
||||
using Netina.Common.Models.Exception;
|
||||
using Netina.Core.CoreServices.Abstracts;
|
||||
using Netina.Domain;
|
||||
using Netina.Domain.Dtos.RequestDtos;
|
||||
using Netina.Domain.Dtos.SmallDtos;
|
||||
using Netina.Domain.MartenEntities.Pages;
|
||||
using Netina.Repository.Repositories.Marten;
|
||||
using Netina.Domain.MartenEntities.Pages;
|
||||
|
||||
namespace Netina.Core.CoreServices;
|
||||
|
||||
public class PageService : IPageService
|
||||
{
|
||||
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public PageService(IMartenRepositoryWrapper martenRepositoryWrapperWrapper)
|
||||
public PageService(IMartenRepositoryWrapper martenRepositoryWrapperWrapper, ICurrentUserService currentUserService)
|
||||
{
|
||||
_martenRepositoryWrapper = martenRepositoryWrapperWrapper;
|
||||
_currentUserService = currentUserService;
|
||||
}
|
||||
public async Task<BasePageSDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -25,7 +20,7 @@ public class PageService : IPageService
|
|||
else if (pageSlug != null)
|
||||
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken);
|
||||
else if (pageName != null)
|
||||
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Name == pageName, cancellationToken);
|
||||
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken);
|
||||
else if (type != null)
|
||||
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken);
|
||||
if (page == null)
|
||||
|
@ -39,7 +34,7 @@ public class PageService : IPageService
|
|||
Id = page.Id,
|
||||
IsCustomPage = page.IsCustomPage,
|
||||
IsHtmlBasePage = page.IsHtmlBasePage,
|
||||
Name = page.Name,
|
||||
Title = page.Title,
|
||||
Slug = page.Slug,
|
||||
Data = page.Data
|
||||
};
|
||||
|
@ -53,8 +48,6 @@ public class PageService : IPageService
|
|||
var pages = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken);
|
||||
foreach (var page in pages)
|
||||
{
|
||||
|
||||
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(page.Type);
|
||||
var dto = new BasePageSDto
|
||||
{
|
||||
Content = page.Content,
|
||||
|
@ -62,9 +55,11 @@ public class PageService : IPageService
|
|||
Id = page.Id,
|
||||
IsCustomPage = page.IsCustomPage,
|
||||
IsHtmlBasePage = page.IsHtmlBasePage,
|
||||
Name = page.Name,
|
||||
Title = page.Title,
|
||||
Slug = page.Slug,
|
||||
Data = page.Data
|
||||
Data = page.Data,
|
||||
CreatedAt = page.CreatedAt,
|
||||
ModifiedAt = page.ModifiedAt
|
||||
};
|
||||
sDtos.Add(dto);
|
||||
}
|
||||
|
@ -77,16 +72,30 @@ public class PageService : IPageService
|
|||
{
|
||||
Content = entity.Content,
|
||||
Description = entity.Description,
|
||||
Id = entity.Id,
|
||||
Id = Guid.NewGuid(),
|
||||
IsCustomPage = entity.IsCustomPage,
|
||||
IsHtmlBasePage = entity.IsHtmlBasePage,
|
||||
Name = entity.Name,
|
||||
Title = entity.Title,
|
||||
Type = entity.Type,
|
||||
Slug = entity.Slug,
|
||||
CreatedAt = DateTime.Now,
|
||||
CreatedBy = _currentUserService.UserName ?? string.Empty
|
||||
};
|
||||
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(entity.Type);
|
||||
basePage.Data = JsonConvert.SerializeObject(((JsonElement)entity.Data).Deserialize(type));
|
||||
if (!basePage.Type.IsNullOrEmpty())
|
||||
{
|
||||
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(entity.Type);
|
||||
basePage.Data = JsonConvert.SerializeObject(((JsonElement)entity.Data).Deserialize(type));
|
||||
}
|
||||
await _martenRepositoryWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken);
|
||||
if (page == null)
|
||||
throw new AppException("Page not found", ApiResultStatusCode.NotFound);
|
||||
await _martenRepositoryWrapper.SetRepository<BasePage>().RemoveEntityAsync(page,cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -5,12 +5,14 @@ public static class SiteMapUIds
|
|||
public const string Brands = "662AF2DC6A2746FA88191F1F3DA94164";
|
||||
public const string Blogs = "4C2F0C2A7A3E41268702D12FDDDB837F";
|
||||
public const string BlogCategories = "B5FF333DC4FF4BB4A309CE3AA32CE45A";
|
||||
public const string Pages = "B463B6C4CC53432C822D79934F528D3E";
|
||||
|
||||
public static List<string> AllSiteMapsUIds => new List<string>
|
||||
{
|
||||
BlogCategories,
|
||||
Categories,
|
||||
Blogs,
|
||||
Brands
|
||||
Brands,
|
||||
Pages
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
public class PageActionRequestDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public bool IsCustomPage { get; set; }
|
||||
|
|
|
@ -5,13 +5,14 @@ namespace Netina.Domain.Dtos.SmallDtos;
|
|||
|
||||
public class BasePageSDto : BaseDto<BasePageSDto,BasePage>
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public bool IsCustomPage { get; set; }
|
||||
public bool IsHtmlBasePage { get; set; }
|
||||
public string Slug { get; set; } = string.Empty;
|
||||
public string Data { get; set; } = string.Empty;
|
||||
public DateTime ModifiedAt { get; set; }
|
||||
|
||||
public T GetData<T>() => JsonConvert.DeserializeObject<T>(Data);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
public class BasePage : MartenEntity
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public bool IsCustomPage { get; set; }
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
using Marten;
|
||||
using Netina.Common.Models.Api;
|
||||
using Netina.Common.Models.Entity;
|
||||
using Netina.Common.Models.Exception;
|
||||
using Netina.Repository.Repositories.Marten;
|
||||
|
||||
namespace Netina.Infrastructure.Marten;
|
||||
|
||||
|
@ -45,18 +41,22 @@ public class MartenRepository<TMartenEntity> : IMartenRepository<TMartenEntity>
|
|||
return entity;
|
||||
}
|
||||
|
||||
public async Task AddOrUpdateEntityAsync(TMartenEntity setting, CancellationToken cancellation)
|
||||
public async Task AddOrUpdateEntityAsync(TMartenEntity entity, CancellationToken cancellation)
|
||||
{
|
||||
if (setting == null)
|
||||
throw new AppException($"{nameof(setting)} is null", ApiResultStatusCode.BadRequest);
|
||||
if (entity == null)
|
||||
throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest);
|
||||
|
||||
await using var session = _documentStore.LightweightSession();
|
||||
session.Store(setting);
|
||||
session.Store(entity);
|
||||
await session.SaveChangesAsync(cancellation);
|
||||
}
|
||||
|
||||
public Task RemoveEntityAsync(CancellationToken cancellation)
|
||||
public async Task RemoveEntityAsync(TMartenEntity entity, CancellationToken cancellation)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (entity == null)
|
||||
throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest);
|
||||
await using var session = _documentStore.LightweightSession();
|
||||
session.Delete(entity);
|
||||
await session.SaveChangesAsync(cancellation);
|
||||
}
|
||||
}
|
|
@ -4,12 +4,12 @@ namespace Netina.Repository.Repositories.Marten;
|
|||
|
||||
public interface IMartenRepository<TMartenEntity> : IScopedDependency where TMartenEntity : IMartenEntity
|
||||
{
|
||||
Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation);
|
||||
Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation);
|
||||
Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation = default);
|
||||
Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default);
|
||||
|
||||
Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation);
|
||||
Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation);
|
||||
Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation = default);
|
||||
Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default);
|
||||
|
||||
Task AddOrUpdateEntityAsync(TMartenEntity setting, CancellationToken cancellation);
|
||||
Task RemoveEntityAsync(CancellationToken cancellation);
|
||||
Task AddOrUpdateEntityAsync(TMartenEntity entity, CancellationToken cancellation = default);
|
||||
Task RemoveEntityAsync(TMartenEntity entity, CancellationToken cancellation = default);
|
||||
}
|
Loading…
Reference in New Issue