Compare commits
No commits in common. "df7c7e071780830d2bb0a3dbe7575e4f66223960" and "f14bf019f17ca33af59d211e20edbe0f04af3aa6" have entirely different histories.
df7c7e0717
...
f14bf019f1
@ -1,7 +1,5 @@
|
|||||||
namespace Fengling.Console.Controllers;
|
namespace Fengling.Console.Controllers;
|
||||||
|
|
||||||
using Fengling.Console.Services;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 租户管理控制器
|
/// 租户管理控制器
|
||||||
/// 提供租户的增删改查以及租户用户、角色、配置管理功能
|
/// 提供租户的增删改查以及租户用户、角色、配置管理功能
|
||||||
@ -12,13 +10,11 @@ using Fengling.Console.Services;
|
|||||||
public class TenantsController : ControllerBase
|
public class TenantsController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ITenantService _tenantService;
|
private readonly ITenantService _tenantService;
|
||||||
private readonly IH5LinkService _h5LinkService;
|
|
||||||
private readonly ILogger<TenantsController> _logger;
|
private readonly ILogger<TenantsController> _logger;
|
||||||
|
|
||||||
public TenantsController(ITenantService tenantService, IH5LinkService h5LinkService, ILogger<TenantsController> logger)
|
public TenantsController(ITenantService tenantService, ILogger<TenantsController> logger)
|
||||||
{
|
{
|
||||||
_tenantService = tenantService;
|
_tenantService = tenantService;
|
||||||
_h5LinkService = h5LinkService;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +64,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(typeof(TenantDto), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(TenantDto), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<ActionResult<TenantDto>> GetTenant(int id)
|
public async Task<ActionResult<TenantDto>> GetTenant(long id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -100,7 +96,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(typeof(IEnumerable<UserDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<UserDto>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<ActionResult<IEnumerable<UserDto>>> GetTenantUsers(int tenantId)
|
public async Task<ActionResult<IEnumerable<UserDto>>> GetTenantUsers(long tenantId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -132,7 +128,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(typeof(IEnumerable<object>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<object>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<ActionResult<IEnumerable<object>>> GetTenantRoles(int tenantId)
|
public async Task<ActionResult<IEnumerable<object>>> GetTenantRoles(long tenantId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -164,7 +160,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(typeof(TenantSettingsDto), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(TenantSettingsDto), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<ActionResult<TenantSettingsDto>> GetTenantSettings(int id)
|
public async Task<ActionResult<TenantSettingsDto>> GetTenantSettings(long id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -196,7 +192,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<IActionResult> UpdateTenantSettings(int id, [FromBody] TenantSettingsDto settings)
|
public async Task<IActionResult> UpdateTenantSettings(long id, [FromBody] TenantSettingsDto settings)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -253,7 +249,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<IActionResult> UpdateTenant(int id, [FromBody] UpdateTenantDto dto)
|
public async Task<IActionResult> UpdateTenant(long id, [FromBody] UpdateTenantDto dto)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -284,7 +280,7 @@ public class TenantsController : ControllerBase
|
|||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<IActionResult> DeleteTenant(int id)
|
public async Task<IActionResult> DeleteTenant(long id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -302,36 +298,4 @@ public class TenantsController : ControllerBase
|
|||||||
return StatusCode(500, new { message = ex.Message });
|
return StatusCode(500, new { message = ex.Message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生成H5访问链接和二维码
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">租户ID</param>
|
|
||||||
/// <returns>H5链接和二维码Base64</returns>
|
|
||||||
/// <response code="200">成功返回链接和二维码</response>
|
|
||||||
/// <response code="404">租户不存在</response>
|
|
||||||
/// <response code="500">服务器内部错误</response>
|
|
||||||
[HttpGet("{id}/h5-link")]
|
|
||||||
[Produces("application/json")]
|
|
||||||
[ProducesResponseType(typeof(H5LinkResult), StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
|
|
||||||
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
|
|
||||||
public async Task<ActionResult<H5LinkResult>> GetH5Link(int id)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var result = await _h5LinkService.GenerateH5LinkAsync(id);
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
catch (KeyNotFoundException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "Tenant not found: {TenantId}", id);
|
|
||||||
return NotFound(new { message = ex.Message });
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error generating H5 link for tenant {TenantId}", id);
|
|
||||||
return StatusCode(500, new { message = "Failed to generate H5 link" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
85
Datas/ApplicationDbContext.cs
Normal file
85
Datas/ApplicationDbContext.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Datas;
|
||||||
|
|
||||||
|
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||||
|
: IdentityDbContext<ApplicationUser, ApplicationRole, long>(options)
|
||||||
|
{
|
||||||
|
public DbSet<Tenant> Tenants { get; set; }
|
||||||
|
public DbSet<AccessLog> AccessLogs { get; set; }
|
||||||
|
public DbSet<AuditLog> AuditLogs { get; set; }
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
|
{
|
||||||
|
base.OnModelCreating(builder);
|
||||||
|
|
||||||
|
builder.Entity<ApplicationUser>(entity =>
|
||||||
|
{
|
||||||
|
entity.Property(e => e.RealName).HasMaxLength(100);
|
||||||
|
entity.Property(e => e.Phone).HasMaxLength(20);
|
||||||
|
entity.HasIndex(e => e.Phone).IsUnique();
|
||||||
|
|
||||||
|
entity.OwnsOne(e => e.TenantInfo, navigationBuilder =>
|
||||||
|
{
|
||||||
|
navigationBuilder.Property(e => e.Id).HasColumnName("TenantId");
|
||||||
|
navigationBuilder.Property(e => e.TenantId).HasColumnName("TenantCode");
|
||||||
|
navigationBuilder.Property(e => e.Name).HasColumnName("TenantName");
|
||||||
|
navigationBuilder.WithOwner();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<ApplicationRole>(entity => { entity.Property(e => e.Description).HasMaxLength(200); });
|
||||||
|
|
||||||
|
builder.Entity<Tenant>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id);
|
||||||
|
entity.HasIndex(e => e.TenantId).IsUnique();
|
||||||
|
entity.Property(e => e.TenantId).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.Name).HasMaxLength(100);
|
||||||
|
entity.Property(e => e.ContactName).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.ContactEmail).HasMaxLength(100);
|
||||||
|
entity.Property(e => e.ContactPhone).HasMaxLength(20);
|
||||||
|
entity.Property(e => e.Status).HasMaxLength(20);
|
||||||
|
entity.Property(e => e.Description).HasMaxLength(500);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<AccessLog>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id);
|
||||||
|
entity.HasIndex(e => e.CreatedAt);
|
||||||
|
entity.HasIndex(e => e.UserName);
|
||||||
|
entity.HasIndex(e => e.TenantId);
|
||||||
|
entity.HasIndex(e => e.Action);
|
||||||
|
entity.HasIndex(e => e.Status);
|
||||||
|
entity.Property(e => e.UserName).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.TenantId).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.Action).HasMaxLength(20);
|
||||||
|
entity.Property(e => e.Resource).HasMaxLength(200);
|
||||||
|
entity.Property(e => e.Method).HasMaxLength(10);
|
||||||
|
entity.Property(e => e.IpAddress).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.UserAgent).HasMaxLength(500);
|
||||||
|
entity.Property(e => e.Status).HasMaxLength(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<AuditLog>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id);
|
||||||
|
entity.HasIndex(e => e.CreatedAt);
|
||||||
|
entity.HasIndex(e => e.Operator);
|
||||||
|
entity.HasIndex(e => e.TenantId);
|
||||||
|
entity.HasIndex(e => e.Operation);
|
||||||
|
entity.HasIndex(e => e.Action);
|
||||||
|
entity.Property(e => e.Operator).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.TenantId).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.Operation).HasMaxLength(20);
|
||||||
|
entity.Property(e => e.Action).HasMaxLength(20);
|
||||||
|
entity.Property(e => e.TargetType).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.TargetName).HasMaxLength(100);
|
||||||
|
entity.Property(e => e.IpAddress).HasMaxLength(50);
|
||||||
|
entity.Property(e => e.Description).HasMaxLength(500);
|
||||||
|
entity.Property(e => e.Status).HasMaxLength(20);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,6 @@
|
|||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
@ -19,8 +18,6 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
|
||||||
<PackageReference Include="NetCorePal.Extensions.AspNetCore" />
|
|
||||||
<PackageReference Include="NetCorePal.Extensions.DistributedLocks.Redis" />
|
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||||
<PackageReference Include="OpenIddict.Abstractions" />
|
<PackageReference Include="OpenIddict.Abstractions" />
|
||||||
<PackageReference Include="OpenIddict.AspNetCore" />
|
<PackageReference Include="OpenIddict.AspNetCore" />
|
||||||
@ -28,14 +25,11 @@
|
|||||||
<PackageReference Include="OpenIddict.Server" />
|
<PackageReference Include="OpenIddict.Server" />
|
||||||
<PackageReference Include="OpenIddict.Server.AspNetCore" />
|
<PackageReference Include="OpenIddict.Server.AspNetCore" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||||
<PackageReference Include="SkiaSharp" />
|
|
||||||
<PackageReference Include="QRCoder" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- <ProjectReference Include="..\Fengling.AuthService\Fengling.AuthService.csproj" />-->
|
<!-- <ProjectReference Include="..\Fengling.AuthService\Fengling.AuthService.csproj" />-->
|
||||||
<ProjectReference Include="..\YarpGateway\YarpGateway.csproj" />
|
<ProjectReference Include="..\YarpGateway\YarpGateway.csproj" />
|
||||||
<ProjectReference Include="..\Fengling.Platform\Fengling.Platform.Infrastructure\Fengling.Platform.Infrastructure.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace Fengling.Console.Models.Dtos;
|
|||||||
public class CreateTenantDto
|
public class CreateTenantDto
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public string TenantCode { get; set; } = string.Empty;
|
public string TenantId { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
@ -26,16 +26,4 @@ public class CreateTenantDto
|
|||||||
public string Status { get; set; } = "active";
|
public string Status { get; set; } = "active";
|
||||||
|
|
||||||
public DateTime? ExpiresAt { get; set; }
|
public DateTime? ExpiresAt { get; set; }
|
||||||
|
|
||||||
[MaxLength(255)]
|
|
||||||
public string? CustomDomain { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(50)]
|
|
||||||
public string? BasePath { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(500)]
|
|
||||||
public string? Logo { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(500)]
|
|
||||||
public string? H5BaseUrl { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class CreateUserDto
|
|||||||
[Required]
|
[Required]
|
||||||
public string RealName { get; set; } = string.Empty;
|
public string RealName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string? PhoneNumber { get; set; }
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
public long? TenantId { get; set; }
|
public long? TenantId { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -10,5 +10,5 @@ public class RoleDto
|
|||||||
public bool IsSystem { get; set; }
|
public bool IsSystem { get; set; }
|
||||||
public List<string>? Permissions { get; set; }
|
public List<string>? Permissions { get; set; }
|
||||||
public int UserCount { get; set; }
|
public int UserCount { get; set; }
|
||||||
public DateTimeOffset CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,17 @@
|
|||||||
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
|
|
||||||
|
|
||||||
namespace Fengling.Console.Models.Dtos;
|
namespace Fengling.Console.Models.Dtos;
|
||||||
|
|
||||||
public class TenantDto
|
public class TenantDto
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public string TenantCode { get; set; } = "";
|
public string TenantId { get; set; } = "";
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
public string ContactName { get; set; } = "";
|
public string ContactName { get; set; } = "";
|
||||||
public string ContactEmail { get; set; } = "";
|
public string ContactEmail { get; set; } = "";
|
||||||
public string? ContactPhone { get; set; }
|
public string? ContactPhone { get; set; }
|
||||||
public int? MaxUsers { get; set; }
|
public int? MaxUsers { get; set; }
|
||||||
public int UserCount { get; set; }
|
public int UserCount { get; set; }
|
||||||
public TenantStatus Status { get; set; } = TenantStatus.Active;
|
public string Status { get; set; } = "active";
|
||||||
public DateTime? ExpiresAt { get; set; }
|
public DateTime? ExpiresAt { get; set; }
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public string? CustomDomain { get; set; }
|
|
||||||
public string? BasePath { get; set; }
|
|
||||||
public string? Logo { get; set; }
|
|
||||||
public string? H5BaseUrl { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
|
|
||||||
|
|
||||||
namespace Fengling.Console.Models.Dtos;
|
namespace Fengling.Console.Models.Dtos;
|
||||||
|
|
||||||
public class TenantQueryDto : PaginationQueryDto
|
public class TenantQueryDto : PaginationQueryDto
|
||||||
@ -8,5 +6,5 @@ public class TenantQueryDto : PaginationQueryDto
|
|||||||
|
|
||||||
public string? TenantId { get; set; }
|
public string? TenantId { get; set; }
|
||||||
|
|
||||||
public TenantStatus? Status { get; set; }
|
public string? Status { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,16 +23,4 @@ public class UpdateTenantDto
|
|||||||
public string Status { get; set; } = "active";
|
public string Status { get; set; } = "active";
|
||||||
|
|
||||||
public DateTime? ExpiresAt { get; set; }
|
public DateTime? ExpiresAt { get; set; }
|
||||||
|
|
||||||
[MaxLength(255)]
|
|
||||||
public string? CustomDomain { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(50)]
|
|
||||||
public string? BasePath { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(500)]
|
|
||||||
public string? Logo { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(500)]
|
|
||||||
public string? H5BaseUrl { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ public class UpdateUserDto
|
|||||||
[Required]
|
[Required]
|
||||||
public string RealName { get; set; } = string.Empty;
|
public string RealName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string? PhoneNumber { get; set; }
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
public bool EmailConfirmed { get; set; }
|
public bool EmailConfirmed { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -6,11 +6,11 @@ public class UserDto
|
|||||||
public string? UserName { get; set; }
|
public string? UserName { get; set; }
|
||||||
public string? Email { get; set; }
|
public string? Email { get; set; }
|
||||||
public string? RealName { get; set; }
|
public string? RealName { get; set; }
|
||||||
public string? PhoneNumber { get; set; }
|
public string? Phone { get; set; }
|
||||||
public string? TenantCode { get; set; } = "";
|
public long TenantId { get; set; }
|
||||||
public string? TenantName { get; set; } = "";
|
public string TenantName { get; set; } = "";
|
||||||
public List<string> Roles { get; set; } = new();
|
public List<string> Roles { get; set; } = new();
|
||||||
public bool EmailConfirmed { get; set; }
|
public bool EmailConfirmed { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
public DateTimeOffset CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
43
Models/Entities/AccessLog.cs
Normal file
43
Models/Entities/AccessLog.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
public class AccessLog
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? UserName { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? TenantId { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string Action { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(200)]
|
||||||
|
public string? Resource { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? Method { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? IpAddress { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string? UserAgent { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string Status { get; set; } = "success";
|
||||||
|
|
||||||
|
public int Duration { get; set; }
|
||||||
|
|
||||||
|
public string? RequestData { get; set; }
|
||||||
|
|
||||||
|
public string? ResponseData { get; set; }
|
||||||
|
|
||||||
|
public string? ErrorMessage { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
}
|
||||||
13
Models/Entities/ApplicationRole.cs
Normal file
13
Models/Entities/ApplicationRole.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
public class ApplicationRole : IdentityRole<long>
|
||||||
|
{
|
||||||
|
public string? Description { get; set; }
|
||||||
|
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||||
|
public long? TenantId { get; set; }
|
||||||
|
public bool IsSystem { get; set; }
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
public List<string>? Permissions { get; set; }
|
||||||
|
}
|
||||||
13
Models/Entities/ApplicationUser.cs
Normal file
13
Models/Entities/ApplicationUser.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
public class ApplicationUser : IdentityUser<long>
|
||||||
|
{
|
||||||
|
public string? RealName { get; set; }
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
public TenantInfo TenantInfo { get; set; } = null!;
|
||||||
|
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||||
|
public DateTime? UpdatedTime { get; set; }
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
|
}
|
||||||
47
Models/Entities/AuditLog.cs
Normal file
47
Models/Entities/AuditLog.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
public class AuditLog
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
[Required]
|
||||||
|
public string Operator { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? TenantId { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string Operation { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string Action { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string? TargetType { get; set; }
|
||||||
|
|
||||||
|
public long? TargetId { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string? TargetName { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string IpAddress { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
public string? OldValue { get; set; }
|
||||||
|
|
||||||
|
public string? NewValue { get; set; }
|
||||||
|
|
||||||
|
public string? ErrorMessage { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string Status { get; set; } = "success";
|
||||||
|
|
||||||
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
}
|
||||||
63
Models/Entities/Tenant.cs
Normal file
63
Models/Entities/Tenant.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
public class Tenant
|
||||||
|
{
|
||||||
|
private long _id;
|
||||||
|
private string _tenantId;
|
||||||
|
private string _name;
|
||||||
|
|
||||||
|
[Key]
|
||||||
|
public long Id
|
||||||
|
{
|
||||||
|
get => _id;
|
||||||
|
set => _id = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
[Required]
|
||||||
|
public string TenantId
|
||||||
|
{
|
||||||
|
get => _tenantId;
|
||||||
|
set => _tenantId = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MaxLength(100)]
|
||||||
|
[Required]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set => _name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MaxLength(50)]
|
||||||
|
[Required]
|
||||||
|
public string ContactName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(100)]
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string ContactEmail { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string? ContactPhone { get; set; }
|
||||||
|
|
||||||
|
public int? MaxUsers { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string Status { get; set; } = "active";
|
||||||
|
|
||||||
|
public DateTime? ExpiresAt { get; set; }
|
||||||
|
|
||||||
|
public DateTime? UpdatedAt { get; set; }
|
||||||
|
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
|
|
||||||
|
public TenantInfo Info => new(Id, TenantId, Name);
|
||||||
|
}
|
||||||
3
Models/Entities/TenantInfo.cs
Normal file
3
Models/Entities/TenantInfo.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
public record TenantInfo(long Id, string TenantId, string Name);
|
||||||
46
Program.cs
46
Program.cs
@ -1,15 +1,14 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Fengling.Console.Repositories;
|
||||||
using Fengling.Console.Services;
|
using Fengling.Console.Services;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
|
|
||||||
using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
|
|
||||||
using Fengling.Platform.Infrastructure;
|
|
||||||
using OpenIddict.Abstractions;
|
using OpenIddict.Abstractions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using NetCorePal.Extensions.DependencyInjection;
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
using OpenIddict.Validation.AspNetCore;
|
using OpenIddict.Validation.AspNetCore;
|
||||||
using YarpGateway.Data;
|
using YarpGateway.Data;
|
||||||
|
|
||||||
@ -17,42 +16,35 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
// Use PlatformDbContext for all identity
|
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||||
builder.Services.AddDbContext<PlatformDbContext>(options =>
|
|
||||||
{
|
{
|
||||||
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"));
|
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"));
|
||||||
if (builder.Environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
options.EnableSensitiveDataLogging();
|
|
||||||
}
|
|
||||||
options.EnableDetailedErrors();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddDbContext<GatewayDbContext>(options =>
|
builder.Services.AddDbContext<GatewayDbContext>(options =>
|
||||||
options.UseNpgsql(builder.Configuration.GetConnectionString("GatewayConnection")));
|
options.UseNpgsql(builder.Configuration.GetConnectionString("GatewayConnection")));
|
||||||
|
|
||||||
// Use Platform's identity
|
|
||||||
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>()
|
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>()
|
||||||
.AddEntityFrameworkStores<PlatformDbContext>()
|
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
builder.Services.AddHttpClient();
|
builder.Services.AddHttpClient();
|
||||||
builder.Services.AddScoped<IOAuthClientService, OAuthClientService>();
|
builder.Services.AddScoped<IOAuthClientService, OAuthClientService>();
|
||||||
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||||
// Register Platform managers
|
builder.Services.AddScoped<ITenantRepository, TenantRepository>();
|
||||||
builder.Services.AddScoped<ITenantStore, TenantStore>();
|
builder.Services.AddScoped<IRoleRepository, RoleRepository>();
|
||||||
builder.Services.AddScoped<ITenantManager, TenantManager>();
|
|
||||||
|
|
||||||
builder.Services.AddScoped<IUserService, UserService>();
|
builder.Services.AddScoped<IUserService, UserService>();
|
||||||
builder.Services.AddScoped<ITenantService, TenantService>();
|
builder.Services.AddScoped<ITenantService, TenantService>();
|
||||||
builder.Services.AddScoped<IRoleService, RoleService>();
|
builder.Services.AddScoped<IRoleService, RoleService>();
|
||||||
builder.Services.AddScoped<IGatewayService, GatewayService>();
|
|
||||||
builder.Services.AddScoped<IH5LinkService, H5LinkService>();
|
|
||||||
|
|
||||||
builder.Services.AddOpenIddict()
|
builder.Services.AddOpenIddict()
|
||||||
.AddCore(options => { options.UseEntityFrameworkCore().UseDbContext<PlatformDbContext>(); })
|
.AddCore(options =>
|
||||||
|
{
|
||||||
|
options.UseEntityFrameworkCore().UseDbContext<ApplicationDbContext>();
|
||||||
|
})
|
||||||
.AddValidation(options =>
|
.AddValidation(options =>
|
||||||
{
|
{
|
||||||
options.SetIssuer("http://localhost:5132/");
|
options.SetIssuer("http://localhost:5132/");
|
||||||
@ -78,8 +70,8 @@ builder.Services.AddCors(options =>
|
|||||||
options.AddPolicy("AllowAll", policy =>
|
options.AddPolicy("AllowAll", policy =>
|
||||||
{
|
{
|
||||||
policy.AllowAnyOrigin()
|
policy.AllowAnyOrigin()
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowAnyHeader();
|
.AllowAnyHeader();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,7 +79,6 @@ builder.Services.AddEndpointsApiExplorer();
|
|||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
c.SwaggerDoc("v1", new() { Title = "Fengling.Console API", Version = "v1" });
|
c.SwaggerDoc("v1", new() { Title = "Fengling.Console API", Version = "v1" });
|
||||||
c.CustomSchemaIds(type => type.FullName);
|
|
||||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||||
if (File.Exists(xmlPath))
|
if (File.Exists(xmlPath))
|
||||||
@ -96,14 +87,13 @@ builder.Services.AddSwaggerGen(c =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddRepositories(typeof(PlatformDbContext).Assembly);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Fengling.Console API V1"); });
|
app.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Fengling.Console API V1");
|
||||||
|
});
|
||||||
|
|
||||||
app.UseCors("AllowAll");
|
app.UseCors("AllowAll");
|
||||||
|
|
||||||
|
|||||||
15
Repositories/IRoleRepository.cs
Normal file
15
Repositories/IRoleRepository.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Repositories;
|
||||||
|
|
||||||
|
public interface IRoleRepository
|
||||||
|
{
|
||||||
|
Task<ApplicationRole?> GetByIdAsync(long id);
|
||||||
|
Task<ApplicationRole?> GetByNameAsync(string name);
|
||||||
|
Task<IEnumerable<ApplicationRole>> GetAllAsync();
|
||||||
|
Task<IEnumerable<ApplicationRole>> GetPagedAsync(int page, int pageSize, string? name = null, string? tenantId = null);
|
||||||
|
Task<int> CountAsync(string? name = null, string? tenantId = null);
|
||||||
|
Task AddAsync(ApplicationRole role);
|
||||||
|
Task UpdateAsync(ApplicationRole role);
|
||||||
|
Task DeleteAsync(ApplicationRole role);
|
||||||
|
}
|
||||||
16
Repositories/ITenantRepository.cs
Normal file
16
Repositories/ITenantRepository.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Repositories;
|
||||||
|
|
||||||
|
public interface ITenantRepository
|
||||||
|
{
|
||||||
|
Task<Tenant?> GetByIdAsync(long id);
|
||||||
|
Task<Tenant?> GetByTenantIdAsync(string tenantId);
|
||||||
|
Task<IEnumerable<Tenant>> GetAllAsync();
|
||||||
|
Task<IEnumerable<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null, string? tenantId = null, string? status = null);
|
||||||
|
Task<int> CountAsync(string? name = null, string? tenantId = null, string? status = null);
|
||||||
|
Task AddAsync(Tenant tenant);
|
||||||
|
Task UpdateAsync(Tenant tenant);
|
||||||
|
Task DeleteAsync(Tenant tenant);
|
||||||
|
Task<int> GetUserCountAsync(long tenantId);
|
||||||
|
}
|
||||||
15
Repositories/IUserRepository.cs
Normal file
15
Repositories/IUserRepository.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Repositories;
|
||||||
|
|
||||||
|
public interface IUserRepository
|
||||||
|
{
|
||||||
|
Task<ApplicationUser?> GetByIdAsync(long id);
|
||||||
|
Task<ApplicationUser?> GetByUserNameAsync(string userName);
|
||||||
|
Task<IEnumerable<ApplicationUser>> GetAllAsync();
|
||||||
|
Task<IEnumerable<ApplicationUser>> GetPagedAsync(int page, int pageSize, string? userName = null, string? email = null, string? tenantId = null);
|
||||||
|
Task<int> CountAsync(string? userName = null, string? email = null, string? tenantId = null);
|
||||||
|
Task AddAsync(ApplicationUser user);
|
||||||
|
Task UpdateAsync(ApplicationUser user);
|
||||||
|
Task DeleteAsync(ApplicationUser user);
|
||||||
|
}
|
||||||
80
Repositories/RoleRepository.cs
Normal file
80
Repositories/RoleRepository.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Repositories;
|
||||||
|
|
||||||
|
public class RoleRepository(ApplicationDbContext context) : IRoleRepository
|
||||||
|
{
|
||||||
|
public async Task<ApplicationRole?> GetByIdAsync(long id)
|
||||||
|
{
|
||||||
|
return await context.Roles.FindAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ApplicationRole?> GetByNameAsync(string name)
|
||||||
|
{
|
||||||
|
return await context.Roles.FirstOrDefaultAsync(r => r.Name == name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ApplicationRole>> GetAllAsync()
|
||||||
|
{
|
||||||
|
return await context.Roles.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ApplicationRole>> GetPagedAsync(int page, int pageSize, string? name = null,
|
||||||
|
string? tenantId = null)
|
||||||
|
{
|
||||||
|
var query = context.Roles.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
query = query.Where(r => r.Name != null && r.Name.Contains(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tenantId))
|
||||||
|
{
|
||||||
|
query = query.Where(r => r.TenantId.ToString() == tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query
|
||||||
|
.OrderByDescending(r => r.CreatedTime)
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CountAsync(string? name = null, string? tenantId = null)
|
||||||
|
{
|
||||||
|
var query = context.Roles.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
query = query.Where(r => r.Name != null && r.Name.Contains(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tenantId))
|
||||||
|
{
|
||||||
|
query = query.Where(r => r.TenantId.ToString() == tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddAsync(ApplicationRole role)
|
||||||
|
{
|
||||||
|
context.Roles.Add(role);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(ApplicationRole role)
|
||||||
|
{
|
||||||
|
context.Roles.Update(role);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(ApplicationRole role)
|
||||||
|
{
|
||||||
|
context.Roles.Remove(role);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
95
Repositories/TenantRepository.cs
Normal file
95
Repositories/TenantRepository.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Repositories;
|
||||||
|
|
||||||
|
public class TenantRepository(ApplicationDbContext context) : ITenantRepository
|
||||||
|
{
|
||||||
|
public async Task<Tenant?> GetByIdAsync(long id)
|
||||||
|
{
|
||||||
|
return await context.Tenants.FindAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Tenant?> GetByTenantIdAsync(string tenantId)
|
||||||
|
{
|
||||||
|
return await context.Tenants.FirstOrDefaultAsync(t => t.TenantId == tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Tenant>> GetAllAsync()
|
||||||
|
{
|
||||||
|
return await context.Tenants.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null,
|
||||||
|
string? tenantId = null, string? status = null)
|
||||||
|
{
|
||||||
|
var query = context.Tenants.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
query = query.Where(t => t.Name.Contains(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tenantId))
|
||||||
|
{
|
||||||
|
query = query.Where(t => t.TenantId.Contains(tenantId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(status))
|
||||||
|
{
|
||||||
|
query = query.Where(t => t.Status == status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query
|
||||||
|
.OrderByDescending(t => t.CreatedAt)
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CountAsync(string? name = null, string? tenantId = null, string? status = null)
|
||||||
|
{
|
||||||
|
var query = context.Tenants.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
query = query.Where(t => t.Name.Contains(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tenantId))
|
||||||
|
{
|
||||||
|
query = query.Where(t => t.TenantId.Contains(tenantId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(status))
|
||||||
|
{
|
||||||
|
query = query.Where(t => t.Status == status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddAsync(Tenant tenant)
|
||||||
|
{
|
||||||
|
context.Tenants.Add(tenant);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(Tenant tenant)
|
||||||
|
{
|
||||||
|
context.Tenants.Update(tenant);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(Tenant tenant)
|
||||||
|
{
|
||||||
|
context.Tenants.Remove(tenant);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> GetUserCountAsync(long tenantId)
|
||||||
|
{
|
||||||
|
return await context.Users.CountAsync(u => u.TenantInfo.Id == tenantId && !u.IsDeleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
96
Repositories/UserRepository.cs
Normal file
96
Repositories/UserRepository.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Fengling.Console.Repositories;
|
||||||
|
|
||||||
|
public class UserRepository : IUserRepository
|
||||||
|
{
|
||||||
|
private readonly ApplicationDbContext _context;
|
||||||
|
|
||||||
|
public UserRepository(ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ApplicationUser?> GetByIdAsync(long id)
|
||||||
|
{
|
||||||
|
return await _context.Users.FindAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ApplicationUser?> GetByUserNameAsync(string userName)
|
||||||
|
{
|
||||||
|
return await _context.Users.FirstOrDefaultAsync(u => u.UserName == userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ApplicationUser>> GetAllAsync()
|
||||||
|
{
|
||||||
|
return await _context.Users.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ApplicationUser>> GetPagedAsync(int page, int pageSize, string? userName = null, string? email = null, string? tenantId = null)
|
||||||
|
{
|
||||||
|
var query = _context.Users.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(userName))
|
||||||
|
{
|
||||||
|
query = query.Where(u => u.UserName != null && u.UserName.Contains(userName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(email))
|
||||||
|
{
|
||||||
|
query = query.Where(u => u.Email != null && u.Email.Contains(email));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tenantId))
|
||||||
|
{
|
||||||
|
query = query.Where(u => u.TenantInfo.Id.ToString() == tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query
|
||||||
|
.OrderByDescending(u => u.CreatedTime)
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CountAsync(string? userName = null, string? email = null, string? tenantId = null)
|
||||||
|
{
|
||||||
|
var query = _context.Users.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(userName))
|
||||||
|
{
|
||||||
|
query = query.Where(u => u.UserName != null && u.UserName.Contains(userName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(email))
|
||||||
|
{
|
||||||
|
query = query.Where(u => u.Email != null && u.Email.Contains(email));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tenantId))
|
||||||
|
{
|
||||||
|
query = query.Where(u => u.TenantInfo.Id.ToString() == tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddAsync(ApplicationUser user)
|
||||||
|
{
|
||||||
|
_context.Users.Add(user);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(ApplicationUser user)
|
||||||
|
{
|
||||||
|
_context.Users.Update(user);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(ApplicationUser user)
|
||||||
|
{
|
||||||
|
_context.Users.Remove(user);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,19 +24,21 @@ public interface IGatewayService
|
|||||||
|
|
||||||
public class GatewayService : IGatewayService
|
public class GatewayService : IGatewayService
|
||||||
{
|
{
|
||||||
private readonly GatewayDbContext _dbContext;
|
private readonly IDbContextFactory<GatewayDbContext> _dbContextFactory;
|
||||||
private readonly ILogger<GatewayService> _logger;
|
private readonly ILogger<GatewayService> _logger;
|
||||||
|
|
||||||
public GatewayService(GatewayDbContext dbContext, ILogger<GatewayService> logger)
|
public GatewayService(IDbContextFactory<GatewayDbContext> dbContextFactory, ILogger<GatewayService> logger)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContextFactory = dbContextFactory;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<GatewayStatisticsDto> GetStatisticsAsync()
|
public async Task<GatewayStatisticsDto> GetStatisticsAsync()
|
||||||
{
|
{
|
||||||
var routes = await _dbContext.TenantRoutes.Where(r => !r.IsDeleted).ToListAsync();
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
var instances = await _dbContext.ServiceInstances.Where(i => !i.IsDeleted).ToListAsync();
|
|
||||||
|
var routes = await db.TenantRoutes.Where(r => !r.IsDeleted).ToListAsync();
|
||||||
|
var instances = await db.ServiceInstances.Where(i => !i.IsDeleted).ToListAsync();
|
||||||
|
|
||||||
return new GatewayStatisticsDto
|
return new GatewayStatisticsDto
|
||||||
{
|
{
|
||||||
@ -55,7 +57,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<List<GatewayServiceDto>> GetServicesAsync(bool globalOnly = false, string? tenantCode = null)
|
public async Task<List<GatewayServiceDto>> GetServicesAsync(bool globalOnly = false, string? tenantCode = null)
|
||||||
{
|
{
|
||||||
var query = _dbContext.TenantRoutes.Where(r => !r.IsDeleted);
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var query = db.TenantRoutes.Where(r => !r.IsDeleted);
|
||||||
|
|
||||||
if (globalOnly)
|
if (globalOnly)
|
||||||
query = query.Where(r => r.IsGlobal);
|
query = query.Where(r => r.IsGlobal);
|
||||||
@ -65,7 +69,7 @@ public class GatewayService : IGatewayService
|
|||||||
var routes = await query.OrderByDescending(r => r.CreatedTime).ToListAsync();
|
var routes = await query.OrderByDescending(r => r.CreatedTime).ToListAsync();
|
||||||
var clusters = routes.Select(r => r.ClusterId).Distinct().ToList();
|
var clusters = routes.Select(r => r.ClusterId).Distinct().ToList();
|
||||||
|
|
||||||
var instances = await _dbContext.ServiceInstances
|
var instances = await db.ServiceInstances
|
||||||
.Where(i => clusters.Contains(i.ClusterId) && !i.IsDeleted)
|
.Where(i => clusters.Contains(i.ClusterId) && !i.IsDeleted)
|
||||||
.GroupBy(i => i.ClusterId)
|
.GroupBy(i => i.ClusterId)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.Count());
|
.ToDictionaryAsync(g => g.Key, g => g.Count());
|
||||||
@ -75,7 +79,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<GatewayServiceDto?> GetServiceAsync(string serviceName, string? tenantCode = null)
|
public async Task<GatewayServiceDto?> GetServiceAsync(string serviceName, string? tenantCode = null)
|
||||||
{
|
{
|
||||||
var route = await _dbContext.TenantRoutes
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var route = await db.TenantRoutes
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.ServiceName == serviceName &&
|
r.ServiceName == serviceName &&
|
||||||
r.IsDeleted == false &&
|
r.IsDeleted == false &&
|
||||||
@ -83,7 +89,7 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
if (route == null) return null;
|
if (route == null) return null;
|
||||||
|
|
||||||
var instances = await _dbContext.ServiceInstances
|
var instances = await db.ServiceInstances
|
||||||
.CountAsync(i => i.ClusterId == route.ClusterId && !i.IsDeleted);
|
.CountAsync(i => i.ClusterId == route.ClusterId && !i.IsDeleted);
|
||||||
|
|
||||||
return MapToServiceDto(route, instances);
|
return MapToServiceDto(route, instances);
|
||||||
@ -91,6 +97,8 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<GatewayServiceDto> RegisterServiceAsync(CreateGatewayServiceDto dto)
|
public async Task<GatewayServiceDto> RegisterServiceAsync(CreateGatewayServiceDto dto)
|
||||||
{
|
{
|
||||||
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
var clusterId = $"{dto.ServicePrefix}-service";
|
var clusterId = $"{dto.ServicePrefix}-service";
|
||||||
var pathPattern = $"/{dto.ServicePrefix}/{dto.Version}/{{**path}}";
|
var pathPattern = $"/{dto.ServicePrefix}/{dto.Version}/{{**path}}";
|
||||||
var destinationId = string.IsNullOrEmpty(dto.DestinationId)
|
var destinationId = string.IsNullOrEmpty(dto.DestinationId)
|
||||||
@ -98,7 +106,7 @@ public class GatewayService : IGatewayService
|
|||||||
: dto.DestinationId;
|
: dto.DestinationId;
|
||||||
|
|
||||||
// Check if route already exists
|
// Check if route already exists
|
||||||
var existingRoute = await _dbContext.TenantRoutes
|
var existingRoute = await db.TenantRoutes
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.ServiceName == dto.ServicePrefix &&
|
r.ServiceName == dto.ServicePrefix &&
|
||||||
r.IsGlobal == dto.IsGlobal &&
|
r.IsGlobal == dto.IsGlobal &&
|
||||||
@ -122,7 +130,7 @@ public class GatewayService : IGatewayService
|
|||||||
Status = 1,
|
Status = 1,
|
||||||
CreatedTime = DateTime.UtcNow
|
CreatedTime = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
await _dbContext.ServiceInstances.AddAsync(instance);
|
await db.ServiceInstances.AddAsync(instance);
|
||||||
|
|
||||||
// Add route
|
// Add route
|
||||||
var routeId = instanceId + 1;
|
var routeId = instanceId + 1;
|
||||||
@ -138,9 +146,9 @@ public class GatewayService : IGatewayService
|
|||||||
IsGlobal = dto.IsGlobal,
|
IsGlobal = dto.IsGlobal,
|
||||||
CreatedTime = DateTime.UtcNow
|
CreatedTime = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
await _dbContext.TenantRoutes.AddAsync(route);
|
await db.TenantRoutes.AddAsync(route);
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
_logger.LogInformation("Registered service {Service} at {Address}", dto.ServicePrefix, dto.ServiceAddress);
|
_logger.LogInformation("Registered service {Service} at {Address}", dto.ServicePrefix, dto.ServiceAddress);
|
||||||
|
|
||||||
@ -149,7 +157,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<bool> UnregisterServiceAsync(string serviceName, string? tenantCode = null)
|
public async Task<bool> UnregisterServiceAsync(string serviceName, string? tenantCode = null)
|
||||||
{
|
{
|
||||||
var route = await _dbContext.TenantRoutes
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var route = await db.TenantRoutes
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.ServiceName == serviceName &&
|
r.ServiceName == serviceName &&
|
||||||
r.IsDeleted == false &&
|
r.IsDeleted == false &&
|
||||||
@ -162,7 +172,7 @@ public class GatewayService : IGatewayService
|
|||||||
route.UpdatedTime = DateTime.UtcNow;
|
route.UpdatedTime = DateTime.UtcNow;
|
||||||
|
|
||||||
// Soft delete instances
|
// Soft delete instances
|
||||||
var instances = await _dbContext.ServiceInstances
|
var instances = await db.ServiceInstances
|
||||||
.Where(i => i.ClusterId == route.ClusterId && !i.IsDeleted)
|
.Where(i => i.ClusterId == route.ClusterId && !i.IsDeleted)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@ -172,7 +182,7 @@ public class GatewayService : IGatewayService
|
|||||||
instance.UpdatedTime = DateTime.UtcNow;
|
instance.UpdatedTime = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
_logger.LogInformation("Unregistered service {Service}", serviceName);
|
_logger.LogInformation("Unregistered service {Service}", serviceName);
|
||||||
|
|
||||||
@ -181,7 +191,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<List<GatewayRouteDto>> GetRoutesAsync(bool globalOnly = false)
|
public async Task<List<GatewayRouteDto>> GetRoutesAsync(bool globalOnly = false)
|
||||||
{
|
{
|
||||||
var query = _dbContext.TenantRoutes.Where(r => !r.IsDeleted);
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var query = db.TenantRoutes.Where(r => !r.IsDeleted);
|
||||||
|
|
||||||
if (globalOnly)
|
if (globalOnly)
|
||||||
query = query.Where(r => r.IsGlobal);
|
query = query.Where(r => r.IsGlobal);
|
||||||
@ -189,7 +201,7 @@ public class GatewayService : IGatewayService
|
|||||||
var routes = await query.OrderByDescending(r => r.Priority).ToListAsync();
|
var routes = await query.OrderByDescending(r => r.Priority).ToListAsync();
|
||||||
var clusters = routes.Select(r => r.ClusterId).Distinct().ToList();
|
var clusters = routes.Select(r => r.ClusterId).Distinct().ToList();
|
||||||
|
|
||||||
var instances = await _dbContext.ServiceInstances
|
var instances = await db.ServiceInstances
|
||||||
.Where(i => clusters.Contains(i.ClusterId) && !i.IsDeleted)
|
.Where(i => clusters.Contains(i.ClusterId) && !i.IsDeleted)
|
||||||
.GroupBy(i => i.ClusterId)
|
.GroupBy(i => i.ClusterId)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.Count());
|
.ToDictionaryAsync(g => g.Key, g => g.Count());
|
||||||
@ -210,7 +222,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<GatewayRouteDto> CreateRouteAsync(CreateGatewayRouteDto dto)
|
public async Task<GatewayRouteDto> CreateRouteAsync(CreateGatewayRouteDto dto)
|
||||||
{
|
{
|
||||||
var existing = await _dbContext.TenantRoutes
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var existing = await db.TenantRoutes
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.ServiceName == dto.ServiceName &&
|
r.ServiceName == dto.ServiceName &&
|
||||||
r.IsGlobal == dto.IsGlobal &&
|
r.IsGlobal == dto.IsGlobal &&
|
||||||
@ -234,8 +248,8 @@ public class GatewayService : IGatewayService
|
|||||||
CreatedTime = DateTime.UtcNow
|
CreatedTime = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
await _dbContext.TenantRoutes.AddAsync(route);
|
await db.TenantRoutes.AddAsync(route);
|
||||||
await _dbContext.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
return new GatewayRouteDto
|
return new GatewayRouteDto
|
||||||
{
|
{
|
||||||
@ -253,7 +267,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<List<GatewayInstanceDto>> GetInstancesAsync(string clusterId)
|
public async Task<List<GatewayInstanceDto>> GetInstancesAsync(string clusterId)
|
||||||
{
|
{
|
||||||
var instances = await _dbContext.ServiceInstances
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var instances = await db.ServiceInstances
|
||||||
.Where(i => i.ClusterId == clusterId && !i.IsDeleted)
|
.Where(i => i.ClusterId == clusterId && !i.IsDeleted)
|
||||||
.OrderByDescending(i => i.Weight)
|
.OrderByDescending(i => i.Weight)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@ -273,7 +289,9 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<GatewayInstanceDto> AddInstanceAsync(CreateGatewayInstanceDto dto)
|
public async Task<GatewayInstanceDto> AddInstanceAsync(CreateGatewayInstanceDto dto)
|
||||||
{
|
{
|
||||||
var existing = await _dbContext.ServiceInstances
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var existing = await db.ServiceInstances
|
||||||
.FirstOrDefaultAsync(i =>
|
.FirstOrDefaultAsync(i =>
|
||||||
i.ClusterId == dto.ClusterId &&
|
i.ClusterId == dto.ClusterId &&
|
||||||
i.DestinationId == dto.DestinationId &&
|
i.DestinationId == dto.DestinationId &&
|
||||||
@ -296,8 +314,8 @@ public class GatewayService : IGatewayService
|
|||||||
CreatedTime = DateTime.UtcNow
|
CreatedTime = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
await _dbContext.ServiceInstances.AddAsync(instance);
|
await db.ServiceInstances.AddAsync(instance);
|
||||||
await _dbContext.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
return new GatewayInstanceDto
|
return new GatewayInstanceDto
|
||||||
{
|
{
|
||||||
@ -314,25 +332,29 @@ public class GatewayService : IGatewayService
|
|||||||
|
|
||||||
public async Task<bool> RemoveInstanceAsync(long instanceId)
|
public async Task<bool> RemoveInstanceAsync(long instanceId)
|
||||||
{
|
{
|
||||||
var instance = await _dbContext.ServiceInstances.FindAsync(instanceId);
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var instance = await db.ServiceInstances.FindAsync(instanceId);
|
||||||
if (instance == null) return false;
|
if (instance == null) return false;
|
||||||
|
|
||||||
instance.IsDeleted = true;
|
instance.IsDeleted = true;
|
||||||
instance.UpdatedTime = DateTime.UtcNow;
|
instance.UpdatedTime = DateTime.UtcNow;
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateInstanceWeightAsync(long instanceId, int weight)
|
public async Task<bool> UpdateInstanceWeightAsync(long instanceId, int weight)
|
||||||
{
|
{
|
||||||
var instance = await _dbContext.ServiceInstances.FindAsync(instanceId);
|
await using var db = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
var instance = await db.ServiceInstances.FindAsync(instanceId);
|
||||||
if (instance == null) return false;
|
if (instance == null) return false;
|
||||||
|
|
||||||
instance.Weight = weight;
|
instance.Weight = weight;
|
||||||
instance.UpdatedTime = DateTime.UtcNow;
|
instance.UpdatedTime = DateTime.UtcNow;
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,55 +0,0 @@
|
|||||||
using Fengling.Platform.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using QRCoder;
|
|
||||||
|
|
||||||
namespace Fengling.Console.Services;
|
|
||||||
|
|
||||||
public interface IH5LinkService
|
|
||||||
{
|
|
||||||
Task<H5LinkResult> GenerateH5LinkAsync(int tenantId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class H5LinkResult
|
|
||||||
{
|
|
||||||
public string Link { get; set; } = string.Empty;
|
|
||||||
public string QrCodeBase64 { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class H5LinkService : IH5LinkService
|
|
||||||
{
|
|
||||||
private readonly ITenantManager _tenantManager;
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
|
|
||||||
public H5LinkService(ITenantManager tenantManager, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_tenantManager = tenantManager;
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<H5LinkResult> GenerateH5LinkAsync(int tenantId)
|
|
||||||
{
|
|
||||||
var tenant = await _tenantManager.FindByIdAsync(tenantId)
|
|
||||||
?? throw new KeyNotFoundException($"Tenant with ID {tenantId} not found");
|
|
||||||
|
|
||||||
var link = GenerateLink(tenant);
|
|
||||||
var qrCodeBase64 = GenerateQrCode(link);
|
|
||||||
|
|
||||||
return new H5LinkResult
|
|
||||||
{
|
|
||||||
Link = link,
|
|
||||||
QrCodeBase64 = qrCodeBase64
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GenerateLink(Fengling.Platform.Domain.AggregatesModel.TenantAggregate.Tenant tenant)
|
|
||||||
{
|
|
||||||
var baseUrl = _configuration["AppSettings:DefaultH5BaseUrl"] ?? "https://h5.example.com";
|
|
||||||
return $"{baseUrl.TrimEnd('/')}/{tenant.TenantCode}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GenerateQrCode(string content)
|
|
||||||
{
|
|
||||||
byte[] qrCodeBytes = PngByteQRCodeHelper.GetQRCode(content, QRCodeGenerator.ECCLevel.M, 20);
|
|
||||||
return Convert.ToBase64String(qrCodeBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -45,10 +45,10 @@ public class OAuthClientService : IOAuthClientService
|
|||||||
var clientIdValue = await _applicationManager.GetClientIdAsync(application);
|
var clientIdValue = await _applicationManager.GetClientIdAsync(application);
|
||||||
var displayNameValue = await _applicationManager.GetDisplayNameAsync(application);
|
var displayNameValue = await _applicationManager.GetDisplayNameAsync(application);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(displayName) && (string.IsNullOrEmpty(displayNameValue) || !displayNameValue.Contains(displayName, StringComparison.OrdinalIgnoreCase)))
|
if (!string.IsNullOrEmpty(displayName) && !displayNameValue.Contains(displayName, StringComparison.OrdinalIgnoreCase))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(clientId) && (string.IsNullOrEmpty(clientIdValue) || !clientIdValue.Contains(clientId, StringComparison.OrdinalIgnoreCase)))
|
if (!string.IsNullOrEmpty(clientId) && !clientIdValue.Contains(clientId, StringComparison.OrdinalIgnoreCase))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var clientType = await _applicationManager.GetClientTypeAsync(application);
|
var clientType = await _applicationManager.GetClientTypeAsync(application);
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
using Fengling.Console.Models.Dtos;
|
using Fengling.Console.Models.Dtos;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
|
using Fengling.Console.Repositories;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
|
|
||||||
using Fengling.Platform.Infrastructure;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
namespace Fengling.Console.Services;
|
namespace Fengling.Console.Services;
|
||||||
|
|
||||||
@ -24,20 +23,20 @@ public interface IRoleService
|
|||||||
|
|
||||||
public class RoleService : IRoleService
|
public class RoleService : IRoleService
|
||||||
{
|
{
|
||||||
private readonly ITenantManager _tenantManager;
|
private readonly IRoleRepository _repository;
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
private readonly RoleManager<ApplicationRole> _roleManager;
|
private readonly RoleManager<ApplicationRole> _roleManager;
|
||||||
private readonly PlatformDbContext _context;
|
private readonly ApplicationDbContext _context;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
public RoleService(
|
public RoleService(
|
||||||
ITenantManager tenantManager,
|
IRoleRepository repository,
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
RoleManager<ApplicationRole> roleManager,
|
RoleManager<ApplicationRole> roleManager,
|
||||||
PlatformDbContext context,
|
ApplicationDbContext context,
|
||||||
IHttpContextAccessor httpContextAccessor)
|
IHttpContextAccessor httpContextAccessor)
|
||||||
{
|
{
|
||||||
_tenantManager = tenantManager;
|
_repository = repository;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_roleManager = roleManager;
|
_roleManager = roleManager;
|
||||||
_context = context;
|
_context = context;
|
||||||
@ -47,24 +46,8 @@ public class RoleService : IRoleService
|
|||||||
public async Task<(IEnumerable<RoleDto> Items, int TotalCount)> GetRolesAsync(int page, int pageSize,
|
public async Task<(IEnumerable<RoleDto> Items, int TotalCount)> GetRolesAsync(int page, int pageSize,
|
||||||
string? name = null, string? tenantId = null)
|
string? name = null, string? tenantId = null)
|
||||||
{
|
{
|
||||||
var query = _context.Roles.AsQueryable();
|
var roles = await _repository.GetPagedAsync(page, pageSize, name, tenantId);
|
||||||
|
var totalCount = await _repository.CountAsync(name, tenantId);
|
||||||
if (!string.IsNullOrEmpty(name))
|
|
||||||
{
|
|
||||||
query = query.Where(r => r.Name != null && r.Name.Contains(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(tenantId))
|
|
||||||
{
|
|
||||||
query = query.Where(r => r.TenantId.HasValue && r.TenantId.Value.ToString().Contains(tenantId));
|
|
||||||
}
|
|
||||||
|
|
||||||
var totalCount = await query.CountAsync();
|
|
||||||
var roles = await query
|
|
||||||
.OrderByDescending(r => r.CreatedTime)
|
|
||||||
.Skip((page - 1) * pageSize)
|
|
||||||
.Take(pageSize)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
var roleDtos = new List<RoleDto>();
|
var roleDtos = new List<RoleDto>();
|
||||||
foreach (var role in roles)
|
foreach (var role in roles)
|
||||||
@ -89,7 +72,7 @@ public class RoleService : IRoleService
|
|||||||
|
|
||||||
public async Task<RoleDto?> GetRoleAsync(long id)
|
public async Task<RoleDto?> GetRoleAsync(long id)
|
||||||
{
|
{
|
||||||
var role = await _context.Roles.FindAsync(id);
|
var role = await _repository.GetByIdAsync(id);
|
||||||
if (role == null) return null;
|
if (role == null) return null;
|
||||||
|
|
||||||
return new RoleDto
|
return new RoleDto
|
||||||
@ -108,7 +91,7 @@ public class RoleService : IRoleService
|
|||||||
|
|
||||||
public async Task<IEnumerable<UserDto>> GetRoleUsersAsync(long id)
|
public async Task<IEnumerable<UserDto>> GetRoleUsersAsync(long id)
|
||||||
{
|
{
|
||||||
var role = await _context.Roles.FindAsync(id);
|
var role = await _repository.GetByIdAsync(id);
|
||||||
if (role == null)
|
if (role == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Role with ID {id} not found");
|
throw new KeyNotFoundException($"Role with ID {id} not found");
|
||||||
@ -120,15 +103,14 @@ public class RoleService : IRoleService
|
|||||||
foreach (var user in users)
|
foreach (var user in users)
|
||||||
{
|
{
|
||||||
var roles = await _userManager.GetRolesAsync(user);
|
var roles = await _userManager.GetRolesAsync(user);
|
||||||
var tenant = user.TenantInfo?.TenantId > 0 ? await _tenantManager.FindByIdAsync(user.TenantInfo.TenantId) : null;
|
|
||||||
userDtos.Add(new UserDto
|
userDtos.Add(new UserDto
|
||||||
{
|
{
|
||||||
Id = user.Id,
|
Id = user.Id,
|
||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
TenantCode = user.TenantInfo?.TenantCode,
|
TenantId = user.TenantInfo.Id,
|
||||||
TenantName = tenant?.Name ?? "",
|
TenantName = user.TenantInfo.Name,
|
||||||
Roles = roles.ToList(),
|
Roles = roles.ToList(),
|
||||||
EmailConfirmed = user.EmailConfirmed,
|
EmailConfirmed = user.EmailConfirmed,
|
||||||
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
||||||
@ -146,7 +128,7 @@ public class RoleService : IRoleService
|
|||||||
Name = dto.Name,
|
Name = dto.Name,
|
||||||
DisplayName = dto.DisplayName,
|
DisplayName = dto.DisplayName,
|
||||||
Description = dto.Description,
|
Description = dto.Description,
|
||||||
TenantId = dto.TenantId.HasValue ? dto.TenantId.Value : null,
|
TenantId = dto.TenantId,
|
||||||
Permissions = dto.Permissions,
|
Permissions = dto.Permissions,
|
||||||
IsSystem = false,
|
IsSystem = false,
|
||||||
CreatedTime = DateTime.UtcNow
|
CreatedTime = DateTime.UtcNow
|
||||||
@ -177,7 +159,7 @@ public class RoleService : IRoleService
|
|||||||
|
|
||||||
public async Task<RoleDto> UpdateRoleAsync(long id, UpdateRoleDto dto)
|
public async Task<RoleDto> UpdateRoleAsync(long id, UpdateRoleDto dto)
|
||||||
{
|
{
|
||||||
var role = await _context.Roles.FindAsync(id);
|
var role = await _repository.GetByIdAsync(id);
|
||||||
if (role == null)
|
if (role == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Role with ID {id} not found");
|
throw new KeyNotFoundException($"Role with ID {id} not found");
|
||||||
@ -194,7 +176,7 @@ public class RoleService : IRoleService
|
|||||||
role.Description = dto.Description;
|
role.Description = dto.Description;
|
||||||
role.Permissions = dto.Permissions;
|
role.Permissions = dto.Permissions;
|
||||||
|
|
||||||
await _roleManager.UpdateAsync(role);
|
await _repository.UpdateAsync(role);
|
||||||
|
|
||||||
await CreateAuditLog("role", "update", "Role", role.Id, role.DisplayName, oldValue,
|
await CreateAuditLog("role", "update", "Role", role.Id, role.DisplayName, oldValue,
|
||||||
System.Text.Json.JsonSerializer.Serialize(role));
|
System.Text.Json.JsonSerializer.Serialize(role));
|
||||||
@ -216,7 +198,7 @@ public class RoleService : IRoleService
|
|||||||
|
|
||||||
public async Task DeleteRoleAsync(long id)
|
public async Task DeleteRoleAsync(long id)
|
||||||
{
|
{
|
||||||
var role = await _context.Roles.FindAsync(id);
|
var role = await _repository.GetByIdAsync(id);
|
||||||
if (role == null)
|
if (role == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Role with ID {id} not found");
|
throw new KeyNotFoundException($"Role with ID {id} not found");
|
||||||
@ -235,14 +217,14 @@ public class RoleService : IRoleService
|
|||||||
await _userManager.RemoveFromRoleAsync(user, role.Name!);
|
await _userManager.RemoveFromRoleAsync(user, role.Name!);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _roleManager.DeleteAsync(role);
|
await _repository.DeleteAsync(role);
|
||||||
|
|
||||||
await CreateAuditLog("role", "delete", "Role", role.Id, role.DisplayName, oldValue);
|
await CreateAuditLog("role", "delete", "Role", role.Id, role.DisplayName, oldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddUserToRoleAsync(long roleId, long userId)
|
public async Task AddUserToRoleAsync(long roleId, long userId)
|
||||||
{
|
{
|
||||||
var role = await _context.Roles.FindAsync(roleId);
|
var role = await _repository.GetByIdAsync(roleId);
|
||||||
if (role == null)
|
if (role == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Role with ID {roleId} not found");
|
throw new KeyNotFoundException($"Role with ID {roleId} not found");
|
||||||
@ -265,7 +247,7 @@ public class RoleService : IRoleService
|
|||||||
|
|
||||||
public async Task RemoveUserFromRoleAsync(long roleId, long userId)
|
public async Task RemoveUserFromRoleAsync(long roleId, long userId)
|
||||||
{
|
{
|
||||||
var role = await _context.Roles.FindAsync(roleId);
|
var role = await _repository.GetByIdAsync(roleId);
|
||||||
if (role == null)
|
if (role == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Role with ID {roleId} not found");
|
throw new KeyNotFoundException($"Role with ID {roleId} not found");
|
||||||
@ -313,4 +295,4 @@ public class RoleService : IRoleService
|
|||||||
_context.AuditLogs.Add(log);
|
_context.AuditLogs.Add(log);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,19 +1,15 @@
|
|||||||
using Fengling.Console.Models.Dtos;
|
using Fengling.Console.Models.Dtos;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
|
using Fengling.Console.Repositories;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
|
|
||||||
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
|
|
||||||
using Fengling.Platform.Infrastructure;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using TenantStatus = Fengling.Platform.Domain.AggregatesModel.TenantAggregate.TenantStatus;
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
namespace Fengling.Console.Services;
|
namespace Fengling.Console.Services;
|
||||||
|
|
||||||
public interface ITenantService
|
public interface ITenantService
|
||||||
{
|
{
|
||||||
Task<(IEnumerable<TenantDto> Items, int TotalCount)> GetTenantsAsync(int page, int pageSize, string? name = null,
|
Task<(IEnumerable<TenantDto> Items, int TotalCount)> GetTenantsAsync(int page, int pageSize, string? name = null, string? tenantId = null, string? status = null);
|
||||||
string? tenantCode = null, TenantStatus? status = null);
|
|
||||||
Task<TenantDto?> GetTenantAsync(long id);
|
Task<TenantDto?> GetTenantAsync(long id);
|
||||||
Task<IEnumerable<UserDto>> GetTenantUsersAsync(long tenantId);
|
Task<IEnumerable<UserDto>> GetTenantUsersAsync(long tenantId);
|
||||||
Task<IEnumerable<object>> GetTenantRolesAsync(long tenantId);
|
Task<IEnumerable<object>> GetTenantRolesAsync(long tenantId);
|
||||||
@ -25,27 +21,27 @@ public interface ITenantService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class TenantService(
|
public class TenantService(
|
||||||
ITenantManager tenantManager,
|
ITenantRepository repository,
|
||||||
|
IUserRepository userRepository,
|
||||||
|
IRoleRepository roleRepository,
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
RoleManager<ApplicationRole> roleManager,
|
ApplicationDbContext context,
|
||||||
PlatformDbContext context,
|
|
||||||
IHttpContextAccessor httpContextAccessor)
|
IHttpContextAccessor httpContextAccessor)
|
||||||
: ITenantService
|
: ITenantService
|
||||||
{
|
{
|
||||||
public async Task<(IEnumerable<TenantDto> Items, int TotalCount)> GetTenantsAsync
|
public async Task<(IEnumerable<TenantDto> Items, int TotalCount)> GetTenantsAsync(int page, int pageSize, string? name = null, string? tenantId = null, string? status = null)
|
||||||
(int page, int pageSize, string? name = null, string? tenantCode = null, TenantStatus? status = null)
|
|
||||||
{
|
{
|
||||||
var tenants = await tenantManager.GetPagedAsync(page, pageSize, name, tenantCode, status);
|
var tenants = await repository.GetPagedAsync(page, pageSize, name, tenantId, status);
|
||||||
var totalCount = await tenantManager.GetCountAsync(name, tenantCode, status);
|
var totalCount = await repository.CountAsync(name, tenantId, status);
|
||||||
|
|
||||||
var tenantDtos = new List<TenantDto>();
|
var tenantDtos = new List<TenantDto>();
|
||||||
foreach (var tenant in tenants)
|
foreach (var tenant in tenants)
|
||||||
{
|
{
|
||||||
var userCount = await tenantManager.GetUserCountAsync(tenant.Id);
|
var userCount = await repository.GetUserCountAsync(tenant.Id);
|
||||||
tenantDtos.Add(new TenantDto
|
tenantDtos.Add(new TenantDto
|
||||||
{
|
{
|
||||||
Id = tenant.Id,
|
Id = tenant.Id,
|
||||||
TenantCode = tenant.TenantCode,
|
TenantId = tenant.TenantId,
|
||||||
Name = tenant.Name,
|
Name = tenant.Name,
|
||||||
ContactName = tenant.ContactName,
|
ContactName = tenant.ContactName,
|
||||||
ContactEmail = tenant.ContactEmail,
|
ContactEmail = tenant.ContactEmail,
|
||||||
@ -64,19 +60,19 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task<TenantDto?> GetTenantAsync(long id)
|
public async Task<TenantDto?> GetTenantAsync(long id)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(id);
|
var tenant = await repository.GetByIdAsync(id);
|
||||||
if (tenant == null) return null;
|
if (tenant == null) return null;
|
||||||
|
|
||||||
return new TenantDto
|
return new TenantDto
|
||||||
{
|
{
|
||||||
Id = tenant.Id,
|
Id = tenant.Id,
|
||||||
TenantCode = tenant.TenantCode,
|
TenantId = tenant.TenantId,
|
||||||
Name = tenant.Name,
|
Name = tenant.Name,
|
||||||
ContactName = tenant.ContactName,
|
ContactName = tenant.ContactName,
|
||||||
ContactEmail = tenant.ContactEmail,
|
ContactEmail = tenant.ContactEmail,
|
||||||
ContactPhone = tenant.ContactPhone,
|
ContactPhone = tenant.ContactPhone,
|
||||||
MaxUsers = tenant.MaxUsers,
|
MaxUsers = tenant.MaxUsers,
|
||||||
UserCount = await tenantManager.GetUserCountAsync(tenant.Id),
|
UserCount = await repository.GetUserCountAsync(tenant.Id),
|
||||||
Status = tenant.Status,
|
Status = tenant.Status,
|
||||||
ExpiresAt = tenant.ExpiresAt,
|
ExpiresAt = tenant.ExpiresAt,
|
||||||
Description = tenant.Description,
|
Description = tenant.Description,
|
||||||
@ -86,16 +82,13 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task<IEnumerable<UserDto>> GetTenantUsersAsync(long tenantId)
|
public async Task<IEnumerable<UserDto>> GetTenantUsersAsync(long tenantId)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(tenantId);
|
var tenant = await repository.GetByIdAsync(tenantId);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Tenant with ID {tenantId} not found");
|
throw new KeyNotFoundException($"Tenant with ID {tenantId} not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
var users = await context.Users
|
var users = await userRepository.GetPagedAsync(1, int.MaxValue, null, null, tenantId.ToString());
|
||||||
.Where(u => u.TenantInfo!.TenantId == tenantId)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
var userDtos = new List<UserDto>();
|
var userDtos = new List<UserDto>();
|
||||||
|
|
||||||
foreach (var user in users)
|
foreach (var user in users)
|
||||||
@ -107,8 +100,8 @@ public class TenantService(
|
|||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
TenantCode = user.TenantInfo.TenantId.ToString(),
|
TenantId = user.TenantInfo.Id,
|
||||||
TenantName = tenant?.Name ?? "",
|
TenantName = user.TenantInfo.Name,
|
||||||
Roles = roles.ToList(),
|
Roles = roles.ToList(),
|
||||||
EmailConfirmed = user.EmailConfirmed,
|
EmailConfirmed = user.EmailConfirmed,
|
||||||
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
||||||
@ -121,16 +114,13 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task<IEnumerable<object>> GetTenantRolesAsync(long tenantId)
|
public async Task<IEnumerable<object>> GetTenantRolesAsync(long tenantId)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(tenantId);
|
var tenant = await repository.GetByIdAsync(tenantId);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Tenant with ID {tenantId} not found");
|
throw new KeyNotFoundException($"Tenant with ID {tenantId} not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
var roles = await context.Roles
|
var roles = await roleRepository.GetPagedAsync(1, int.MaxValue, null, tenantId.ToString());
|
||||||
.Where(r => r.TenantId == tenantId)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return roles.Select(r => new
|
return roles.Select(r => new
|
||||||
{
|
{
|
||||||
id = r.Id,
|
id = r.Id,
|
||||||
@ -141,7 +131,7 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task<TenantSettingsDto> GetTenantSettingsAsync(long id)
|
public async Task<TenantSettingsDto> GetTenantSettingsAsync(long id)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(id);
|
var tenant = await repository.GetByIdAsync(id);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
||||||
@ -160,46 +150,39 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task UpdateTenantSettingsAsync(long id, TenantSettingsDto settings)
|
public async Task UpdateTenantSettingsAsync(long id, TenantSettingsDto settings)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(id);
|
var tenant = await repository.GetByIdAsync(id);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
await CreateAuditLog("tenant", "update", "TenantSettings", tenant.Id, tenant.Name, null, System.Text.Json.JsonSerializer.Serialize(settings));
|
await CreateAuditLog("tenant", "update", "TenantSettings", tenant.Id, tenant.TenantId, null, System.Text.Json.JsonSerializer.Serialize(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TenantDto> CreateTenantAsync(CreateTenantDto dto)
|
public async Task<TenantDto> CreateTenantAsync(CreateTenantDto dto)
|
||||||
{
|
{
|
||||||
var tenant = new Tenant
|
var tenant = new Tenant
|
||||||
{
|
{
|
||||||
TenantCode = dto.TenantCode,
|
TenantId = dto.TenantId,
|
||||||
Name = dto.Name,
|
Name = dto.Name,
|
||||||
ContactName = dto.ContactName,
|
ContactName = dto.ContactName,
|
||||||
ContactEmail = dto.ContactEmail,
|
ContactEmail = dto.ContactEmail,
|
||||||
ContactPhone = dto.ContactPhone,
|
ContactPhone = dto.ContactPhone,
|
||||||
MaxUsers = dto.MaxUsers,
|
MaxUsers = dto.MaxUsers,
|
||||||
Description = dto.Description,
|
Description = dto.Description,
|
||||||
|
Status = dto.Status,
|
||||||
ExpiresAt = dto.ExpiresAt,
|
ExpiresAt = dto.ExpiresAt,
|
||||||
Status = TenantStatus.Active,
|
|
||||||
CreatedAt = DateTime.UtcNow
|
CreatedAt = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await tenantManager.CreateAsync(tenant);
|
await repository.AddAsync(tenant);
|
||||||
|
|
||||||
if (!result.Succeeded)
|
await CreateAuditLog("tenant", "create", "Tenant", tenant.Id, tenant.TenantId, null, System.Text.Json.JsonSerializer.Serialize(dto));
|
||||||
{
|
|
||||||
var errors = string.Join(", ", result.Errors.Select(e => e.Description));
|
|
||||||
throw new InvalidOperationException($"Failed to create tenant: {errors}");
|
|
||||||
}
|
|
||||||
|
|
||||||
await CreateAuditLog("tenant", "create", "Tenant", tenant.Id, tenant.Name, null,
|
|
||||||
System.Text.Json.JsonSerializer.Serialize(dto));
|
|
||||||
|
|
||||||
return new TenantDto
|
return new TenantDto
|
||||||
{
|
{
|
||||||
Id = tenant.Id,
|
Id = tenant.Id,
|
||||||
TenantCode = tenant.TenantCode,
|
TenantId = tenant.TenantId,
|
||||||
Name = tenant.Name,
|
Name = tenant.Name,
|
||||||
ContactName = tenant.ContactName,
|
ContactName = tenant.ContactName,
|
||||||
ContactEmail = tenant.ContactEmail,
|
ContactEmail = tenant.ContactEmail,
|
||||||
@ -215,7 +198,7 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task<TenantDto> UpdateTenantAsync(long id, UpdateTenantDto dto)
|
public async Task<TenantDto> UpdateTenantAsync(long id, UpdateTenantDto dto)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(id);
|
var tenant = await repository.GetByIdAsync(id);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
||||||
@ -227,29 +210,26 @@ public class TenantService(
|
|||||||
tenant.ContactName = dto.ContactName;
|
tenant.ContactName = dto.ContactName;
|
||||||
tenant.ContactEmail = dto.ContactEmail;
|
tenant.ContactEmail = dto.ContactEmail;
|
||||||
tenant.ContactPhone = dto.ContactPhone;
|
tenant.ContactPhone = dto.ContactPhone;
|
||||||
|
tenant.MaxUsers = dto.MaxUsers;
|
||||||
|
tenant.Description = dto.Description;
|
||||||
|
tenant.Status = dto.Status;
|
||||||
|
tenant.ExpiresAt = dto.ExpiresAt;
|
||||||
tenant.UpdatedAt = DateTime.UtcNow;
|
tenant.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
var result = await tenantManager.UpdateAsync(tenant);
|
await repository.UpdateAsync(tenant);
|
||||||
|
|
||||||
if (!result.Succeeded)
|
await CreateAuditLog("tenant", "update", "Tenant", tenant.Id, tenant.TenantId, oldValue, System.Text.Json.JsonSerializer.Serialize(tenant));
|
||||||
{
|
|
||||||
var errors = string.Join(", ", result.Errors.Select(e => e.Description));
|
|
||||||
throw new InvalidOperationException($"Failed to update tenant: {errors}");
|
|
||||||
}
|
|
||||||
|
|
||||||
await CreateAuditLog("tenant", "update", "Tenant", tenant.Id, tenant.Name, oldValue,
|
|
||||||
System.Text.Json.JsonSerializer.Serialize(tenant));
|
|
||||||
|
|
||||||
return new TenantDto
|
return new TenantDto
|
||||||
{
|
{
|
||||||
Id = tenant.Id,
|
Id = tenant.Id,
|
||||||
TenantCode = tenant.TenantCode,
|
TenantId = tenant.TenantId,
|
||||||
Name = tenant.Name,
|
Name = tenant.Name,
|
||||||
ContactName = tenant.ContactName,
|
ContactName = tenant.ContactName,
|
||||||
ContactEmail = tenant.ContactEmail,
|
ContactEmail = tenant.ContactEmail,
|
||||||
ContactPhone = tenant.ContactPhone,
|
ContactPhone = tenant.ContactPhone,
|
||||||
MaxUsers = tenant.MaxUsers,
|
MaxUsers = tenant.MaxUsers,
|
||||||
UserCount = await tenantManager.GetUserCountAsync(tenant.Id),
|
UserCount = await repository.GetUserCountAsync(tenant.Id),
|
||||||
Status = tenant.Status,
|
Status = tenant.Status,
|
||||||
ExpiresAt = tenant.ExpiresAt,
|
ExpiresAt = tenant.ExpiresAt,
|
||||||
Description = tenant.Description,
|
Description = tenant.Description,
|
||||||
@ -259,7 +239,7 @@ public class TenantService(
|
|||||||
|
|
||||||
public async Task DeleteTenantAsync(long id)
|
public async Task DeleteTenantAsync(long id)
|
||||||
{
|
{
|
||||||
var tenant = await tenantManager.FindByIdAsync(id);
|
var tenant = await repository.GetByIdAsync(id);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
throw new KeyNotFoundException($"Tenant with ID {id} not found");
|
||||||
@ -267,39 +247,30 @@ public class TenantService(
|
|||||||
|
|
||||||
var oldValue = System.Text.Json.JsonSerializer.Serialize(tenant);
|
var oldValue = System.Text.Json.JsonSerializer.Serialize(tenant);
|
||||||
|
|
||||||
var users = await context.Users
|
var users = await userRepository.GetPagedAsync(1, int.MaxValue, null, null, id.ToString());
|
||||||
.Where(u => u.TenantInfo.TenantId == id)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
foreach (var user in users)
|
foreach (var user in users)
|
||||||
{
|
{
|
||||||
user.IsDeleted = true;
|
user.IsDeleted = true;
|
||||||
user.UpdatedTime = DateTime.UtcNow;
|
user.UpdatedTime = DateTime.UtcNow;
|
||||||
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
await context.SaveChangesAsync();
|
|
||||||
|
|
||||||
tenant.IsDeleted = true;
|
tenant.IsDeleted = true;
|
||||||
var result = await tenantManager.UpdateAsync(tenant);
|
await repository.UpdateAsync(tenant);
|
||||||
|
|
||||||
if (!result.Succeeded)
|
await CreateAuditLog("tenant", "delete", "Tenant", tenant.Id, tenant.TenantId, oldValue);
|
||||||
{
|
|
||||||
var errors = string.Join(", ", result.Errors.Select(e => e.Description));
|
|
||||||
throw new InvalidOperationException($"Failed to delete tenant: {errors}");
|
|
||||||
}
|
|
||||||
|
|
||||||
await CreateAuditLog("tenant", "delete", "Tenant", tenant.Id, tenant.Name, oldValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateAuditLog(string operation, string action, string targetType, long? targetId, string? targetName, string? oldValue = null, string? newValue = null)
|
private async Task CreateAuditLog(string operation, string action, string targetType, long? targetId, string? targetName, string? oldValue = null, string? newValue = null)
|
||||||
{
|
{
|
||||||
var httpContext = httpContextAccessor.HttpContext;
|
var httpContext = httpContextAccessor.HttpContext;
|
||||||
var userName = httpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier) ?? httpContext?.User?.Identity?.Name ?? "system";
|
var userName = httpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier) ?? httpContext?.User?.Identity?.Name ?? "system";
|
||||||
var tenantIdClaim = httpContext?.User?.FindFirstValue("TenantId");
|
var tenantId = httpContext?.User?.FindFirstValue("TenantId");
|
||||||
|
|
||||||
var log = new AuditLog
|
var log = new AuditLog
|
||||||
{
|
{
|
||||||
Operator = userName,
|
Operator = userName,
|
||||||
TenantId = tenantIdClaim,
|
TenantId = tenantId,
|
||||||
Operation = operation,
|
Operation = operation,
|
||||||
Action = action,
|
Action = action,
|
||||||
TargetType = targetType,
|
TargetType = targetType,
|
||||||
|
|||||||
@ -1,19 +1,15 @@
|
|||||||
using Fengling.Console.Models.Dtos;
|
using Fengling.Console.Models.Dtos;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
|
using Fengling.Console.Repositories;
|
||||||
using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
|
|
||||||
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
|
|
||||||
using Fengling.Platform.Infrastructure;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Fengling.Console.Datas;
|
||||||
|
using Fengling.Console.Models.Entities;
|
||||||
|
|
||||||
namespace Fengling.Console.Services;
|
namespace Fengling.Console.Services;
|
||||||
|
|
||||||
public interface IUserService
|
public interface IUserService
|
||||||
{
|
{
|
||||||
Task<(IEnumerable<UserDto> Items, int TotalCount)> GetUsersAsync(int page, int pageSize, string? userName = null,
|
Task<(IEnumerable<UserDto> Items, int TotalCount)> GetUsersAsync(int page, int pageSize, string? userName = null, string? email = null, string? tenantId = null);
|
||||||
string? email = null, string? tenantCode = null);
|
|
||||||
|
|
||||||
Task<UserDto?> GetUserAsync(long id);
|
Task<UserDto?> GetUserAsync(long id);
|
||||||
Task<UserDto> CreateUserAsync(CreateUserDto dto);
|
Task<UserDto> CreateUserAsync(CreateUserDto dto);
|
||||||
Task<UserDto> UpdateUserAsync(long id, UpdateUserDto dto);
|
Task<UserDto> UpdateUserAsync(long id, UpdateUserDto dto);
|
||||||
@ -22,59 +18,32 @@ public interface IUserService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class UserService(
|
public class UserService(
|
||||||
ITenantManager tenantManager,
|
IUserRepository repository,
|
||||||
|
ITenantRepository tenantRepository,
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
RoleManager<ApplicationRole> roleManager,
|
RoleManager<ApplicationRole> roleManager,
|
||||||
PlatformDbContext context,
|
ApplicationDbContext context,
|
||||||
IHttpContextAccessor httpContextAccessor)
|
IHttpContextAccessor httpContextAccessor)
|
||||||
: IUserService
|
: IUserService
|
||||||
{
|
{
|
||||||
public async Task<(IEnumerable<UserDto> Items, int TotalCount)> GetUsersAsync(int page, int pageSize,
|
public async Task<(IEnumerable<UserDto> Items, int TotalCount)> GetUsersAsync(int page, int pageSize, string? userName = null, string? email = null, string? tenantId = null)
|
||||||
string? userName = null, string? email = null,
|
|
||||||
string? tenantCode = null)
|
|
||||||
{
|
{
|
||||||
var query = context.Users.AsQueryable();
|
var users = await repository.GetPagedAsync(page, pageSize, userName, email, tenantId);
|
||||||
|
var totalCount = await repository.CountAsync(userName, email, tenantId);
|
||||||
if (!string.IsNullOrEmpty(userName))
|
|
||||||
{
|
|
||||||
query = query.Where(u => u.UserName != null && u.UserName.Contains(userName));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(email))
|
|
||||||
{
|
|
||||||
query = query.Where(u => u.Email != null && u.Email.Contains(email));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(tenantCode))
|
|
||||||
{
|
|
||||||
query = query.Where(u => u.TenantInfo != null &&
|
|
||||||
u.TenantInfo.TenantCode != null &&
|
|
||||||
u.TenantInfo.TenantCode.Contains(tenantCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
var totalCount = await query.CountAsync();
|
|
||||||
var users = await query
|
|
||||||
.OrderByDescending(u => u.CreatedTime)
|
|
||||||
.Skip((page - 1) * pageSize)
|
|
||||||
.Take(pageSize)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
var userDtos = new List<UserDto>();
|
var userDtos = new List<UserDto>();
|
||||||
foreach (var user in users)
|
foreach (var user in users)
|
||||||
{
|
{
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
var roles = await userManager.GetRolesAsync(user);
|
||||||
var tenant = user.TenantInfo?.TenantId > 0
|
|
||||||
? await tenantManager.FindByIdAsync(user.TenantInfo.TenantId)
|
|
||||||
: null;
|
|
||||||
userDtos.Add(new UserDto
|
userDtos.Add(new UserDto
|
||||||
{
|
{
|
||||||
Id = user.Id,
|
Id = user.Id,
|
||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
PhoneNumber = user.PhoneNumber,
|
Phone = user.Phone,
|
||||||
TenantCode = user.TenantInfo?.TenantCode,
|
TenantId = user.TenantInfo.Id,
|
||||||
TenantName = tenant?.Name ?? "",
|
TenantName = user.TenantInfo.Name,
|
||||||
Roles = roles.ToList(),
|
Roles = roles.ToList(),
|
||||||
EmailConfirmed = user.EmailConfirmed,
|
EmailConfirmed = user.EmailConfirmed,
|
||||||
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
||||||
@ -87,20 +56,19 @@ public class UserService(
|
|||||||
|
|
||||||
public async Task<UserDto?> GetUserAsync(long id)
|
public async Task<UserDto?> GetUserAsync(long id)
|
||||||
{
|
{
|
||||||
var user = await context.Users.FindAsync(id);
|
var user = await repository.GetByIdAsync(id);
|
||||||
if (user == null) return null;
|
if (user == null) return null;
|
||||||
|
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
var roles = await userManager.GetRolesAsync(user);
|
||||||
var tenant = user.TenantInfo?.TenantId > 0 ? await tenantManager.FindByIdAsync(user.TenantInfo.TenantId) : null;
|
|
||||||
return new UserDto
|
return new UserDto
|
||||||
{
|
{
|
||||||
Id = user.Id,
|
Id = user.Id,
|
||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
PhoneNumber = user.PhoneNumber,
|
Phone = user.Phone,
|
||||||
TenantCode = user.TenantInfo?.TenantCode,
|
TenantId = user.TenantInfo.Id,
|
||||||
TenantName = tenant?.Name ?? "",
|
TenantName = user.TenantInfo.Name,
|
||||||
Roles = roles.ToList(),
|
Roles = roles.ToList(),
|
||||||
EmailConfirmed = user.EmailConfirmed,
|
EmailConfirmed = user.EmailConfirmed,
|
||||||
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
||||||
@ -110,28 +78,25 @@ public class UserService(
|
|||||||
|
|
||||||
public async Task<UserDto> CreateUserAsync(CreateUserDto dto)
|
public async Task<UserDto> CreateUserAsync(CreateUserDto dto)
|
||||||
{
|
{
|
||||||
|
var tenantId = dto.TenantId ?? 0;
|
||||||
Tenant? tenant = null;
|
Tenant? tenant = null;
|
||||||
|
|
||||||
if (dto.TenantId.HasValue && dto.TenantId.Value > 0)
|
if (tenantId != 0)
|
||||||
{
|
{
|
||||||
tenant = await tenantManager.FindByIdAsync(dto.TenantId.Value);
|
tenant = await tenantRepository.GetByIdAsync(tenantId);
|
||||||
if (tenant == null)
|
if (tenant == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Invalid tenant ID");
|
throw new InvalidOperationException("Invalid tenant ID");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tenantInfo = tenant != null
|
|
||||||
? new TenantInfo(tenant.Id, tenant.TenantCode, tenant.Name)
|
|
||||||
: new TenantInfo(0, "", "");
|
|
||||||
|
|
||||||
var user = new ApplicationUser
|
var user = new ApplicationUser
|
||||||
{
|
{
|
||||||
UserName = dto.UserName,
|
UserName = dto.UserName,
|
||||||
Email = dto.Email,
|
Email = dto.Email,
|
||||||
RealName = dto.RealName,
|
RealName = dto.RealName,
|
||||||
PhoneNumber = dto.PhoneNumber,
|
Phone = dto.Phone,
|
||||||
TenantInfo = tenantInfo,
|
TenantInfo = new TenantInfo(tenantId, tenant?.TenantId ?? "default", tenant?.Name ?? "默认租户"),
|
||||||
EmailConfirmed = dto.EmailConfirmed,
|
EmailConfirmed = dto.EmailConfirmed,
|
||||||
CreatedTime = DateTime.UtcNow
|
CreatedTime = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
@ -142,7 +107,7 @@ public class UserService(
|
|||||||
throw new InvalidOperationException(string.Join(", ", result.Errors.Select(e => e.Description)));
|
throw new InvalidOperationException(string.Join(", ", result.Errors.Select(e => e.Description)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.RoleIds.Count != 0)
|
if (dto.RoleIds != null && dto.RoleIds.Any())
|
||||||
{
|
{
|
||||||
foreach (var roleId in dto.RoleIds)
|
foreach (var roleId in dto.RoleIds)
|
||||||
{
|
{
|
||||||
@ -160,8 +125,7 @@ public class UserService(
|
|||||||
await userManager.SetLockoutEndDateAsync(user, DateTimeOffset.MaxValue);
|
await userManager.SetLockoutEndDateAsync(user, DateTimeOffset.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
await CreateAuditLog("user", "create", "User", user.Id, user.UserName, null,
|
await CreateAuditLog("user", "create", "User", user.Id, user.UserName, null, System.Text.Json.JsonSerializer.Serialize(dto));
|
||||||
System.Text.Json.JsonSerializer.Serialize(dto));
|
|
||||||
|
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
var roles = await userManager.GetRolesAsync(user);
|
||||||
return new UserDto
|
return new UserDto
|
||||||
@ -170,9 +134,9 @@ public class UserService(
|
|||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
PhoneNumber = user.PhoneNumber,
|
Phone = user.Phone,
|
||||||
TenantCode = user.TenantInfo.TenantId.ToString(),
|
TenantId = user.TenantInfo.Id,
|
||||||
TenantName = tenant?.Name ?? "",
|
TenantName = user.TenantInfo.Name,
|
||||||
Roles = roles.ToList(),
|
Roles = roles.ToList(),
|
||||||
EmailConfirmed = user.EmailConfirmed,
|
EmailConfirmed = user.EmailConfirmed,
|
||||||
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
||||||
@ -182,7 +146,7 @@ public class UserService(
|
|||||||
|
|
||||||
public async Task<UserDto> UpdateUserAsync(long id, UpdateUserDto dto)
|
public async Task<UserDto> UpdateUserAsync(long id, UpdateUserDto dto)
|
||||||
{
|
{
|
||||||
var user = await context.Users.FindAsync(id);
|
var user = await repository.GetByIdAsync(id);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"User with ID {id} not found");
|
throw new KeyNotFoundException($"User with ID {id} not found");
|
||||||
@ -192,12 +156,10 @@ public class UserService(
|
|||||||
|
|
||||||
user.Email = dto.Email;
|
user.Email = dto.Email;
|
||||||
user.RealName = dto.RealName;
|
user.RealName = dto.RealName;
|
||||||
user.PhoneNumber = dto.PhoneNumber;
|
user.Phone = dto.Phone;
|
||||||
user.EmailConfirmed = dto.EmailConfirmed;
|
user.EmailConfirmed = dto.EmailConfirmed;
|
||||||
user.UpdatedTime = DateTime.UtcNow;
|
user.UpdatedTime = DateTime.UtcNow;
|
||||||
|
|
||||||
await userManager.UpdateAsync(user);
|
|
||||||
|
|
||||||
if (dto.IsActive)
|
if (dto.IsActive)
|
||||||
{
|
{
|
||||||
await userManager.SetLockoutEnabledAsync(user, false);
|
await userManager.SetLockoutEnabledAsync(user, false);
|
||||||
@ -209,10 +171,9 @@ public class UserService(
|
|||||||
await userManager.SetLockoutEndDateAsync(user, DateTimeOffset.MaxValue);
|
await userManager.SetLockoutEndDateAsync(user, DateTimeOffset.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tenant = user.TenantInfo?.TenantId > 0 ? await tenantManager.FindByIdAsync(user.TenantInfo.TenantId) : null;
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
await CreateAuditLog("user", "update", "User", user.Id, user.UserName, oldValue,
|
await CreateAuditLog("user", "update", "User", user.Id, user.UserName, oldValue, System.Text.Json.JsonSerializer.Serialize(user));
|
||||||
System.Text.Json.JsonSerializer.Serialize(user));
|
|
||||||
|
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
var roles = await userManager.GetRolesAsync(user);
|
||||||
return new UserDto
|
return new UserDto
|
||||||
@ -221,9 +182,9 @@ public class UserService(
|
|||||||
UserName = user.UserName,
|
UserName = user.UserName,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
RealName = user.RealName,
|
RealName = user.RealName,
|
||||||
PhoneNumber = user.PhoneNumber,
|
Phone = user.Phone,
|
||||||
TenantCode = user.TenantInfo?.TenantCode,
|
TenantId = user.TenantInfo.Id,
|
||||||
TenantName = tenant?.Name ?? "",
|
TenantName = user.TenantInfo.Name,
|
||||||
Roles = roles.ToList(),
|
Roles = roles.ToList(),
|
||||||
EmailConfirmed = user.EmailConfirmed,
|
EmailConfirmed = user.EmailConfirmed,
|
||||||
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
IsActive = !user.LockoutEnabled || user.LockoutEnd == null || user.LockoutEnd < DateTimeOffset.UtcNow,
|
||||||
@ -252,7 +213,7 @@ public class UserService(
|
|||||||
|
|
||||||
public async Task DeleteUserAsync(long id)
|
public async Task DeleteUserAsync(long id)
|
||||||
{
|
{
|
||||||
var user = await context.Users.FindAsync(id);
|
var user = await repository.GetByIdAsync(id);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"User with ID {id} not found");
|
throw new KeyNotFoundException($"User with ID {id} not found");
|
||||||
@ -266,18 +227,16 @@ public class UserService(
|
|||||||
await CreateAuditLog("user", "delete", "User", user.Id, user.UserName, oldValue);
|
await CreateAuditLog("user", "delete", "User", user.Id, user.UserName, oldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateAuditLog(string operation, string action, string targetType, long? targetId,
|
private async Task CreateAuditLog(string operation, string action, string targetType, long? targetId, string? targetName, string? oldValue = null, string? newValue = null)
|
||||||
string? targetName, string? oldValue = null, string? newValue = null)
|
|
||||||
{
|
{
|
||||||
var httpContext = httpContextAccessor.HttpContext;
|
var httpContext = httpContextAccessor.HttpContext;
|
||||||
var userName = httpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier) ??
|
var userName = httpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier) ?? httpContext?.User?.Identity?.Name ?? "system";
|
||||||
httpContext?.User?.Identity?.Name ?? "system";
|
var tenantId = httpContext?.User?.FindFirstValue("TenantId");
|
||||||
var tenantIdClaim = httpContext?.User?.FindFirstValue("TenantId");
|
|
||||||
|
|
||||||
var log = new AuditLog
|
var log = new AuditLog
|
||||||
{
|
{
|
||||||
Operator = userName,
|
Operator = userName,
|
||||||
TenantId = tenantIdClaim,
|
TenantId = tenantId,
|
||||||
Operation = operation,
|
Operation = operation,
|
||||||
Action = action,
|
Action = action,
|
||||||
TargetType = targetType,
|
TargetType = targetType,
|
||||||
@ -293,4 +252,4 @@ public class UserService(
|
|||||||
context.AuditLogs.Add(log);
|
context.AuditLogs.Add(log);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -1,56 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<startup>
|
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
|
||||||
</startup>
|
|
||||||
<runtime>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build.Utilities.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build.Tasks.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.IO.Redist" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.1" newVersion="6.0.0.1" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
</runtime>
|
|
||||||
</configuration>
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,260 +0,0 @@
|
|||||||
{
|
|
||||||
"runtimeTarget": {
|
|
||||||
"name": ".NETCoreApp,Version=v6.0",
|
|
||||||
"signature": ""
|
|
||||||
},
|
|
||||||
"compilationOptions": {},
|
|
||||||
"targets": {
|
|
||||||
".NETCoreApp,Version=v6.0": {
|
|
||||||
"Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost/4.14.0-3.25262.10": {
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.Build.Locator": "1.6.10",
|
|
||||||
"Microsoft.CodeAnalysis.NetAnalyzers": "8.0.0-preview.23468.1",
|
|
||||||
"Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers": "3.3.4-beta1.22504.1",
|
|
||||||
"Microsoft.DotNet.XliffTasks": "9.0.0-beta.25255.5",
|
|
||||||
"Microsoft.VisualStudio.Threading.Analyzers": "17.13.2",
|
|
||||||
"Newtonsoft.Json": "13.0.3",
|
|
||||||
"Roslyn.Diagnostics.Analyzers": "3.11.0-beta1.24081.1",
|
|
||||||
"System.Collections.Immutable": "9.0.0",
|
|
||||||
"System.CommandLine": "2.0.0-beta4.24528.1"
|
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll": {}
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
"cs/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "cs"
|
|
||||||
},
|
|
||||||
"de/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "de"
|
|
||||||
},
|
|
||||||
"es/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "es"
|
|
||||||
},
|
|
||||||
"fr/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "fr"
|
|
||||||
},
|
|
||||||
"it/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "it"
|
|
||||||
},
|
|
||||||
"ja/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "ja"
|
|
||||||
},
|
|
||||||
"ko/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "ko"
|
|
||||||
},
|
|
||||||
"pl/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "pl"
|
|
||||||
},
|
|
||||||
"pt-BR/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "pt-BR"
|
|
||||||
},
|
|
||||||
"ru/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "ru"
|
|
||||||
},
|
|
||||||
"tr/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "tr"
|
|
||||||
},
|
|
||||||
"zh-Hans/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "zh-Hans"
|
|
||||||
},
|
|
||||||
"zh-Hant/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": {
|
|
||||||
"locale": "zh-Hant"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.Build.Locator/1.6.10": {
|
|
||||||
"runtime": {
|
|
||||||
"lib/net6.0/Microsoft.Build.Locator.dll": {
|
|
||||||
"assemblyVersion": "1.0.0.0",
|
|
||||||
"fileVersion": "1.6.10.57384"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.BannedApiAnalyzers/3.11.0-beta1.24081.1": {},
|
|
||||||
"Microsoft.CodeAnalysis.NetAnalyzers/8.0.0-preview.23468.1": {},
|
|
||||||
"Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers/3.3.4-beta1.22504.1": {},
|
|
||||||
"Microsoft.CodeAnalysis.PublicApiAnalyzers/3.11.0-beta1.24081.1": {},
|
|
||||||
"Microsoft.DotNet.XliffTasks/9.0.0-beta.25255.5": {},
|
|
||||||
"Microsoft.VisualStudio.Threading.Analyzers/17.13.2": {},
|
|
||||||
"Newtonsoft.Json/13.0.3": {
|
|
||||||
"runtime": {
|
|
||||||
"lib/net6.0/Newtonsoft.Json.dll": {
|
|
||||||
"assemblyVersion": "13.0.0.0",
|
|
||||||
"fileVersion": "13.0.3.27908"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Roslyn.Diagnostics.Analyzers/3.11.0-beta1.24081.1": {
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.CodeAnalysis.BannedApiAnalyzers": "3.11.0-beta1.24081.1",
|
|
||||||
"Microsoft.CodeAnalysis.PublicApiAnalyzers": "3.11.0-beta1.24081.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Collections.Immutable/9.0.0": {
|
|
||||||
"dependencies": {
|
|
||||||
"System.Memory": "4.5.5",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"lib/netstandard2.0/System.Collections.Immutable.dll": {
|
|
||||||
"assemblyVersion": "9.0.0.0",
|
|
||||||
"fileVersion": "9.0.24.52809"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.CommandLine/2.0.0-beta4.24528.1": {
|
|
||||||
"dependencies": {
|
|
||||||
"System.Memory": "4.5.5"
|
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"lib/netstandard2.0/System.CommandLine.dll": {
|
|
||||||
"assemblyVersion": "2.0.0.0",
|
|
||||||
"fileVersion": "2.0.24.52801"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
"lib/netstandard2.0/cs/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "cs"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/de/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "de"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/es/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "es"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/fr/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "fr"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/it/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "it"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/ja/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "ja"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/ko/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "ko"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/pl/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "pl"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/pt-BR/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "pt-BR"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/ru/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "ru"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/tr/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "tr"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/zh-Hans/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "zh-Hans"
|
|
||||||
},
|
|
||||||
"lib/netstandard2.0/zh-Hant/System.CommandLine.resources.dll": {
|
|
||||||
"locale": "zh-Hant"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Memory/4.5.5": {},
|
|
||||||
"System.Runtime.CompilerServices.Unsafe/6.0.0": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"libraries": {
|
|
||||||
"Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost/4.14.0-3.25262.10": {
|
|
||||||
"type": "project",
|
|
||||||
"serviceable": false,
|
|
||||||
"sha512": ""
|
|
||||||
},
|
|
||||||
"Microsoft.Build.Locator/1.6.10": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-DJhCkTGqy1LMJzEmG/2qxRTMHwdPc3WdVoGQI5o5mKHVo4dsHrCMLIyruwU/NSvPNSdvONlaf7jdFXnAMuxAuA==",
|
|
||||||
"path": "microsoft.build.locator/1.6.10",
|
|
||||||
"hashPath": "microsoft.build.locator.1.6.10.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.BannedApiAnalyzers/3.11.0-beta1.24081.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-DH6L3rsbjppLrHM2l2/NKbnMaYd0NFHx2pjZaFdrVcRkONrV3i9FHv6Id8Dp6/TmjhXQsJVJJFbhhjkpuP1xxg==",
|
|
||||||
"path": "microsoft.codeanalysis.bannedapianalyzers/3.11.0-beta1.24081.1",
|
|
||||||
"hashPath": "microsoft.codeanalysis.bannedapianalyzers.3.11.0-beta1.24081.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.NetAnalyzers/8.0.0-preview.23468.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-ZhIvyxmUCqb8OiU/VQfxfuAmIB4lQsjqhMVYKeoyxzSI+d7uR5Pzx3ZKoaIhPizQ15wa4lnyD6wg3TnSJ6P4LA==",
|
|
||||||
"path": "microsoft.codeanalysis.netanalyzers/8.0.0-preview.23468.1",
|
|
||||||
"hashPath": "microsoft.codeanalysis.netanalyzers.8.0.0-preview.23468.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers/3.3.4-beta1.22504.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-2XRlqPAzVke7Sb80+UqaC7o57OwfK+tIr+aIOxrx41RWDMeR2SBUW7kL4sd6hfLFfBNsLo3W5PT+UwfvwPaOzA==",
|
|
||||||
"path": "microsoft.codeanalysis.performancesensitiveanalyzers/3.3.4-beta1.22504.1",
|
|
||||||
"hashPath": "microsoft.codeanalysis.performancesensitiveanalyzers.3.3.4-beta1.22504.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.PublicApiAnalyzers/3.11.0-beta1.24081.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-3bYGBihvoNO0rhCOG1U9O50/4Q8suZ+glHqQLIAcKvnodSnSW+dYWYzTNb1UbS8pUS8nAUfxSFMwuMup/G5DtQ==",
|
|
||||||
"path": "microsoft.codeanalysis.publicapianalyzers/3.11.0-beta1.24081.1",
|
|
||||||
"hashPath": "microsoft.codeanalysis.publicapianalyzers.3.11.0-beta1.24081.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.DotNet.XliffTasks/9.0.0-beta.25255.5": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-bb0fZB5ViPscdfYeWlmtyXJMzNkgcpkV5RWmXktfV9lwIUZgNZmFotUXrdcTyZzrN7v1tQK/Y6BGnbkP9gEsXg==",
|
|
||||||
"path": "microsoft.dotnet.xlifftasks/9.0.0-beta.25255.5",
|
|
||||||
"hashPath": "microsoft.dotnet.xlifftasks.9.0.0-beta.25255.5.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.VisualStudio.Threading.Analyzers/17.13.2": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-Qcd8IlaTXZVq3wolBnzby1P7kWihdWaExtD8riumiKuG1sHa8EgjV/o70TMjTaeUMhomBbhfdC9OPwAHoZfnjQ==",
|
|
||||||
"path": "microsoft.visualstudio.threading.analyzers/17.13.2",
|
|
||||||
"hashPath": "microsoft.visualstudio.threading.analyzers.17.13.2.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Newtonsoft.Json/13.0.3": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
|
|
||||||
"path": "newtonsoft.json/13.0.3",
|
|
||||||
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Roslyn.Diagnostics.Analyzers/3.11.0-beta1.24081.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-reHqZCDKifA+DURcL8jUfYkMGL4FpgNt5LI0uWTS6IpM8kKVbu/kO8byZsqfhBu4wUzT3MBDcoMfzhZPdENIpg==",
|
|
||||||
"path": "roslyn.diagnostics.analyzers/3.11.0-beta1.24081.1",
|
|
||||||
"hashPath": "roslyn.diagnostics.analyzers.3.11.0-beta1.24081.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"System.Collections.Immutable/9.0.0": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==",
|
|
||||||
"path": "system.collections.immutable/9.0.0",
|
|
||||||
"hashPath": "system.collections.immutable.9.0.0.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"System.CommandLine/2.0.0-beta4.24528.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-Xt8tsSU8yd0ZpbT9gl5DAwkMYWLo8PV1fq2R/belrUbHVVOIKqhLfbWksbdknUDpmzMHZenBtD6AGAp9uJTa2w==",
|
|
||||||
"path": "system.commandline/2.0.0-beta4.24528.1",
|
|
||||||
"hashPath": "system.commandline.2.0.0-beta4.24528.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"System.Memory/4.5.5": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
|
||||||
"path": "system.memory/4.5.5",
|
|
||||||
"hashPath": "system.memory.4.5.5.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"System.Runtime.CompilerServices.Unsafe/6.0.0": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
|
|
||||||
"path": "system.runtime.compilerservices.unsafe/6.0.0",
|
|
||||||
"hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@ -1,605 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<runtime>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build.Utilities.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Build.Tasks.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.VisualBasic.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Win32.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections.Concurrent" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections.NonGeneric" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections.Specialized" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ComponentModel.EventBasedAsync" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ComponentModel.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ComponentModel.TypeConverter" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ComponentModel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Data.Common" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.Contracts" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.FileVersionInfo" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.Process" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.TextWriterTraceListener" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.TraceSource" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.Tracing" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Drawing.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.Compression.ZipFile" publicKeyToken="b77a5c561934e089" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.FileSystem.AccessControl" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.FileSystem.DriveInfo" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.FileSystem.Watcher" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.IsolatedStorage" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.MemoryMappedFiles" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.Pipes.AccessControl" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.Pipes" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Linq.Expressions" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Linq.Parallel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Linq.Queryable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Linq" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.HttpListener" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.Mail" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.NameResolution" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.NetworkInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.Ping" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.Requests" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.Security" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.ServicePoint" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.Sockets" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.WebClient" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.WebHeaderCollection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.WebProxy" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.WebSockets.Client" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Net.WebSockets" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ObjectModel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reflection.Emit.ILGeneration" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reflection.Emit.Lightweight" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reflection.Emit" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reflection.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Resources.Writer" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.CompilerServices.VisualC" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.InteropServices" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.Numerics" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.Serialization.Formatters" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.Serialization.Json" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.Serialization.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.Serialization.Xml" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.AccessControl" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Claims" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Cng" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Csp" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.X509Certificates" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Principal.Windows" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Text.Encoding.Extensions" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Text.RegularExpressions" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading.Overlapped" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading.Tasks.Parallel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading.Thread" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading.ThreadPool" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Transactions.Local" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Web.HttpUtility" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Xml.ReaderWriter" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Xml.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Xml.XPath" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Xml.XmlSerializer" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="netstandard" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Configuration.ConfigurationManager" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Xml" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.CodeDom" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
</runtime>
|
|
||||||
</configuration>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"runtimeOptions": {
|
|
||||||
"tfm": "net6.0",
|
|
||||||
"framework": {
|
|
||||||
"name": "Microsoft.NETCore.App",
|
|
||||||
"version": "6.0.0"
|
|
||||||
},
|
|
||||||
"rollForward": "Major",
|
|
||||||
"configProperties": {
|
|
||||||
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user