mirror of https://github.com/abpframework/abp.git
177 changed files with 8117 additions and 3014 deletions
@ -1,30 +1,35 @@ |
|||||
using Microsoft.AspNetCore.Mvc; |
using Microsoft.AspNetCore.Mvc; |
||||
using Microsoft.Extensions.Options; |
using Microsoft.Extensions.Options; |
||||
using Volo.Abp.Auditing; |
using Volo.Abp.Auditing; |
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.Auditing |
namespace Volo.Abp.AspNetCore.Mvc.Auditing |
||||
{ |
{ |
||||
[Route("api/audit-test")] |
[Route("api/audit-test")] |
||||
[Audited] |
[Audited] |
||||
public class AuditTestController : AbpController |
public class AuditTestController : AbpController |
||||
{ |
{ |
||||
private readonly AbpAuditingOptions _options; |
private readonly AbpAuditingOptions _options; |
||||
|
|
||||
public AuditTestController(IOptions<AbpAuditingOptions> options) |
public AuditTestController(IOptions<AbpAuditingOptions> options) |
||||
{ |
{ |
||||
_options = options.Value; |
_options = options.Value; |
||||
} |
} |
||||
|
|
||||
[Route("audit-success")] |
[Route("audit-success")] |
||||
public IActionResult AuditSuccessForGetRequests() |
public IActionResult AuditSuccessForGetRequests() |
||||
{ |
{ |
||||
return Ok(); |
return Ok(); |
||||
} |
} |
||||
|
|
||||
[Route("audit-fail")] |
[Route("audit-fail")] |
||||
public IActionResult AuditFailForGetRequests() |
public IActionResult AuditFailForGetRequests() |
||||
{ |
{ |
||||
throw new UserFriendlyException("Exception occurred!"); |
throw new UserFriendlyException("Exception occurred!"); |
||||
} |
} |
||||
} |
[Route("audit-fail-object")] |
||||
} |
public object AuditFailForGetRequestsReturningObject() |
||||
|
{ |
||||
|
throw new UserFriendlyException("Exception occurred!"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|||||
@ -1,55 +1,65 @@ |
|||||
using System; |
using System; |
||||
using Microsoft.Extensions.DependencyInjection; |
using Microsoft.Extensions.DependencyInjection; |
||||
using Microsoft.Extensions.DependencyInjection.Extensions; |
using Microsoft.Extensions.DependencyInjection.Extensions; |
||||
using Microsoft.Extensions.Hosting; |
using Microsoft.Extensions.Hosting; |
||||
using Microsoft.Extensions.Options; |
using Microsoft.Extensions.Options; |
||||
using NSubstitute; |
using NSubstitute; |
||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||
using Volo.Abp.Auditing; |
using Volo.Abp.Auditing; |
||||
using Xunit; |
using Xunit; |
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.Auditing |
namespace Volo.Abp.AspNetCore.Mvc.Auditing |
||||
{ |
{ |
||||
public class AuditTestController_Tests : AspNetCoreMvcTestBase |
public class AuditTestController_Tests : AspNetCoreMvcTestBase |
||||
{ |
{ |
||||
private readonly AbpAuditingOptions _options; |
private readonly AbpAuditingOptions _options; |
||||
private IAuditingStore _auditingStore; |
private IAuditingStore _auditingStore; |
||||
|
|
||||
public AuditTestController_Tests() |
public AuditTestController_Tests() |
||||
{ |
{ |
||||
_options = ServiceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value; |
_options = ServiceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value; |
||||
_auditingStore = ServiceProvider.GetRequiredService<IAuditingStore>(); |
_auditingStore = ServiceProvider.GetRequiredService<IAuditingStore>(); |
||||
} |
} |
||||
|
|
||||
protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) |
protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) |
||||
{ |
{ |
||||
_auditingStore = Substitute.For<IAuditingStore>(); |
_auditingStore = Substitute.For<IAuditingStore>(); |
||||
services.Replace(ServiceDescriptor.Singleton(_auditingStore)); |
services.Replace(ServiceDescriptor.Singleton(_auditingStore)); |
||||
base.ConfigureServices(context, services); |
base.ConfigureServices(context, services); |
||||
} |
} |
||||
|
|
||||
[Fact] |
[Fact] |
||||
public async Task Should_Trigger_Middleware_And_AuditLog_Success_For_GetRequests() |
public async Task Should_Trigger_Middleware_And_AuditLog_Success_For_GetRequests() |
||||
{ |
{ |
||||
_options.IsEnabledForGetRequests = true; |
_options.IsEnabledForGetRequests = true; |
||||
_options.AlwaysLogOnException = false; |
_options.AlwaysLogOnException = false; |
||||
await GetResponseAsync("api/audit-test/audit-success"); |
await GetResponseAsync("api/audit-test/audit-success"); |
||||
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); //Won't work, save happens out of scope
|
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
||||
} |
} |
||||
|
|
||||
[Fact] |
[Fact] |
||||
public async Task Should_Trigger_Middleware_And_AuditLog_Exception_Always() |
public async Task Should_Trigger_Middleware_And_AuditLog_Exception_Always() |
||||
{ |
{ |
||||
_options.IsEnabled = true; |
_options.IsEnabled = true; |
||||
_options.AlwaysLogOnException = true; |
_options.AlwaysLogOnException = true; |
||||
|
|
||||
try |
try |
||||
{ |
{ |
||||
await GetResponseAsync("api/audit-test/audit-fail", System.Net.HttpStatusCode.Forbidden); |
await GetResponseAsync("api/audit-test/audit-fail", System.Net.HttpStatusCode.Forbidden); |
||||
} |
} |
||||
catch { } |
catch { } |
||||
|
|
||||
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); //Won't work, save happens out of scope
|
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
||||
} |
} |
||||
} |
[Fact] |
||||
} |
public async Task Should_Trigger_Middleware_And_AuditLog_Exception_When_Returns_Object() |
||||
|
{ |
||||
|
_options.IsEnabled = true; |
||||
|
_options.AlwaysLogOnException = true; |
||||
|
|
||||
|
await GetResponseAsync("api/audit-test/audit-fail-object", System.Net.HttpStatusCode.Forbidden); |
||||
|
|
||||
|
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|||||
@ -1,465 +0,0 @@ |
|||||
// <auto-generated />
|
|
||||
using System; |
|
||||
using Microsoft.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|
||||
using Microsoft.EntityFrameworkCore.Metadata; |
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|
||||
using VoloDocs.EntityFrameworkCore; |
|
||||
|
|
||||
namespace VoloDocs.EntityFrameworkCore.Migrations |
|
||||
{ |
|
||||
[DbContext(typeof(VoloDocsDbContext))] |
|
||||
[Migration("20181225134002_Initial20181225")] |
|
||||
partial class Initial20181225 |
|
||||
{ |
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|
||||
{ |
|
||||
#pragma warning disable 612, 618
|
|
||||
modelBuilder |
|
||||
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846") |
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128) |
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.IsRequired() |
|
||||
.HasColumnName("ConcurrencyStamp") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<bool>("IsStatic"); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("Regex") |
|
||||
.HasMaxLength(512); |
|
||||
|
|
||||
b.Property<string>("RegexDescription") |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<bool>("Required"); |
|
||||
|
|
||||
b.Property<int>("ValueType"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.ToTable("AbpClaimTypes"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.IsRequired() |
|
||||
.HasColumnName("ConcurrencyStamp") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<bool>("IsDefault") |
|
||||
.HasColumnName("IsDefault"); |
|
||||
|
|
||||
b.Property<bool>("IsPublic") |
|
||||
.HasColumnName("IsPublic"); |
|
||||
|
|
||||
b.Property<bool>("IsStatic") |
|
||||
.HasColumnName("IsStatic"); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("NormalizedName") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("NormalizedName"); |
|
||||
|
|
||||
b.ToTable("AbpRoles"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("ClaimType") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("ClaimValue") |
|
||||
.HasMaxLength(1024); |
|
||||
|
|
||||
b.Property<Guid>("RoleId"); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("RoleId"); |
|
||||
|
|
||||
b.ToTable("AbpRoleClaims"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<int>("AccessFailedCount") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnName("AccessFailedCount") |
|
||||
.HasDefaultValue(0); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.HasColumnName("ConcurrencyStamp"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid?>("DeleterId") |
|
||||
.HasColumnName("DeleterId"); |
|
||||
|
|
||||
b.Property<DateTime?>("DeletionTime") |
|
||||
.HasColumnName("DeletionTime"); |
|
||||
|
|
||||
b.Property<string>("Email") |
|
||||
.HasColumnName("Email") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<bool>("EmailConfirmed") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnName("EmailConfirmed") |
|
||||
.HasDefaultValue(false); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<bool>("IsDeleted") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnName("IsDeleted") |
|
||||
.HasDefaultValue(false); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.Property<bool>("LockoutEnabled") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnName("LockoutEnabled") |
|
||||
.HasDefaultValue(false); |
|
||||
|
|
||||
b.Property<DateTimeOffset?>("LockoutEnd"); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.HasColumnName("Name") |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<string>("NormalizedEmail") |
|
||||
.HasColumnName("NormalizedEmail") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("NormalizedUserName") |
|
||||
.IsRequired() |
|
||||
.HasColumnName("NormalizedUserName") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("PasswordHash") |
|
||||
.HasColumnName("PasswordHash") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("PhoneNumber") |
|
||||
.HasColumnName("PhoneNumber") |
|
||||
.HasMaxLength(16); |
|
||||
|
|
||||
b.Property<bool>("PhoneNumberConfirmed") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnName("PhoneNumberConfirmed") |
|
||||
.HasDefaultValue(false); |
|
||||
|
|
||||
b.Property<string>("SecurityStamp") |
|
||||
.IsRequired() |
|
||||
.HasColumnName("SecurityStamp") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("Surname") |
|
||||
.HasColumnName("Surname") |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId") |
|
||||
.HasColumnName("TenantId"); |
|
||||
|
|
||||
b.Property<bool>("TwoFactorEnabled") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnName("TwoFactorEnabled") |
|
||||
.HasDefaultValue(false); |
|
||||
|
|
||||
b.Property<string>("UserName") |
|
||||
.IsRequired() |
|
||||
.HasColumnName("UserName") |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("Email"); |
|
||||
|
|
||||
b.HasIndex("NormalizedEmail"); |
|
||||
|
|
||||
b.HasIndex("NormalizedUserName"); |
|
||||
|
|
||||
b.HasIndex("UserName"); |
|
||||
|
|
||||
b.ToTable("AbpUsers"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("ClaimType") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(256); |
|
||||
|
|
||||
b.Property<string>("ClaimValue") |
|
||||
.HasMaxLength(1024); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.Property<Guid>("UserId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("UserId"); |
|
||||
|
|
||||
b.ToTable("AbpUserClaims"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => |
|
||||
{ |
|
||||
b.Property<Guid>("UserId"); |
|
||||
|
|
||||
b.Property<string>("LoginProvider") |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<string>("ProviderDisplayName") |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("ProviderKey") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(196); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.HasKey("UserId", "LoginProvider"); |
|
||||
|
|
||||
b.HasIndex("LoginProvider", "ProviderKey"); |
|
||||
|
|
||||
b.ToTable("AbpUserLogins"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => |
|
||||
{ |
|
||||
b.Property<Guid>("UserId"); |
|
||||
|
|
||||
b.Property<Guid>("RoleId"); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.HasKey("UserId", "RoleId"); |
|
||||
|
|
||||
b.HasIndex("RoleId", "UserId"); |
|
||||
|
|
||||
b.ToTable("AbpUserRoles"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => |
|
||||
{ |
|
||||
b.Property<Guid>("UserId"); |
|
||||
|
|
||||
b.Property<string>("LoginProvider") |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.Property<string>("Value"); |
|
||||
|
|
||||
b.HasKey("UserId", "LoginProvider", "Name"); |
|
||||
|
|
||||
b.ToTable("AbpUserTokens"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("ProviderKey") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<string>("ProviderName") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("Name", "ProviderName", "ProviderKey"); |
|
||||
|
|
||||
b.ToTable("AbpPermissionGrants"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("ProviderKey") |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<string>("ProviderName") |
|
||||
.HasMaxLength(64); |
|
||||
|
|
||||
b.Property<string>("Value") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(2048); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("Name", "ProviderName", "ProviderKey"); |
|
||||
|
|
||||
b.ToTable("AbpSettings"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Docs.Projects.Project", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd(); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.HasColumnName("ConcurrencyStamp"); |
|
||||
|
|
||||
b.Property<string>("DefaultDocumentName") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("DocumentStoreType"); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<string>("Format"); |
|
||||
|
|
||||
b.Property<string>("LatestVersionBranchName") |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("MainWebsiteUrl"); |
|
||||
|
|
||||
b.Property<string>("MinimumVersion"); |
|
||||
|
|
||||
b.Property<string>("Name") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("NavigationDocumentName") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(128); |
|
||||
|
|
||||
b.Property<string>("ShortName") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(32); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.ToTable("DocsProjects"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => |
|
||||
{ |
|
||||
b.HasOne("Volo.Abp.Identity.IdentityRole") |
|
||||
.WithMany("Claims") |
|
||||
.HasForeignKey("RoleId") |
|
||||
.OnDelete(DeleteBehavior.Cascade); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => |
|
||||
{ |
|
||||
b.HasOne("Volo.Abp.Identity.IdentityUser") |
|
||||
.WithMany("Claims") |
|
||||
.HasForeignKey("UserId") |
|
||||
.OnDelete(DeleteBehavior.Cascade); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => |
|
||||
{ |
|
||||
b.HasOne("Volo.Abp.Identity.IdentityUser") |
|
||||
.WithMany("Logins") |
|
||||
.HasForeignKey("UserId") |
|
||||
.OnDelete(DeleteBehavior.Cascade); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => |
|
||||
{ |
|
||||
b.HasOne("Volo.Abp.Identity.IdentityRole") |
|
||||
.WithMany() |
|
||||
.HasForeignKey("RoleId") |
|
||||
.OnDelete(DeleteBehavior.Cascade); |
|
||||
|
|
||||
b.HasOne("Volo.Abp.Identity.IdentityUser") |
|
||||
.WithMany("Roles") |
|
||||
.HasForeignKey("UserId") |
|
||||
.OnDelete(DeleteBehavior.Cascade); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => |
|
||||
{ |
|
||||
b.HasOne("Volo.Abp.Identity.IdentityUser") |
|
||||
.WithMany("Tokens") |
|
||||
.HasForeignKey("UserId") |
|
||||
.OnDelete(DeleteBehavior.Cascade); |
|
||||
}); |
|
||||
#pragma warning restore 612, 618
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,670 @@ |
|||||
|
// <auto-generated />
|
||||
|
using System; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
|
using Microsoft.EntityFrameworkCore.Metadata; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
using VoloDocs.EntityFrameworkCore; |
||||
|
|
||||
|
namespace VoloDocs.EntityFrameworkCore.Migrations |
||||
|
{ |
||||
|
[DbContext(typeof(VoloDocsDbContext))] |
||||
|
[Migration("20200218014727_init")] |
||||
|
partial class init |
||||
|
{ |
||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
|
{ |
||||
|
#pragma warning disable 612, 618
|
||||
|
modelBuilder |
||||
|
.HasAnnotation("ProductVersion", "3.1.1") |
||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128) |
||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.IsRequired() |
||||
|
.HasColumnName("ConcurrencyStamp") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnName("ExtraProperties") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<bool>("IsStatic") |
||||
|
.HasColumnType("bit"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("Regex") |
||||
|
.HasColumnType("nvarchar(512)") |
||||
|
.HasMaxLength(512); |
||||
|
|
||||
|
b.Property<string>("RegexDescription") |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<bool>("Required") |
||||
|
.HasColumnType("bit"); |
||||
|
|
||||
|
b.Property<int>("ValueType") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("AbpClaimTypes"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.IsRequired() |
||||
|
.HasColumnName("ConcurrencyStamp") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnName("ExtraProperties") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<bool>("IsDefault") |
||||
|
.HasColumnName("IsDefault") |
||||
|
.HasColumnType("bit"); |
||||
|
|
||||
|
b.Property<bool>("IsPublic") |
||||
|
.HasColumnName("IsPublic") |
||||
|
.HasColumnType("bit"); |
||||
|
|
||||
|
b.Property<bool>("IsStatic") |
||||
|
.HasColumnName("IsStatic") |
||||
|
.HasColumnType("bit"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("NormalizedName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("NormalizedName"); |
||||
|
|
||||
|
b.ToTable("AbpRoles"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("ClaimType") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ClaimValue") |
||||
|
.HasColumnType("nvarchar(1024)") |
||||
|
.HasMaxLength(1024); |
||||
|
|
||||
|
b.Property<Guid>("RoleId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("RoleId"); |
||||
|
|
||||
|
b.ToTable("AbpRoleClaims"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<int>("AccessFailedCount") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("AccessFailedCount") |
||||
|
.HasColumnType("int") |
||||
|
.HasDefaultValue(0); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.HasColumnName("ConcurrencyStamp") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnName("CreationTime") |
||||
|
.HasColumnType("datetime2"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnName("CreatorId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<Guid?>("DeleterId") |
||||
|
.HasColumnName("DeleterId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<DateTime?>("DeletionTime") |
||||
|
.HasColumnName("DeletionTime") |
||||
|
.HasColumnType("datetime2"); |
||||
|
|
||||
|
b.Property<string>("Email") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("Email") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<bool>("EmailConfirmed") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("EmailConfirmed") |
||||
|
.HasColumnType("bit") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnName("ExtraProperties") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<bool>("IsDeleted") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("IsDeleted") |
||||
|
.HasColumnType("bit") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnName("LastModificationTime") |
||||
|
.HasColumnType("datetime2"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnName("LastModifierId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<bool>("LockoutEnabled") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("LockoutEnabled") |
||||
|
.HasColumnType("bit") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTimeOffset?>("LockoutEnd") |
||||
|
.HasColumnType("datetimeoffset"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.HasColumnName("Name") |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("NormalizedEmail") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("NormalizedEmail") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("NormalizedUserName") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("NormalizedUserName") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("PasswordHash") |
||||
|
.HasColumnName("PasswordHash") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("PhoneNumber") |
||||
|
.HasColumnName("PhoneNumber") |
||||
|
.HasColumnType("nvarchar(16)") |
||||
|
.HasMaxLength(16); |
||||
|
|
||||
|
b.Property<bool>("PhoneNumberConfirmed") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("PhoneNumberConfirmed") |
||||
|
.HasColumnType("bit") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<string>("SecurityStamp") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("SecurityStamp") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("Surname") |
||||
|
.HasColumnName("Surname") |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnName("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<bool>("TwoFactorEnabled") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("TwoFactorEnabled") |
||||
|
.HasColumnType("bit") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<string>("UserName") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("UserName") |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("Email"); |
||||
|
|
||||
|
b.HasIndex("NormalizedEmail"); |
||||
|
|
||||
|
b.HasIndex("NormalizedUserName"); |
||||
|
|
||||
|
b.HasIndex("UserName"); |
||||
|
|
||||
|
b.ToTable("AbpUsers"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("ClaimType") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(256)") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ClaimValue") |
||||
|
.HasColumnType("nvarchar(1024)") |
||||
|
.HasMaxLength(1024); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<Guid>("UserId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("UserId"); |
||||
|
|
||||
|
b.ToTable("AbpUserClaims"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => |
||||
|
{ |
||||
|
b.Property<Guid>("UserId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("LoginProvider") |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("ProviderDisplayName") |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ProviderKey") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(196)") |
||||
|
.HasMaxLength(196); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.HasKey("UserId", "LoginProvider"); |
||||
|
|
||||
|
b.HasIndex("LoginProvider", "ProviderKey"); |
||||
|
|
||||
|
b.ToTable("AbpUserLogins"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => |
||||
|
{ |
||||
|
b.Property<Guid>("UserId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<Guid>("RoleId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.HasKey("UserId", "RoleId"); |
||||
|
|
||||
|
b.HasIndex("RoleId", "UserId"); |
||||
|
|
||||
|
b.ToTable("AbpUserRoles"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => |
||||
|
{ |
||||
|
b.Property<Guid>("UserId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("LoginProvider") |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("Value") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.HasKey("UserId", "LoginProvider", "Name"); |
||||
|
|
||||
|
b.ToTable("AbpUserTokens"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ProviderKey") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("ProviderName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("Name", "ProviderName", "ProviderKey"); |
||||
|
|
||||
|
b.ToTable("AbpPermissionGrants"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ProviderKey") |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("ProviderName") |
||||
|
.HasColumnType("nvarchar(64)") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("Value") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(2048)") |
||||
|
.HasMaxLength(2048); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("Name", "ProviderName", "ProviderKey"); |
||||
|
|
||||
|
b.ToTable("AbpSettings"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Docs.Documents.Document", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.HasColumnName("ConcurrencyStamp") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("Content") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnType("datetime2"); |
||||
|
|
||||
|
b.Property<string>("EditLink") |
||||
|
.HasColumnType("nvarchar(2048)") |
||||
|
.HasMaxLength(2048); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnName("ExtraProperties") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("FileName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("Format") |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("LanguageCode") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<DateTime>("LastCachedTime") |
||||
|
.HasColumnType("datetime2"); |
||||
|
|
||||
|
b.Property<DateTime>("LastUpdatedTime") |
||||
|
.HasColumnType("datetime2"); |
||||
|
|
||||
|
b.Property<string>("LocalDirectory") |
||||
|
.HasColumnType("nvarchar(512)") |
||||
|
.HasMaxLength(512); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(255)") |
||||
|
.HasMaxLength(255); |
||||
|
|
||||
|
b.Property<Guid>("ProjectId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("RawRootUrl") |
||||
|
.HasColumnType("nvarchar(2048)") |
||||
|
.HasMaxLength(2048); |
||||
|
|
||||
|
b.Property<string>("RootUrl") |
||||
|
.HasColumnType("nvarchar(2048)") |
||||
|
.HasMaxLength(2048); |
||||
|
|
||||
|
b.Property<string>("Version") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("DocsDocuments"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b => |
||||
|
{ |
||||
|
b.Property<Guid>("DocumentId") |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("Username") |
||||
|
.HasColumnType("nvarchar(450)"); |
||||
|
|
||||
|
b.Property<string>("AvatarUrl") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("UserProfileUrl") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.HasKey("DocumentId", "Username"); |
||||
|
|
||||
|
b.ToTable("DocsDocumentContributors"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Docs.Projects.Project", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("uniqueidentifier"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.HasColumnName("ConcurrencyStamp") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("DefaultDocumentName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("DocumentStoreType") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnName("ExtraProperties") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("Format") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("LatestVersionBranchName") |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("MainWebsiteUrl") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("MinimumVersion") |
||||
|
.HasColumnType("nvarchar(max)"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("NavigationDocumentName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ParametersDocumentName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(128)") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ShortName") |
||||
|
.IsRequired() |
||||
|
.HasColumnType("nvarchar(32)") |
||||
|
.HasMaxLength(32); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("DocsProjects"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityRole", null) |
||||
|
.WithMany("Claims") |
||||
|
.HasForeignKey("RoleId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser", null) |
||||
|
.WithMany("Claims") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser", null) |
||||
|
.WithMany("Logins") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityRole", null) |
||||
|
.WithMany() |
||||
|
.HasForeignKey("RoleId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
|
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser", null) |
||||
|
.WithMany("Roles") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser", null) |
||||
|
.WithMany("Tokens") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Docs.Documents.Document", null) |
||||
|
.WithMany("Contributors") |
||||
|
.HasForeignKey("DocumentId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
#pragma warning restore 612, 618
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
|
||||
|
namespace Volo.Docs.Admin.Documents |
||||
|
{ |
||||
|
public interface IDocumentAdminAppService : IApplicationService |
||||
|
{ |
||||
|
Task PullAllAsync(PullAllDocumentInput input); |
||||
|
|
||||
|
Task PullAsync(PullDocumentInput input); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using Volo.Docs.Documents; |
||||
|
|
||||
|
namespace Volo.Docs.Admin.Documents |
||||
|
{ |
||||
|
public class PullAllDocumentInput |
||||
|
{ |
||||
|
public Guid ProjectId { get; set; } |
||||
|
|
||||
|
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)] |
||||
|
public string LanguageCode { get; set; } |
||||
|
|
||||
|
[StringLength(DocumentConsts.MaxVersionNameLength)] |
||||
|
public string Version { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using Volo.Docs.Documents; |
||||
|
|
||||
|
namespace Volo.Docs.Admin.Documents |
||||
|
{ |
||||
|
public class PullDocumentInput |
||||
|
{ |
||||
|
public Guid ProjectId { get; set; } |
||||
|
|
||||
|
[StringLength(DocumentConsts.MaxNameLength)] |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)] |
||||
|
public string LanguageCode { get; set; } |
||||
|
|
||||
|
[StringLength(DocumentConsts.MaxVersionNameLength)] |
||||
|
public string Version { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,106 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Newtonsoft.Json; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Docs.Documents; |
||||
|
using Volo.Docs.Projects; |
||||
|
|
||||
|
namespace Volo.Docs.Admin.Documents |
||||
|
{ |
||||
|
[Authorize(DocsAdminPermissions.Documents.Default)] |
||||
|
public class DocumentAdminAppService : ApplicationService, IDocumentAdminAppService |
||||
|
{ |
||||
|
private readonly IProjectRepository _projectRepository; |
||||
|
private readonly IDocumentRepository _documentRepository; |
||||
|
private readonly IDocumentSourceFactory _documentStoreFactory; |
||||
|
private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache; |
||||
|
|
||||
|
public DocumentAdminAppService(IProjectRepository projectRepository, |
||||
|
IDocumentRepository documentRepository, |
||||
|
IDocumentSourceFactory documentStoreFactory, |
||||
|
IDistributedCache<DocumentUpdateInfo> documentUpdateCache) |
||||
|
{ |
||||
|
_projectRepository = projectRepository; |
||||
|
_documentRepository = documentRepository; |
||||
|
_documentStoreFactory = documentStoreFactory; |
||||
|
_documentUpdateCache = documentUpdateCache; |
||||
|
} |
||||
|
|
||||
|
public async Task PullAllAsync(PullAllDocumentInput input) |
||||
|
{ |
||||
|
var project = await _projectRepository.GetAsync(input.ProjectId); |
||||
|
|
||||
|
var navigationFile = await GetDocumentAsync( |
||||
|
project, |
||||
|
project.NavigationDocumentName, |
||||
|
input.LanguageCode, |
||||
|
input.Version |
||||
|
); |
||||
|
|
||||
|
var nav = JsonConvert.DeserializeObject<NavigationNode>(navigationFile.Content); |
||||
|
var leafs = nav.Items.GetAllNodes(x => x.Items) |
||||
|
.Where(x => x.IsLeaf && !x.Path.IsNullOrWhiteSpace()) |
||||
|
.ToList(); |
||||
|
|
||||
|
var source = _documentStoreFactory.Create(project.DocumentStoreType); |
||||
|
|
||||
|
var documents = new List<Document>(); |
||||
|
foreach (var leaf in leafs) |
||||
|
{ |
||||
|
var sourceDocument = |
||||
|
await source.GetDocumentAsync(project, leaf.Path, input.LanguageCode, input.Version); |
||||
|
documents.Add(sourceDocument); |
||||
|
} |
||||
|
|
||||
|
foreach (var document in documents) |
||||
|
{ |
||||
|
await _documentRepository.DeleteAsync(document.ProjectId, document.Name, |
||||
|
document.LanguageCode, |
||||
|
document.Version); |
||||
|
|
||||
|
await _documentRepository.InsertAsync(document, true); |
||||
|
await UpdateDocumentUpdateInfoCache(document); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task PullAsync(PullDocumentInput input) |
||||
|
{ |
||||
|
var project = await _projectRepository.GetAsync(input.ProjectId); |
||||
|
|
||||
|
var source = _documentStoreFactory.Create(project.DocumentStoreType); |
||||
|
var sourceDocument = await source.GetDocumentAsync(project, input.Name, input.LanguageCode, input.Version); |
||||
|
|
||||
|
await _documentRepository.DeleteAsync(sourceDocument.ProjectId, sourceDocument.Name, |
||||
|
sourceDocument.LanguageCode, sourceDocument.Version); |
||||
|
await _documentRepository.InsertAsync(sourceDocument, true); |
||||
|
await UpdateDocumentUpdateInfoCache(sourceDocument); |
||||
|
} |
||||
|
|
||||
|
private async Task UpdateDocumentUpdateInfoCache(Document document) |
||||
|
{ |
||||
|
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}"; |
||||
|
await _documentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo |
||||
|
{ |
||||
|
Name = document.Name, |
||||
|
CreationTime = document.CreationTime, |
||||
|
LastUpdatedTime = document.LastUpdatedTime |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private async Task<Document> GetDocumentAsync( |
||||
|
Project project, |
||||
|
string documentName, |
||||
|
string languageCode, |
||||
|
string version) |
||||
|
{ |
||||
|
version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version; |
||||
|
var source = _documentStoreFactory.Create(project.DocumentStoreType); |
||||
|
var document = await source.GetDocumentAsync(project, documentName, languageCode, version); |
||||
|
return document; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
using Volo.Docs.Admin.Documents; |
||||
|
|
||||
|
namespace Volo.Docs.Admin |
||||
|
{ |
||||
|
[RemoteService] |
||||
|
[Area("docs")] |
||||
|
[ControllerName("DocumentsAdmin")] |
||||
|
[Route("api/docs/admin/documents")] |
||||
|
public class DocumentsAdminController : AbpController, IDocumentAdminAppService |
||||
|
{ |
||||
|
private readonly IDocumentAdminAppService _documentAdminAppService; |
||||
|
|
||||
|
public DocumentsAdminController(IDocumentAdminAppService documentAdminAppService) |
||||
|
{ |
||||
|
_documentAdminAppService = documentAdminAppService; |
||||
|
} |
||||
|
|
||||
|
[HttpPost] |
||||
|
[Route("PullAll")] |
||||
|
public Task PullAllAsync(PullAllDocumentInput input) |
||||
|
{ |
||||
|
return _documentAdminAppService.PullAllAsync(input); |
||||
|
} |
||||
|
|
||||
|
[HttpPost] |
||||
|
[Route("Pull")] |
||||
|
public Task PullAsync(PullDocumentInput input) |
||||
|
{ |
||||
|
return _documentAdminAppService.PullAsync(input); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
@page |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
||||
|
@using Volo.Docs.Admin.Pages.Docs.Admin.Projects |
||||
|
@inherits Volo.Docs.Admin.Pages.Docs.Admin.DocsAdminPage |
||||
|
@model Volo.Docs.Admin.Pages.Docs.Admin.Projects.PullModel |
||||
|
@{ |
||||
|
Layout = null; |
||||
|
} |
||||
|
|
||||
|
@if (Model.PullDocument != null) |
||||
|
{ |
||||
|
<abp-dynamic-form submit-button="false" abp-model="@Model.PullDocument" asp-page="/Docs/Admin/Projects/Pull"> |
||||
|
<abp-modal size="@(AbpModalSize.Default)"> |
||||
|
<abp-modal-header title="@L["Pull"].Value"></abp-modal-header> |
||||
|
<abp-modal-body> |
||||
|
<abp-form-content /> |
||||
|
</abp-modal-body> |
||||
|
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"> |
||||
|
</abp-modal-footer> |
||||
|
</abp-modal> |
||||
|
</abp-dynamic-form> |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Docs.Admin.Documents; |
||||
|
using Volo.Docs.Admin.Projects; |
||||
|
using Volo.Docs.Documents; |
||||
|
|
||||
|
namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects |
||||
|
{ |
||||
|
public class PullModel : DocsAdminPageModel |
||||
|
{ |
||||
|
[BindProperty] |
||||
|
public PullDocumentViewModel PullDocument { get; set; } |
||||
|
|
||||
|
private readonly IProjectAdminAppService _projectAppService; |
||||
|
private readonly IDocumentAdminAppService _documentAppService; |
||||
|
|
||||
|
public PullModel(IProjectAdminAppService projectAppService, |
||||
|
IDocumentAdminAppService documentAppService) |
||||
|
{ |
||||
|
_projectAppService = projectAppService; |
||||
|
_documentAppService = documentAppService; |
||||
|
} |
||||
|
|
||||
|
public async Task<ActionResult> OnGetAsync(Guid id) |
||||
|
{ |
||||
|
var project = await _projectAppService.GetAsync(id); |
||||
|
|
||||
|
PullDocument = new PullDocumentViewModel() |
||||
|
{ |
||||
|
ProjectId = project.Id, |
||||
|
All = false |
||||
|
}; |
||||
|
|
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
public async Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
if (PullDocument.All) |
||||
|
{ |
||||
|
await _documentAppService.PullAllAsync( |
||||
|
ObjectMapper.Map<PullDocumentViewModel, PullAllDocumentInput>(PullDocument)); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
await _documentAppService.PullAsync( |
||||
|
ObjectMapper.Map<PullDocumentViewModel, PullDocumentInput>(PullDocument)); |
||||
|
} |
||||
|
|
||||
|
return NoContent(); |
||||
|
} |
||||
|
|
||||
|
public class PullDocumentViewModel |
||||
|
{ |
||||
|
[HiddenInput] |
||||
|
public Guid ProjectId { get; set; } |
||||
|
|
||||
|
public bool All { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
[StringLength(DocumentConsts.MaxNameLength)] |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)] |
||||
|
public string LanguageCode { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
[StringLength(DocumentConsts.MaxVersionNameLength)] |
||||
|
public string Version { get; set; } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
var abp = abp || {}; |
||||
|
|
||||
|
$(function () { |
||||
|
abp.modals.projectPull = function () { |
||||
|
var initModal = function (publicApi, args) { |
||||
|
var $form = publicApi.getForm(); |
||||
|
var fg = $form.find("#PullDocument_Name").parent(); |
||||
|
var nameInput = fg.html(); |
||||
|
|
||||
|
$form.find("input:checkbox").change(function() { |
||||
|
if ($(this).prop("checked")) { |
||||
|
fg.html(""); |
||||
|
} else { |
||||
|
fg.html(nameInput); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
return { |
||||
|
initModal: initModal |
||||
|
}; |
||||
|
}; |
||||
|
}); |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Docs.Documents |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class DocumentUpdateInfo |
||||
|
{ |
||||
|
public virtual string Name { get; set; } |
||||
|
|
||||
|
public virtual DateTime CreationTime { get; set; } |
||||
|
|
||||
|
public virtual DateTime LastUpdatedTime { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -1,27 +1,110 @@ |
|||||
|
using System; |
||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using JetBrains.Annotations; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
|
||||
namespace Volo.Docs.Documents |
namespace Volo.Docs.Documents |
||||
{ |
{ |
||||
public class Document |
public class Document : AggregateRoot<Guid> |
||||
{ |
{ |
||||
public string Title { get; set; } |
public virtual Guid ProjectId { get; protected set; } |
||||
|
|
||||
public string Content { get; set; } |
public virtual string Name { get; protected set; } |
||||
|
|
||||
public string Format { get; set; } |
public virtual string Version { get; protected set; } |
||||
|
|
||||
public string EditLink { get; set; } |
public virtual string LanguageCode { get; protected set; } |
||||
|
|
||||
public string RootUrl { get; set; } |
public virtual string FileName { get; set; } |
||||
|
|
||||
public string RawRootUrl { get; set; } |
public virtual string Content { get; set; } |
||||
|
|
||||
public string Version { get; set; } |
public virtual string Format { get; set; } |
||||
|
|
||||
public string LocalDirectory { get; set; } |
public virtual string EditLink { get; set; } |
||||
|
|
||||
public string FileName { get; set; } |
public virtual string RootUrl { get; set; } |
||||
|
|
||||
public List<DocumentContributor> Contributors { get; set; } |
public virtual string RawRootUrl { get; set; } |
||||
|
|
||||
|
public virtual string LocalDirectory { get; set; } |
||||
|
|
||||
|
public virtual DateTime CreationTime { get; set; } |
||||
|
|
||||
|
public virtual DateTime LastUpdatedTime { get; set; } |
||||
|
|
||||
|
public virtual DateTime LastCachedTime { get; set; } |
||||
|
|
||||
|
public virtual List<DocumentContributor> Contributors { get; set; } |
||||
|
|
||||
|
protected Document() |
||||
|
{ |
||||
|
Contributors = new List<DocumentContributor>(); |
||||
|
ExtraProperties = new Dictionary<string, object>(); |
||||
|
} |
||||
|
|
||||
|
public Document( |
||||
|
Guid id, |
||||
|
Guid projectId, |
||||
|
[NotNull] string name, |
||||
|
[NotNull] string version, |
||||
|
[NotNull] string languageCode, |
||||
|
[NotNull] string fileName, |
||||
|
[NotNull] string content, |
||||
|
[NotNull] string format, |
||||
|
[NotNull] string editLink, |
||||
|
[NotNull] string rootUrl, |
||||
|
[NotNull] string rawRootUrl, |
||||
|
[NotNull] string localDirectory, |
||||
|
DateTime creationTime, |
||||
|
DateTime lastUpdatedTime, |
||||
|
DateTime lastCachedTime |
||||
|
) |
||||
|
{ |
||||
|
Id = id; |
||||
|
ProjectId = projectId; |
||||
|
|
||||
|
Name = Check.NotNullOrWhiteSpace(name, nameof(name)); |
||||
|
Version = Check.NotNullOrWhiteSpace(version, nameof(version)); |
||||
|
LanguageCode = Check.NotNullOrWhiteSpace(languageCode, nameof(languageCode)); |
||||
|
FileName = Check.NotNullOrWhiteSpace(fileName, nameof(fileName)); |
||||
|
Content = Check.NotNullOrWhiteSpace(content, nameof(content)); |
||||
|
Format = Check.NotNullOrWhiteSpace(format, nameof(format)); |
||||
|
EditLink = Check.NotNullOrWhiteSpace(editLink, nameof(editLink)); |
||||
|
RootUrl = Check.NotNullOrWhiteSpace(rootUrl, nameof(rootUrl)); |
||||
|
RawRootUrl = Check.NotNullOrWhiteSpace(rawRootUrl, nameof(rawRootUrl)); |
||||
|
LocalDirectory = Check.NotNull(localDirectory, nameof(localDirectory)); |
||||
|
|
||||
|
CreationTime = creationTime; |
||||
|
LastUpdatedTime = lastUpdatedTime; |
||||
|
LastCachedTime = lastCachedTime; |
||||
|
|
||||
|
Contributors = new List<DocumentContributor>(); |
||||
|
ExtraProperties = new Dictionary<string, object>(); |
||||
|
} |
||||
|
|
||||
|
public virtual void AddContributor(string username, string userProfileUrl, string avatarUrl) |
||||
|
{ |
||||
|
Contributors.AddIfNotContains(new DocumentContributor(Id, username, userProfileUrl, avatarUrl)); |
||||
|
} |
||||
|
|
||||
|
public virtual void RemoveAllContributors() |
||||
|
{ |
||||
|
Contributors.Clear(); |
||||
|
} |
||||
|
|
||||
|
public virtual void RemoveContributor(string username, string userProfileUrl, string avatarUrl) |
||||
|
{ |
||||
|
Contributors.RemoveAll(r => |
||||
|
r.Username == username && r.UserProfileUrl == userProfileUrl && r.AvatarUrl == avatarUrl); |
||||
|
} |
||||
|
|
||||
|
public virtual DocumentContributor FindContributor(string username, string userProfileUrl, string avatarUrl) |
||||
|
{ |
||||
|
return Contributors.FirstOrDefault(r => |
||||
|
r.Username == username && r.UserProfileUrl == userProfileUrl && r.AvatarUrl == avatarUrl); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
@ -1,15 +1,39 @@ |
|||||
using System; |
using System; |
||||
using System.Collections.Generic; |
using Volo.Abp.Domain.Entities; |
||||
using System.Text; |
|
||||
|
|
||||
namespace Volo.Docs.Documents |
namespace Volo.Docs.Documents |
||||
{ |
{ |
||||
public class DocumentContributor |
public class DocumentContributor : Entity |
||||
{ |
{ |
||||
|
public Guid DocumentId { get; set; } |
||||
|
|
||||
public string Username { get; set; } |
public string Username { get; set; } |
||||
|
|
||||
public string UserProfileUrl { get; set; } |
public string UserProfileUrl { get; set; } |
||||
|
|
||||
public string AvatarUrl { get; set; } |
public string AvatarUrl { get; set; } |
||||
|
|
||||
|
protected DocumentContributor() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public virtual bool Equals(Guid documentId, string username) |
||||
|
{ |
||||
|
return DocumentId == documentId && Username == username; |
||||
|
} |
||||
|
|
||||
|
public DocumentContributor(Guid documentId, string username, string userProfileUrl, string avatarUrl) |
||||
|
{ |
||||
|
DocumentId = documentId; |
||||
|
Username = username; |
||||
|
UserProfileUrl = userProfileUrl; |
||||
|
AvatarUrl = avatarUrl; |
||||
|
} |
||||
|
|
||||
|
public override object[] GetKeys() |
||||
|
{ |
||||
|
return new object[] { DocumentId, Username }; |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Docs.Documents |
||||
|
{ |
||||
|
public class DocumentSourceOptions |
||||
|
{ |
||||
|
public Dictionary<string, Type> Sources { get; set; } |
||||
|
|
||||
|
public DocumentSourceOptions() |
||||
|
{ |
||||
|
Sources = new Dictionary<string, Type>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,15 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace Volo.Docs.Documents |
|
||||
{ |
|
||||
public class DocumentStoreOptions |
|
||||
{ |
|
||||
public Dictionary<string, Type> Stores { get; set; } |
|
||||
|
|
||||
public DocumentStoreOptions() |
|
||||
{ |
|
||||
Stores = new Dictionary<string, Type>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
|
namespace Volo.Docs.Documents |
||||
|
{ |
||||
|
public interface IDocumentRepository : IBasicRepository<Document> |
||||
|
{ |
||||
|
Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version, |
||||
|
bool includeDetails = true, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task DeleteAsync(Guid projectId, string name, string languageCode, string version, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Volo.Docs.Documents |
||||
|
{ |
||||
|
public interface IDocumentSourceFactory |
||||
|
{ |
||||
|
IDocumentSource Create(string sourceType); |
||||
|
} |
||||
|
} |
||||
@ -1,7 +0,0 @@ |
|||||
namespace Volo.Docs.Documents |
|
||||
{ |
|
||||
public interface IDocumentStoreFactory |
|
||||
{ |
|
||||
IDocumentStore Create(string storeType); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,36 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
using Volo.Docs.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Volo.Docs.Documents |
||||
|
{ |
||||
|
public class EFCoreDocumentRepository : EfCoreRepository<IDocsDbContext, Document>, IDocumentRepository |
||||
|
{ |
||||
|
public EFCoreDocumentRepository(IDbContextProvider<IDocsDbContext> dbContextProvider) |
||||
|
: base(dbContextProvider) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version, |
||||
|
bool includeDetails = true, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await DbSet.IncludeDetails(includeDetails) |
||||
|
.FirstOrDefaultAsync(x => |
||||
|
x.ProjectId == projectId && x.Name == name && x.LanguageCode == languageCode && |
||||
|
x.Version == version, |
||||
|
cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public async Task DeleteAsync(Guid projectId, string name, string languageCode, string version, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
await DeleteAsync(x => |
||||
|
x.ProjectId == projectId && x.Name == name && x.LanguageCode == languageCode && |
||||
|
x.Version == version, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System.Linq; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Volo.Docs.Documents; |
||||
|
|
||||
|
namespace Volo.Docs.EntityFrameworkCore |
||||
|
{ |
||||
|
public static class DocsEfCoreQueryableExtensions |
||||
|
{ |
||||
|
public static IQueryable<Document> IncludeDetails(this IQueryable<Document> queryable, bool include = true) |
||||
|
{ |
||||
|
return !include ? queryable : queryable.Include(x => x.Contributors); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using MongoDB.Driver.Linq; |
||||
|
using Volo.Abp.Domain.Repositories.MongoDB; |
||||
|
using Volo.Abp.MongoDB; |
||||
|
using Volo.Docs.MongoDB; |
||||
|
|
||||
|
namespace Volo.Docs.Documents |
||||
|
{ |
||||
|
public class MongoDocumentRepository : MongoDbRepository<IDocsMongoDbContext, Document, Guid>, IDocumentRepository |
||||
|
{ |
||||
|
public MongoDocumentRepository(IMongoDbContextProvider<IDocsMongoDbContext> dbContextProvider) |
||||
|
: base(dbContextProvider) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version, |
||||
|
bool includeDetails = true, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await GetMongoQueryable().FirstOrDefaultAsync(x => x.ProjectId == projectId && |
||||
|
x.Name == name && |
||||
|
x.LanguageCode == languageCode && |
||||
|
x.Version == version, cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public async Task DeleteAsync(Guid projectId, string name, string languageCode, string version, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
await DeleteAsync(x => |
||||
|
x.ProjectId == projectId && x.Name == name && x.LanguageCode == languageCode && |
||||
|
x.Version == version, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,30 +0,0 @@ |
|||||
using System; |
|
||||
using Newtonsoft.Json; |
|
||||
|
|
||||
namespace Volo.Docs.Documents |
|
||||
{ |
|
||||
public class NavigationWithDetailsDto : DocumentWithDetailsDto |
|
||||
{ |
|
||||
[JsonProperty("items")] |
|
||||
public NavigationNode RootNode { get; set; } |
|
||||
|
|
||||
public void ConvertItems() |
|
||||
{ |
|
||||
if (Content.IsNullOrEmpty()) |
|
||||
{ |
|
||||
RootNode = new NavigationNode(); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
RootNode = JsonConvert.DeserializeObject<NavigationNode>(Content); |
|
||||
} |
|
||||
catch (JsonException ex) |
|
||||
{ |
|
||||
//todo: should log the exception?
|
|
||||
RootNode = new NavigationNode(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,53 @@ |
|||||
|
@using Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent |
||||
|
@model DocumentNotFoundPageModel |
||||
|
@{ |
||||
|
} |
||||
|
<div class="row position-relative vh-100" style="background: #e8e8e8;"> |
||||
|
<div class="center"> |
||||
|
<span class="notfound-404">404</span> |
||||
|
<h1> |
||||
|
<strong>"@Model.DocumentName"</strong> not found in <strong>@Model.ProjectName</strong> documents, with <strong>@Model.Version</strong> version and <strong>@Model.LanguageCode</strong> language. |
||||
|
</h1> |
||||
|
<br /> |
||||
|
<a href="@(Model.DocumentsUrlPrefix + Model.LanguageCode + "/" +Model.ProjectName + "/" + Model.Version)" class="btn btn-primary px-4"> |
||||
|
Go Back |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<style> |
||||
|
h1 { |
||||
|
font-size: 1.75em; |
||||
|
line-height: 1.75; |
||||
|
color: #777; |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
|
||||
|
h1 strong { |
||||
|
color: #222; |
||||
|
} |
||||
|
|
||||
|
.center { |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
top: 50%; |
||||
|
-webkit-transform: translate(-50%, -50%); |
||||
|
-ms-transform: translate(-50%, -50%); |
||||
|
transform: translate(-50%, -50%); |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.notfound-404 { |
||||
|
font-size: 300px; |
||||
|
font-weight: 700; |
||||
|
line-height: 1.25; |
||||
|
margin: 0px; |
||||
|
color: #fff; |
||||
|
text-transform: uppercase; |
||||
|
display: block; |
||||
|
margin-bottom: -150px; |
||||
|
z-index: -1; |
||||
|
position: relative; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,15 @@ |
|||||
|
namespace Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent |
||||
|
{ |
||||
|
public class DocumentNotFoundPageModel |
||||
|
{ |
||||
|
public string ProjectName { get; set; } |
||||
|
|
||||
|
public string LanguageCode { get; set; } |
||||
|
|
||||
|
public string Version { get; set; } |
||||
|
|
||||
|
public string DocumentName { get; set; } |
||||
|
|
||||
|
public string DocumentsUrlPrefix { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
|
||||
|
namespace Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent |
||||
|
{ |
||||
|
public class DocumentNotFoundViewComponent : AbpViewComponent |
||||
|
{ |
||||
|
private readonly DocsUiOptions _options; |
||||
|
|
||||
|
public DocumentNotFoundViewComponent(IOptions<DocsUiOptions> options) |
||||
|
{ |
||||
|
_options = options.Value; |
||||
|
} |
||||
|
public IViewComponentResult Invoke(DocumentNotFoundPageModel model, string defaultErrorMessageKey) |
||||
|
{ |
||||
|
model.DocumentsUrlPrefix = _options.RoutePrefix; |
||||
|
|
||||
|
return View("~/Pages/Documents/Shared/DocumentNotFoundComponent/Default.cshtml", model); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Volo.Docs.Admin.Documents; |
||||
|
using Volo.Docs.Documents; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Docs |
||||
|
{ |
||||
|
public class DocumentAdminAppService_Tests : DocsAdminApplicationTestBase |
||||
|
{ |
||||
|
private readonly IDocumentAdminAppService _documentAdminAppService; |
||||
|
private readonly IDocumentRepository _documentRepository; |
||||
|
private readonly DocsTestData _testData; |
||||
|
|
||||
|
public DocumentAdminAppService_Tests() |
||||
|
{ |
||||
|
_documentAdminAppService = GetRequiredService<IDocumentAdminAppService>(); |
||||
|
_documentRepository = GetRequiredService<IDocumentRepository>(); |
||||
|
_testData = GetRequiredService<DocsTestData>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task PullAsync() |
||||
|
{ |
||||
|
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-I.md", "en", "1.0.0")).ShouldBeNull(); |
||||
|
|
||||
|
await _documentAdminAppService.PullAsync(new PullDocumentInput |
||||
|
{ |
||||
|
ProjectId = _testData.PorjectId, |
||||
|
Name = "Part-I.md", |
||||
|
LanguageCode = "en", |
||||
|
Version = "1.0.0" |
||||
|
}); |
||||
|
|
||||
|
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-I.md", "en", "1.0.0")).ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task PullAllAsync() |
||||
|
{ |
||||
|
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-I.md", "en", "1.0.0")).ShouldBeNull(); |
||||
|
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-II.md", "en", "1.0.0")).ShouldBeNull(); |
||||
|
|
||||
|
await _documentAdminAppService.PullAllAsync(new PullAllDocumentInput |
||||
|
{ |
||||
|
ProjectId = _testData.PorjectId, |
||||
|
LanguageCode = "en", |
||||
|
Version = "1.0.0" |
||||
|
}); |
||||
|
|
||||
|
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-I.md", "en", "1.0.0")).ShouldNotBeNull(); |
||||
|
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-II.md", "en", "1.0.0")).ShouldNotBeNull(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using Shouldly; |
||||
|
using Volo.Docs.Documents; |
||||
|
using Volo.Docs.FileSystem.Documents; |
||||
|
using Volo.Docs.GitHub.Documents; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Docs |
||||
|
{ |
||||
|
public class DocumentSourceFactory_Tests : DocsDomainTestBase |
||||
|
{ |
||||
|
private readonly IDocumentSourceFactory _documentSourceFactory; |
||||
|
|
||||
|
public DocumentSourceFactory_Tests() |
||||
|
{ |
||||
|
_documentSourceFactory = GetRequiredService<IDocumentSourceFactory>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Create() |
||||
|
{ |
||||
|
_documentSourceFactory.Create(GithubDocumentSource.Type).GetType().ShouldBe(typeof(GithubDocumentSource)); |
||||
|
_documentSourceFactory.Create(FileSystemDocumentSource.Type).GetType().ShouldBe(typeof(FileSystemDocumentSource)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,25 +0,0 @@ |
|||||
using Shouldly; |
|
||||
using Volo.Docs.Documents; |
|
||||
using Volo.Docs.FileSystem.Documents; |
|
||||
using Volo.Docs.GitHub.Documents; |
|
||||
using Xunit; |
|
||||
|
|
||||
namespace Volo.Docs |
|
||||
{ |
|
||||
public class DocumentStoreFactory_Tests : DocsDomainTestBase |
|
||||
{ |
|
||||
private readonly IDocumentStoreFactory _documentStoreFactory; |
|
||||
|
|
||||
public DocumentStoreFactory_Tests() |
|
||||
{ |
|
||||
_documentStoreFactory = GetRequiredService<IDocumentStoreFactory>(); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Create() |
|
||||
{ |
|
||||
_documentStoreFactory.Create(GithubDocumentStore.Type).GetType().ShouldBe(typeof(GithubDocumentStore)); |
|
||||
_documentStoreFactory.Create(FileSystemDocumentStore.Type).GetType().ShouldBe(typeof(FileSystemDocumentStore)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,6 @@ |
|||||
|
namespace Volo.Docs.EntityFrameworkCore |
||||
|
{ |
||||
|
public class DocumentRepository_Tests : DocumentRepository_Tests<DocsEntityFrameworkCoreTestModule> |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using Volo.Docs.MongoDB; |
||||
|
|
||||
|
namespace Volo.Docs.Document |
||||
|
{ |
||||
|
public class DocumentRepository_Tests : DocumentRepository_Tests<DocsMongoDBTestModule> |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Docs.Documents; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Docs |
||||
|
{ |
||||
|
public abstract class DocumentRepository_Tests<TStartupModule> : DocsTestBase<TStartupModule> |
||||
|
where TStartupModule : IAbpModule |
||||
|
{ |
||||
|
protected readonly IDocumentRepository DocumentRepository; |
||||
|
protected readonly DocsTestData DocsTestData; |
||||
|
|
||||
|
protected DocumentRepository_Tests() |
||||
|
{ |
||||
|
DocumentRepository = GetRequiredService<IDocumentRepository>(); |
||||
|
DocsTestData = GetRequiredService<DocsTestData>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task FindAsync() |
||||
|
{ |
||||
|
var document = await DocumentRepository.FindAsync(DocsTestData.PorjectId, "CLI.md", "en", "2.0.0"); |
||||
|
document.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task DeleteAsync() |
||||
|
{ |
||||
|
(await DocumentRepository.GetListAsync()).ShouldNotBeEmpty(); |
||||
|
|
||||
|
await DocumentRepository.DeleteAsync(DocsTestData.PorjectId, "CLI.md", "en", "2.0.0"); |
||||
|
|
||||
|
(await DocumentRepository.GetListAsync()).ShouldBeEmpty(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue