diff --git a/MiGu.DB/Domains/Migrators/DataMigrators.cs b/MiGu.DB/Domains/Migrators/DataMigrators.cs
index 8bdfece..6e3a643 100644
--- a/MiGu.DB/Domains/Migrators/DataMigrators.cs
+++ b/MiGu.DB/Domains/Migrators/DataMigrators.cs
@@ -29,35 +29,16 @@ public sealed class SimpleFieldsCarTypeBackfillMigrator : IDataMigrator
}
}
-///
-/// 把库内旧状态字符串刷成规范枚举名(Available/Idle→Empty,Occupied→FullContainer)。
-/// 仅 Sqlite 表名/列名;绕过枚举 HasConversion(ExecuteUpdate + 字符串比较会 InvalidCast)。
-///
-public sealed class LegacyStatusNormalizationMigrator : IDataMigrator
+/// 库区 LayoutMode 空值补 Flat(raw UPDATE,避开枚举 converter)。
+public sealed class AreaLayoutModeDefaultMigrator : IDataMigrator
{
public int Order => 15;
- public string Name => "Wms.LegacyStatusNormalization";
+ public string Name => "Wms.AreaLayoutModeDefault";
public async Task MigrateAsync(DbContext db, CancellationToken ct = default)
{
if (db is not MiGuDbContext) return;
- await db.Database.ExecuteSqlRawAsync(
- """
- UPDATE wms_storages
- SET Status = 'Empty'
- WHERE Status IN ('Available', 'Idle')
- """,
- ct);
-
- await db.Database.ExecuteSqlRawAsync(
- """
- UPDATE wms_storages
- SET Status = 'FullContainer'
- WHERE Status = 'Occupied'
- """,
- ct);
-
await db.Database.ExecuteSqlRawAsync(
"""
UPDATE wms_areas
@@ -98,7 +79,7 @@ public static class DataMigratorRegistration
public static IServiceCollection AddMiGuDataMigrators(this IServiceCollection services)
{
services.AddSingleton();
- services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton();
return services;
}
diff --git a/MiGu.DB/Domains/Transport/TransportEntities.cs b/MiGu.DB/Domains/Transport/TransportEntities.cs
index c071a36..a35a05b 100644
--- a/MiGu.DB/Domains/Transport/TransportEntities.cs
+++ b/MiGu.DB/Domains/Transport/TransportEntities.cs
@@ -96,9 +96,3 @@ public static class WmsReservationStatuses
public const WmsReservationStatus Released = WmsReservationStatus.Released;
public const WmsReservationStatus Expired = WmsReservationStatus.Expired;
}
-
-public static class WmsDispatchStatuses
-{
- public const WmsDispatchStatus Dispatched = WmsDispatchStatus.Dispatched;
- public const WmsDispatchStatus Failed = WmsDispatchStatus.Failed;
-}
diff --git a/MiGu.DB/Domains/Transport/TransportEnums.cs b/MiGu.DB/Domains/Transport/TransportEnums.cs
index 06621d4..014477c 100644
--- a/MiGu.DB/Domains/Transport/TransportEnums.cs
+++ b/MiGu.DB/Domains/Transport/TransportEnums.cs
@@ -27,9 +27,3 @@ public enum WmsReservationStatus
Released,
Expired
}
-
-public enum WmsDispatchStatus
-{
- Dispatched,
- Failed
-}
diff --git a/MiGu.DB/Domains/Wms/WmsEnums.cs b/MiGu.DB/Domains/Wms/WmsEnums.cs
index 55f3bae..e5bf428 100644
--- a/MiGu.DB/Domains/Wms/WmsEnums.cs
+++ b/MiGu.DB/Domains/Wms/WmsEnums.cs
@@ -2,7 +2,6 @@ namespace MiGu.DB.Domains.Wms;
///
/// WMS 状态/类型枚举。列以字符串存储(见约定 HasConversion<string>),成员名即库内合法值。
-/// 旧别名(Available/Idle/Occupied 等)不进入枚举,由 LegacyStatusNormalizationMigrator 刷库。
///
public enum AreaLayoutMode
{
diff --git a/MiGu.DB/Domains/Wms/WmsStatusHelpers.cs b/MiGu.DB/Domains/Wms/WmsStatusHelpers.cs
index 23d6e5a..5961b1d 100644
--- a/MiGu.DB/Domains/Wms/WmsStatusHelpers.cs
+++ b/MiGu.DB/Domains/Wms/WmsStatusHelpers.cs
@@ -33,17 +33,8 @@ public static class StorageStatuses
public static readonly HashSet All = new()
{ Empty, EmptyContainer, FullContainer, Disabled };
- ///
- /// 写路径归一:兼容历史字符串 Available/Idle/Occupied。
- /// 库内残留旧值须靠 DataMigrator 刷掉,不能依赖 converter 读侧归一(WHERE 会漏行)。
- ///
- public static StorageStatus Normalize(string? status) => status switch
- {
- "Available" or "Idle" => Empty,
- "Occupied" => FullContainer,
- _ when Enum.TryParse(status, true, out var e) && All.Contains(e) => e,
- _ => Empty
- };
+ public static StorageStatus ParseOr(string? value, StorageStatus fallback = StorageStatus.Empty) =>
+ Enum.TryParse(value, true, out var e) && All.Contains(e) ? e : fallback;
}
public static class ContainerStatuses
diff --git a/MiGu.DB/MIGRATIONS.md b/MiGu.DB/MIGRATIONS.md
index ec1f1ea..2ca301d 100644
--- a/MiGu.DB/MIGRATIONS.md
+++ b/MiGu.DB/MIGRATIONS.md
@@ -94,7 +94,7 @@ dotnet ef migrations add <迁移名称> `
### 3.4 应用到本地库
-启动 `MiGu.Server` 即可(`EnsurePlatformDatabaseAsync` → `MigrateMiGuDbAsync`),或:
+启动 `MiGu.Server` 即可(`Program.cs` 直接调用 `MigrateMiGuDbAsync`),或:
```powershell
dotnet ef database update `
@@ -151,7 +151,7 @@ dotnet ef database update <目标迁移名> `
→ **[MiGu.Server/README.md · 数据库启动流程](../MiGu.Server/README.md#数据库启动流程)**
-摘要:`EnsurePlatformDatabaseAsync` → `MigrateMiGuDbAsync`;`Database:SchemaMode` 为 `EnsureCreated` 或 `Migrate`;之后按需跑 `IDataMigrator`。
+摘要:`MigrateMiGuDbAsync`;`Database:SchemaMode` 为 `EnsureCreated` 或 `Migrate`;之后按需跑 `IDataMigrator`。
**Migrate 基线:** 已有表、无 History 时,会把**全部** pending Migration 写入 `__EFMigrationsHistory`(假定 EnsureCreated 库已对齐模型 tip)。发版前若开发期改过模型,须先 `migrations add` 再切 `Migrate`。
@@ -165,7 +165,7 @@ dotnet ef database update <目标迁移名> `
| 刷旧枚举字符串、回填列 | 新增 `IDataMigrator`,注册到 `AddMiGuDataMigrators` |
| 开发机整库清空重来 | 删 `data/platform.db*` 后启动(等同空库 Migrate);**不要**在生产用 EnsureDeleted |
-注意:带 `HasConversion` 的枚举列,用 `ExecuteUpdate` + 原始字符串比较可能触发转换异常;旧值刷库需绕过 converter(参见 `LegacyStatusNormalizationMigrator`)。
+注意:带 `HasConversion` 的枚举列,用 `ExecuteUpdate` + 原始字符串比较可能触发转换异常;空 LayoutMode 等特例用 raw UPDATE(参见 `AreaLayoutModeDefaultMigrator`)。
---
diff --git a/MiGu.DB/README.md b/MiGu.DB/README.md
index 451fd30..debc756 100644
--- a/MiGu.DB/README.md
+++ b/MiGu.DB/README.md
@@ -17,7 +17,7 @@
```csharp
builder.Services.AddPlatformPersistence(builder.Configuration); // 内部 AddMiGuDb
-await app.Services.EnsurePlatformDatabaseAsync(); // 内部 MigrateMiGuDbAsync
+await app.Services.MigrateMiGuDbAsync();
```
**启动流程、SchemaMode、开发/发版配置说明见 [MiGu.Server/README.md · 数据库启动流程](../MiGu.Server/README.md#数据库启动流程)。**
@@ -27,7 +27,6 @@ await app.Services.EnsurePlatformDatabaseAsync(); // 内部 Migrat
## 实体与枚举
- 业务状态字段为 **enum**,约定自动 `HasConversion()`(严格 1:1,不做读侧归一)。
-- 旧库值(如 `Available`/`Idle`)由 `LegacyStatusNormalizationMigrator` 一次性刷成规范名。
- `Version` 为乐观并发令牌;软删走全局 `HasQueryFilter`。
- 复数辅助类(`StorageStatuses`、`LocationKinds`…)负责 API 字符串解析与集合校验。
diff --git a/MiGu.Server/Controllers/FleetController.cs b/MiGu.Server/Controllers/FleetController.cs
index cea75a9..1ada520 100644
--- a/MiGu.Server/Controllers/FleetController.cs
+++ b/MiGu.Server/Controllers/FleetController.cs
@@ -15,9 +15,9 @@ public sealed class FleetController : ControllerBase
private readonly FleetHealthService _health;
private readonly CdmTaskSyncer _cdmSyncer;
private readonly AlarmCollector _alarmCollector;
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
- public FleetController(FleetHealthService health, CdmTaskSyncer cdmSyncer, AlarmCollector alarmCollector, PlatformDbContext db)
+ public FleetController(FleetHealthService health, CdmTaskSyncer cdmSyncer, AlarmCollector alarmCollector, MiGuDbContext db)
{
_health = health;
_cdmSyncer = cdmSyncer;
diff --git a/MiGu.Server/Controllers/WmsController.cs b/MiGu.Server/Controllers/WmsController.cs
index 908c615..feccc1a 100644
--- a/MiGu.Server/Controllers/WmsController.cs
+++ b/MiGu.Server/Controllers/WmsController.cs
@@ -192,10 +192,6 @@ public sealed class WmsController : ControllerBase
public Task> ContainerMaterials([FromQuery] string? q, [FromQuery] Guid? containerId) =>
_service.ContainerMaterials(q, containerId);
- [HttpPost("container-materials")]
- public async Task SaveContainerMaterial([FromBody] BindMaterialRequest req) =>
- Ok(await _service.BindMaterial(req, User.ActorName()));
-
[HttpPost("container-materials/bind")]
public async Task BindMaterial([FromBody] BindMaterialRequest req) =>
Ok(await _service.BindMaterial(req, User.ActorName()));
diff --git a/MiGu.Server/Dashboard/DashboardShortcutService.cs b/MiGu.Server/Dashboard/DashboardShortcutService.cs
index 7e3f668..9343b1e 100644
--- a/MiGu.Server/Dashboard/DashboardShortcutService.cs
+++ b/MiGu.Server/Dashboard/DashboardShortcutService.cs
@@ -7,7 +7,7 @@ namespace MiGu.Server.Dashboard;
public sealed class DashboardShortcutService
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
private readonly RbacStore _rbac;
private static readonly JsonSerializerOptions JsonOpts = new()
@@ -15,7 +15,7 @@ public sealed class DashboardShortcutService
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
- public DashboardShortcutService(PlatformDbContext db, RbacStore rbac)
+ public DashboardShortcutService(MiGuDbContext db, RbacStore rbac)
{
_db = db;
_rbac = rbac;
diff --git a/MiGu.Server/Fleet/AlarmCollector.cs b/MiGu.Server/Fleet/AlarmCollector.cs
index 6c2e919..6defd45 100644
--- a/MiGu.Server/Fleet/AlarmCollector.cs
+++ b/MiGu.Server/Fleet/AlarmCollector.cs
@@ -76,7 +76,7 @@ public sealed class AlarmCollector
try
{
using var scope = _scopeFactory.CreateScope();
- var db = scope.ServiceProvider.GetRequiredService();
+ var db = scope.ServiceProvider.GetRequiredService();
await ReconcileAsync(db, current, ct);
}
catch (Exception ex)
@@ -161,7 +161,7 @@ public sealed class AlarmCollector
}
}
- private static async Task ReconcileAsync(PlatformDbContext db, Dictionary current, CancellationToken ct)
+ private static async Task ReconcileAsync(MiGuDbContext db, Dictionary current, CancellationToken ct)
{
var now = DateTimeOffset.UtcNow;
var active = await db.VehicleAlarms.Where(a => a.Status == "active").ToListAsync(ct);
diff --git a/MiGu.Server/Fleet/CdmTaskSync.cs b/MiGu.Server/Fleet/CdmTaskSync.cs
index 1609426..7c7342a 100644
--- a/MiGu.Server/Fleet/CdmTaskSync.cs
+++ b/MiGu.Server/Fleet/CdmTaskSync.cs
@@ -80,7 +80,7 @@ public sealed class CdmTaskSyncer
try
{
using var scope = _scopeFactory.CreateScope();
- var db = scope.ServiceProvider.GetRequiredService();
+ var db = scope.ServiceProvider.GetRequiredService();
await UpsertAsync(db, dtos, ct);
}
catch (Exception ex)
@@ -126,7 +126,7 @@ public sealed class CdmTaskSyncer
}
}
- private static async Task UpsertAsync(PlatformDbContext db, IReadOnlyList dtos, CancellationToken ct)
+ private static async Task UpsertAsync(MiGuDbContext db, IReadOnlyList dtos, CancellationToken ct)
{
var valid = dtos.Where(d => !string.IsNullOrWhiteSpace(d.id)).ToList();
if (valid.Count == 0) return;
diff --git a/MiGu.Server/GlobalUsings.Db.cs b/MiGu.Server/GlobalUsings.Db.cs
index b4c7f3b..c3811e3 100644
--- a/MiGu.Server/GlobalUsings.Db.cs
+++ b/MiGu.Server/GlobalUsings.Db.cs
@@ -1,5 +1,5 @@
-global using PlatformDbContext = MiGu.DB.Kernel.Context.MiGuDbContext;
-global using EntityBase = MiGu.DB.Kernel.Entities.AggregateRoot;
+global using MiGu.DB.Kernel.Context;
+global using MiGu.DB.Kernel.Entities;
global using SimpleField = MiGu.DB.Domains.SimpleFields.SimpleField;
global using UserDashboardShortcut = MiGu.DB.Domains.Dashboard.UserDashboardShortcut;
global using Warehouse = MiGu.DB.Domains.Wms.Warehouse;
diff --git a/MiGu.Server/Persistence/PlatformPersistence.cs b/MiGu.Server/Persistence/PlatformPersistence.cs
index 5750a3b..a176778 100644
--- a/MiGu.Server/Persistence/PlatformPersistence.cs
+++ b/MiGu.Server/Persistence/PlatformPersistence.cs
@@ -21,8 +21,4 @@ public static class PlatformPersistence
services.AddScoped();
return services;
}
-
- /// 启动建库/迁移入口(内部即 MigrateMiGuDbAsync:Migrate + 基线 + DataMigrator)。
- public static Task EnsurePlatformDatabaseAsync(this IServiceProvider services)
- => services.MigrateMiGuDbAsync();
}
diff --git a/MiGu.Server/Program.cs b/MiGu.Server/Program.cs
index 8dd4939..e0d93cc 100644
--- a/MiGu.Server/Program.cs
+++ b/MiGu.Server/Program.cs
@@ -8,6 +8,7 @@ using MiGu.Server.Configs;
using MiGu.Server.Launcher;
using MiGu.Server.OpenApi;
using MiGu.Server.Ota;
+using MiGu.DB.Kernel.Hosting;
using MiGu.Server.Persistence;
using Yarp.ReverseProxy.Transforms;
@@ -279,7 +280,7 @@ builder.Services.AddHostedService();
builder.Services.AddHttpClient(nameof(WatchDogClient));
var app = builder.Build();
-await app.Services.EnsurePlatformDatabaseAsync();
+await app.Services.MigrateMiGuDbAsync();
// 启动期主动构造 JwtIssuer / InternalTokenStore:让 secret 校验日志在请求来之前打印。
_ = app.Services.GetRequiredService();
diff --git a/MiGu.Server/README.md b/MiGu.Server/README.md
index 73727f7..6a94aef 100644
--- a/MiGu.Server/README.md
+++ b/MiGu.Server/README.md
@@ -110,8 +110,8 @@ AddPlatformPersistence(configuration) # 注册 AddMiGuDb + Wms/SimpleFields
builder.Build()
│
▼
-EnsurePlatformDatabaseAsync() # → MiGu.DB.MigrateMiGuDbAsync()
- │ # Schema 初始化 + 可选 IDataMigrator
+MigrateMiGuDbAsync() # Schema 初始化 + 可选 IDataMigrator
+ │
▼
… 其余中间件 …
UseMiddleware # 请求级写入 IActorContext(审计戳)
diff --git a/MiGu.Server/SimpleFields/SimpleFieldService.cs b/MiGu.Server/SimpleFields/SimpleFieldService.cs
index e32e214..47bb27b 100644
--- a/MiGu.Server/SimpleFields/SimpleFieldService.cs
+++ b/MiGu.Server/SimpleFields/SimpleFieldService.cs
@@ -6,9 +6,9 @@ namespace MiGu.Server.SimpleFields;
public sealed class SimpleFieldService
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
- public SimpleFieldService(PlatformDbContext db) => _db = db;
+ public SimpleFieldService(MiGuDbContext db) => _db = db;
public async Task> ListAsync(string? fieldType = null, string? carType = null, string? q = null)
{
diff --git a/MiGu.Server/Wms/WmsModels.cs b/MiGu.Server/Wms/WmsModels.cs
index 7464f33..0bb0d60 100644
--- a/MiGu.Server/Wms/WmsModels.cs
+++ b/MiGu.Server/Wms/WmsModels.cs
@@ -20,7 +20,7 @@ public sealed record ContainerMaterialSnapshot(
public abstract record CommonRequest(Guid? Id, long? Version, bool IsLock, string Remark, string Extend);
public sealed record MasterDataRequest(
- Guid? Id, long? Version, string Code, string Name, string Type, string Status, bool Enabled, int SortOrder,
+ Guid? Id, long? Version, string Code, string Name, string Type, bool Enabled, int SortOrder,
bool IsLock, string Remark, string Extend) : CommonRequest(Id, Version, IsLock, Remark, Extend);
public sealed record AreaRequest(
@@ -57,8 +57,3 @@ public sealed record ContainerLocationRequest(
public sealed record BindMaterialRequest(
Guid? Id, long? Version, Guid ContainerId, Guid MaterialId, string Source, string Reason,
bool IsLock, string Remark, string Extend) : CommonRequest(Id, Version, IsLock, Remark, Extend);
-
-public sealed record ContainerMaterialRequest(
- Guid? Id, long? Version, Guid ContainerId, Guid MaterialId, decimal Quantity, string BatchNo, string SerialNo,
- string Status, DateTimeOffset? LoadedAt, DateTimeOffset? UnloadedAt, string Source, string Reason,
- bool IsLock, string Remark, string Extend) : CommonRequest(Id, Version, IsLock, Remark, Extend);
diff --git a/MiGu.Server/Wms/WmsReferenceValidator.cs b/MiGu.Server/Wms/WmsReferenceValidator.cs
index b435a31..72a8870 100644
--- a/MiGu.Server/Wms/WmsReferenceValidator.cs
+++ b/MiGu.Server/Wms/WmsReferenceValidator.cs
@@ -5,9 +5,9 @@ namespace MiGu.Server.Wms;
public sealed class WmsReferenceValidator
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
- public WmsReferenceValidator(PlatformDbContext db)
+ public WmsReferenceValidator(MiGuDbContext db)
{
_db = db;
}
diff --git a/MiGu.Server/Wms/WmsService.cs b/MiGu.Server/Wms/WmsService.cs
index e39324f..7e563ab 100644
--- a/MiGu.Server/Wms/WmsService.cs
+++ b/MiGu.Server/Wms/WmsService.cs
@@ -10,14 +10,14 @@ namespace MiGu.Server.Wms;
public sealed class WmsService
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
private readonly IUnitOfWork _uow;
private readonly IServiceProvider _services;
private readonly WmsReferenceValidator _refs;
private readonly JsonSerializerOptions _json = new(JsonSerializerDefaults.Web);
public WmsService(
- PlatformDbContext db,
+ MiGuDbContext db,
IUnitOfWork uow,
IServiceProvider services,
WmsReferenceValidator refs)
@@ -158,7 +158,7 @@ public sealed class WmsService
StampCreate(entity, actor);
_db.Warehouses.Add(entity);
}
- await EnsureUnique(_db.Warehouses, x => x.Code == req.Code && x.Id != entity.Id, "仓库编码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Code == req.Code && x.Id != entity.Id, "仓库编码已存在");
entity.Code = req.Code.Trim();
entity.Name = req.Name.Trim();
entity.Type = req.Type.TrimOr("Default");
@@ -185,7 +185,7 @@ public sealed class WmsService
StampCreate(entity, actor);
_db.WarehouseAreas.Add(entity);
}
- await EnsureUnique(_db.WarehouseAreas, x => x.Code == req.Code && x.Id != entity.Id, "库区编码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Code == req.Code && x.Id != entity.Id, "库区编码已存在");
entity.WarehouseId = warehouseId;
entity.Code = req.Code.Trim();
entity.Name = req.Name.Trim();
@@ -214,7 +214,7 @@ public sealed class WmsService
StampCreate(entity, actor);
_db.Storages.Add(entity);
}
- await EnsureUnique(_db.Storages, x => x.Code == req.Code && x.Id != entity.Id, "库位编码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Code == req.Code && x.Id != entity.Id, "库位编码已存在");
entity.AreaId = req.AreaId;
entity.Code = req.Code.Trim();
entity.Name = req.Name.Trim();
@@ -227,7 +227,7 @@ public sealed class WmsService
entity.SiteCode = req.SiteCode.TrimOr(entity.SiteId);
entity.Barcode = req.Barcode.TrimOr("");
entity.Capacity = 1;
- var status = StorageStatuses.Normalize(req.Status);
+ var status = StorageStatuses.ParseOr(req.Status);
if (status == StorageStatuses.Disabled || req.Enabled == false)
entity.Status = req.Enabled ? status : StorageStatuses.Disabled;
else if (!string.IsNullOrWhiteSpace(req.Status) && StorageStatuses.All.Contains(status))
@@ -326,7 +326,7 @@ public sealed class WmsService
StampCreate(entity, actor);
_db.Containers.Add(entity);
}
- await EnsureUnique(_db.Containers, x => x.Code == req.Code && x.Id != entity.Id, "容器编码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Code == req.Code && x.Id != entity.Id, "容器编码已存在");
entity.AreaId = req.AreaId;
entity.Code = req.Code.Trim();
entity.Name = req.Name.Trim();
@@ -353,7 +353,7 @@ public sealed class WmsService
StampCreate(entity, actor);
_db.MaterialTypes.Add(entity);
}
- await EnsureUnique(_db.MaterialTypes, x => x.Code == req.Code && x.Id != entity.Id, "物料类型编码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Code == req.Code && x.Id != entity.Id, "物料类型编码已存在");
entity.Code = req.Code.Trim();
entity.Name = req.Name.Trim();
entity.Spec = req.Spec.TrimOr("");
@@ -378,9 +378,9 @@ public sealed class WmsService
StampCreate(entity, actor);
_db.Materials.Add(entity);
}
- await EnsureUnique(_db.Materials, x => x.Code == req.Code && x.Id != entity.Id, "物料编码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Code == req.Code && x.Id != entity.Id, "物料编码已存在");
if (!string.IsNullOrWhiteSpace(req.Barcode))
- await EnsureUnique(_db.Materials, x => x.Barcode == req.Barcode && x.Id != entity.Id, "物料条码已存在");
+ await Repo().EnsureUniqueAsync(x => x.Barcode == req.Barcode && x.Id != entity.Id, "物料条码已存在");
entity.Code = req.Code.Trim();
entity.Name = req.Name.Trim();
entity.TypeCode = req.TypeCode.TrimOr("");
@@ -425,9 +425,9 @@ public sealed class WmsService
await _uow.SaveChangesAsync();
}
- public async Task DeleteEntity(Guid id, long? version, string actor) where T : EntityBase
+ public async Task DeleteEntity(Guid id, long? version, string actor)
+ where T : class, IEntity, ISoftDeletable, IVersioned, ILockable, IAuditable
{
- var entity = await FindEditable(id, version);
if (typeof(T) == typeof(WarehouseArea))
{
if (await _db.Storages.AnyAsync(x => x.AreaId == id))
@@ -444,10 +444,8 @@ public sealed class WmsService
if (await _db.ContainerMaterials.AnyAsync(x => x.MaterialId == id))
throw new InvalidOperationException("物料仍在绑定中,不能删除");
}
- entity.IsDeleted = true;
- entity.DeletedAt = DateTimeOffset.UtcNow;
- entity.DeletedBy = actor;
- entity.UpdatedBy = actor;
+
+ await Repo().SoftDeleteAsync(id, version);
await _uow.SaveChangesAsync();
}
@@ -497,8 +495,7 @@ public sealed class WmsService
}
else
{
- EnsureVersion(current, req.Version);
- EnsureUnlocked(current);
+ await Repo().GetEditableAsync(current.Id, req.Version);
}
current.LocationType = locationType;
@@ -540,7 +537,7 @@ public sealed class WmsService
{
var current = await _db.ContainerLocations.FirstOrDefaultAsync(x => x.ContainerId == containerId)
?? throw new InvalidOperationException("容器当前位置不存在");
- EnsureUnlocked(current);
+ await Repo().GetEditableAsync(current.Id, null);
Guid? fromStorageId = null;
if (current.LocationType == ContainerLocationTypes.Storage && Guid.TryParse(current.LocationId, out var fs))
fromStorageId = fs;
@@ -614,15 +611,9 @@ public sealed class WmsService
return current;
}
- /// 兼容旧接口:忽略数量,按实体绑定。
- public Task SaveContainerMaterial(ContainerMaterialRequest req, string actor) =>
- BindMaterial(new BindMaterialRequest(req.Id, req.Version, req.ContainerId, req.MaterialId, req.Source, req.Reason, req.IsLock, req.Remark, req.Extend), actor);
-
public async Task UnbindMaterial(Guid bindingId, string actor, string reason = "", bool archive = false)
{
- var current = await _db.ContainerMaterials.FirstOrDefaultAsync(x => x.Id == bindingId)
- ?? throw new InvalidOperationException("绑定不存在");
- EnsureUnlocked(current);
+ var current = await Repo().GetEditableAsync(bindingId, null);
var material = await _db.Materials.FirstOrDefaultAsync(x => x.Id == current.MaterialId);
var before = Snapshot(current);
var now = DateTimeOffset.UtcNow;
@@ -718,46 +709,6 @@ public sealed class WmsService
return wh;
}
- public async Task MigrateLegacyAsync(string actor = "system")
- {
- var wh = await EnsureDefaultWarehouseAsync(actor);
- var areas = await _db.WarehouseAreas.Where(x => x.WarehouseId == Guid.Empty).ToListAsync();
- foreach (var a in areas)
- a.WarehouseId = wh.Id;
-
- var storages = await _db.Storages.ToListAsync();
- foreach (var s in storages)
- {
- if (s.LevelNo <= 0) s.LevelNo = 1;
- if (s.DepthNo <= 0) s.DepthNo = 1;
- if (string.IsNullOrWhiteSpace(s.SiteCode)) s.SiteCode = s.SiteId;
- if (!StorageStatuses.All.Contains(s.Status))
- s.Status = StorageStatuses.Empty;
- if (!s.Enabled) s.Status = StorageStatuses.Disabled;
- }
-
- var containers = await _db.Containers.ToListAsync();
- foreach (var c in containers)
- {
- if (!ContainerStatuses.All.Contains(c.Status))
- c.Status = ContainerStatuses.EmptyMaterial;
- }
-
- var binds = await _db.ContainerMaterials.ToListAsync();
- foreach (var b in binds)
- {
- b.Quantity = 1;
- if (b.BoundAt == default) b.BoundAt = b.LoadedAt == default ? DateTimeOffset.UtcNow : b.LoadedAt;
- if (!ContainerMaterialStatuses.ActiveBind.Contains(b.Status))
- b.Status = ContainerMaterialStatuses.Bound;
- }
-
- await _uow.SaveChangesAsync();
-
- foreach (var s in storages.Where(x => x.Status != StorageStatuses.Disabled))
- await SyncOccupancyStatus(storageId: s.Id);
- }
-
public async Task> LocationHistory(Guid? containerId = null)
{
var rows = await (containerId.HasValue
@@ -857,16 +808,13 @@ public sealed class WmsService
});
}
+ private IEditableRepository Repo()
+ where T : class, IEntity, ISoftDeletable, IVersioned, ILockable
+ => _services.GetRequiredService>();
+
private Task FindEditable(Guid id, long? version)
where T : class, IEntity, ISoftDeletable, IVersioned, ILockable
- => _services.GetRequiredService>().GetEditableAsync(id, version);
-
- private static void EnsureVersion(EntityBase entity, long? version)
- {
- if (version.HasValue && entity.Version != version.Value)
- throw new MiGu.DB.Abstractions.Exceptions.ConcurrencyConflictException(
- entity.GetType().Name, entity.Id, version);
- }
+ => Repo().GetEditableAsync(id, version);
private static bool IsUniqueConstraintViolation(DbUpdateException ex)
{
@@ -882,19 +830,13 @@ public sealed class WmsService
return false;
}
- private static void EnsureUnlocked(EntityBase entity)
- {
- if (entity.IsLock)
- throw new MiGu.DB.Abstractions.Exceptions.EntityLockedException(entity.GetType().Name, entity.Id);
- }
-
- private static void StampCreate(EntityBase entity, string actor)
+ private static void StampCreate(AggregateRoot entity, string actor)
{
entity.CreatedBy = actor;
entity.UpdatedBy = actor;
}
- private void ApplyCommon(EntityBase entity, CommonRequest req, string actor)
+ private void ApplyCommon(AggregateRoot entity, CommonRequest req, string actor)
{
entity.IsLock = req.IsLock;
entity.Remark = req.Remark.TrimOr("");
@@ -902,11 +844,6 @@ public sealed class WmsService
entity.UpdatedBy = actor;
}
- private static async Task EnsureUnique(IQueryable query, System.Linq.Expressions.Expression> predicate, string message)
- {
- if (await query.AnyAsync(predicate)) throw new InvalidOperationException(message);
- }
-
private string NormalizeExtend(string? extend)
{
if (string.IsNullOrWhiteSpace(extend)) return "{}";
diff --git a/MiGu.Server/Wms/WmsStatusAliases.cs b/MiGu.Server/Wms/WmsStatusAliases.cs
index b5be817..ad4578e 100644
--- a/MiGu.Server/Wms/WmsStatusAliases.cs
+++ b/MiGu.Server/Wms/WmsStatusAliases.cs
@@ -16,4 +16,3 @@ global using WmsDefaults = MiGu.DB.Domains.Wms.WmsDefaults;
global using WmsTransportTaskStatuses = MiGu.DB.Domains.Transport.WmsTransportTaskStatuses;
global using WmsTransportTriggerTypes = MiGu.DB.Domains.Transport.WmsTransportTriggerTypes;
global using WmsReservationStatuses = MiGu.DB.Domains.Transport.WmsReservationStatuses;
-global using WmsDispatchStatuses = MiGu.DB.Domains.Transport.WmsDispatchStatuses;
diff --git a/MiGu.Server/Wms/WmsTransportPlanner.cs b/MiGu.Server/Wms/WmsTransportPlanner.cs
index f978bab..926b532 100644
--- a/MiGu.Server/Wms/WmsTransportPlanner.cs
+++ b/MiGu.Server/Wms/WmsTransportPlanner.cs
@@ -6,10 +6,10 @@ namespace MiGu.Server.Wms;
public sealed class WmsTransportPlanner
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
private readonly JsonSerializerOptions _json = new(JsonSerializerDefaults.Web);
- public WmsTransportPlanner(PlatformDbContext db) => _db = db;
+ public WmsTransportPlanner(MiGuDbContext db) => _db = db;
public async Task PreviewAsync(WmsTransportRequest request)
{
diff --git a/MiGu.Server/Wms/WmsTransportRuleService.cs b/MiGu.Server/Wms/WmsTransportRuleService.cs
index d207288..fbd6fbc 100644
--- a/MiGu.Server/Wms/WmsTransportRuleService.cs
+++ b/MiGu.Server/Wms/WmsTransportRuleService.cs
@@ -7,12 +7,12 @@ namespace MiGu.Server.Wms;
public sealed class WmsTransportRuleService
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
private readonly IEditableRepository _rules;
private readonly IUnitOfWork _uow;
public WmsTransportRuleService(
- PlatformDbContext db,
+ MiGuDbContext db,
IEditableRepository rules,
IUnitOfWork uow)
{
@@ -71,13 +71,13 @@ public sealed class WmsTransportRuleService
await _uow.SaveChangesAsync();
}
- private static void StampCreate(EntityBase entity, string actor)
+ private static void StampCreate(AggregateRoot entity, string actor)
{
entity.CreatedBy = actor;
entity.UpdatedBy = actor;
}
- private static void ApplyCommon(EntityBase entity, CommonRequest req, string actor)
+ private static void ApplyCommon(AggregateRoot entity, CommonRequest req, string actor)
{
entity.IsLock = req.IsLock;
entity.Remark = req.Remark.TrimOr("");
diff --git a/MiGu.Server/Wms/WmsTransportTaskService.cs b/MiGu.Server/Wms/WmsTransportTaskService.cs
index fb842f5..c387f2f 100644
--- a/MiGu.Server/Wms/WmsTransportTaskService.cs
+++ b/MiGu.Server/Wms/WmsTransportTaskService.cs
@@ -6,14 +6,14 @@ namespace MiGu.Server.Wms;
public sealed class WmsTransportTaskService
{
- private readonly PlatformDbContext _db;
+ private readonly MiGuDbContext _db;
private readonly WmsTransportPlanner _planner;
private readonly WmsService _wms;
private readonly IWmsDispatchAdapter _dispatch;
private readonly JsonSerializerOptions _json = new(JsonSerializerDefaults.Web);
public WmsTransportTaskService(
- PlatformDbContext db,
+ MiGuDbContext db,
WmsTransportPlanner planner,
WmsService wms,
IWmsDispatchAdapter dispatch)
@@ -331,7 +331,7 @@ public sealed class WmsTransportTaskService
GeneratedAt = DateTimeOffset.UtcNow
};
- private static void StampCreate(EntityBase entity, string actor)
+ private static void StampCreate(AggregateRoot entity, string actor)
{
entity.CreatedBy = actor;
entity.UpdatedBy = actor;
diff --git a/frontends/apps/simple-platform-vue/src/types/wms.ts b/frontends/apps/simple-platform-vue/src/types/wms.ts
index 7e664a5..9b02643 100644
--- a/frontends/apps/simple-platform-vue/src/types/wms.ts
+++ b/frontends/apps/simple-platform-vue/src/types/wms.ts
@@ -206,7 +206,6 @@ export interface MasterDataPayload {
code: string
name: string
type: string
- status: string
enabled: boolean
sortOrder: number
isLock: boolean
diff --git a/frontends/apps/simple-platform-vue/src/views/admin/WarehouseManagementView.vue b/frontends/apps/simple-platform-vue/src/views/admin/WarehouseManagementView.vue
index 12794ee..1eb5f81 100644
--- a/frontends/apps/simple-platform-vue/src/views/admin/WarehouseManagementView.vue
+++ b/frontends/apps/simple-platform-vue/src/views/admin/WarehouseManagementView.vue
@@ -563,7 +563,7 @@ async function submitDialog() {
...masterForm,
barcode: containerBarcode.value,
length: 0, width: 0, height: 0,
- status: 'EmptyMaterial'
+ status: containers.value.find((c) => c.id === masterForm.id)?.status ?? 'EmptyMaterial'
})
}
else if (kind === 'storage') await wmsApi.saveStorage(storageForm)
@@ -683,7 +683,6 @@ function baseMaster(row?: WarehouseArea | Container): MasterDataPayload {
code: row?.code ?? '',
name: row?.name ?? '',
type: 'type' in (row ?? {}) ? (row as WarehouseArea).type : (row as Container | undefined)?.containerType ?? 'Box',
- status: (row as Container | undefined)?.status ?? 'Idle',
enabled: row?.enabled ?? true,
sortOrder: (row as WarehouseArea | undefined)?.sortOrder ?? 0
}