using Admin.NET.Plugin.AiDOP.Entity.S8.OrderFlow; namespace Admin.NET.Plugin.AiDOP.SeedData; /// /// S8-ORDER-EXECUTION-ORDER-REVIEW-SUBSTEP-PERSIST-1:ORDER_REVIEW_PLAN_CALC 阶段 L3 责任单元种子。 /// 20 单 × 5 L2 × N 责任单元(4+3+3+3+2 = 15 / 单)= 300 行;每条 L3 由父 L2 的 piHours / actualHours 按 /// 部门权重严格回卷生成(合计 = 父 L2 同字段),actualHours 缺失时全部 pending。 /// 责任单元仅使用既有真实业务部门:法律事务部 / 技术售前组 / 综合主计划 / 试验站 / 市场部 / 研发中心。 /// [IncreSeed] public class S8OrderFlowSubstepUnitSeedData : ISqlSugarEntitySeedData { public IEnumerable HasData() => S8OrderFlowSubstepUnitDataset.BuildUnits(); } internal static class S8OrderFlowSubstepUnitDataset { internal const long UnitIdBase = 1329909130000L; internal const string FlowCode = "ORDER_REVIEW_PLAN_CALC"; /// L3 责任单元定义。 internal readonly record struct UnitDef(string Code, string Name, decimal Weight); /// /// 5 个 L2 子节点的 L3 责任单元模板:每个 substep_code → 责任单元列表(含权重,合计 1.00)。 /// UnitCode 既有 4 项(LEGAL / TECH_PRESALE / GENERAL_PLAN / LAB),新增 2 项(MARKETING / RND)。 /// 部门名全部来自既有 stage-meta / 既有 seed,未引入新部门。 /// internal static readonly Dictionary L3Template = new() { ["OPINION_REVIEW"] = new[] { new UnitDef("LEGAL", "法律事务部", 0.30m), new UnitDef("TECH_PRESALE", "技术售前组", 0.35m), new UnitDef("GENERAL_PLAN", "综合主计划", 0.15m), new UnitDef("LAB", "试验站", 0.20m), }, ["OPINION_FEEDBACK"] = new[] { new UnitDef("MARKETING", "市场部", 0.40m), new UnitDef("TECH_PRESALE", "技术售前组", 0.35m), new UnitDef("GENERAL_PLAN", "综合主计划", 0.25m), }, ["SECOND_REVIEW"] = new[] { new UnitDef("TECH_PRESALE", "技术售前组", 0.40m), new UnitDef("RND", "研发中心", 0.35m), new UnitDef("GENERAL_PLAN", "综合主计划", 0.25m), }, ["LEADER_REVIEW"] = new[] { new UnitDef("MARKETING", "市场部", 0.35m), new UnitDef("RND", "研发中心", 0.40m), new UnitDef("GENERAL_PLAN", "综合主计划", 0.25m), }, ["CONTRACT_SEAL"] = new[] { new UnitDef("LEGAL", "法律事务部", 0.70m), new UnitDef("MARKETING", "市场部", 0.30m), }, }; public static IEnumerable BuildUnits() { long seq = 0; foreach (var spec in S8OrderFlowDataset.Specs) { var orderId = S8OrderFlowDataset.OrderIdBase + spec.Idx; var scenario = spec.OrderCode == "SO-2026-001" ? "PPT" : "DEMO"; var l2Rows = S8OrderFlowSubstepDataset.BuildL2Rows(spec); for (var substepIdx = 0; substepIdx < S8OrderFlowSubstepDataset.L2Def.Length; substepIdx++) { var (substepCode, _, _) = S8OrderFlowSubstepDataset.L2Def[substepIdx]; var template = L3Template[substepCode]; var substepId = S8OrderFlowSubstepDataset.SubstepIdAt(spec.Idx, substepIdx); var l2Row = l2Rows[substepIdx]; var weights = template.Select(u => u.Weight).ToArray(); var piHoursArr = S8OrderFlowSubstepDataset.AllocateByWeight(l2Row.PiHours, weights); decimal[]? actualHoursArr = l2Row.ActualHours == null ? null : S8OrderFlowSubstepDataset.AllocateByWeight(l2Row.ActualHours.Value, weights); for (var i = 0; i < template.Length; i++) { var unit = template[i]; var actual = actualHoursArr?[i]; var status = actual == null ? "pending" : S8OrderFlowSubstepDataset.ClassifyByPi(actual.Value, piHoursArr[i]); yield return new AdoS8OrderFlowSubstepUnit { Id = UnitIdBase + (++seq), SubstepId = substepId, OrderId = orderId, OrderCode = spec.OrderCode, OrderFlowCode = FlowCode, SubstepCode = substepCode, UnitCode = unit.Code, UnitName = unit.Name, PiHours = piHoursArr[i], ActualHours = actual, Status = status, SortNo = i + 1, ScenarioCode = scenario, DataSource = "SEED", TenantId = 1, FactoryId = 1, CreatedAt = S8OrderFlowDataset.CreatedAt, UpdatedAt = null, IsDeleted = false, }; } } } } }