using Admin.NET.Plugin.AiDOP.Entity.S8.OrderFlow;
namespace Admin.NET.Plugin.AiDOP.SeedData;
///
/// S8-ORDER-CHAIN-PRODUCT-DESIGN-PPT-STATIC-AND-SINGLE-ORDER-ALIGN-1:S8 订单链路产品设计阶段基准业务初始化数据种子。
/// 20 单 × 63 图号;按业务口径修正:
/// 1) COUNT(DISTINCT drawing_no) = 63;STANDARD=52 / NON_STANDARD=11
/// 2) SUM(product_quantity ALL) = 382;STANDARD=357 / NON_STANDARD=25
/// 3) PRODUCT_DESIGN 阶段统一 KPI=3 天:STANDARD 与 NON_STANDARD 的 kpi_days 均为 3
/// 4) NON_STANDARD 图号 actual_days 全部 > 3 → is_achieved=false / status='red'
/// 5) STANDARD 51 张图号 actual_days ≤ 3 → is_achieved=true / status='green';1 张超期 actual=4.50 → red
/// 6) AVG(actual_days WHERE product_type='STANDARD') 落在 [1.17, 1.21]
/// 7) AVG(actual_days WHERE product_type='NON_STANDARD') 落在 [9.25, 9.31]
/// 图号编码:常规 D-{OrderCode}-G{NN};非标 D-{OrderCode}-X{NN}(绑定 SO-2026-001..020 真实 OrderCode)。
/// 责任人字段承载具体设计师姓名(产品设计阶段基准业务初始化数据,6 人按全表全局递增序号 seq 循环分配,确保 6 桶全覆盖)。
/// 默认基线展示(顶部 2.5 / 98 + 分类汇总 354/28/382 PPT 口径)由 snapshot 表与前端基线数据共同支撑;
/// 本表负责单订单态与多订单态的图号粒度真实数据。
///
[IncreSeed]
public class S8OrderFlowProductDesignDrawingSeedData
: ISqlSugarEntitySeedData
{
public IEnumerable HasData()
=> S8OrderFlowProductDesignDrawingDataset.BuildDrawings();
}
internal static class S8OrderFlowProductDesignDrawingDataset
{
/// 图号 id 基址(与其他 S8 种子号段隔离)。
internal const long IdBase = 1329909130000L;
internal const string ProductTypeStandard = "STANDARD";
internal const string ProductTypeNonStandard = "NON_STANDARD";
/// 常规产品 KPI(天)。PRODUCT_DESIGN 阶段统一标准。
internal const decimal StandardKpiDays = 3.00m;
/// 非标产品 KPI(天)。与常规产品同阶段标准。
internal const decimal NonStandardKpiDays = 3.00m;
/// 产品设计阶段基准业务初始化数据:设计师姓名清单(6 人按全表全局递增序号 seq 循环分配,sort_no 仅为订单内序号,无法保证 6 桶全覆盖)。
private static readonly string[] Designers =
{
"李海峰",
"陈思远",
"王明华",
"赵建国",
"刘振宇",
"周启明",
};
///
/// 每订单 (常规图号数, 非标图号数)。20 行合计 52 / 11;其中 4 单 4 图、16 单 3 图。
/// 非标集中在大客户、P1 优先级与 in_progress 订单上,与业务直觉一致。
///
private static readonly (int StdCount, int NonStdCount)[] PerOrderConfig =
{
// SO-2026-001..005
(3, 1), (3, 1), (3, 1), (3, 0), (3, 0),
// SO-2026-006..010
(2, 1), (2, 1), (2, 1), (3, 0), (3, 0),
// SO-2026-011..015
(3, 0), (2, 1), (3, 0), (3, 0), (3, 0),
// SO-2026-016..020
(3, 0), (2, 1), (2, 1), (2, 1), (2, 1),
};
/// 52 张常规图号 spec:合计 actual_days=61.88、qty=357、1 张超期 (qty=3)。
private static readonly DrawingSpec[] StandardSequence = BuildStandardSequence();
/// 11 张非标图号 spec:合计 actual_days=102.08、qty=25;全部 actual_days > 3 → 全部不达标 red。
private static readonly DrawingSpec[] NonStandardSequence = BuildNonStandardSequence();
/// 单张图号的回卷规格:actual_days / quantity / is_achieved / status。
internal readonly record struct DrawingSpec(decimal ActualDays, int Quantity, bool IsAchieved, string Status);
private static DrawingSpec[] BuildStandardSequence()
{
// 52 张分布:24×(1.13, qty=7) + 24×(1.12, qty=7) + 2×(1.13, qty=6) + 1×(1.12, qty=6) + 1×(4.50, qty=3, red)
// actual_days 合计 = 24×1.13 + 24×1.12 + 2×1.13 + 1×1.12 + 4.50
// = 27.12 + 26.88 + 2.26 + 1.12 + 4.50 = 61.88 → avg 1.190 (在 [1.17, 1.21])
// quantity 合计 = 24×7 + 24×7 + 2×6 + 1×6 + 3 = 168 + 168 + 12 + 6 + 3 = 357
var seq = new DrawingSpec[52];
for (var i = 0; i < 24; i++) seq[i] = new DrawingSpec(1.13m, 7, true, "green");
for (var i = 24; i < 48; i++) seq[i] = new DrawingSpec(1.12m, 7, true, "green");
seq[48] = new DrawingSpec(1.13m, 6, true, "green");
seq[49] = new DrawingSpec(1.13m, 6, true, "green");
seq[50] = new DrawingSpec(1.12m, 6, true, "green");
// 唯一一张超期常规图号:actual=4.50 > kpi=3 → (4.5-3)/3 = 0.50 > 0.20 → red
seq[51] = new DrawingSpec(4.50m, 3, false, "red");
return seq;
}
private static DrawingSpec[] BuildNonStandardSequence()
{
// 11 张分布:5×(8.34, qty=1) + 4×(8.34, qty=2) + 2×(13.51, qty=6)
// actual_days 合计 = 9×8.34 + 2×13.51 = 75.06 + 27.02 = 102.08 → avg 9.28 (在 [9.25, 9.31])
// quantity 合计 = 5×1 + 4×2 + 2×6 = 5 + 8 + 12 = 25
// 非标 KPI=3 后,所有 actual_days ≥ 8.34 > 3 → 全部 is_achieved=false / status='red'
var seq = new DrawingSpec[11];
for (var i = 0; i < 5; i++) seq[i] = new DrawingSpec(8.34m, 1, false, "red");
for (var i = 5; i < 9; i++) seq[i] = new DrawingSpec(8.34m, 2, false, "red");
seq[9] = new DrawingSpec(13.51m, 6, false, "red");
seq[10] = new DrawingSpec(13.51m, 6, false, "red");
return seq;
}
public static IEnumerable BuildDrawings()
{
int stdCursor = 0, nonStdCursor = 0;
long seq = 0;
for (var i = 0; i < S8OrderFlowDataset.Specs.Length; i++)
{
var orderSpec = S8OrderFlowDataset.Specs[i];
var (stdN, nonStdN) = PerOrderConfig[i];
// 图号粒度计划开始 = release_at + 5 天(ORDER_REVIEW KPI=5 天结束后进入 PRODUCT_DESIGN)。
// 所有图号同基准开始,actualEnd 由 actualDays 派生,保证 actualEnd - actualStart 严格等于 actualDays。
var plannedStart = S8OrderFlowDataset.ReleaseBase.AddDays(5);
var sortNo = 0;
for (var g = 0; g < stdN; g++)
{
sortNo++;
var spec = StandardSequence[stdCursor++];
yield return BuildDrawing(
seq: ++seq,
orderSpec: orderSpec,
sortNo: sortNo,
drawingNo: $"D-{orderSpec.OrderCode}-G{g + 1:D2}",
productType: ProductTypeStandard,
kpiDays: StandardKpiDays,
plannedStart: plannedStart,
spec: spec);
}
for (var x = 0; x < nonStdN; x++)
{
sortNo++;
var spec = NonStandardSequence[nonStdCursor++];
yield return BuildDrawing(
seq: ++seq,
orderSpec: orderSpec,
sortNo: sortNo,
drawingNo: $"D-{orderSpec.OrderCode}-X{x + 1:D2}",
productType: ProductTypeNonStandard,
kpiDays: NonStandardKpiDays,
plannedStart: plannedStart,
spec: spec);
}
}
}
private static AdoS8OrderFlowProductDesignDrawing BuildDrawing(
long seq,
S8OrderFlowDataset.OrderSpec orderSpec,
int sortNo,
string drawingNo,
string productType,
decimal kpiDays,
DateTime plannedStart,
DrawingSpec spec)
{
// 计划区间按 KPI 推算;非标 KPI 与常规 KPI 同阶段标准 3 天,但非标设计周期允许 actual_days 较长。
var plannedEnd = plannedStart.AddDays((double)kpiDays);
var actualStart = plannedStart;
var actualEnd = actualStart.AddDays((double)spec.ActualDays);
var responsible = Designers[(seq - 1) % Designers.Length];
return new AdoS8OrderFlowProductDesignDrawing
{
Id = IdBase + seq,
TenantId = 1,
FactoryId = 1,
OrderCode = orderSpec.OrderCode,
DrawingNo = drawingNo,
ProductType = productType,
ProductQuantity = spec.Quantity,
ResponsiblePerson = responsible,
PlannedStartDate = plannedStart,
PlannedEndDate = plannedEnd,
ActualStartDate = actualStart,
ActualEndDate = actualEnd,
KpiDays = kpiDays,
ActualDays = spec.ActualDays,
IsAchieved = spec.IsAchieved,
Status = spec.Status,
SortNo = sortNo,
IsDeleted = false,
CreateTime = S8OrderFlowDataset.CreatedAt,
UpdateTime = null,
};
}
}