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