From f880d72d07ef45dbc99ea366f13d4a4e3f10e445 Mon Sep 17 00:00:00 2001 From: "Amir.H Khademi" Date: Mon, 22 Apr 2024 13:33:39 +0330 Subject: [PATCH] feat : add slug to blog and products , refactor domain project --- .../appsettings.DevelopmentHamyan.json | 2 +- .../Controller/BlogCategoryController.cs | 10 +- Netina.Api/Controller/BlogController.cs | 19 +- Netina.Api/Controller/SeedController.cs | 10 +- Netina.Api/Netina.Api.csproj | 18 +- Netina.Api/Program.cs | 1 - .../Configurations/ServiceExtensions.cs | 25 +- Netina.Common/Netina.Common.csproj | 2 +- Netina.Core/BaseServices/SiteMapService.cs | 9 +- Netina.Core/Netina.Core.csproj | 4 +- Netina.Core/QuartzServices/JobScheduler.cs | 42 + .../QuartzServices/SiteMapScheduledJob.cs | 22 + .../CommandQueries/Commands/BrandCommands.cs | 4 +- .../Commands/DiscountCommands.cs | 6 +- .../Commands/OrderBagCommands.cs | 7 +- .../CommandQueries/Commands/OrderCommands.cs | 5 +- .../Commands/PaymentCommands.cs | 4 +- .../Commands/ProductCategoryCommands.cs | 5 +- .../Commands/ProductCommands.cs | 5 +- .../CommandQueries/Commands/ReviewCommands.cs | 4 +- .../Commands/ShippingCommands.cs | 4 +- .../CommandQueries/Queries/AddressQueries.cs | 4 +- .../CommandQueries/Queries/BlogQueries.cs | 4 + .../CommandQueries/Queries/BrandQueries.cs | 5 +- .../CommandQueries/Queries/DiscountQueries.cs | 5 +- .../Queries/NewsletterQueries.cs | 4 +- .../CommandQueries/Queries/OrderBagQueries.cs | 4 +- .../CommandQueries/Queries/OrderQueries.cs | 7 +- .../CommandQueries/Queries/PaymentQueries.cs | 4 +- .../Queries/ProductCategoryQueries.cs | 5 +- .../CommandQueries/Queries/ProductQueries.cs | 5 +- .../CommandQueries/Queries/ReviewQueries.cs | 5 +- .../CommandQueries/Queries/ShippingQueries.cs | 4 +- .../Dtos/FilterDtos/BaseFilterDto.cs | 4 +- .../Dtos/FilterDtos/ExpressDeliveryFilter.cs | 4 +- .../Dtos/FilterDtos/PriceFilterDto.cs | 4 +- .../Dtos/LargDtos/BlogCategoryLDto.cs | 6 +- Netina.Domain/Dtos/LargDtos/BlogLDto.cs | 7 +- Netina.Domain/Dtos/LargDtos/BrandLDto.cs | 6 +- Netina.Domain/Dtos/LargDtos/DiscountLDto.cs | 6 +- .../Dtos/LargDtos/ProductCategoryLDto.cs | 6 +- Netina.Domain/Dtos/LargDtos/ProductLDto.cs | 7 +- Netina.Domain/Dtos/LargDtos/ReviewLDto.cs | 5 +- .../SeedDtos/SeedBlogRequestDto.cs | 1 + .../Dtos/RequestDtos/UserActionRequestDto.cs | 4 +- .../Dtos/ResponseDtos/GetBlogsResponseDto.cs | 8 + .../ResponseDtos/GetProductResponseDto.cs | 4 +- .../ResponseDtos/GetProductsResponseDto.cs | 1 - .../Dtos/ResponseDtos/ProfileResponseDto.cs | 4 +- .../ResponseDtos/VerifyCodeResponseDto.cs | 4 +- .../Dtos/SmallDtos/ApplicationUserSDto.cs | 7 +- Netina.Domain/Dtos/SmallDtos/BasePageSDto.cs | 3 +- .../Dtos/SmallDtos/BlogCategorySDto.cs | 6 +- Netina.Domain/Dtos/SmallDtos/BlogSDto.cs | 7 +- Netina.Domain/Dtos/SmallDtos/BrandSDto.cs | 5 +- Netina.Domain/Dtos/SmallDtos/CustomerSDto.cs | 7 +- Netina.Domain/Dtos/SmallDtos/DiscountSDto.cs | 6 +- Netina.Domain/Dtos/SmallDtos/ManagerSDto.cs | 7 +- Netina.Domain/Dtos/SmallDtos/MarketerSDto.cs | 7 +- .../Dtos/SmallDtos/NewsletterMemberSDto.cs | 5 +- .../Dtos/SmallDtos/OrderDeliverySDto.cs | 5 +- .../Dtos/SmallDtos/OrderProductSDto.cs | 6 +- Netina.Domain/Dtos/SmallDtos/OrderSDto.cs | 6 +- .../Dtos/SmallDtos/ProductCategorySDto.cs | 5 +- Netina.Domain/Dtos/SmallDtos/ProductSDto.cs | 6 +- Netina.Domain/Dtos/SmallDtos/ReviewSDto.cs | 5 +- Netina.Domain/Dtos/SmallDtos/ShippingSDto.cs | 5 +- .../Dtos/SmallDtos/SpecificationSDto.cs | 5 +- .../Dtos/SmallDtos/StorageFileSDto.cs | 4 - .../Dtos/SmallDtos/UserAddressSDto.cs | 5 +- .../Accounting/Accounting.Aggregate.cs | 4 +- Netina.Domain/Entities/Accounting/Payment.cs | 7 +- .../Entities/Blogs/Blog.Aggregate.cs | 12 +- Netina.Domain/Entities/Blogs/Blog.cs | 8 +- Netina.Domain/Entities/Blogs/BlogCategory.cs | 4 +- .../Entities/Brands/Brand.Aggregate.cs | 4 +- Netina.Domain/Entities/Brands/Brand.cs | 5 +- .../Entities/Brands/BrandStorageFile.cs | 5 +- .../Entities/Discounts/CategoryDiscount.cs | 5 +- .../Entities/Discounts/Discount.Aggregate.cs | 4 +- Netina.Domain/Entities/Discounts/Discount.cs | 7 +- .../Entities/Discounts/ProductDiscount.cs | 5 +- .../Entities/Orders/Order.Aggregate.cs | 4 +- Netina.Domain/Entities/Orders/Order.cs | 5 +- .../Entities/Orders/OrderDelivery.cs | 6 +- Netina.Domain/Entities/Orders/OrderProduct.cs | 6 +- .../ProductCategory.Aggregate.cs | 4 +- .../ProductCategories/ProductCategory.cs | 5 +- .../ProductCategoryStorageFile.cs | 5 +- .../Entities/Products/Product.Aggregate.cs | 6 +- Netina.Domain/Entities/Products/Product.cs | 12 +- .../Entities/Products/ProductStorageFile.cs | 5 +- Netina.Domain/Entities/Products/Review.cs | 5 +- .../Entities/Products/Specification.cs | 4 +- .../StorageFiles/StorageFile.Aggregate.cs | 4 +- .../Entities/StorageFiles/StorageFile.cs | 5 +- .../Entities/Users/ApplicationUser.cs | 4 +- Netina.Domain/Entities/Users/Customer.cs | 4 +- Netina.Domain/Entities/Users/Manager.cs | 4 +- .../Entities/Users/NewsletterMember.cs | 4 +- Netina.Domain/Entities/Users/UserAddress.cs | 4 +- .../Entities/Users/UserFavoriteProduct.cs | 5 +- Netina.Domain/Entities/Warehouses/Shipping.cs | 4 +- Netina.Domain/Mappers/BlogCategoryMapper.g.cs | 49 +- Netina.Domain/Mappers/BlogMapper.g.cs | 16 +- Netina.Domain/Mappers/ProductMapper.g.cs | 11 + Netina.Domain/MapsterRegister.cs | 57 +- .../MartenEntities/Pages/BasePage.cs | 4 +- Netina.Domain/MartenEntities/Pages/FAQPage.cs | 4 +- .../MartenEntities/Settings/BaseSetting.cs | 4 +- Netina.Domain/Netina.Domain.csproj | 6 +- .../Netina.Infrastructure.csproj | 4 +- .../Services/Scrapers/DigikalaScraper.cs | 1 + .../Handlers/Blogs/GetBlogsQueryHandler.cs | 33 + ...21111942_AddSlugBlogAndProduct.Designer.cs | 2013 +++++++++++++++++ .../20240421111942_AddSlugBlogAndProduct.cs | 44 + .../ApplicationContextModelSnapshot.cs | 8 + Netina.Repository/Netina.Repository.csproj | 9 +- .../Base/Contracts/IRepositoryWrapper.cs | 7 +- .../Repositories/Base/RepositoryWrapper.cs | 4 - Netina.Repository/RepositoryConfig.cs | 1 + .../Abstracts/IDbInitializerService.cs | 1 + .../Services/DbInitializerService.cs | 29 +- .../Program.cs | 12 +- .../Services/RestServices/ISeedRestApi.cs | 2 + 125 files changed, 2477 insertions(+), 474 deletions(-) create mode 100644 Netina.Core/QuartzServices/JobScheduler.cs create mode 100644 Netina.Core/QuartzServices/SiteMapScheduledJob.cs create mode 100644 Netina.Domain/CommandQueries/Queries/BlogQueries.cs create mode 100644 Netina.Domain/Dtos/ResponseDtos/GetBlogsResponseDto.cs create mode 100644 Netina.Repository/Handlers/Blogs/GetBlogsQueryHandler.cs create mode 100644 Netina.Repository/Migrations/20240421111942_AddSlugBlogAndProduct.Designer.cs create mode 100644 Netina.Repository/Migrations/20240421111942_AddSlugBlogAndProduct.cs diff --git a/Netina.Api/AppSettings/appsettings.DevelopmentHamyan.json b/Netina.Api/AppSettings/appsettings.DevelopmentHamyan.json index af5a4b3..9a239fd 100644 --- a/Netina.Api/AppSettings/appsettings.DevelopmentHamyan.json +++ b/Netina.Api/AppSettings/appsettings.DevelopmentHamyan.json @@ -17,7 +17,7 @@ "TaxesFee": 9 }, "SiteSettings": { - "BaseUrl": "http://localhost:32770", + "BaseUrl": "http://192.168.1.12:32770", "WebSiteUrl": "https://hamyanedalat.com", "AdminPanelBaseUrl": "https://admin.hamyanedalat.com", "StorageBaseUrl": "https://storage.hamyanedalat.com", diff --git a/Netina.Api/Controller/BlogCategoryController.cs b/Netina.Api/Controller/BlogCategoryController.cs index 3c73b35..c6ec9d8 100644 --- a/Netina.Api/Controller/BlogCategoryController.cs +++ b/Netina.Api/Controller/BlogCategoryController.cs @@ -1,8 +1,4 @@ -using Netina.Common.Models.Exception; -using Netina.Domain.Dtos.SmallDtos; -using Netina.Domain.Entities.Blogs; -using Netina.Domain.Models.Claims; -using Netina.Repository.Repositories.Base.Contracts; +using Netina.Domain.Entities.Blogs; namespace Netina.Api.Controller; @@ -41,7 +37,7 @@ public class BlogCategoryController : ICarterModule if (page != null) { return TypedResults.Ok(await repositoryWrapper.SetRepository().TableNoTracking - .OrderByDescending(b => b.CreatedAt).Skip(page.Value * 10).Take(10) + .OrderByDescending(b => b.Name).Skip(page.Value * 10).Take(10) .Select(BlogCategoryMapper.ProjectToSDto) .ToListAsync(cancellationToken)); } @@ -49,7 +45,7 @@ public class BlogCategoryController : ICarterModule { return TypedResults.Ok(await repositoryWrapper.SetRepository().TableNoTracking - .OrderByDescending(b => b.CreatedAt) + .OrderByDescending(b => b.Name) .Select(BlogCategoryMapper.ProjectToSDto) .ToListAsync(cancellationToken)); } diff --git a/Netina.Api/Controller/BlogController.cs b/Netina.Api/Controller/BlogController.cs index 131d53a..deb3dc2 100644 --- a/Netina.Api/Controller/BlogController.cs +++ b/Netina.Api/Controller/BlogController.cs @@ -23,24 +23,27 @@ public class BlogController : ICarterModule .HasApiVersion(1.0); group.MapPost("", Post) - .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) + .RequireAuthorization(builder => + builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() + .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .HasApiVersion(1.0); group.MapPut("", Put) - .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) + .RequireAuthorization(builder => + builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() + .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .HasApiVersion(1.0); group.MapDelete("{id}", Delete) - .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) + .RequireAuthorization(builder => + builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() + .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .HasApiVersion(1.0); } // GET:Get All Entity - public async Task GetAllAsync([FromQuery] int page, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) - => TypedResults.Ok(await repositoryWrapper.SetRepository().TableNoTracking - .OrderByDescending(b=>b.CreatedAt) - .Skip(page*10).Take(10) - .Select(BlogMapper.ProjectToSDto).ToListAsync(cancellationToken)); + public async Task GetAllAsync([FromQuery] int page, [FromQuery] Guid? blogCategoryId, IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new GetBlogsQuery(page, CategoryId: blogCategoryId), cancellationToken)); // GET:Get An Entity By Id public async Task GetAsync(Guid id, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) diff --git a/Netina.Api/Controller/SeedController.cs b/Netina.Api/Controller/SeedController.cs index 2f247f0..1a927f6 100644 --- a/Netina.Api/Controller/SeedController.cs +++ b/Netina.Api/Controller/SeedController.cs @@ -105,7 +105,15 @@ public class SeedController : ICarterModule throw new AppException("Key is not valid", ApiResultStatusCode.UnAuthorized); foreach (var seedBlogRequestDto in request) { - var ent = Blog.Create(seedBlogRequestDto.Title, seedBlogRequestDto.Content, seedBlogRequestDto.Tags, seedBlogRequestDto.ReadingTime, + if (seedBlogRequestDto.CategoryId == default) + { + var noCategory = await repositoryWrapper.SetRepository() + .TableNoTracking + .FirstOrDefaultAsync(bc => bc.Name == "دسته بندی نشده", cancellationToken); + if(noCategory != null) + seedBlogRequestDto.CategoryId = noCategory.Id; + } + var ent = Blog.Create(seedBlogRequestDto.Title,seedBlogRequestDto.Slug, seedBlogRequestDto.Content, seedBlogRequestDto.Tags, seedBlogRequestDto.ReadingTime, seedBlogRequestDto.Summery, seedBlogRequestDto.IsSuggested, seedBlogRequestDto.CategoryId); foreach (var storageFileSDto in seedBlogRequestDto.Files) diff --git a/Netina.Api/Netina.Api.csproj b/Netina.Api/Netina.Api.csproj index 4cd5895..fad8fbd 100644 --- a/Netina.Api/Netina.Api.csproj +++ b/Netina.Api/Netina.Api.csproj @@ -11,7 +11,7 @@ - + @@ -19,25 +19,25 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + - + @@ -52,7 +52,7 @@ - + diff --git a/Netina.Api/Program.cs b/Netina.Api/Program.cs index 800275b..b19f22a 100644 --- a/Netina.Api/Program.cs +++ b/Netina.Api/Program.cs @@ -17,7 +17,6 @@ var siteSetting = configuration.GetSection(nameof(SiteSettings)).Get(configuration.GetSection(nameof(SiteSettings))); - // Add services to the container. builder.Services.AddControllers(); diff --git a/Netina.Api/WebFramework/Configurations/ServiceExtensions.cs b/Netina.Api/WebFramework/Configurations/ServiceExtensions.cs index 68f8a24..3e0a476 100644 --- a/Netina.Api/WebFramework/Configurations/ServiceExtensions.cs +++ b/Netina.Api/WebFramework/Configurations/ServiceExtensions.cs @@ -1,14 +1,29 @@ -using Marten; -using Netina.Domain.Entities.Users; -using Netina.Domain.Models.Settings; -using Netina.Repository.Extensions; -using Netina.Repository.Models; +using Autofac.Extras.Quartz; +using Marten; +using System.Collections.Specialized; +using Netina.Core.QuartzServices; using Weasel.Core; namespace Netina.Api.WebFramework.Configurations; public static class ServiceExtensions { + public static void AddSchedulerToAutoFac(this ContainerBuilder builder) + { + // configure and register Quartz + var schedulerConfig = new NameValueCollection { + {"quartz.threadPool.threadCount", "3"}, + {"quartz.scheduler.threadName", "BrizCo_Scheduler"} + }; + + builder.RegisterModule(new QuartzAutofacFactoryModule + { + ConfigurationProvider = c => schedulerConfig + }); + + builder.RegisterModule(new QuartzAutofacJobsModule(typeof(JobScheduler).Assembly)); + builder.RegisterType().AsSelf(); + } public static void AddIpRateLimit(this IServiceCollection services, IConfigurationRoot configuration) { diff --git a/Netina.Common/Netina.Common.csproj b/Netina.Common/Netina.Common.csproj index dbe9777..b49a057 100644 --- a/Netina.Common/Netina.Common.csproj +++ b/Netina.Common/Netina.Common.csproj @@ -11,7 +11,7 @@ - +