|
|
@@ -0,0 +1,318 @@
|
|
|
+using Admin.NET.Plugin.AiDOP.Entity.S8.Demo;
|
|
|
+
|
|
|
+namespace Admin.NET.Plugin.AiDOP;
|
|
|
+
|
|
|
+/// <summary>
|
|
|
+/// ORDER-FLOW-BE-DEMO-DATASET-RESET-1:demo 订单执行档案种子(1 主表 + 阶段子表 + 1 快照)。
|
|
|
+/// 全局基线:tenant_id=0 / factory_id=0。SO-2026-001 = PPT 第 1 页标准案例;其余 19 单覆盖筛选维度。
|
|
|
+/// </summary>
|
|
|
+[IncreSeed]
|
|
|
+public class S8DemoOrderFlowSeedData : ISqlSugarEntitySeedData<AdoDemoOrderFlow>
|
|
|
+{
|
|
|
+ public IEnumerable<AdoDemoOrderFlow> HasData() => S8DemoOrderFlowDataset.BuildOrders();
|
|
|
+}
|
|
|
+
|
|
|
+[IncreSeed]
|
|
|
+public class S8DemoOrderFlowStageSeedData : ISqlSugarEntitySeedData<AdoDemoOrderFlowStage>
|
|
|
+{
|
|
|
+ public IEnumerable<AdoDemoOrderFlowStage> HasData() => S8DemoOrderFlowDataset.BuildStages();
|
|
|
+}
|
|
|
+
|
|
|
+[IncreSeed]
|
|
|
+public class S8DemoOrderFlowSnapshotSeedData : ISqlSugarEntitySeedData<AdoDemoOrderFlowSnapshot>
|
|
|
+{
|
|
|
+ public IEnumerable<AdoDemoOrderFlowSnapshot> HasData() => S8DemoOrderFlowDataset.BuildSnapshot();
|
|
|
+}
|
|
|
+
|
|
|
+internal static class S8DemoOrderFlowDataset
|
|
|
+{
|
|
|
+ private static readonly DateTime CreatedAt = DateTime.Parse("2026-05-11 00:00:00");
|
|
|
+ private const long OrderIdBase = 1329909000000L;
|
|
|
+ private const long StageIdBase = 1329909010000L;
|
|
|
+ private const long SnapshotIdBase = 1329909020000L;
|
|
|
+
|
|
|
+ private record OrderSpec(
|
|
|
+ int Idx, string SoNo, string ProductName,
|
|
|
+ string CustomerName, string CustomerCode, string CustomerType,
|
|
|
+ string ProductLine, string MaterialCode, string Region,
|
|
|
+ string Priority, string SupplierGroup,
|
|
|
+ string WorkflowStatus, string CurrentNodeKey, string FocusNodeKey,
|
|
|
+ int ExceptionCount, int? ResponseMinutes, int? ProcessingMinutes, int? TotalLossMinutes);
|
|
|
+
|
|
|
+ // SO-2026-001 单独硬编码:必须严格匹配 PPT 第 1 页。其余 19 单按模板生成。
|
|
|
+ private static readonly OrderSpec[] Specs =
|
|
|
+ {
|
|
|
+ new(1, "SO-2026-001", "高压接线盒", "电气设备厂A", "C001", "KA", "A产品线", "XX", "华北", "P2", "A", "completed", "final_assembly_shipping", "final_assembly_shipping", 2, 2880, 1440, 4320),
|
|
|
+ new(2, "SO-2026-002", "转向机总成", "电气设备厂B", "C002", "KA", "B产品线", "YY", "华东", "P3", "B", "completed", "final_assembly_shipping", "material_procurement", 1, 110, 850, 960),
|
|
|
+ new(3, "SO-2026-003", "电池箱横梁", "电气设备厂C", "C003", "KA", "C产品线", "ZZ", "华南", "P2", "C", "completed", "final_assembly_shipping", "body_production", 1, 80, 720, 800),
|
|
|
+ new(4, "SO-2026-004", "高压接线盒", "电气设备厂D", "C004", "SMB", "A产品线", "XX", "华北", "P3", "A", "completed", "final_assembly_shipping", "product_design", 1, 95, 680, 775),
|
|
|
+ new(5, "SO-2026-005", "电池箱横梁", "电气设备厂E", "C005", "MICRO", "C产品线", "ZZ", "华南", "P2", "B", "completed", "final_assembly_shipping", "product_design", 1, 70, 610, 680),
|
|
|
+ new(6, "SO-2026-006", "驱动总成支架", "电气设备厂A", "C001", "KA", "A产品线", "XX", "华北", "P2", "C", "completed", "final_assembly_shipping", "material_procurement", 2, 130, 1240, 2350),
|
|
|
+ new(7, "SO-2026-007", "减速器壳体", "电气设备厂B", "C002", "KA", "B产品线", "YY", "华东", "P2", "A", "completed", "final_assembly_shipping", "body_production", 2, 145, 1080, 2210),
|
|
|
+ new(8, "SO-2026-008", "项目定制骨架", "电气设备厂C", "C003", "KA", "C产品线", "ZZ", "华南", "P1", "B", "completed", "final_assembly_shipping", "body_production", 2, 165, 1320, 2640),
|
|
|
+ new(9, "SO-2026-009", "控制器外壳", "电气设备厂D", "C004", "SMB", "A产品线", "XX", "华北", "P2", "C", "completed", "final_assembly_shipping", "order_review", 1, 60, 540, 600),
|
|
|
+ new(10, "SO-2026-010", "试制急单件", "电气设备厂E", "C005", "MICRO", "C产品线", "ZZ", "华南", "P2", "A", "completed", "final_assembly_shipping", "product_design", 1, 88, 730, 818),
|
|
|
+ new(11, "SO-2026-011", "冷却模块框架", "电气设备厂A", "C001", "KA", "B产品线", "YY", "华东", "P2", "B", "completed", "final_assembly_shipping", "final_assembly_shipping", 1, 50, 410, 460),
|
|
|
+ new(12, "SO-2026-012", "动力舱隔板", "电气设备厂B", "C002", "KA", "B产品线", "YY", "华东", "P2", "C", "completed", "final_assembly_shipping", "material_procurement", 1, 100, 920, 1020),
|
|
|
+ new(13, "SO-2026-013", "模组支架", "电气设备厂C", "C003", "KA", "C产品线", "ZZ", "华南", "P2", "A", "completed", "final_assembly_shipping", "body_production", 1, 92, 860, 952),
|
|
|
+ new(14, "SO-2026-014", "一体化支撑件", "电气设备厂D", "C004", "SMB", "A产品线", "XX", "华北", "P3", "B", "completed", "final_assembly_shipping", "material_procurement", 1, 75, 700, 775),
|
|
|
+ new(15, "SO-2026-015", "项目定制骨架", "电气设备厂E", "C005", "MICRO", "C产品线", "ZZ", "华南", "P2", "C", "completed", "final_assembly_shipping", "order_review", 1, 65, 580, 645),
|
|
|
+ new(16, "SO-2026-016", "控制器外壳", "电气设备厂A", "C001", "KA", "A产品线", "XX", "华北", "P2", "A", "in_progress", "order_review", "order_review", 1, 90, null, null),
|
|
|
+ new(17, "SO-2026-017", "转向机总成", "电气设备厂B", "C002", "KA", "B产品线", "YY", "华东", "P2", "B", "in_progress", "product_design", "product_design", 1, 105, null, null),
|
|
|
+ new(18, "SO-2026-018", "项目定制骨架", "电气设备厂C", "C003", "KA", "C产品线", "ZZ", "华南", "P2", "C", "in_progress", "material_procurement", "material_procurement", 1, 120, null, null),
|
|
|
+ new(19, "SO-2026-019", "驱动总成支架", "电气设备厂D", "C004", "SMB", "A产品线", "XX", "华北", "P1", "A", "in_progress", "body_production", "body_production", 2, 140, null, null),
|
|
|
+ new(20, "SO-2026-020", "试制急单件", "电气设备厂E", "C005", "MICRO", "C产品线", "ZZ", "华南", "P1", "B", "in_progress", "final_assembly_shipping", "final_assembly_shipping", 1, 55, null, null),
|
|
|
+ };
|
|
|
+
|
|
|
+ private static readonly (string key, string name, decimal kpi)[] StageDef =
|
|
|
+ {
|
|
|
+ ("order_review", "订单评审", 5m),
|
|
|
+ ("product_design", "产品设计", 3m),
|
|
|
+ ("material_procurement", "材料采购", 14m),
|
|
|
+ ("body_production", "本体生产", 6m),
|
|
|
+ ("final_assembly_shipping", "总装发货", 3m),
|
|
|
+ };
|
|
|
+
|
|
|
+ public static IEnumerable<AdoDemoOrderFlow> BuildOrders()
|
|
|
+ {
|
|
|
+ foreach (var spec in Specs)
|
|
|
+ {
|
|
|
+ var lifecycle = BuildLifecycleValues(spec);
|
|
|
+ var release = new DateTime(2026, 4, 15, 9, 0, 0);
|
|
|
+ var lastEnd = lifecycle.Last().actualEnd;
|
|
|
+ var targetCycle = StageDef.Sum(s => s.kpi);
|
|
|
+ decimal? currentCycleDays = null;
|
|
|
+ decimal? actualCycleDays = null;
|
|
|
+ if (spec.WorkflowStatus == "completed" && lastEnd.HasValue)
|
|
|
+ {
|
|
|
+ var days = decimal.Round((decimal)(lastEnd.Value - release).TotalDays, 1);
|
|
|
+ currentCycleDays = days;
|
|
|
+ actualCycleDays = days;
|
|
|
+ }
|
|
|
+ var currentStage = lifecycle.FirstOrDefault(x => x.key == spec.CurrentNodeKey);
|
|
|
+ var nodeStatus = currentStage.status switch
|
|
|
+ {
|
|
|
+ "red" => "red",
|
|
|
+ "yellow" => "yellow",
|
|
|
+ "pending" => "yellow",
|
|
|
+ _ => "green",
|
|
|
+ };
|
|
|
+
|
|
|
+ yield return new AdoDemoOrderFlow
|
|
|
+ {
|
|
|
+ Id = OrderIdBase + spec.Idx,
|
|
|
+ SoNo = spec.SoNo,
|
|
|
+ ProductName = spec.ProductName,
|
|
|
+ ProductLine = spec.ProductLine,
|
|
|
+ CustomerName = spec.CustomerName,
|
|
|
+ CustomerCode = spec.CustomerCode,
|
|
|
+ CustomerType = spec.CustomerType,
|
|
|
+ Region = spec.Region,
|
|
|
+ Priority = spec.Priority,
|
|
|
+ MaterialCode = spec.MaterialCode,
|
|
|
+ SupplierGroup = spec.SupplierGroup,
|
|
|
+ WorkflowStatus = spec.WorkflowStatus,
|
|
|
+ CurrentNodeKey = spec.CurrentNodeKey,
|
|
|
+ FocusNodeKey = spec.FocusNodeKey,
|
|
|
+ CurrentNodeLabel = NameOf(spec.CurrentNodeKey),
|
|
|
+ NodeStatus = nodeStatus,
|
|
|
+ ReleaseAt = release,
|
|
|
+ TargetCycleDays = targetCycle,
|
|
|
+ CurrentCycleDays = currentCycleDays,
|
|
|
+ ActualCycleDays = actualCycleDays,
|
|
|
+ NodeVarianceDays = currentStage.nodeVar,
|
|
|
+ CumulativeVarianceDays = currentStage.cumVar,
|
|
|
+ ExceptionCount = spec.ExceptionCount,
|
|
|
+ ResponseMinutes = spec.ResponseMinutes,
|
|
|
+ ProcessingMinutes = spec.ProcessingMinutes,
|
|
|
+ TotalLossMinutes = spec.TotalLossMinutes,
|
|
|
+ ExceptionStatus = spec.WorkflowStatus == "completed" ? "已闭环" : "处理中",
|
|
|
+ SortNo = spec.Idx,
|
|
|
+ TenantId = 0,
|
|
|
+ FactoryId = 0,
|
|
|
+ CreatedAt = CreatedAt,
|
|
|
+ UpdatedAt = null,
|
|
|
+ IsDeleted = false,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IEnumerable<AdoDemoOrderFlowStage> BuildStages()
|
|
|
+ {
|
|
|
+ long stageSeq = 0;
|
|
|
+ foreach (var spec in Specs)
|
|
|
+ {
|
|
|
+ var orderId = OrderIdBase + spec.Idx;
|
|
|
+ var lifecycle = BuildLifecycleValues(spec);
|
|
|
+ for (var i = 0; i < lifecycle.Length; i++)
|
|
|
+ {
|
|
|
+ var s = lifecycle[i];
|
|
|
+ yield return new AdoDemoOrderFlowStage
|
|
|
+ {
|
|
|
+ Id = StageIdBase + (++stageSeq),
|
|
|
+ OrderId = orderId,
|
|
|
+ StageKey = s.key,
|
|
|
+ StageName = s.name,
|
|
|
+ SortNo = i + 1,
|
|
|
+ PlannedDays = s.kpi,
|
|
|
+ ActualDays = s.actualDays,
|
|
|
+ ExpectedDate = s.expected.Date,
|
|
|
+ ActualStartAt = s.actualStart,
|
|
|
+ ActualEndAt = s.actualEnd,
|
|
|
+ Status = s.status,
|
|
|
+ NodeVarianceDays = s.nodeVar,
|
|
|
+ CumulativeVarianceDays = s.cumVar,
|
|
|
+ TenantId = 0,
|
|
|
+ FactoryId = 0,
|
|
|
+ CreatedAt = CreatedAt,
|
|
|
+ UpdatedAt = null,
|
|
|
+ IsDeleted = false,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IEnumerable<AdoDemoOrderFlowSnapshot> BuildSnapshot()
|
|
|
+ {
|
|
|
+ const string stageJson = """
|
|
|
+[
|
|
|
+ {"stageKey":"order_review","stageName":"订单评审","ownerDept":"市场部","kpiAvgDays":5.0,"actualAvgDays":6.2,"onTimeRate":59,"green":62,"yellow":19,"red":24,"pending":0},
|
|
|
+ {"stageKey":"product_design","stageName":"产品设计","ownerDept":"研发中心","kpiAvgDays":3.0,"actualAvgDays":2.6,"onTimeRate":96,"green":99,"yellow":2,"red":2,"pending":2},
|
|
|
+ {"stageKey":"material_procurement","stageName":"材料采购","ownerDept":"供应链部","kpiAvgDays":14.0,"actualAvgDays":15.5,"onTimeRate":85,"green":86,"yellow":1,"red":14,"pending":4},
|
|
|
+ {"stageKey":"body_production","stageName":"本体生产","ownerDept":"生产部","kpiAvgDays":6.0,"actualAvgDays":6.7,"onTimeRate":89,"green":87,"yellow":2,"red":9,"pending":7},
|
|
|
+ {"stageKey":"final_assembly_shipping","stageName":"总装发货","ownerDept":"生产部","kpiAvgDays":3.0,"actualAvgDays":2.9,"onTimeRate":96,"green":92,"yellow":1,"red":3,"pending":9}
|
|
|
+]
|
|
|
+""";
|
|
|
+ yield return new AdoDemoOrderFlowSnapshot
|
|
|
+ {
|
|
|
+ Id = SnapshotIdBase + 1,
|
|
|
+ SnapshotCode = "CHAIN_AGGREGATE_BASELINE",
|
|
|
+ SnapshotLabel = "基线聚合 · 样本 105",
|
|
|
+ TotalOrders = 105,
|
|
|
+ TotalCustomers = 5,
|
|
|
+ AvgResponseMinutes = 91.20m,
|
|
|
+ AvgProcessingMinutes = 1060.50m,
|
|
|
+ AvgLossMinutes = 1472.50m,
|
|
|
+ StageSnapshotsJson = stageJson.Trim(),
|
|
|
+ Remark = "演示基线快照,与明细 20 单不一致是预期",
|
|
|
+ TenantId = 0,
|
|
|
+ FactoryId = 0,
|
|
|
+ CreatedAt = CreatedAt,
|
|
|
+ UpdatedAt = null,
|
|
|
+ IsDeleted = false,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string NameOf(string key) => StageDef.First(s => s.key == key).name;
|
|
|
+
|
|
|
+ private record StageRow(
|
|
|
+ string key, string name, decimal kpi, decimal actualDays,
|
|
|
+ DateTime expected, DateTime? actualStart, DateTime? actualEnd,
|
|
|
+ string status, decimal? nodeVar, decimal? cumVar);
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// SO-2026-001 严格按 PPT;其余 19 单按 spec.FocusNodeKey 套模板。
|
|
|
+ /// </summary>
|
|
|
+ private static StageRow[] BuildLifecycleValues(OrderSpec spec)
|
|
|
+ {
|
|
|
+ if (spec.SoNo == "SO-2026-001") return BuildSo001Lifecycle();
|
|
|
+
|
|
|
+ // 模板:默认每阶段 actualDays=KPI, nodeVar=0, status=green;
|
|
|
+ // 焦点阶段按一份固定偏差替换;total 5 阶段连续日期。
|
|
|
+ var release = new DateTime(2026, 4, 15, 9, 0, 0);
|
|
|
+ var (focusNodeVar, focusActual) = spec.FocusNodeKey switch
|
|
|
+ {
|
|
|
+ "order_review" => (+2m, 7m),
|
|
|
+ "product_design" => (+2m, 5m),
|
|
|
+ "material_procurement" => (+2m, 16m),
|
|
|
+ "body_production" => (+2m, 8m),
|
|
|
+ "final_assembly_shipping" => (+1m, 4m),
|
|
|
+ _ => (0m, 0m),
|
|
|
+ };
|
|
|
+ var focusStatus = spec.FocusNodeKey switch
|
|
|
+ {
|
|
|
+ "order_review" => "red",
|
|
|
+ "product_design" => "red",
|
|
|
+ "material_procurement" => "yellow",
|
|
|
+ "body_production" => "yellow",
|
|
|
+ "final_assembly_shipping" => "yellow",
|
|
|
+ _ => "green",
|
|
|
+ };
|
|
|
+
|
|
|
+ var rows = new StageRow[5];
|
|
|
+ var cumVar = 0m;
|
|
|
+ var cursor = release;
|
|
|
+ for (var i = 0; i < 5; i++)
|
|
|
+ {
|
|
|
+ var (key, name, kpi) = StageDef[i];
|
|
|
+ decimal actualDays = kpi;
|
|
|
+ decimal nodeVar = 0;
|
|
|
+ string status = "green";
|
|
|
+ if (key == spec.FocusNodeKey)
|
|
|
+ {
|
|
|
+ actualDays = focusActual;
|
|
|
+ nodeVar = focusNodeVar;
|
|
|
+ status = focusStatus;
|
|
|
+ }
|
|
|
+ cumVar += nodeVar;
|
|
|
+
|
|
|
+ DateTime? actualStart = null;
|
|
|
+ DateTime? actualEnd = null;
|
|
|
+ string currentNodeKey = spec.CurrentNodeKey;
|
|
|
+ int currentNodeIdx = Array.FindIndex(StageDef, s => s.key == currentNodeKey);
|
|
|
+
|
|
|
+ // in_progress 单:当前节点之前 actualEnd 都填;当前节点仅 actualStart;之后阶段都为 null
|
|
|
+ if (spec.WorkflowStatus == "completed" || i < currentNodeIdx)
|
|
|
+ {
|
|
|
+ actualStart = cursor;
|
|
|
+ actualEnd = cursor.AddDays((double)actualDays);
|
|
|
+ cursor = actualEnd.Value;
|
|
|
+ }
|
|
|
+ else if (i == currentNodeIdx)
|
|
|
+ {
|
|
|
+ actualStart = cursor;
|
|
|
+ actualEnd = null;
|
|
|
+ actualDays = 0; // 仍未完成
|
|
|
+ status = "pending";
|
|
|
+ nodeVar = 0;
|
|
|
+ cumVar = (i == 0) ? 0m : rows[i - 1].cumVar ?? 0m;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ actualStart = null;
|
|
|
+ actualEnd = null;
|
|
|
+ actualDays = 0;
|
|
|
+ status = "pending";
|
|
|
+ nodeVar = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ DateTime expected = release.AddDays((double)StageDef.Take(i + 1).Sum(s => s.kpi));
|
|
|
+
|
|
|
+ rows[i] = new StageRow(
|
|
|
+ key, name, kpi,
|
|
|
+ actualDays,
|
|
|
+ expected,
|
|
|
+ actualStart,
|
|
|
+ actualEnd,
|
|
|
+ status,
|
|
|
+ status == "pending" ? null : nodeVar,
|
|
|
+ status == "pending" ? null : cumVar);
|
|
|
+ }
|
|
|
+ return rows;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>SO-2026-001 PPT 第 1 页 hard-coded 真值(不可改)。</summary>
|
|
|
+ private static StageRow[] BuildSo001Lifecycle()
|
|
|
+ {
|
|
|
+ DateTime D(int m, int d, int h, int mi) => new(2026, m, d, h, mi, 0);
|
|
|
+
|
|
|
+ return new[]
|
|
|
+ {
|
|
|
+ new StageRow("order_review", "订单评审", 5m, 5m, new DateTime(2026, 4, 20), D(4, 15, 9, 0), D(4, 20, 15, 0), "green", 0m, 0m),
|
|
|
+ new StageRow("product_design", "产品设计", 3m, 5m, new DateTime(2026, 4, 23), D(4, 20, 15, 0), D(4, 25, 10, 0), "red", +2m, +2m),
|
|
|
+ new StageRow("material_procurement", "材料采购", 14m, 13m, new DateTime(2026, 5, 6), D(4, 25, 10, 0), D(5, 7, 14, 0), "yellow",-1m, +1m),
|
|
|
+ new StageRow("body_production", "本体生产", 6m, 5m, new DateTime(2026, 5, 12), D(5, 7, 14, 0), D(5, 12, 18, 0), "green", -1m, 0m),
|
|
|
+ new StageRow("final_assembly_shipping", "总装发货", 3m, 3m, new DateTime(2026, 5, 15), D(5, 12, 18, 0), D(5, 15, 10, 0), "green", 0m, 0m),
|
|
|
+ };
|
|
|
+ }
|
|
|
+}
|