S8DemoOrderFlowService.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using System.Text.Json;
  2. using Admin.NET.Plugin.AiDOP.Dto.S8.Demo;
  3. using Admin.NET.Plugin.AiDOP.Entity.S8.Demo;
  4. namespace Admin.NET.Plugin.AiDOP.Service.S8.Demo;
  5. /// <summary>
  6. /// ORDER-FLOW-BE-DEMO-DATASET-RESET-1:订单执行档案 demo 只读服务。
  7. /// 双口径:/orders 返回 20 单明细;/aggregate-snapshot 返回独立 105 单基线快照(非明细汇总)。
  8. /// </summary>
  9. public class S8DemoOrderFlowService : ITransient
  10. {
  11. private readonly SqlSugarRepository<AdoDemoOrderFlow> _orderRep;
  12. private readonly SqlSugarRepository<AdoDemoOrderFlowStage> _stageRep;
  13. private readonly SqlSugarRepository<AdoDemoOrderFlowSnapshot> _snapshotRep;
  14. public S8DemoOrderFlowService(
  15. SqlSugarRepository<AdoDemoOrderFlow> orderRep,
  16. SqlSugarRepository<AdoDemoOrderFlowStage> stageRep,
  17. SqlSugarRepository<AdoDemoOrderFlowSnapshot> snapshotRep)
  18. {
  19. _orderRep = orderRep;
  20. _stageRep = stageRep;
  21. _snapshotRep = snapshotRep;
  22. }
  23. public async Task<List<AdoDemoOrderFlowDto>> ListOrdersAsync()
  24. {
  25. var orders = await _orderRep.AsQueryable()
  26. .OrderBy(x => x.SortNo)
  27. .ToListAsync();
  28. if (orders.Count == 0) return new List<AdoDemoOrderFlowDto>();
  29. var orderIds = orders.Select(o => o.Id).ToList();
  30. var stages = await _stageRep.AsQueryable()
  31. .Where(s => orderIds.Contains(s.OrderId))
  32. .OrderBy(s => s.OrderId).OrderBy(s => s.SortNo)
  33. .ToListAsync();
  34. var stagesByOrder = stages.GroupBy(s => s.OrderId).ToDictionary(g => g.Key, g => g.ToList());
  35. return orders.Select(o => MapOrder(o, stagesByOrder.TryGetValue(o.Id, out var ls) ? ls : new())).ToList();
  36. }
  37. public async Task<AdoDemoOrderFlowDto?> GetOrderAsync(string soNo)
  38. {
  39. var order = await _orderRep.AsQueryable().FirstAsync(x => x.SoNo == soNo);
  40. if (order == null) return null;
  41. var stages = await _stageRep.AsQueryable()
  42. .Where(s => s.OrderId == order.Id)
  43. .OrderBy(s => s.SortNo)
  44. .ToListAsync();
  45. return MapOrder(order, stages);
  46. }
  47. public async Task<AdoDemoOrderFlowSnapshotDto?> GetAggregateSnapshotAsync()
  48. {
  49. var row = await _snapshotRep.AsQueryable()
  50. .Where(x => x.SnapshotCode == "CHAIN_AGGREGATE_BASELINE")
  51. .FirstAsync();
  52. if (row == null) return null;
  53. return new AdoDemoOrderFlowSnapshotDto
  54. {
  55. SnapshotCode = row.SnapshotCode,
  56. SnapshotLabel = row.SnapshotLabel,
  57. TotalOrders = row.TotalOrders,
  58. TotalCustomers = row.TotalCustomers,
  59. AvgResponseMinutes = row.AvgResponseMinutes,
  60. AvgProcessingMinutes = row.AvgProcessingMinutes,
  61. AvgLossMinutes = row.AvgLossMinutes,
  62. StageSnapshots = ParseStageSnapshots(row.StageSnapshotsJson),
  63. Remark = row.Remark,
  64. };
  65. }
  66. private static AdoDemoOrderFlowDto MapOrder(AdoDemoOrderFlow o, List<AdoDemoOrderFlowStage> stages) => new()
  67. {
  68. SoNo = o.SoNo,
  69. ProductName = o.ProductName,
  70. ProductLine = o.ProductLine,
  71. CustomerName = o.CustomerName,
  72. CustomerCode = o.CustomerCode,
  73. CustomerType = o.CustomerType,
  74. Region = o.Region,
  75. Priority = o.Priority,
  76. MaterialCode = o.MaterialCode,
  77. SupplierGroup = o.SupplierGroup,
  78. WorkflowStatus = o.WorkflowStatus,
  79. CurrentNodeKey = o.CurrentNodeKey,
  80. FocusNodeKey = o.FocusNodeKey,
  81. CurrentNodeLabel = o.CurrentNodeLabel,
  82. NodeStatus = o.NodeStatus,
  83. ReleaseAt = FormatDateTime(o.ReleaseAt),
  84. TargetCycleDays = o.TargetCycleDays,
  85. CurrentCycleDays = o.CurrentCycleDays,
  86. ActualCycleDays = o.ActualCycleDays,
  87. NodeVarianceDays = o.NodeVarianceDays,
  88. CumulativeVarianceDays = o.CumulativeVarianceDays,
  89. ExceptionCount = o.ExceptionCount,
  90. ResponseMinutes = o.ResponseMinutes,
  91. ProcessingMinutes = o.ProcessingMinutes,
  92. TotalLossMinutes = o.TotalLossMinutes,
  93. ExceptionStatus = o.ExceptionStatus,
  94. Lifecycle = stages.OrderBy(s => s.SortNo).Select(MapStage).ToList(),
  95. };
  96. private static AdoDemoOrderFlowStageDto MapStage(AdoDemoOrderFlowStage s) => new()
  97. {
  98. StageKey = s.StageKey,
  99. StageName = s.StageName,
  100. SortNo = s.SortNo,
  101. PlannedDays = s.PlannedDays,
  102. ActualDays = s.ActualDays,
  103. ExpectedDate = s.ExpectedDate.ToString("yyyy-MM-dd"),
  104. ActualStartAt = s.ActualStartAt.HasValue ? FormatDateTime(s.ActualStartAt.Value) : null,
  105. ActualEndAt = s.ActualEndAt.HasValue ? FormatDateTime(s.ActualEndAt.Value) : null,
  106. Status = s.Status,
  107. NodeVarianceDays = s.NodeVarianceDays,
  108. CumulativeVarianceDays = s.CumulativeVarianceDays,
  109. };
  110. private static string FormatDateTime(DateTime dt) => dt.ToString("yyyy-MM-dd HH:mm");
  111. private static readonly JsonSerializerOptions JsonOpts = new()
  112. {
  113. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  114. PropertyNameCaseInsensitive = true,
  115. };
  116. private static List<AdoDemoOrderFlowStageSnapshotItem> ParseStageSnapshots(string json)
  117. {
  118. if (string.IsNullOrWhiteSpace(json)) return new();
  119. var items = JsonSerializer.Deserialize<List<AdoDemoOrderFlowStageSnapshotItem>>(json, JsonOpts);
  120. return items ?? new();
  121. }
  122. }