Forráskód Böngészése

feat(s8): 材料采购默认态关键材料补齐影响台次与准时齐套率

S8-ORDER-CHAIN-MATERIAL-PROCUREMENT-BASELINE-FIELD-ALIGN-1

- AdoS8OrderFlowProcurementPivot 新增 impact_count(int?) / kit_rate(decimal(5,4)?)
- Seed 为 BASELINE_PPT 关键材料 grand 单元回填 XX(55/0.85) / YY(23/0.84) / ZZ(10/0.97)
- Service.BuildPivot KeyMaterials 透传 ImpactCount / KitRate
- UpdateScripts/1.0.125.sql 幂等 ALTER + 3 行 UPDATE
- csproj 注册 1.0.125.sql + patch 至 1.0.125

bump version server 1.0.124 → 1.0.125
YY968XX 4 napja
szülő
commit
51aebd4561

+ 6 - 3
server/Admin.NET.Web.Entry/Admin.NET.Web.Entry.csproj

@@ -11,9 +11,9 @@
     <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
     <Copyright>Admin.NET</Copyright>
     <Description>Admin.NET 通用权限开发平台</Description>
-    <AssemblyVersion>1.0.124</AssemblyVersion>
-    <FileVersion>1.0.124</FileVersion>
-    <Version>1.0.124</Version>
+    <AssemblyVersion>1.0.125</AssemblyVersion>
+    <FileVersion>1.0.125</FileVersion>
+    <Version>1.0.125</Version>
   </PropertyGroup>
 
   <ItemGroup>
@@ -73,6 +73,9 @@
     <None Update="UpdateScripts\1.0.124.sql">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
+    <None Update="UpdateScripts\1.0.125.sql">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
   <ItemGroup>

+ 93 - 0
server/Admin.NET.Web.Entry/UpdateScripts/1.0.125.sql

@@ -0,0 +1,93 @@
+-- 1.0.125.sql
+-- S8-ORDER-CHAIN-MATERIAL-PROCUREMENT-BASELINE-FIELD-ALIGN-1
+-- 给既有库 ado_s8_order_flow_procurement_pivot 表补两列:impact_count(影响台次)/ kit_rate(准时齐套率),
+-- 并为 BASELINE_PPT 的 XX / YY / ZZ 关键材料 grand 单元(supplier_code=TOTAL && spec_code=TOTAL)回填业务基线值。
+--
+-- 修正范围:
+--   ado_s8_order_flow_procurement_pivot:
+--     1) 幂等加列 impact_count INT NULL;
+--     2) 幂等加列 kit_rate DECIMAL(5,4) NULL;
+--     3) 限定 order_id IS NULL && supplier_code='TOTAL' && spec_code='TOTAL' && is_deleted=0
+--        分别 UPDATE XX(55, 0.8500) / YY(23, 0.8400) / ZZ(10, 0.9700) 三行。
+--
+-- 安全边界:
+--   * 仅 ALTER TABLE ADD COLUMN(幂等)+ UPDATE(精确 4 条件限定单行)
+--   * 禁 DELETE / TRUNCATE / DROP;表行数保持原 48 行不变
+--   * 不动 cycle_days / status / scenario_code / data_source 等既有字段值
+--   * 不动 ado_s8_order_flow_order / stage / substep / substep_unit / snapshot
+--   * 不动 ado_s8_order_flow_product_design_drawing(产品设计阶段)
+--   * 不动 S0 / .vscode / Database.json / SysMenu
+--   * 不引入 TOTAL material 行(保持现有 3 material × 4 supplier × 4 spec = 48 行结构)
+--
+-- 幂等性:
+--   * ALTER:通过 information_schema.COLUMNS 判断列是否存在,PREPARE/EXECUTE 条件执行
+--   * UPDATE:四条件复合 WHERE 唯一定位 grand 单元,二次执行得到同样结果
+--
+-- 兼容性:
+--   * MySQL 5.7+ / 8.x 通用语法
+--
+-- 验证(阶段 4 重演后必查):
+--   SELECT material_code, impact_count, kit_rate
+--     FROM ado_s8_order_flow_procurement_pivot
+--    WHERE order_id IS NULL
+--      AND supplier_code = 'TOTAL'
+--      AND spec_code = 'TOTAL'
+--      AND is_deleted = 0
+--    ORDER BY material_code;
+--   → 3 行:XX=55/0.8500,YY=23/0.8400,ZZ=10/0.9700
+-- 2026-05-25
+
+
+-- ─── 1) 幂等加列:impact_count ───
+SET @col_exists := (
+  SELECT COUNT(*) FROM information_schema.COLUMNS
+   WHERE TABLE_SCHEMA = DATABASE()
+     AND TABLE_NAME = 'ado_s8_order_flow_procurement_pivot'
+     AND COLUMN_NAME = 'impact_count'
+);
+SET @sql := IF(@col_exists = 0,
+  'ALTER TABLE `ado_s8_order_flow_procurement_pivot` ADD COLUMN `impact_count` INT NULL COMMENT ''影响台次''',
+  'SELECT 1');
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+
+-- ─── 2) 幂等加列:kit_rate ───
+SET @col_exists := (
+  SELECT COUNT(*) FROM information_schema.COLUMNS
+   WHERE TABLE_SCHEMA = DATABASE()
+     AND TABLE_NAME = 'ado_s8_order_flow_procurement_pivot'
+     AND COLUMN_NAME = 'kit_rate'
+);
+SET @sql := IF(@col_exists = 0,
+  'ALTER TABLE `ado_s8_order_flow_procurement_pivot` ADD COLUMN `kit_rate` DECIMAL(5,4) NULL COMMENT ''准时齐套率''',
+  'SELECT 1');
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+
+-- ─── 3) 回填 BASELINE_PPT grand 单元(每条 UPDATE 精确命中 1 行) ───
+UPDATE `ado_s8_order_flow_procurement_pivot`
+   SET `impact_count` = 55,
+       `kit_rate` = 0.8500
+ WHERE `order_id` IS NULL
+   AND `material_code` = 'XX'
+   AND `supplier_code` = 'TOTAL'
+   AND `spec_code` = 'TOTAL'
+   AND `is_deleted` = 0;
+
+UPDATE `ado_s8_order_flow_procurement_pivot`
+   SET `impact_count` = 23,
+       `kit_rate` = 0.8400
+ WHERE `order_id` IS NULL
+   AND `material_code` = 'YY'
+   AND `supplier_code` = 'TOTAL'
+   AND `spec_code` = 'TOTAL'
+   AND `is_deleted` = 0;
+
+UPDATE `ado_s8_order_flow_procurement_pivot`
+   SET `impact_count` = 10,
+       `kit_rate` = 0.9700
+ WHERE `order_id` IS NULL
+   AND `material_code` = 'ZZ'
+   AND `supplier_code` = 'TOTAL'
+   AND `spec_code` = 'TOTAL'
+   AND `is_deleted` = 0;

