feat & fix : add version 0.17.16.23 , fix respons home page , add changelog

add change log dialog , add home page view model
release
Amir Hossein Khademi 2024-02-25 18:21:01 +03:30
parent 07982e63ad
commit fdd14db53d
24 changed files with 1962 additions and 13 deletions

View File

@ -17,7 +17,8 @@
"TaxesFee": 9
},
"SiteSettings": {
"BaseUrl": "https://api.vesmeh.com",
"BaseUrl": "https://api.vesmook.com",
"AdminPanelBaseUrl": "https://admin.vesmook.com",
"KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
"UserSetting": {
"Username": "09214802813",

View File

@ -18,6 +18,7 @@
},
"SiteSettings": {
"BaseUrl": "http://192.168.88.251:32770",
"AdminPanelBaseUrl": "https://admin.vesmook.com",
"KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
"UserSetting": {
"Username": "netinashop",

View File

@ -0,0 +1,19 @@
namespace NetinaShop.Api.Controller;
public class DashboardController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Dashboard")
.MapGroup("api/dashboard")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("home", GetHomeDashboardAsync)
.WithDisplayName("Get Home Dashboard")
.HasApiVersion(1.0);
}
private async Task<IResult> GetHomeDashboardAsync([FromServices] IDashboardService dashboardService, CancellationToken cancellationToken)
=> TypedResults.Ok(await dashboardService.GetHomeDashboardAsyncTask(cancellationToken));
}

View File

@ -1,8 +1,4 @@
using NetinaShop.Repository.Repositories.Entity.Abstracts;
using System.Reflection;
using System.Text.Json;
namespace NetinaShop.Api.Controller;
namespace NetinaShop.Api.Controller;
public class PageController : ICarterModule
{

View File

@ -26,6 +26,10 @@ public class UserController : ICarterModule
.WithDisplayName("GetUser")
.HasApiVersion(1.0);
group.MapGet("/changelog", GetChangeLogAsync)
.WithDisplayName("GetChangeLog")
.HasApiVersion(1.0);
group.MapPost("", Post)
.HasApiVersion(1.0);
@ -36,6 +40,9 @@ public class UserController : ICarterModule
.HasApiVersion(1.0);
}
private async Task<IResult> GetChangeLogAsync(IUserService userService, CancellationToken cancellationToken)
=> TypedResults.Ok(await userService.GetAdminChangeLogAsync(cancellationToken));
public async Task<IResult> GetUserInfoAsync(IUserService userService,ICurrentUserService currentUserService, CancellationToken cancellationToken)
{

View File

@ -74,6 +74,7 @@
<Using Include="NetinaShop.Common.Models.Mapper" />
<Using Include="NetinaShop.Core" />
<Using Include="NetinaShop.Core.Abstracts" />
<Using Include="NetinaShop.Core.BaseServices.Abstracts" />
<Using Include="NetinaShop.Core.CoreServices.Abstracts" />
<Using Include="NetinaShop.Core.Models.Api" />
<Using Include="NetinaShop.Core.Utilities" />

View File

@ -0,0 +1,6 @@
namespace NetinaShop.Core.Abstracts;
public interface IExternalFilesService : IScopedDependency
{
Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,6 @@
namespace NetinaShop.Core.BaseServices.Abstracts;
public interface IDashboardService : IScopedDependency
{
public Task<HomeDashboardDto> GetHomeDashboardAsyncTask(CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,45 @@
using NetinaShop.Domain.Entities.Blogs;
using NetinaShop.Domain.Entities.Brands;
namespace NetinaShop.Core.BaseServices;
public class DashboardService : IDashboardService
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly UserManager<ApplicationUser> _userManager;
public DashboardService(IRepositoryWrapper repositoryWrapper,UserManager<ApplicationUser> userManager)
{
_repositoryWrapper = repositoryWrapper;
_userManager = userManager;
}
public async Task<HomeDashboardDto> GetHomeDashboardAsyncTask(CancellationToken cancellationToken = default)
{
var response = new HomeDashboardDto();
response.BlogsCount = await _repositoryWrapper.SetRepository<Blog>()
.TableNoTracking
.CountAsync(cancellationToken);
response.ProductsCount = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.CountAsync(cancellationToken);
response.TodayOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.OrderAt.Date == DateTime.Today.Date)
.CountAsync(cancellationToken);
response.UnSubmittedOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.OrderStatus == OrderStatus.Paid || o.OrderStatus == OrderStatus.Submitted)
.CountAsync(cancellationToken);
response.BrandsCount = await _repositoryWrapper.SetRepository<Brand>()
.TableNoTracking
.CountAsync(cancellationToken);
response.SubscribersCount = await _userManager.Users.CountAsync(cancellationToken);
return response;
}
}

View File

@ -10,6 +10,7 @@ public interface IUserService : IScopedDependency
Task<bool> EditUserAsync(UserActionRequestDto request, CancellationToken cancellationToken);
Task<bool> EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken);
Task<bool> RemoveUserAsync(Guid userId, CancellationToken cancellationToken);
Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default);
Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default);

