154 lines
4.6 KiB
C#
154 lines
4.6 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace MiGu.Server.Wms;
|
|
|
|
public sealed class TransportSelector
|
|
{
|
|
public int SchemaVersion { get; set; } = 1;
|
|
public StorageSelectorFilter? Storage { get; set; }
|
|
public ContainerSelectorFilter? Container { get; set; }
|
|
public MaterialSelectorFilter? Material { get; set; }
|
|
public List<RankingRule> Ranking { get; set; } = [];
|
|
}
|
|
|
|
public sealed class StorageSelectorFilter
|
|
{
|
|
public List<string> AreaIds { get; set; } = [];
|
|
public List<string> StorageTypes { get; set; } = [];
|
|
public List<string> ZoneCodes { get; set; } = [];
|
|
public List<string> StatusIn { get; set; } = [];
|
|
public List<string> SiteIds { get; set; } = [];
|
|
public bool? AllowInbound { get; set; }
|
|
public bool? AllowOutbound { get; set; }
|
|
public bool RequireSiteId { get; set; }
|
|
public bool RequireEmpty { get; set; }
|
|
public bool RequireOccupied { get; set; }
|
|
public List<string> ExcludeStorageIds { get; set; } = [];
|
|
}
|
|
|
|
public sealed class ContainerSelectorFilter
|
|
{
|
|
public List<string> ContainerTypes { get; set; } = [];
|
|
public List<string> StatusIn { get; set; } = [];
|
|
public bool ExcludeReserved { get; set; } = true;
|
|
}
|
|
|
|
public sealed class MaterialSelectorFilter
|
|
{
|
|
public List<string> MaterialIds { get; set; } = [];
|
|
public List<string> Categories { get; set; } = [];
|
|
public List<string> StatusIn { get; set; } = [];
|
|
public decimal? MinQuantity { get; set; }
|
|
public string BatchNoMode { get; set; } = "Any";
|
|
}
|
|
|
|
public sealed class RankingRule
|
|
{
|
|
public string Field { get; set; } = "";
|
|
public string Direction { get; set; } = "asc";
|
|
}
|
|
|
|
public sealed class TransportTaskOptions
|
|
{
|
|
public bool AutoReserve { get; set; } = true;
|
|
public bool RequireManualConfirm { get; set; }
|
|
public bool AllowSameStorage { get; set; }
|
|
public int ReservationTtlSeconds { get; set; } = 600;
|
|
public string DispatchMode { get; set; } = "Manual";
|
|
public int MaxCandidateCount { get; set; } = 20;
|
|
}
|
|
|
|
public static class TransportSelectorParser
|
|
{
|
|
private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web)
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
|
};
|
|
|
|
public static TransportSelector ParseSelector(string? json)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(json) || json.Trim() == "{}")
|
|
return new TransportSelector();
|
|
try
|
|
{
|
|
return JsonSerializer.Deserialize<TransportSelector>(json, Json) ?? new TransportSelector();
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
throw new InvalidOperationException($"Selector JSON 无效: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public static TransportTaskOptions ParseTaskOptions(string? json)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(json) || json.Trim() == "{}")
|
|
return new TransportTaskOptions();
|
|
try
|
|
{
|
|
return JsonSerializer.Deserialize<TransportTaskOptions>(json, Json) ?? new TransportTaskOptions();
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
throw new InvalidOperationException($"TaskOptions JSON 无效: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public static string NormalizeSelectorJson(string? json) =>
|
|
JsonSerializer.Serialize(ParseSelector(json), Json);
|
|
|
|
public static string NormalizeTaskOptionsJson(string? json) =>
|
|
JsonSerializer.Serialize(ParseTaskOptions(json), Json);
|
|
}
|
|
|
|
public sealed record WmsTransportRequest(
|
|
string TriggerType,
|
|
Guid? RuleId,
|
|
string? RequestSiteId,
|
|
Guid? MaterialId,
|
|
decimal? Quantity,
|
|
Guid? ContainerId,
|
|
Guid? SourceStorageId,
|
|
Guid? TargetStorageId,
|
|
string? BatchNo,
|
|
int Priority,
|
|
string Reason,
|
|
Dictionary<string, string>? Tags);
|
|
|
|
public sealed record TransportCandidatePair(
|
|
Guid RuleId,
|
|
string RuleCode,
|
|
Guid SourceStorageId,
|
|
string SourceStorageCode,
|
|
Guid TargetStorageId,
|
|
string TargetStorageCode,
|
|
Guid ContainerId,
|
|
string ContainerCode,
|
|
Guid? MaterialId,
|
|
string? MaterialCode,
|
|
decimal? Quantity,
|
|
int Score,
|
|
List<string> RejectReasons);
|
|
|
|
public sealed record TransportCandidatePreview(
|
|
WmsTransportRequest Request,
|
|
List<TransportCandidatePair> Candidates,
|
|
List<RulePreviewResult> RuleResults);
|
|
|
|
public sealed record RulePreviewResult(
|
|
Guid RuleId,
|
|
string RuleCode,
|
|
string RuleName,
|
|
int CandidateCount,
|
|
List<string> RejectReasons);
|
|
|
|
public sealed record DispatchTransportCommand(
|
|
Guid TaskId,
|
|
string SourceSiteId,
|
|
string TargetSiteId,
|
|
string ContainerCode,
|
|
int Priority,
|
|
string BusinessType,
|
|
string Reason);
|