调整项目

This commit is contained in:
movingsam 2026-02-21 15:05:37 +08:00
parent c1f1e09796
commit b97c2038a6
14 changed files with 1694 additions and 180 deletions

View File

@ -5,7 +5,7 @@ namespace Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
public class ApplicationRole : IdentityRole<long>
{
public string? Description { get; set; }
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
public DateTimeOffset CreatedTime { get; set; } = DateTimeOffset.UtcNow;
public long? TenantId { get; set; }
public bool IsSystem { get; set; }
public string? DisplayName { get; set; }

View File

@ -1,19 +1,24 @@
namespace Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
/// <summary>
///
/// 租户信息
/// </summary>
/// <param name="TenantId"></param>
/// <param name="TenantCode"></param>
/// <param name="TenantName"></param>
public record TenantInfo(long TenantId, string TenantCode, string TenantName)
public record TenantInfo(long? TenantId, string? TenantCode, string? TenantName)
{
/// <summary>
///
/// 租户信息
/// </summary>
/// <param name="tenant"></param>
public TenantInfo(Tenant tenant)
: this(tenant.Id, tenant.TenantCode, tenant.Name)
public TenantInfo(Tenant? tenant)
: this(tenant?.Id, tenant?.TenantCode, tenant?.Name)
{
}
/// <summary>
/// 无租户,系统级
/// </summary>
public static TenantInfo Admin => new TenantInfo(null, null, null);
}

View File

@ -5,10 +5,9 @@ namespace Fengling.Platform.Domain.AggregatesModel.UserAggregate;
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 string RealName { get; set; }
public TenantInfo? TenantInfo { get; set; }
public DateTimeOffset CreatedTime { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? UpdatedTime { get; set; }
public bool IsDeleted { get; set; }
}
}

View File

@ -4,7 +4,7 @@ using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
public interface ITenantStore
{
Task<Tenant?> FindByIdAsync(long tenantId, CancellationToken cancellationToken = default);
Task<Tenant?> FindByIdAsync(long? tenantId, CancellationToken cancellationToken = default);
Task<Tenant?> FindByTenantCodeAsync(string tenantCode, CancellationToken cancellationToken = default);
Task<IList<Tenant>> GetAllAsync(CancellationToken cancellationToken = default);
Task<IList<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null, string? tenantCode = null, TenantStatus? status = null, CancellationToken cancellationToken = default);

View File

@ -1,95 +0,0 @@
// <auto-generated />
using System;
using Fengling.Platform.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Fengling.Platform.Infrastructure.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20260218145512_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.TenantAggregate.Tenant", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<string>("ContactEmail")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<string>("ContactName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("ContactPhone")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<bool>("Deleted")
.HasColumnType("boolean");
b.Property<string>("Description")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<DateTime?>("ExpiresAt")
.HasColumnType("timestamp with time zone");
b.Property<int?>("MaxUsers")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<int>("RowVersion")
.IsConcurrencyToken()
.HasColumnType("integer");
b.Property<int>("Status")
.HasColumnType("integer");
b.Property<string>("TenantCode")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("Status");
b.HasIndex("TenantCode")
.IsUnique();
b.ToTable("Platform_Tenants", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,57 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Fengling.Platform.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Platform_Tenants",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false),
TenantCode = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
ContactName = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
ContactEmail = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
ContactPhone = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
MaxUsers = table.Column<int>(type: "integer", nullable: true),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
ExpiresAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
Description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
Status = table.Column<int>(type: "integer", nullable: false),
Deleted = table.Column<bool>(type: "boolean", nullable: false),
RowVersion = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Platform_Tenants", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Platform_Tenants_Status",
table: "Platform_Tenants",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_Platform_Tenants_TenantCode",
table: "Platform_Tenants",
column: "TenantCode",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Platform_Tenants");
}
}
}

View File