View File

@ -10,20 +10,17 @@ public class UserService : IUserService
private readonly ICurrentUserService _currentUserService;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IJwtService _jwtService;
private readonly IExternalFilesService _externalFilesService;
public UserService(ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
IRepositoryWrapper repositoryWrapper,
IJwtService jwtService)
IExternalFilesService externalFilesService)
{
_currentUserService = currentUserService;
_userManager = userManager;
_roleManager = roleManager;
_repositoryWrapper = repositoryWrapper;
_jwtService = jwtService;
_externalFilesService = externalFilesService;
}
@ -256,8 +253,26 @@ public class UserService : IUserService
return true;
}
public async Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default)
{
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
var currentVersion = await _externalFilesService.GetAdminChangeLogAsync(cancellationToken);
if (!(user.LatestVersionUsed < currentVersion.VersionNumber)) return currentVersion;
currentVersion.IsNewVersion = true;
user.LatestVersionUsed = currentVersion.VersionNumber;
//await _userManager.UpdateAsync(user);
return currentVersion;
}
public async Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default)
{

View File

@ -23,7 +23,6 @@
<ItemGroup>
<Folder Include="BaseServices\Abstracts\" />
<Folder Include="EntityServices\ProductHandlers\" />
<Folder Include="EntityServices\ReviewHandlers\" />
<Folder Include="Models\Api\" />
@ -50,6 +49,7 @@
<Using Include="NetinaShop.Core.EntityServices.Abstracts" />
<Using Include="NetinaShop.Domain.CommandQueries.Commands" />
<Using Include="NetinaShop.Domain.CommandQueries.Queries" />
<Using Include="NetinaShop.Domain.Dtos.DashboardDtos" />
<Using Include="NetinaShop.Domain.Dtos.RequestDtos" />
<Using Include="NetinaShop.Domain.Dtos.ResponseDtos" />
<Using Include="NetinaShop.Domain.Dtos.SmallDtos" />

View File

@ -0,0 +1,11 @@
namespace NetinaShop.Domain.Dtos.DashboardDtos;
public class HomeDashboardDto
{
public int ProductsCount { get; set; }
public int BlogsCount { get; set; }
public int TodayOrdersCount { get; set; }
public int UnSubmittedOrdersCount { get; set; }
public int BrandsCount { get; set; }
public int SubscribersCount { get; set; }
}

View File

@ -0,0 +1,14 @@
namespace NetinaShop.Domain.Dtos.ResponseDtos;
public class AdminChangeLogResponseDto
{
public string Version { get; set; } = string.Empty;
public double VersionNumber { get; set; }
public string VersionName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public List<string> Features { get; set; } = new();
public List<string> BugFixes { get; set; } = new();
public bool IsNewVersion { get; set; } = false;
}

View File

@ -10,6 +10,8 @@ public class ApplicationUser : IdentityUser<Guid>
public string LastName { get; set; } = string.Empty;
public string NationalId { get; set; } = string.Empty;
public double LatestVersionUsed { get; set; }
public DateTime BirthDate { get; set; }
public Gender Gender { get; set; }
public SignUpStatus SignUpStatus { get; set; }

View File

@ -10,6 +10,7 @@ public class SiteSettings
{
public JwtSettings JwtSettings { get; set; } = new JwtSettings();
public string BaseUrl { get; set; } = string.Empty;
public string AdminPanelBaseUrl { get; set; } = string.Empty;
public RedisSettings MasterRedisConfiguration { get; set; } = new RedisSettings();
public UserSetting UserSetting { get; set; } = new UserSetting();
public string KaveNegarApiKey { get; set; } = string.Empty;

View File

@ -37,6 +37,7 @@
<ItemGroup>
<Folder Include="Dtos\FilterDtos\" />
<Folder Include="Dtos\DashboardDtos\" />
<Folder Include="Entities\StorageFiles\" />
<Folder Include="Models\Settings\" />
</ItemGroup>

View File

@ -5,4 +5,5 @@ public static class RestAddress
public static string BaseKaveNegar => "https://api.kavenegar.com/v1/";
public static string BaseZarinpal => "https://api.zarinpal.com/pg";
public static string DigikalaApi => "https://api.digikala.com";
public static string AdminPanel => "https://admin.vesmook.com";
}

View File

@ -0,0 +1,9 @@
using NetinaShop.Domain.Dtos.ResponseDtos;
namespace NetinaShop.Infrastructure.RestServices;
public interface IFileRestApi
{
[Get("/version.json")]
Task<AdminChangeLogResponseDto> GetAdminChangeLog();
}

View File

@ -7,6 +7,7 @@ public interface IRestApiWrapper : IScopedDependency
IKaveNegarRestApi KaveNegarRestApi { get; }
IZarinpalRestApi ZarinpalRestApi { get; }
IDigikalaRestApi DigikalaRestApi { get; }
IFileRestApi FileRestApi(string address);
}
public class RestApiWrapper : IRestApiWrapper
@ -14,4 +15,10 @@ public class RestApiWrapper : IRestApiWrapper
public IKaveNegarRestApi KaveNegarRestApi => RestService.For<IKaveNegarRestApi>(RestAddress.BaseKaveNegar);
public IZarinpalRestApi ZarinpalRestApi => RestService.For<IZarinpalRestApi>(RestAddress.BaseZarinpal);
public IDigikalaRestApi DigikalaRestApi => RestService.For<IDigikalaRestApi>(RestAddress.DigikalaApi);
public IFileRestApi FileRestApi(string address)
{
return RestService.For<IFileRestApi>(address);
}
}

View File

@ -0,0 +1,19 @@
using NetinaShop.Domain.Dtos.ResponseDtos;
namespace NetinaShop.Infrastructure.Services;
public class ExternalFilesService : IExternalFilesService
{
private readonly IRestApiWrapper _restApiWrapper;
private readonly SiteSettings _siteSetting;
public ExternalFilesService(IRestApiWrapper restApiWrapper,IOptionsSnapshot<SiteSettings> snapshot)
{
_restApiWrapper = restApiWrapper;
_siteSetting = snapshot.Value;
}
public Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default)
{
return _restApiWrapper.FileRestApi(_siteSetting.AdminPanelBaseUrl).GetAdminChangeLog();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NetinaShop.Repository.Migrations
{
/// <inheritdoc />
public partial class AddUserVersionUsed : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<double>(
name: "LatestVersionUsed",
schema: "public",
table: "Users",
type: "double precision",
nullable: false,
defaultValue: 0.0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "LatestVersionUsed",
schema: "public",
table: "Users");
}
}
}

View File

@ -1064,6 +1064,9 @@ namespace NetinaShop.Repository.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<double>("LatestVersionUsed")
.HasColumnType("double precision");
b.Property<bool>("LockoutEnabled")
.HasColumnType("boolean");