using System.Text;
using System.Text.Json;
namespace Admin.NET.Plugin.AiDOP.Order;
///
/// 销售订单保存前后快照与差异文本(用于操作日志)
///
internal static class SeOrderAuditHelper
{
private static readonly JsonSerializerOptions JsonOpt = new()
{
WriteIndented = false,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
public static string SnapshotOrderJson(SeOrder o)
{
var dict = OrderToFlat(o);
return JsonSerializer.Serialize(dict, JsonOpt);
}
public static string SnapshotEntriesJson(IEnumerable entries)
{
var list = entries
.OrderBy(e => e.EntrySeq ?? 0)
.Select(EntryToFlat)
.ToList();
return JsonSerializer.Serialize(list, JsonOpt);
}
public static string BuildCombinedSnapshotJson(SeOrder? order, List entries)
{
var root = new
{
header = order == null ? null : OrderToFlat(order),
entries = entries.OrderBy(e => e.EntrySeq ?? 0).Select(EntryToFlat).ToList()
};
return JsonSerializer.Serialize(root, JsonOpt);
}
/// 生成「变动前 / 变动后」可读文本 + 结构化 JSON
public static (string Content, string? BeforeJson, string? AfterJson) BuildUpdateDiff(
SeOrder beforeOrder,
List beforeEntries,
SeOrder afterOrder,
List afterEntries)
{
var beforeCombined = BuildCombinedSnapshotJson(beforeOrder, beforeEntries);
var afterCombined = BuildCombinedSnapshotJson(afterOrder, afterEntries);
var sb = new StringBuilder();
sb.Append("修改订单,订单编号:").Append(afterOrder.BillNo ?? "—").Append('。').AppendLine();
var hBefore = OrderToFlat(beforeOrder);
var hAfter = OrderToFlat(afterOrder);
foreach (var key in hBefore.Keys.Union(hAfter.Keys))
{
hBefore.TryGetValue(key, out var ov);
hAfter.TryGetValue(key, out var nv);
if (string.Equals(ov, nv, StringComparison.Ordinal)) continue;
sb.Append(" 【").Append(key).Append("】变动前:「").Append(ov ?? "—").Append("」→ 变动后:「").Append(nv ?? "—").AppendLine("」");
}
var beforeById = beforeEntries.ToDictionary(e => e.Id);
var afterById = afterEntries.ToDictionary(e => e.Id);
foreach (var id in beforeById.Keys.Union(afterById.Keys))
{
beforeById.TryGetValue(id, out var eb);
afterById.TryGetValue(id, out var ea);
if (eb == null && ea != null)
{
sb.Append(" 【新增明细】行").Append(ea.EntrySeq).Append(" 物料:").AppendLine(ea.ItemNumber ?? "—");
continue;
}
if (eb != null && ea == null)
{
sb.Append(" 【删除明细】行").Append(eb.EntrySeq).Append(" 物料:").AppendLine(eb.ItemNumber ?? "—");
continue;
}
if (eb == null || ea == null) continue;
var fb = EntryToFlat(eb);
var fa = EntryToFlat(ea);
var lineChanged = false;
foreach (var key in fb.Keys.Union(fa.Keys))
{
fb.TryGetValue(key, out var ov);
fa.TryGetValue(key, out var nv);
if (string.Equals(ov, nv, StringComparison.Ordinal)) continue;
if (!lineChanged)
{
sb.Append(" 【明细行").Append(ea.EntrySeq).Append("】物料 ").Append(ea.ItemNumber ?? "—").AppendLine();
lineChanged = true;
}
sb.Append(" ").Append(key).Append(":变动前「").Append(ov ?? "—").Append("」→ 变动后「").Append(nv ?? "—").AppendLine("」");
}
}
var content = sb.ToString().TrimEnd();
if (content.IndexOf('→') < 0 && content.IndexOf("【新增明细】", StringComparison.Ordinal) < 0 && content.IndexOf("【删除明细】", StringComparison.Ordinal) < 0)
content = "修改订单,订单编号:" + (afterOrder.BillNo ?? "—") + "。(主表与明细字段无变化)";
return (content, beforeCombined, afterCombined);
}
private static Dictionary OrderToFlat(SeOrder o) => new()
{
["订单编号"] = o.BillNo,
["订单类型"] = o.OrderType switch { 1 => "销售", 2 => "计划", _ => o.OrderType?.ToString() },
["客户编码"] = o.CustomNo,
["客户名称"] = o.CustomName,
["签订日期"] = o.Date?.ToString("yyyy-MM-dd"),
["客户级别"] = o.CustomLevel?.ToString(),
["加急"] = o.Urgent == 1 ? "加急" : "普通",
["客户订单号"] = o.BillFrom,
["国家"] = o.Country,
["客户下单日期"] = o.RDate?.ToString("yyyy-MM-dd"),
["流程状态"] = o.FlowState,
};
private static Dictionary EntryToFlat(SeOrderEntry e) => new()
{
["明细Id"] = e.Id.ToString(),
["行号"] = e.EntrySeq?.ToString(),
["物料编码"] = e.ItemNumber,
["物料名称"] = e.ItemName,
["规格"] = e.Specification,
["单位"] = e.Unit,
["数量"] = e.Qty?.ToString("0.######"),
["客户要求交期"] = e.PlanDate?.ToString("yyyy-MM-dd"),
["最终交货日期"] = e.Date?.ToString("yyyy-MM-dd"),
["系统建议交期"] = e.SysCapacityDate?.ToString("yyyy-MM-dd"),
["备注"] = e.Remark,
["进度"] = e.Progress switch { 0 => "再评审", 1 => "新建", 2 => "评审", 3 => "确认", _ => e.Progress?.ToString() },
["交付数量"] = e.DeliverCount?.ToString("0.######"),
};
}