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,
};
}
}
}
}
}