新增MES库区管理功能,包含免密接口、数据处理逻辑及相关控制器、服务和实体的实现。支持库区的增删改查操作,优化用户体验并增强系统的实时数据同步能力。
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
using System.Globalization;
|
||||
using YY.Admin.Core.Entity;
|
||||
|
||||
namespace YY.Admin.Core.Util;
|
||||
|
||||
/// <summary>
|
||||
/// 「已入场重量」桌面端本地累计计算器。
|
||||
/// 与后端 IMesXslRawMaterialEntryService.sumEnteredWeightByBillNos 保持同一口径:
|
||||
/// ① 把 totalPortions / portionWeight 按 "x/y/z/" 拆分
|
||||
/// ② 逐位 (份数 × 每份重量) 累加,得到该 entry 的小计
|
||||
/// ③ 同一榜单(BillNo)下所有 entry 的小计再次累加
|
||||
/// 任一位置解析失败或缺失:静默跳过,保证 UI 降级可用。
|
||||
/// </summary>
|
||||
public static class EnteredWeightCalculator
|
||||
{
|
||||
/// <summary>累计一条入场记录的小计。</summary>
|
||||
public static double SumOneEntry(string? totalPortions, string? portionWeight)
|
||||
{
|
||||
var portions = SplitJoined(totalPortions);
|
||||
var weights = SplitJoined(portionWeight);
|
||||
if (portions.Length == 0 || weights.Length == 0)
|
||||
{
|
||||
return 0d;
|
||||
}
|
||||
var n = Math.Min(portions.Length, weights.Length);
|
||||
double sum = 0d;
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
if (!TryParse(portions[i], out var p) || !TryParse(weights[i], out var w))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sum += p * w;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// <summary>按 BillNo 分组累计「已入场重量」。返回 Dictionary<BillNo, 总和>。</summary>
|
||||
public static Dictionary<string, double> SumByBillNos(
|
||||
IEnumerable<MesXslRawMaterialEntry> entries,
|
||||
IEnumerable<string?> billNos)
|
||||
{
|
||||
var keys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var b in billNos)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(b)) keys.Add(b!);
|
||||
}
|
||||
var result = new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase);
|
||||
if (keys.Count == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var e in entries)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.BillNo) || !keys.Contains(e.BillNo!))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var sub = SumOneEntry(e.TotalPortions, e.PortionWeight);
|
||||
if (sub == 0d)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (result.TryGetValue(e.BillNo!, out var acc))
|
||||
{
|
||||
result[e.BillNo!] = acc + sub;
|
||||
}
|
||||
else
|
||||
{
|
||||
result[e.BillNo!] = sub;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string[] SplitJoined(string? value)
|
||||
{
|
||||
// 兼容 "x/y/z" 与 "x/y/z/" 两种格式;过滤空段
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
return value.Split('/')
|
||||
.Select(s => s.Trim())
|
||||
.Where(s => s.Length > 0)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static bool TryParse(string s, out double v) =>
|
||||
double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out v);
|
||||
}
|
||||
Reference in New Issue
Block a user