@ -0,0 +1,565 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using Fengling.Platform.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Fengling.Platform.Infrastructure.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20260221065049_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.RoleAggregate.ApplicationRole", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<DateTimeOffset>("CreatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("DisplayName")
.HasColumnType("text");
b.Property<bool>("IsSystem")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.PrimitiveCollection<List<string>>("Permissions")
.HasColumnType("text[]");
b.Property<long?>("TenantId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.TenantAggregate.Tenant", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("ContactEmail")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<string>("ContactName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("ContactPhone")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<DateTime?>("ExpiresAt")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<int?>("MaxUsers")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<long>("RowVersion")
.HasColumnType("bigint");
b.Property<int>("Status")
.HasColumnType("integer");
b.Property<string>("TenantCode")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("Status");
b.HasIndex("TenantCode")
.IsUnique();
b.ToTable("Platform_Tenants", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.AccessLog", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Action")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("Duration")
.HasColumnType("integer");
b.Property<string>("ErrorMessage")
.HasColumnType("text");
b.Property<string>("IpAddress")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Method")
.HasMaxLength(10)
.HasColumnType("character varying(10)");
b.Property<string>("RequestData")
.HasColumnType("text");
b.Property<string>("Resource")
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("ResponseData")
.HasColumnType("text");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("TenantId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("UserAgent")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("UserName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.HasIndex("Action");
b.HasIndex("CreatedAt");
b.HasIndex("Status");
b.HasIndex("TenantId");
b.HasIndex("UserName");
b.ToTable("AccessLogs");
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<int>("AccessFailedCount")
.HasColumnType("integer");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<DateTimeOffset>("CreatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("boolean");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<bool>("LockoutEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("timestamp with time zone");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("boolean");
b.Property<string>("RealName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("SecurityStamp")
.HasColumnType("text");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("UpdatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.HasIndex("PhoneNumber")
.IsUnique();
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.AuditLog", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Action")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("ErrorMessage")
.HasColumnType("text");
b.Property<string>("IpAddress")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("NewValue")
.HasColumnType("text");
b.Property<string>("OldValue")
.HasColumnType("text");
b.Property<string>("Operation")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("Operator")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<long?>("TargetId")
.HasColumnType("bigint");
b.Property<string>("TargetName")
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<string>("TargetType")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("TenantId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.HasIndex("Action");
b.HasIndex("CreatedAt");
b.HasIndex("Operation");
b.HasIndex("Operator");
b.HasIndex("TenantId");
b.ToTable("AuditLogs");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<long>("RoleId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("ProviderKey")
.HasColumnType("text");
b.Property<string>("ProviderDisplayName")
.HasColumnType("text");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
{
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<long>("RoleId")
.HasColumnType("bigint");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
{
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Value")
.HasColumnType("text");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", b =>
{
b.OwnsOne("Fengling.Platform.Domain.AggregatesModel.TenantAggregate.TenantInfo", "TenantInfo", b1 =>
{
b1.Property<long>("ApplicationUserId")
.HasColumnType("bigint");
b1.Property<string>("TenantCode")
.HasColumnType("text")
.HasColumnName("TenantCode");
b1.Property<long?>("TenantId")
.HasColumnType("bigint")
.HasColumnName("TenantId");
b1.Property<string>("TenantName")
.HasColumnType("text")
.HasColumnName("TenantName");
b1.HasKey("ApplicationUserId");
b1.ToTable("AspNetUsers");
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.Navigation("TenantInfo");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.RoleAggregate.ApplicationRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.RoleAggregate.ApplicationRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,391 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Fengling.Platform.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AccessLogs",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserName = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
TenantId = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
Action = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Resource = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
Method = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: true),
IpAddress = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
UserAgent = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Duration = table.Column<int>(type: "integer", nullable: false),
RequestData = table.Column<string>(type: "text", nullable: true),
ResponseData = table.Column<string>(type: "text", nullable: true),
ErrorMessage = table.Column<string>(type: "text", nullable: true),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AccessLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Description = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
CreatedTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
TenantId = table.Column<long>(type: "bigint", nullable: true),
IsSystem = table.Column<bool>(type: "boolean", nullable: false),
DisplayName = table.Column<string>(type: "text", nullable: true),
Permissions = table.Column<List<string>>(type: "text[]", nullable: true),
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RealName = table.Column<string>(type: "text", nullable: false),
TenantId = table.Column<long>(type: "bigint", nullable: true),
TenantCode = table.Column<string>(type: "text", nullable: true),
TenantName = table.Column<string>(type: "text", nullable: true),
CreatedTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
UpdatedTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false),
UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
PasswordHash = table.Column<string>(type: "text", nullable: true),
SecurityStamp = table.Column<string>(type: "text", nullable: true),
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
PhoneNumber = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
AccessFailedCount = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AuditLogs",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Operator = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
TenantId = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
Operation = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Action = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
TargetType = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
TargetId = table.Column<long>(type: "bigint", nullable: true),
TargetName = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
IpAddress = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
OldValue = table.Column<string>(type: "text", nullable: true),
NewValue = table.Column<string>(type: "text", nullable: true),
ErrorMessage = table.Column<string>(type: "text", nullable: true),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AuditLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Platform_Tenants",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
TenantCode = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
ContactName = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
ContactEmail = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
ContactPhone = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
MaxUsers = table.Column<int>(type: "integer", nullable: true),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
ExpiresAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
Description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
Status = table.Column<int>(type: "integer", nullable: false),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false),
RowVersion = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Platform_Tenants", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoleId = table.Column<long>(type: "bigint", nullable: false),
ClaimType = table.Column<string>(type: "text", nullable: true),
ClaimValue = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserId = table.Column<long>(type: "bigint", nullable: false),
ClaimType = table.Column<string>(type: "text", nullable: true),
ClaimValue = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(type: "text", nullable: false),
ProviderKey = table.Column<string>(type: "text", nullable: false),
ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
UserId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<long>(type: "bigint", nullable: false),
RoleId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<long>(type: "bigint", nullable: false),
LoginProvider = table.Column<string>(type: "text", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
Value = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AccessLogs_Action",
table: "AccessLogs",
column: "Action");
migrationBuilder.CreateIndex(
name: "IX_AccessLogs_CreatedAt",
table: "AccessLogs",
column: "CreatedAt");
migrationBuilder.CreateIndex(
name: "IX_AccessLogs_Status",
table: "AccessLogs",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_AccessLogs_TenantId",
table: "AccessLogs",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_AccessLogs_UserName",
table: "AccessLogs",
column: "UserName");
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "IX_AspNetUsers_PhoneNumber",
table: "AspNetUsers",
column: "PhoneNumber",
unique: true);
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AuditLogs_Action",
table: "AuditLogs",
column: "Action");
migrationBuilder.CreateIndex(
name: "IX_AuditLogs_CreatedAt",
table: "AuditLogs",
column: "CreatedAt");
migrationBuilder.CreateIndex(
name: "IX_AuditLogs_Operation",
table: "AuditLogs",
column: "Operation");
migrationBuilder.CreateIndex(
name: "IX_AuditLogs_Operator",
table: "AuditLogs",
column: "Operator");
migrationBuilder.CreateIndex(
name: "IX_AuditLogs_TenantId",
table: "AuditLogs",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_Platform_Tenants_Status",
table: "Platform_Tenants",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_Platform_Tenants_TenantCode",
table: "Platform_Tenants",
column: "TenantCode",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AccessLogs");
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "AuditLogs");
migrationBuilder.DropTable(
name: "Platform_Tenants");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

View File

@ -1,5 +1,6 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using Fengling.Platform.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -22,11 +23,62 @@ namespace Fengling.Platform.Infrastructure.Migrations
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.RoleAggregate.ApplicationRole", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<DateTimeOffset>("CreatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("DisplayName")
.HasColumnType("text");
b.Property<bool>("IsSystem")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.PrimitiveCollection<List<string>>("Permissions")
.HasColumnType("text[]");
b.Property<long?>("TenantId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.TenantAggregate.Tenant", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("ContactEmail")
.IsRequired()
.HasMaxLength(100)
@ -44,9 +96,6 @@ namespace Fengling.Platform.Infrastructure.Migrations
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<bool>("Deleted")
.HasColumnType("boolean");
b.Property<string>("Description")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
@ -54,6 +103,9 @@ namespace Fengling.Platform.Infrastructure.Migrations
b.Property<DateTime?>("ExpiresAt")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<int?>("MaxUsers")
.HasColumnType("integer");
@ -62,9 +114,8 @@ namespace Fengling.Platform.Infrastructure.Migrations
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<int>("RowVersion")
.IsConcurrencyToken()
.HasColumnType("integer");
b.Property<long>("RowVersion")
.HasColumnType("bigint");
b.Property<int>("Status")
.HasColumnType("integer");
@ -86,6 +137,425 @@ namespace Fengling.Platform.Infrastructure.Migrations
b.ToTable("Platform_Tenants", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.AccessLog", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Action")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("Duration")
.HasColumnType("integer");
b.Property<string>("ErrorMessage")
.HasColumnType("text");
b.Property<string>("IpAddress")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Method")
.HasMaxLength(10)
.HasColumnType("character varying(10)");
b.Property<string>("RequestData")
.HasColumnType("text");
b.Property<string>("Resource")
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("ResponseData")
.HasColumnType("text");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("TenantId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("UserAgent")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("UserName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.HasIndex("Action");
b.HasIndex("CreatedAt");
b.HasIndex("Status");
b.HasIndex("TenantId");
b.HasIndex("UserName");
b.ToTable("AccessLogs");
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<int>("AccessFailedCount")
.HasColumnType("integer");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<DateTimeOffset>("CreatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("boolean");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<bool>("LockoutEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("timestamp with time zone");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("boolean");
b.Property<string>("RealName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("SecurityStamp")
.HasColumnType("text");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("UpdatedTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.HasIndex("PhoneNumber")
.IsUnique();
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.AuditLog", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Action")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("ErrorMessage")
.HasColumnType("text");
b.Property<string>("IpAddress")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("NewValue")
.HasColumnType("text");
b.Property<string>("OldValue")
.HasColumnType("text");
b.Property<string>("Operation")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("Operator")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<long?>("TargetId")
.HasColumnType("bigint");
b.Property<string>("TargetName")
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<string>("TargetType")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("TenantId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.HasIndex("Action");
b.HasIndex("CreatedAt");
b.HasIndex("Operation");
b.HasIndex("Operator");
b.HasIndex("TenantId");
b.ToTable("AuditLogs");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<long>("RoleId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("ProviderKey")
.HasColumnType("text");
b.Property<string>("ProviderDisplayName")
.HasColumnType("text");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
{
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<long>("RoleId")
.HasColumnType("bigint");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
{
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Value")
.HasColumnType("text");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", b =>
{
b.OwnsOne("Fengling.Platform.Domain.AggregatesModel.TenantAggregate.TenantInfo", "TenantInfo", b1 =>
{
b1.Property<long>("ApplicationUserId")
.HasColumnType("bigint");
b1.Property<string>("TenantCode")
.HasColumnType("text")
.HasColumnName("TenantCode");
b1.Property<long?>("TenantId")
.HasColumnType("bigint")
.HasColumnName("TenantId");
b1.Property<string>("TenantName")
.HasColumnType("text")
.HasColumnName("TenantName");
b1.HasKey("ApplicationUserId");
b1.ToTable("AspNetUsers");
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.Navigation("TenantInfo");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.RoleAggregate.ApplicationRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.RoleAggregate.ApplicationRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
{
b.HasOne("Fengling.Platform.Domain.AggregatesModel.UserAggregate.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}

View File

@ -0,0 +1,191 @@
CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (
"MigrationId" character varying(150) NOT NULL,
"ProductVersion" character varying(32) NOT NULL,
CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId")
);
START TRANSACTION;
CREATE TABLE "AccessLogs" (
"Id" bigint GENERATED BY DEFAULT AS IDENTITY,
"UserName" character varying(50),
"TenantId" character varying(50),
"Action" character varying(20) NOT NULL,
"Resource" character varying(200),
"Method" character varying(10),
"IpAddress" character varying(50),
"UserAgent" character varying(500),
"Status" character varying(20) NOT NULL,
"Duration" integer NOT NULL,
"RequestData" text,
"ResponseData" text,
"ErrorMessage" text,
"CreatedAt" timestamp with time zone NOT NULL,
CONSTRAINT "PK_AccessLogs" PRIMARY KEY ("Id")
);
CREATE TABLE "AspNetRoles" (
"Id" bigint GENERATED BY DEFAULT AS IDENTITY,
"Description" character varying(200),
"CreatedTime" timestamp with time zone NOT NULL,
"TenantId" bigint,
"IsSystem" boolean NOT NULL,
"DisplayName" text,
"Permissions" text[],
"Name" character varying(256),
"NormalizedName" character varying(256),
"ConcurrencyStamp" text,
CONSTRAINT "PK_AspNetRoles" PRIMARY KEY ("Id")
);
CREATE TABLE "AspNetUsers" (
"Id" bigint GENERATED BY DEFAULT AS IDENTITY,
"RealName" text NOT NULL,
"TenantId" bigint,
"TenantCode" text,
"TenantName" text,
"CreatedTime" timestamp with time zone NOT NULL,
"UpdatedTime" timestamp with time zone,
"IsDeleted" boolean NOT NULL,
"UserName" character varying(256),
"NormalizedUserName" character varying(256),
"Email" character varying(256),
"NormalizedEmail" character varying(256),
"EmailConfirmed" boolean NOT NULL,
"PasswordHash" text,
"SecurityStamp" text,
"ConcurrencyStamp" text,
"PhoneNumber" character varying(20),
"PhoneNumberConfirmed" boolean NOT NULL,
"TwoFactorEnabled" boolean NOT NULL,
"LockoutEnd" timestamp with time zone,
"LockoutEnabled" boolean NOT NULL,
"AccessFailedCount" integer NOT NULL,
CONSTRAINT "PK_AspNetUsers" PRIMARY KEY ("Id")
);
CREATE TABLE "AuditLogs" (
"Id" bigint GENERATED BY DEFAULT AS IDENTITY,
"Operator" character varying(50) NOT NULL,
"TenantId" character varying(50),
"Operation" character varying(20) NOT NULL,
"Action" character varying(20) NOT NULL,
"TargetType" character varying(50),
"TargetId" bigint,
"TargetName" character varying(100),
"IpAddress" character varying(50) NOT NULL,
"Description" character varying(500),
"OldValue" text,
"NewValue" text,
"ErrorMessage" text,
"Status" character varying(20) NOT NULL,
"CreatedAt" timestamp with time zone NOT NULL,
CONSTRAINT "PK_AuditLogs" PRIMARY KEY ("Id")
);
CREATE TABLE "Platform_Tenants" (
"Id" bigint GENERATED BY DEFAULT AS IDENTITY,
"TenantCode" character varying(50) NOT NULL,
"Name" character varying(100) NOT NULL,
"ContactName" character varying(50) NOT NULL,
"ContactEmail" character varying(100) NOT NULL,
"ContactPhone" character varying(20),
"MaxUsers" integer,
"CreatedAt" timestamp with time zone NOT NULL,
"UpdatedAt" timestamp with time zone,
"ExpiresAt" timestamp with time zone,
"Description" character varying(500),
"Status" integer NOT NULL,
"IsDeleted" boolean NOT NULL,
"RowVersion" bigint NOT NULL,
CONSTRAINT "PK_Platform_Tenants" PRIMARY KEY ("Id")
);
CREATE TABLE "AspNetRoleClaims" (
"Id" integer GENERATED BY DEFAULT AS IDENTITY,
"RoleId" bigint NOT NULL,
"ClaimType" text,
"ClaimValue" text,
CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY ("Id"),
CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE
);
CREATE TABLE "AspNetUserClaims" (
"Id" integer GENERATED BY DEFAULT AS IDENTITY,
"UserId" bigint NOT NULL,
"ClaimType" text,
"ClaimValue" text,
CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY ("Id"),
CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE
);
CREATE TABLE "AspNetUserLogins" (
"LoginProvider" text NOT NULL,
"ProviderKey" text NOT NULL,
"ProviderDisplayName" text,
"UserId" bigint NOT NULL,
CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey"),
CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE
);
CREATE TABLE "AspNetUserRoles" (
"UserId" bigint NOT NULL,
"RoleId" bigint NOT NULL,
CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId"),
CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE,
CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE
);
CREATE TABLE "AspNetUserTokens" (
"UserId" bigint NOT NULL,
"LoginProvider" text NOT NULL,
"Name" text NOT NULL,
"Value" text,
CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name"),
CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE
);
CREATE INDEX "IX_AccessLogs_Action" ON "AccessLogs" ("Action");
CREATE INDEX "IX_AccessLogs_CreatedAt" ON "AccessLogs" ("CreatedAt");
CREATE INDEX "IX_AccessLogs_Status" ON "AccessLogs" ("Status");
CREATE INDEX "IX_AccessLogs_TenantId" ON "AccessLogs" ("TenantId");
CREATE INDEX "IX_AccessLogs_UserName" ON "AccessLogs" ("UserName");
CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "AspNetRoleClaims" ("RoleId");
CREATE UNIQUE INDEX "RoleNameIndex" ON "AspNetRoles" ("NormalizedName");
CREATE INDEX "IX_AspNetUserClaims_UserId" ON "AspNetUserClaims" ("UserId");
CREATE INDEX "IX_AspNetUserLogins_UserId" ON "AspNetUserLogins" ("UserId");
CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "AspNetUserRoles" ("RoleId");
CREATE INDEX "EmailIndex" ON "AspNetUsers" ("NormalizedEmail");
CREATE UNIQUE INDEX "IX_AspNetUsers_PhoneNumber" ON "AspNetUsers" ("PhoneNumber");
CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName");
CREATE INDEX "IX_AuditLogs_Action" ON "AuditLogs" ("Action");
CREATE INDEX "IX_AuditLogs_CreatedAt" ON "AuditLogs" ("CreatedAt");
CREATE INDEX "IX_AuditLogs_Operation" ON "AuditLogs" ("Operation");
CREATE INDEX "IX_AuditLogs_Operator" ON "AuditLogs" ("Operator");
CREATE INDEX "IX_AuditLogs_TenantId" ON "AuditLogs" ("TenantId");
CREATE INDEX "IX_Platform_Tenants_Status" ON "Platform_Tenants" ("Status");
CREATE UNIQUE INDEX "IX_Platform_Tenants_TenantCode" ON "Platform_Tenants" ("TenantCode");
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20260221065049_Initial', '10.0.0');
COMMIT;

View File

@ -24,9 +24,8 @@ public partial class PlatformDbContext(DbContextOptions<PlatformDbContext> optio
modelBuilder.Entity<ApplicationUser>(entity =>
{
entity.Property(e => e.RealName).HasMaxLength(100);
entity.Property(e => e.Phone).HasMaxLength(20);
entity.HasIndex(e => e.Phone).IsUnique();
entity.Property(e => e.PhoneNumber).HasMaxLength(20);
entity.HasIndex(e => e.PhoneNumber).IsUnique();
entity.OwnsOne(e => e.TenantInfo, navigationBuilder =>
{

View File

@ -1,15 +1,24 @@
using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
using Fengling.Platform.Domain.AggregatesModel.TenantAggregate;
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
namespace Fengling.Platform.Infrastructure;
public static class SeedData
{
public static async Task<Tenant> InitializeAsync(this PlatformDbContext context)
public static async Task<Tenant> InitializeAsync(this IServiceScope scope)
{
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<ApplicationRole>>();
var context= scope.ServiceProvider.GetRequiredService<PlatformDbContext>();
await context.Database.EnsureCreatedAsync();
var adminTenant = context.Tenants
.FirstOrDefault(t => t.Name == "Administrator");
.FirstOrDefault(t => t.TenantCode == "Administrator");
if (adminTenant != null)
{
return adminTenant;
@ -17,7 +26,7 @@ public static class SeedData
adminTenant = new Tenant
{
TenantCode = "admin",
TenantCode = "Administrator",
Name = "超级系统",
ContactName = "",
ContactEmail = "",
@ -25,6 +34,42 @@ public static class SeedData
CreatedAt = DateTime.UtcNow
};
await context.Tenants.AddAsync(adminTenant);
var role = await roleManager.Roles
.OfType<ApplicationRole>()
.AsQueryable()
.FirstOrDefaultAsync(x=>x.Name == "admin" && x.TenantId ==null);
if (role == null)
{
role = new ApplicationRole()
{
CreatedTime = DateTimeOffset.UtcNow,
TenantId = null,
Name = "admin", Description = "系统管理员",
DisplayName = "系统管理员",
IsSystem = true,
};
await roleManager.CreateAsync(role);
}
var user = await userManager.FindByNameAsync("admin");
if (user != null)
{
user = new ApplicationUser()
{
UserName = "admin",
RealName = "系统超级管理员",
Email = "samsu9194@163.com",
TenantInfo = new TenantInfo(adminTenant),
PhoneNumber = "15921072307"
};
await userManager.AddToRoleAsync(user, "admin");
await userManager.CreateAsync(user, "admin");
}
await context.SaveChangesAsync();
return adminTenant;
}

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
public interface ITenantManager
{
Task<Tenant?> FindByIdAsync(long tenantId, CancellationToken cancellationToken = default);
Task<Tenant?> FindByIdAsync(long? tenantId, CancellationToken cancellationToken = default);
Task<Tenant?> FindByTenantCodeAsync(string tenantCode, CancellationToken cancellationToken = default);
Task<IList<Tenant>> GetAllAsync(CancellationToken cancellationToken = default);
Task<IList<Tenant>> GetPagedAsync(int page, int pageSize, string? name = null, string? tenantCode = null, TenantStatus? status = null, CancellationToken cancellationToken = default);
@ -19,7 +19,7 @@ public interface ITenantManager
public sealed class TenantManager(ITenantStore store) : ITenantManager
{
public async Task<Tenant?> FindByIdAsync(long tenantId, CancellationToken cancellationToken = default)
public async Task<Tenant?> FindByIdAsync(long? tenantId, CancellationToken cancellationToken = default)
{
return await store.FindByIdAsync(tenantId, cancellationToken);
}

View File

@ -17,8 +17,9 @@ public class TenantStore : ITenantStore
public void Dispose() { }
public virtual Task<Tenant?> FindByIdAsync(long tenantId, CancellationToken cancellationToken = default)
public virtual Task<Tenant?> FindByIdAsync(long? tenantId, CancellationToken cancellationToken = default)
{
if (tenantId == null) return Task.FromResult<Tenant?>(null);
return _tenants.FirstOrDefaultAsync(t => t.Id == tenantId, cancellationToken);
}