From ed085089229844e8dc87c86f686a5abb6e40d243 Mon Sep 17 00:00:00 2001 From: root <295172551@qq.com> Date: Sun, 6 Jul 2025 01:48:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8D=8F=E8=AE=AE=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=A7=BB=E9=99=A4IsForceUpdate=EF=BC=8C=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0IsRunning=E7=8A=B6=E6=80=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CreateDevice/CreateDeviceCommand.cs | 5 + .../CreateDeviceCommandHandler.cs | 4 +- .../CreateDevice/CreateDeviceResponse.cs | 5 + .../UpdateDevice/UpdateDeviceCommand.cs | 5 + .../UpdateDeviceCommandHandler.cs | 4 +- .../UpdateDevice/UpdateDeviceResponse.cs | 5 + .../GetDeviceByIdQueryHandler.cs | 1 + .../GetDeviceById/GetDeviceByIdResponse.cs | 5 + .../GetDevices/GetDevicesQueryHandler.cs | 1 + .../CreateProtocolVersionCommand.cs | 5 +- .../CreateProtocolVersionCommandHandler.cs | 2 - .../CreateProtocolVersionResponse.cs | 5 +- .../UpdateProtocolVersionCommand.cs | 5 +- .../UpdateProtocolVersionCommandHandler.cs | 2 - .../UpdateProtocolVersionResponse.cs | 5 +- .../GetProtocolVersionByIdQueryHandler.cs | 1 - .../GetProtocolVersionByIdResponse.cs | 5 +- .../GetProtocolVersionsQueryHandler.cs | 1 - .../Entities/Device/CellularDevice.cs | 31 +- .../Entities/Device/ProtocolVersion.cs | 18 +- .../Device/CellularDeviceConfiguration.cs | 2 + .../Device/ProtocolVersionConfiguration.cs | 1 - ...0_InitProtocolVersionAndDevice.Designer.cs | 582 +++++++++++++++++ ...0705173130_InitProtocolVersionAndDevice.cs | 183 ++++++ ...otocolVersionAndCellularDevice.Designer.cs | 583 ++++++++++++++++++ ..._UpdateProtocolVersionAndCellularDevice.cs | 64 ++ .../Migrations/AppDbContextModelSnapshot.cs | 35 +- src/X1.WebAPI/Devices.http | 73 +++ src/X1.WebAPI/ProtocolVersions.http | 3 - 29 files changed, 1574 insertions(+), 67 deletions(-) create mode 100644 src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.Designer.cs create mode 100644 src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.cs create mode 100644 src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.Designer.cs create mode 100644 src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.cs create mode 100644 src/X1.WebAPI/Devices.http diff --git a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs index 85ee15d..13a049b 100644 --- a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs +++ b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs @@ -51,4 +51,9 @@ public class CreateDeviceCommand : IRequest public bool IsEnabled { get; set; } = true; + + /// + /// 设备状态(启动/未启动) + /// + public bool IsRunning { get; set; } = false; } \ No newline at end of file diff --git a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs index 9647bdd..04c85a5 100644 --- a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs +++ b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs @@ -51,7 +51,8 @@ public class CreateDeviceCommandHandler : IRequestHandler public bool IsEnabled { get; set; } + /// + /// 设备状态(启动/未启动) + /// + public bool IsRunning { get; set; } + /// /// 创建时间 /// diff --git a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs index a96e27c..9038836 100644 --- a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs +++ b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs @@ -57,4 +57,9 @@ public class UpdateDeviceCommand : IRequest public bool IsEnabled { get; set; } = true; + + /// + /// 设备状态(启动/未启动) + /// + public bool IsRunning { get; set; } = false; } \ No newline at end of file diff --git a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs index 02a610f..233e7e4 100644 --- a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs +++ b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs @@ -64,7 +64,8 @@ public class UpdateDeviceCommandHandler : IRequestHandler public bool IsEnabled { get; set; } + /// + /// 设备状态(启动/未启动) + /// + public bool IsRunning { get; set; } + /// /// 更新时间 /// diff --git a/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs b/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs index 643deb4..fb605a1 100644 --- a/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs +++ b/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs @@ -52,6 +52,7 @@ public class GetDeviceByIdQueryHandler : IRequestHandler public bool IsEnabled { get; set; } + /// + /// 设备状态(启动/未启动) + /// + public bool IsRunning { get; set; } + /// /// 创建时间 /// diff --git a/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs b/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs index 6412509..afdbb73 100644 --- a/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs +++ b/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs @@ -79,6 +79,7 @@ public class GetDevicesQueryHandler : IRequestHandler public DateTime? ReleaseDate { get; set; } - /// - /// 是否强制更新 - /// - public bool IsForceUpdate { get; set; } = false; + /// /// 最低支持版本 diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs b/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs index a941f68..1fa41ff 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs @@ -49,7 +49,6 @@ public class CreateProtocolVersionCommandHandler : IRequestHandler public DateTime? ReleaseDate { get; set; } - /// - /// 是否强制更新 - /// - public bool IsForceUpdate { get; set; } + /// /// 最低支持版本 diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs index 3b1fa47..78163d1 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs @@ -45,10 +45,7 @@ public class UpdateProtocolVersionCommand : IRequest public DateTime? ReleaseDate { get; set; } - /// - /// 是否强制更新 - /// - public bool IsForceUpdate { get; set; } = false; + /// /// 最低支持版本 diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs index e757303..0d610a3 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs @@ -60,7 +60,6 @@ public class UpdateProtocolVersionCommandHandler : IRequestHandler public DateTime? ReleaseDate { get; set; } - /// - /// 是否强制更新 - /// - public bool IsForceUpdate { get; set; } + /// /// 最低支持版本 diff --git a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs index 0f3a5a2..84ba21f 100644 --- a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs @@ -50,7 +50,6 @@ public class GetProtocolVersionByIdQueryHandler : IRequestHandler public DateTime? ReleaseDate { get; set; } - /// - /// 是否强制更新 - /// - public bool IsForceUpdate { get; set; } + /// /// 最低支持版本 diff --git a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs index 8f9f086..4af8074 100644 --- a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs @@ -84,7 +84,6 @@ public class GetProtocolVersionsQueryHandler : IRequestHandler public bool IsEnabled { get; private set; } = true; + /// + /// 设备状态(启动/未启动) + /// + public bool IsRunning { get; private set; } = false; + /// /// 创建设备 /// @@ -71,7 +76,8 @@ public class CellularDevice : AuditableEntity string protocolVersionId, int agentPort, string ipAddress, - bool isEnabled = true) + bool isEnabled = true, + bool isRunning = false) { var device = new CellularDevice { @@ -83,6 +89,7 @@ public class CellularDevice : AuditableEntity AgentPort = agentPort, IpAddress = ipAddress, IsEnabled = isEnabled, + IsRunning = isRunning, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; @@ -100,7 +107,8 @@ public class CellularDevice : AuditableEntity string protocolVersionId, int agentPort, string ipAddress, - bool isEnabled = true) + bool isEnabled = true, + bool isRunning = false) { Name = name; SerialNumber = serialNumber; @@ -109,6 +117,7 @@ public class CellularDevice : AuditableEntity AgentPort = agentPort; IpAddress = ipAddress; IsEnabled = isEnabled; + IsRunning = isRunning; UpdatedAt = DateTime.UtcNow; } @@ -129,4 +138,22 @@ public class CellularDevice : AuditableEntity IsEnabled = false; UpdatedAt = DateTime.UtcNow; } + + /// + /// 启动设备 + /// + public void Start() + { + IsRunning = true; + UpdatedAt = DateTime.UtcNow; + } + + /// + /// 停止设备 + /// + public void Stop() + { + IsRunning = false; + UpdatedAt = DateTime.UtcNow; + } } \ No newline at end of file diff --git a/src/X1.Domain/Entities/Device/ProtocolVersion.cs b/src/X1.Domain/Entities/Device/ProtocolVersion.cs index b627afa..feb8c65 100644 --- a/src/X1.Domain/Entities/Device/ProtocolVersion.cs +++ b/src/X1.Domain/Entities/Device/ProtocolVersion.cs @@ -40,10 +40,7 @@ public class ProtocolVersion : AuditableEntity /// public DateTime? ReleaseDate { get; private set; } - /// - /// 是否强制更新 - /// - public bool IsForceUpdate { get; private set; } + /// /// 最低支持版本 @@ -60,7 +57,6 @@ public class ProtocolVersion : AuditableEntity string? description = null, bool isEnabled = true, DateTime? releaseDate = null, - bool isForceUpdate = false, string? minimumSupportedVersion = null) { var protocolVersion = new ProtocolVersion @@ -71,7 +67,6 @@ public class ProtocolVersion : AuditableEntity Description = description, IsEnabled = isEnabled, ReleaseDate = releaseDate, - IsForceUpdate = isForceUpdate, MinimumSupportedVersion = minimumSupportedVersion, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow @@ -89,7 +84,6 @@ public class ProtocolVersion : AuditableEntity string? description = null, bool isEnabled = true, DateTime? releaseDate = null, - bool isForceUpdate = false, string? minimumSupportedVersion = null) { Name = name; @@ -97,7 +91,6 @@ public class ProtocolVersion : AuditableEntity Description = description; IsEnabled = isEnabled; ReleaseDate = releaseDate; - IsForceUpdate = isForceUpdate; MinimumSupportedVersion = minimumSupportedVersion; UpdatedAt = DateTime.UtcNow; } @@ -120,12 +113,5 @@ public class ProtocolVersion : AuditableEntity UpdatedAt = DateTime.UtcNow; } - /// - /// 设置强制更新 - /// - public void SetForceUpdate(bool isForceUpdate) - { - IsForceUpdate = isForceUpdate; - UpdatedAt = DateTime.UtcNow; - } + } \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs b/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs index 2faa370..b848cbe 100644 --- a/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs +++ b/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs @@ -22,7 +22,9 @@ public class CellularDeviceConfiguration : IEntityTypeConfiguration d.Description).HasMaxLength(500).HasComment("设备描述"); builder.Property(d => d.ProtocolVersionId).IsRequired().HasMaxLength(50).HasComment("协议版本ID"); builder.Property(d => d.AgentPort).IsRequired().HasComment("Agent端口"); + builder.Property(d => d.IpAddress).IsRequired().HasMaxLength(45).HasComment("IP地址"); builder.Property(d => d.IsEnabled).IsRequired().HasComment("是否启用"); + builder.Property(d => d.IsRunning).IsRequired().HasComment("设备状态(启动/未启动)"); builder.Property(d => d.CreatedAt).IsRequired().HasComment("创建时间"); builder.Property(d => d.UpdatedAt).IsRequired().HasComment("更新时间"); diff --git a/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs b/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs index b3afa3d..e0c86d9 100644 --- a/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs +++ b/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs @@ -21,7 +21,6 @@ public class ProtocolVersionConfiguration : IEntityTypeConfiguration v.Description).HasMaxLength(500).HasComment("版本描述"); builder.Property(v => v.IsEnabled).IsRequired().HasComment("是否启用"); builder.Property(v => v.ReleaseDate).HasComment("发布日期"); - builder.Property(v => v.IsForceUpdate).IsRequired().HasComment("是否强制更新"); builder.Property(v => v.MinimumSupportedVersion).HasMaxLength(20).HasComment("最低支持版本"); builder.Property(v => v.CreatedAt).IsRequired().HasComment("创建时间"); builder.Property(v => v.UpdatedAt).IsRequired().HasComment("更新时间"); diff --git a/src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.Designer.cs b/src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.Designer.cs new file mode 100644 index 0000000..bd0f114 --- /dev/null +++ b/src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.Designer.cs @@ -0,0 +1,582 @@ +// +using System; +using CellularManagement.Infrastructure.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace X1.Infrastructure.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250705173130_InitProtocolVersionAndDevice")] + partial class InitProtocolVersionAndDevice + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("CellularManagement.Domain.Entities.AppRole", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("角色ID,主键"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasComment("并发控制戳"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("角色描述"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("角色名称"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("标准化角色名称(大写)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("IX_Roles_Name"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("Roles", null, t => + { + t.HasComment("角色表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.AppUser", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("用户ID,主键"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasComment("登录失败次数"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasComment("并发控制戳"); + + b.Property("CreatedTime") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("电子邮箱"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasComment("邮箱是否已验证"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasComment("用户状态(true: 启用, false: 禁用)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已删除"); + + b.Property("LastLoginTime") + .HasColumnType("timestamp with time zone") + .HasComment("最后登录时间"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasComment("是否启用账户锁定"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasComment("账户锁定结束时间"); + + b.Property("ModifiedTime") + .HasColumnType("timestamp with time zone") + .HasComment("修改时间"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("标准化电子邮箱(大写)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("标准化账号(大写)"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasComment("密码哈希值"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("text") + .HasComment("电话号码"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasComment("电话号码是否已验证"); + + b.Property("RealName") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("用户名"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasComment("安全戳,用于并发控制"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasComment("是否启用双因素认证"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("账号"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("IX_Users_Email"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.HasIndex("PhoneNumber") + .IsUnique() + .HasDatabaseName("IX_Users_PhoneNumber"); + + b.HasIndex("UserName") + .IsUnique() + .HasDatabaseName("IX_Users_UserName"); + + b.ToTable("Users", null, t => + { + t.HasComment("用户表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Device.CellularDevice", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("设备ID"); + + b.Property("AgentPort") + .HasColumnType("integer") + .HasComment("Agent端口"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("设备描述"); + + b.Property("IpAddress") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("character varying(45)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean") + .HasComment("是否启用"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("设备名称"); + + b.Property("ProtocolVersionId") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("协议版本ID"); + + b.Property("SerialNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("序列号"); + + b.Property("UpdatedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ProtocolVersionId") + .HasDatabaseName("IX_CellularDevices_ProtocolVersionId"); + + b.HasIndex("SerialNumber") + .IsUnique() + .HasDatabaseName("IX_CellularDevices_SerialNumber"); + + b.ToTable("CellularDevices", null, t => + { + t.HasComment("蜂窝设备表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Device.ProtocolVersion", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("版本ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("版本描述"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean") + .HasComment("是否启用"); + + b.Property("IsForceUpdate") + .HasColumnType("boolean") + .HasComment("是否强制更新"); + + b.Property("MinimumSupportedVersion") + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasComment("最低支持版本"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("版本名称"); + + b.Property("ReleaseDate") + .HasColumnType("timestamp with time zone") + .HasComment("发布日期"); + + b.Property("UpdatedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .HasColumnType("text"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasComment("版本号"); + + b.HasKey("Id"); + + b.HasIndex("Version") + .IsUnique() + .HasDatabaseName("IX_ProtocolVersions_Version"); + + b.ToTable("ProtocolVersions", null, t => + { + t.HasComment("协议版本表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Logging.LoginLog", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("日志ID"); + + b.Property("Browser") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("浏览器信息"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FailureReason") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("失败原因"); + + b.Property("IpAddress") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("登录IP"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsSuccess") + .HasColumnType("boolean") + .HasComment("登录状态(成功/失败)"); + + b.Property("Location") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("登录位置"); + + b.Property("LoginSource") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("LoginTime") + .HasColumnType("timestamp with time zone") + .HasComment("登录时间"); + + b.Property("LoginType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("OperatingSystem") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("操作系统信息"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserAgent") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("设备信息"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("character varying(450)") + .HasComment("用户ID"); + + b.HasKey("Id"); + + b.HasIndex("IpAddress") + .HasDatabaseName("IX_LoginLogs_IpAddress"); + + b.HasIndex("LoginTime") + .HasDatabaseName("IX_LoginLogs_LoginTime"); + + b.HasIndex("UserId") + .HasDatabaseName("IX_LoginLogs_UserId"); + + b.HasIndex("UserId", "LoginTime") + .HasDatabaseName("IX_LoginLogs_UserId_LoginTime"); + + b.ToTable("LoginLogs", null, t => + { + t.HasComment("用户登录日志表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Permission", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Permissions", (string)null); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.RolePermission", b => + { + b.Property("RoleId") + .HasColumnType("text"); + + b.Property("PermissionId") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("RoleId", "PermissionId"); + + b.HasIndex("PermissionId"); + + b.ToTable("RolePermissions", (string)null); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.UserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", null, t => + { + t.HasComment("用户角色关系表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Device.CellularDevice", b => + { + b.HasOne("CellularManagement.Domain.Entities.Device.ProtocolVersion", "ProtocolVersion") + .WithMany() + .HasForeignKey("ProtocolVersionId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ProtocolVersion"); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Logging.LoginLog", b => + { + b.HasOne("CellularManagement.Domain.Entities.AppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.RolePermission", b => + { + b.HasOne("CellularManagement.Domain.Entities.Permission", "Permission") + .WithMany("RolePermissions") + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CellularManagement.Domain.Entities.AppRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.UserRole", b => + { + b.HasOne("CellularManagement.Domain.Entities.AppRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CellularManagement.Domain.Entities.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Permission", b => + { + b.Navigation("RolePermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.cs b/src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.cs new file mode 100644 index 0000000..bb2e8ac --- /dev/null +++ b/src/X1.Infrastructure/Migrations/20250705173130_InitProtocolVersionAndDevice.cs @@ -0,0 +1,183 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace X1.Infrastructure.Migrations +{ + /// + public partial class InitProtocolVersionAndDevice : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProtocolType", + table: "ProtocolVersions"); + + migrationBuilder.AlterColumn( + name: "Version", + table: "ProtocolVersions", + type: "character varying(20)", + maxLength: 20, + nullable: false, + comment: "版本号", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "版本号"); + + migrationBuilder.AlterColumn( + name: "ReleaseDate", + table: "ProtocolVersions", + type: "timestamp with time zone", + nullable: true, + comment: "发布日期", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "ProtocolVersions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "版本名称", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "MinimumSupportedVersion", + table: "ProtocolVersions", + type: "character varying(20)", + maxLength: 20, + nullable: true, + comment: "最低支持版本", + oldClrType: typeof(string), + oldType: "character varying(20)", + oldMaxLength: 20, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "IsForceUpdate", + table: "ProtocolVersions", + type: "boolean", + nullable: false, + comment: "是否强制更新", + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "IsEnabled", + table: "ProtocolVersions", + type: "boolean", + nullable: false, + comment: "是否启用", + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "Description", + table: "ProtocolVersions", + type: "character varying(500)", + maxLength: 500, + nullable: true, + comment: "版本描述", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true, + oldComment: "版本描述"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Version", + table: "ProtocolVersions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "版本号", + oldClrType: typeof(string), + oldType: "character varying(20)", + oldMaxLength: 20, + oldComment: "版本号"); + + migrationBuilder.AlterColumn( + name: "ReleaseDate", + table: "ProtocolVersions", + type: "timestamp with time zone", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldNullable: true, + oldComment: "发布日期"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "ProtocolVersions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "版本名称"); + + migrationBuilder.AlterColumn( + name: "MinimumSupportedVersion", + table: "ProtocolVersions", + type: "character varying(20)", + maxLength: 20, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(20)", + oldMaxLength: 20, + oldNullable: true, + oldComment: "最低支持版本"); + + migrationBuilder.AlterColumn( + name: "IsForceUpdate", + table: "ProtocolVersions", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "是否强制更新"); + + migrationBuilder.AlterColumn( + name: "IsEnabled", + table: "ProtocolVersions", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "是否启用"); + + migrationBuilder.AlterColumn( + name: "Description", + table: "ProtocolVersions", + type: "character varying(200)", + maxLength: 200, + nullable: true, + comment: "版本描述", + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500, + oldNullable: true, + oldComment: "版本描述"); + + migrationBuilder.AddColumn( + name: "ProtocolType", + table: "ProtocolVersions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + defaultValue: ""); + } + } +} diff --git a/src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.Designer.cs b/src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.Designer.cs new file mode 100644 index 0000000..e777ceb --- /dev/null +++ b/src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.Designer.cs @@ -0,0 +1,583 @@ +// +using System; +using CellularManagement.Infrastructure.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace X1.Infrastructure.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250705174217_UpdateProtocolVersionAndCellularDevice")] + partial class UpdateProtocolVersionAndCellularDevice + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("CellularManagement.Domain.Entities.AppRole", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("角色ID,主键"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasComment("并发控制戳"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("角色描述"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("角色名称"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("标准化角色名称(大写)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("IX_Roles_Name"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("Roles", null, t => + { + t.HasComment("角色表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.AppUser", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("用户ID,主键"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasComment("登录失败次数"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasComment("并发控制戳"); + + b.Property("CreatedTime") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("电子邮箱"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasComment("邮箱是否已验证"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasComment("用户状态(true: 启用, false: 禁用)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已删除"); + + b.Property("LastLoginTime") + .HasColumnType("timestamp with time zone") + .HasComment("最后登录时间"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasComment("是否启用账户锁定"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasComment("账户锁定结束时间"); + + b.Property("ModifiedTime") + .HasColumnType("timestamp with time zone") + .HasComment("修改时间"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("标准化电子邮箱(大写)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("标准化账号(大写)"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasComment("密码哈希值"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("text") + .HasComment("电话号码"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasComment("电话号码是否已验证"); + + b.Property("RealName") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("用户名"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasComment("安全戳,用于并发控制"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasComment("是否启用双因素认证"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasComment("账号"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("IX_Users_Email"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.HasIndex("PhoneNumber") + .IsUnique() + .HasDatabaseName("IX_Users_PhoneNumber"); + + b.HasIndex("UserName") + .IsUnique() + .HasDatabaseName("IX_Users_UserName"); + + b.ToTable("Users", null, t => + { + t.HasComment("用户表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Device.CellularDevice", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("设备ID"); + + b.Property("AgentPort") + .HasColumnType("integer") + .HasComment("Agent端口"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("设备描述"); + + b.Property("IpAddress") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("character varying(45)") + .HasComment("IP地址"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean") + .HasComment("是否启用"); + + b.Property("IsRunning") + .HasColumnType("boolean") + .HasComment("设备状态(启动/未启动)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("设备名称"); + + b.Property("ProtocolVersionId") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("协议版本ID"); + + b.Property("SerialNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("序列号"); + + b.Property("UpdatedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ProtocolVersionId") + .HasDatabaseName("IX_CellularDevices_ProtocolVersionId"); + + b.HasIndex("SerialNumber") + .IsUnique() + .HasDatabaseName("IX_CellularDevices_SerialNumber"); + + b.ToTable("CellularDevices", null, t => + { + t.HasComment("蜂窝设备表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Device.ProtocolVersion", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("版本ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("版本描述"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean") + .HasComment("是否启用"); + + b.Property("MinimumSupportedVersion") + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasComment("最低支持版本"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("版本名称"); + + b.Property("ReleaseDate") + .HasColumnType("timestamp with time zone") + .HasComment("发布日期"); + + b.Property("UpdatedAt") + .IsRequired() + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .HasColumnType("text"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasComment("版本号"); + + b.HasKey("Id"); + + b.HasIndex("Version") + .IsUnique() + .HasDatabaseName("IX_ProtocolVersions_Version"); + + b.ToTable("ProtocolVersions", null, t => + { + t.HasComment("协议版本表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Logging.LoginLog", b => + { + b.Property("Id") + .HasColumnType("text") + .HasComment("日志ID"); + + b.Property("Browser") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("浏览器信息"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FailureReason") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("失败原因"); + + b.Property("IpAddress") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("登录IP"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsSuccess") + .HasColumnType("boolean") + .HasComment("登录状态(成功/失败)"); + + b.Property("Location") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("登录位置"); + + b.Property("LoginSource") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("LoginTime") + .HasColumnType("timestamp with time zone") + .HasComment("登录时间"); + + b.Property("LoginType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("OperatingSystem") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("操作系统信息"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserAgent") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("设备信息"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("character varying(450)") + .HasComment("用户ID"); + + b.HasKey("Id"); + + b.HasIndex("IpAddress") + .HasDatabaseName("IX_LoginLogs_IpAddress"); + + b.HasIndex("LoginTime") + .HasDatabaseName("IX_LoginLogs_LoginTime"); + + b.HasIndex("UserId") + .HasDatabaseName("IX_LoginLogs_UserId"); + + b.HasIndex("UserId", "LoginTime") + .HasDatabaseName("IX_LoginLogs_UserId_LoginTime"); + + b.ToTable("LoginLogs", null, t => + { + t.HasComment("用户登录日志表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Permission", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Permissions", (string)null); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.RolePermission", b => + { + b.Property("RoleId") + .HasColumnType("text"); + + b.Property("PermissionId") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("RoleId", "PermissionId"); + + b.HasIndex("PermissionId"); + + b.ToTable("RolePermissions", (string)null); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.UserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", null, t => + { + t.HasComment("用户角色关系表"); + }); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Device.CellularDevice", b => + { + b.HasOne("CellularManagement.Domain.Entities.Device.ProtocolVersion", "ProtocolVersion") + .WithMany() + .HasForeignKey("ProtocolVersionId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ProtocolVersion"); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Logging.LoginLog", b => + { + b.HasOne("CellularManagement.Domain.Entities.AppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.RolePermission", b => + { + b.HasOne("CellularManagement.Domain.Entities.Permission", "Permission") + .WithMany("RolePermissions") + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CellularManagement.Domain.Entities.AppRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.UserRole", b => + { + b.HasOne("CellularManagement.Domain.Entities.AppRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CellularManagement.Domain.Entities.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CellularManagement.Domain.Entities.Permission", b => + { + b.Navigation("RolePermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.cs b/src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.cs new file mode 100644 index 0000000..3927af6 --- /dev/null +++ b/src/X1.Infrastructure/Migrations/20250705174217_UpdateProtocolVersionAndCellularDevice.cs @@ -0,0 +1,64 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace X1.Infrastructure.Migrations +{ + /// + public partial class UpdateProtocolVersionAndCellularDevice : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsForceUpdate", + table: "ProtocolVersions"); + + migrationBuilder.AlterColumn( + name: "IpAddress", + table: "CellularDevices", + type: "character varying(45)", + maxLength: 45, + nullable: false, + comment: "IP地址", + oldClrType: typeof(string), + oldType: "character varying(45)", + oldMaxLength: 45); + + migrationBuilder.AddColumn( + name: "IsRunning", + table: "CellularDevices", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "设备状态(启动/未启动)"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsRunning", + table: "CellularDevices"); + + migrationBuilder.AddColumn( + name: "IsForceUpdate", + table: "ProtocolVersions", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否强制更新"); + + migrationBuilder.AlterColumn( + name: "IpAddress", + table: "CellularDevices", + type: "character varying(45)", + maxLength: 45, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(45)", + oldMaxLength: 45, + oldComment: "IP地址"); + } + } +} diff --git a/src/X1.Infrastructure/Migrations/AppDbContextModelSnapshot.cs b/src/X1.Infrastructure/Migrations/AppDbContextModelSnapshot.cs index 594bacf..90fdd87 100644 --- a/src/X1.Infrastructure/Migrations/AppDbContextModelSnapshot.cs +++ b/src/X1.Infrastructure/Migrations/AppDbContextModelSnapshot.cs @@ -227,7 +227,8 @@ namespace X1.Infrastructure.Migrations b.Property("IpAddress") .IsRequired() .HasMaxLength(45) - .HasColumnType("character varying(45)"); + .HasColumnType("character varying(45)") + .HasComment("IP地址"); b.Property("IsDeleted") .HasColumnType("boolean"); @@ -236,6 +237,10 @@ namespace X1.Infrastructure.Migrations .HasColumnType("boolean") .HasComment("是否启用"); + b.Property("IsRunning") + .HasColumnType("boolean") + .HasComment("设备状态(启动/未启动)"); + b.Property("Name") .IsRequired() .HasMaxLength(100) @@ -292,35 +297,31 @@ namespace X1.Infrastructure.Migrations .HasColumnType("text"); b.Property("Description") - .HasMaxLength(200) - .HasColumnType("character varying(200)") + .HasMaxLength(500) + .HasColumnType("character varying(500)") .HasComment("版本描述"); b.Property("IsDeleted") .HasColumnType("boolean"); b.Property("IsEnabled") - .HasColumnType("boolean"); - - b.Property("IsForceUpdate") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("是否启用"); b.Property("MinimumSupportedVersion") .HasMaxLength(20) - .HasColumnType("character varying(20)"); + .HasColumnType("character varying(20)") + .HasComment("最低支持版本"); b.Property("Name") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ProtocolType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("版本名称"); b.Property("ReleaseDate") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("发布日期"); b.Property("UpdatedAt") .IsRequired() @@ -332,8 +333,8 @@ namespace X1.Infrastructure.Migrations b.Property("Version") .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") + .HasMaxLength(20) + .HasColumnType("character varying(20)") .HasComment("版本号"); b.HasKey("Id"); diff --git a/src/X1.WebAPI/Devices.http b/src/X1.WebAPI/Devices.http new file mode 100644 index 0000000..3008396 --- /dev/null +++ b/src/X1.WebAPI/Devices.http @@ -0,0 +1,73 @@ +### 设备 CRUD API 测试 + +### 1. 创建设备 +POST {{baseUrl}}/api/devices +Content-Type: application/json +Authorization: Bearer {{token}} + +{ + "deviceName": "测试设备1", + "serialNumber": "SN001", + "description": "这是一个测试设备", + "protocolVersionId": "{{protocolVersionId}}", + "agentPort": 8080, + "ipAddress": "192.168.1.100", + "isEnabled": true, + "isRunning": false +} + +### 2. 创建另一个设备 +POST {{baseUrl}}/api/devices +Content-Type: application/json +Authorization: Bearer {{token}} + +{ + "deviceName": "测试设备2", + "serialNumber": "SN002", + "description": "这是另一个测试设备", + "protocolVersionId": "{{protocolVersionId}}", + "agentPort": 8081, + "ipAddress": "192.168.1.101", + "isEnabled": true, + "isRunning": true +} + +### 3. 获取设备列表 +GET {{baseUrl}}/api/devices?pageNumber=1&pageSize=10 +Authorization: Bearer {{token}} + +### 4. 搜索设备 +GET {{baseUrl}}/api/devices?searchTerm=测试&pageNumber=1&pageSize=10 +Authorization: Bearer {{token}} + +### 5. 根据ID获取设备 +GET {{baseUrl}}/api/devices/{{deviceId}} +Authorization: Bearer {{token}} + +### 6. 更新设备 +PUT {{baseUrl}}/api/devices/{{deviceId}} +Content-Type: application/json +Authorization: Bearer {{token}} + +{ + "deviceId": "{{deviceId}}", + "deviceName": "测试设备1(已更新)", + "serialNumber": "SN001-UPDATED", + "description": "这是一个已更新的测试设备", + "protocolVersionId": "{{protocolVersionId}}", + "agentPort": 8082, + "ipAddress": "192.168.1.102", + "isEnabled": true, + "isRunning": true +} + +### 7. 删除设备 +DELETE {{baseUrl}}/api/devices/{{deviceId}} +Authorization: Bearer {{token}} + +### 环境变量设置 +# 在 VS Code 的 REST Client 扩展中设置以下变量: +# baseUrl: http://localhost:5000 +# token: 你的JWT令牌 +# protocolVersionId: 从协议版本创建响应中获取的协议版本ID +# deviceId: 从设备创建响应中获取的设备ID \ No newline at end of file diff --git a/src/X1.WebAPI/ProtocolVersions.http b/src/X1.WebAPI/ProtocolVersions.http index e39e19c..4e14e1d 100644 --- a/src/X1.WebAPI/ProtocolVersions.http +++ b/src/X1.WebAPI/ProtocolVersions.http @@ -11,7 +11,6 @@ Authorization: Bearer {{token}} "description": "HTTP协议1.1版本", "isEnabled": true, "releaseDate": "1997-01-01T00:00:00Z", - "isForceUpdate": false, "minimumSupportedVersion": "1.0.0" } @@ -26,7 +25,6 @@ Authorization: Bearer {{token}} "description": "HTTP协议2.0版本", "isEnabled": true, "releaseDate": "2015-05-14T00:00:00Z", - "isForceUpdate": true, "minimumSupportedVersion": "1.1.0" } @@ -58,7 +56,6 @@ Authorization: Bearer {{token}} "description": "HTTP协议1.1版本(已更新)", "isEnabled": true, "releaseDate": "1997-01-01T00:00:00Z", - "isForceUpdate": true, "minimumSupportedVersion": "1.0.0" }