+ 8 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowProcurementPivot.cs

@@ -45,6 +45,14 @@ public class AdoS8OrderFlowProcurementPivot
     [SugarColumn(ColumnName = "status", Length = 16)]
     public string Status { get; set; } = "green";
 
+    /// <summary>影响台次。仅 grand 单元(supplier_code=TOTAL 且 spec_code=TOTAL)承载该材料的台次合计,其它细粒度单元保持 NULL。</summary>
+    [SugarColumn(ColumnName = "impact_count", ColumnDataType = "int", IsNullable = true)]
+    public int? ImpactCount { get; set; }
+
+    /// <summary>准时齐套率。decimal(5,4),取值范围 0.0000~1.0000;仅 grand 单元承载该材料的齐套率,其它细粒度单元保持 NULL。</summary>
+    [SugarColumn(ColumnName = "kit_rate", DecimalDigits = 4, Length = 5, IsNullable = true)]
+    public decimal? KitRate { get; set; }
+
     /// <summary>PPT(YY 真值)/ DEMO(XX, ZZ 演示 fixture)。</summary>
     [SugarColumn(ColumnName = "scenario_code", Length = 16)]
     public string ScenarioCode { get; set; } = "DEMO";

+ 22 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/S8OrderFlowProcurementPivotSeedData.cs

@@ -36,6 +36,17 @@ internal static class S8OrderFlowProcurementPivotDataset
     private const decimal XxMultiplier = 0.85m;
     private const decimal ZzMultiplier = 1.10m;
 
+    /// <summary>
+    /// BASELINE_PPT 关键材料 grand 单元的"影响台次 / 准时齐套率"业务基线。
+    /// 仅在 supplier_code=TOTAL && spec_code=TOTAL 行写入,其余 45 行保持 NULL。
+    /// </summary>
+    private static readonly Dictionary<string, (int ImpactCount, decimal KitRate)> GrandUnitBaseline = new()
+    {
+        ["XX"] = (55, 0.8500m),
+        ["YY"] = (23, 0.8400m),
+        ["ZZ"] = (10, 0.9700m),
+    };
+
     public static IEnumerable<AdoS8OrderFlowProcurementPivot> BuildRows()
     {
         long seq = 0;
@@ -55,6 +66,15 @@ internal static class S8OrderFlowProcurementPivotDataset
                         ? rawCycle
                         : decimal.Round(rawCycle * mult, 3);
 
+                    var isGrand = Suppliers[s] == "TOTAL" && Specs[p] == "TOTAL";
+                    int? impactCount = null;
+                    decimal? kitRate = null;
+                    if (isGrand && GrandUnitBaseline.TryGetValue(material, out var baseline))
+                    {
+                        impactCount = baseline.ImpactCount;
+                        kitRate = baseline.KitRate;
+                    }
+
                     yield return new AdoS8OrderFlowProcurementPivot
                     {
                         Id = PivotIdBase + (++seq),
@@ -65,6 +85,8 @@ internal static class S8OrderFlowProcurementPivotDataset
                         SpecCode = Specs[p],
                         CycleDays = cycleDays,
                         Status = ClassifyStatus(cycleDays),
+                        ImpactCount = impactCount,
+                        KitRate = kitRate,
                         ScenarioCode = scenario,
                         DataSource = "SEED",
                         TenantId = 1,

+ 2 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/OrderFlow/S8OrderFlowService.cs

@@ -640,6 +640,8 @@ public class S8OrderFlowService : ITransient
                     MaterialCode = material,
                     AvgCycleDays = grand.CycleDays,
                     CycleStatus = grand.Status,
+                    ImpactCount = grand.ImpactCount,
+                    KitRate = grand.KitRate,
                     ResultStatus = grand.Status,
                 });
             }