feat & fix : add version 0.17.16.23 , fix respons home page , add changelog
add change log dialog , add home page view modelrelease
parent
07982e63ad
commit
fdd14db53d
|
@ -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",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
},
|
||||
"SiteSettings": {
|
||||
"BaseUrl": "http://192.168.88.251:32770",
|
||||
"AdminPanelBaseUrl": "https://admin.vesmook.com",
|
||||
"KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
|
||||
"UserSetting": {
|
||||
"Username": "netinashop",
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
namespace NetinaShop.Core.Abstracts;
|
||||
|
||||
public interface IExternalFilesService : IScopedDependency
|
||||
{
|
||||
Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace NetinaShop.Core.BaseServices.Abstracts;
|
||||
|
||||
public interface IDashboardService : IScopedDependency
|
||||
{
|
||||
public Task<HomeDashboardDto> GetHomeDashboardAsyncTask(CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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; }
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Folder Include="Dtos\FilterDtos\" />
|
||||
<Folder Include="Dtos\DashboardDtos\" />
|
||||
<Folder Include="Entities\StorageFiles\" />
|
||||
<Folder Include="Models\Settings\" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -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";
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using NetinaShop.Domain.Dtos.ResponseDtos;
|
||||
|
||||
namespace NetinaShop.Infrastructure.RestServices;
|
||||
|
||||
public interface IFileRestApi
|
||||
{
|
||||
[Get("/version.json")]
|
||||
Task<AdminChangeLogResponseDto> GetAdminChangeLog();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
1752
NetinaShop.Repository/Migrations/20240225133310_AddUserVersionUsed.Designer.cs
generated
100644
1752
NetinaShop.Repository/Migrations/20240225133310_AddUserVersionUsed.Designer.cs
generated
100644
File diff suppressed because it is too large
Load Diff
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1064,6 +1064,9 @@ namespace NetinaShop.Repository.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double>("LatestVersionUsed")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
|
|
Loading…
Reference in New Issue