新增 WMS 搬运规则与任务管理

支持搬运规则维护、候选预览、任务生成、预占、下发、取消和完成,并完善仓储管理前端交互。
This commit is contained in:
ArtoriasWu
2026-06-25 11:02:22 +08:00
parent 1cb8091bbe
commit 15405ba114
101 changed files with 4167704 additions and 152 deletions
@@ -18,6 +18,10 @@ public sealed class PlatformDbContext : DbContext
public DbSet<ContainerMaterial> ContainerMaterials => Set<ContainerMaterial>();
public DbSet<ContainerLocationHistory> ContainerLocationHistories => Set<ContainerLocationHistory>();
public DbSet<ContainerMaterialHistory> ContainerMaterialHistories => Set<ContainerMaterialHistory>();
public DbSet<WmsTransportRule> WmsTransportRules => Set<WmsTransportRule>();
public DbSet<WmsTransportTask> WmsTransportTasks => Set<WmsTransportTask>();
public DbSet<WmsTransportReservation> WmsTransportReservations => Set<WmsTransportReservation>();
public DbSet<WmsTransportTaskHistory> WmsTransportTaskHistories => Set<WmsTransportTaskHistory>();
public DbSet<SimpleField> SimpleFields => Set<SimpleField>();
public DbSet<UserDashboardShortcut> UserDashboardShortcuts => Set<UserDashboardShortcut>();
@@ -29,6 +33,12 @@ public sealed class PlatformDbContext : DbContext
var nullableGuid = new ValueConverter<Guid?, string?>(
v => v.HasValue ? v.Value.ToString("D") : null,
v => string.IsNullOrWhiteSpace(v) ? null : Guid.Parse(v));
var dateTimeOffset = new ValueConverter<DateTimeOffset, string>(
v => v.UtcDateTime.ToString("O"),
v => DateTimeOffset.Parse(v));
var nullableDateTimeOffset = new ValueConverter<DateTimeOffset?, string?>(
v => v.HasValue ? v.Value.UtcDateTime.ToString("O") : null,
v => string.IsNullOrWhiteSpace(v) ? null : DateTimeOffset.Parse(v));
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
@@ -36,6 +46,10 @@ public sealed class PlatformDbContext : DbContext
modelBuilder.Entity(entity.ClrType).Property(p.Name).HasConversion(guid).HasMaxLength(36);
foreach (var p in entity.ClrType.GetProperties().Where(p => p.PropertyType == typeof(Guid?)))
modelBuilder.Entity(entity.ClrType).Property(p.Name).HasConversion(nullableGuid).HasMaxLength(36);
foreach (var p in entity.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset)))
modelBuilder.Entity(entity.ClrType).Property(p.Name).HasConversion(dateTimeOffset).HasMaxLength(40);
foreach (var p in entity.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset?)))
modelBuilder.Entity(entity.ClrType).Property(p.Name).HasConversion(nullableDateTimeOffset).HasMaxLength(40);
}
ConfigureEntityBase<WarehouseArea>(modelBuilder, "wms_areas");
@@ -44,9 +58,13 @@ public sealed class PlatformDbContext : DbContext
ConfigureEntityBase<Material>(modelBuilder, "wms_materials");
ConfigureEntityBase<ContainerLocation>(modelBuilder, "wms_container_locations");
ConfigureEntityBase<ContainerMaterial>(modelBuilder, "wms_container_materials");
ConfigureEntityBase<WmsTransportRule>(modelBuilder, "wms_transport_rules");
ConfigureEntityBase<WmsTransportTask>(modelBuilder, "wms_transport_tasks");
ConfigureEntityBase<WmsTransportReservation>(modelBuilder, "wms_transport_reservations");
ConfigureHistory<ContainerLocationHistory>(modelBuilder, "wms_container_location_history");
ConfigureHistory<ContainerMaterialHistory>(modelBuilder, "wms_container_material_history");
ConfigureTransportTaskHistory(modelBuilder);
modelBuilder.Entity<WarehouseArea>().HasIndex(x => x.Code).IsUnique();
modelBuilder.Entity<Storage>().HasIndex(x => x.Code).IsUnique();
@@ -57,6 +75,15 @@ public sealed class PlatformDbContext : DbContext
modelBuilder.Entity<ContainerLocation>().HasIndex(x => new { x.LocationType, x.LocationId });
modelBuilder.Entity<ContainerMaterial>().HasIndex(x => new { x.ContainerId, x.MaterialId, x.BatchNo, x.SerialNo }).IsUnique();
modelBuilder.Entity<WmsTransportRule>().HasIndex(x => x.Code).IsUnique();
modelBuilder.Entity<WmsTransportRule>().HasIndex(x => new { x.TriggerType, x.Enabled, x.Priority });
modelBuilder.Entity<WmsTransportTask>().HasIndex(x => x.Status);
modelBuilder.Entity<WmsTransportTask>().HasIndex(x => x.ContainerId);
modelBuilder.Entity<WmsTransportTask>().HasIndex(x => x.TargetStorageId);
modelBuilder.Entity<WmsTransportReservation>().HasIndex(x => new { x.ContainerId, x.Status });
modelBuilder.Entity<WmsTransportReservation>().HasIndex(x => new { x.TargetStorageId, x.Status });
modelBuilder.Entity<WmsTransportTask>().Property(x => x.Quantity).HasPrecision(18, 4);
modelBuilder.Entity<ContainerMaterial>().Property(x => x.Quantity).HasPrecision(18, 4);
modelBuilder.Entity<ContainerMaterialHistory>().Property(x => x.QuantityDelta).HasPrecision(18, 4);
@@ -165,4 +192,19 @@ public sealed class PlatformDbContext : DbContext
e.HasIndex(x => x.OperatedAt);
e.HasIndex(x => x.EventType);
}
private static void ConfigureTransportTaskHistory(ModelBuilder modelBuilder)
{
var e = modelBuilder.Entity<WmsTransportTaskHistory>();
e.ToTable("wms_transport_task_history");
e.HasKey(x => x.Id);
e.Property(x => x.FromStatus).HasMaxLength(32);
e.Property(x => x.ToStatus).HasMaxLength(32);
e.Property(x => x.Operator).HasMaxLength(128);
e.Property(x => x.Reason).HasMaxLength(500);
e.Property(x => x.ErrorMessage).HasMaxLength(1000);
e.Property(x => x.SnapshotJson).HasColumnType("text");
e.HasIndex(x => x.TaskId);
e.HasIndex(x => x.OperatedAt);
}
}