S8SceneCode.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. namespace Admin.NET.Plugin.AiDOP.Infrastructure.S8;
  2. /// <summary>
  3. /// S8 异常场景码常量(双轨)。
  4. ///
  5. /// 新单模块 scene(S1-S7)与旧复合 scene(S1S7_DELIVERY 等)共存:
  6. /// - 新代码请使用 S1-S7 单模块 scene;
  7. /// - 旧复合常量保留向下兼容,<see cref="Modules"/> / <see cref="Label"/>
  8. /// /<see cref="S8ModuleCode.FromScene"/> 等仍可识别。
  9. ///
  10. /// 迁移轨道:S8-SCENE-MIGRATE-CODE-DUALRAIL-1(本轮,仅代码双轨,不动 DB)。
  11. /// 后续 S8-SCENE-MIGRATE-CONFIG-S1S7-1 才迁移 scene_config / exception_type / watch_rule。
  12. /// </summary>
  13. public static class S8SceneCode
  14. {
  15. // ─────────────── 新单模块 scene_code(S1-S7) ──────────────────────────────
  16. /// <summary>S1 产销协同</summary>
  17. public const string S1 = "S1";
  18. /// <summary>S2 制造协同</summary>
  19. public const string S2 = "S2";
  20. /// <summary>S3 供应协同</summary>
  21. public const string S3 = "S3";
  22. /// <summary>S4 采购执行</summary>
  23. public const string S4 = "S4";
  24. /// <summary>S5 物料仓储</summary>
  25. public const string S5 = "S5";
  26. /// <summary>S6 生产执行</summary>
  27. public const string S6 = "S6";
  28. /// <summary>S7 成品仓储</summary>
  29. public const string S7 = "S7";
  30. // ─────────────── 旧复合 scene_code(保留兼容;新代码请勿使用) ─────────────
  31. /// <summary>交付异常(S1 订单评审变更 + S7 成品出库交期)— 旧复合 scene,保留兼容。</summary>
  32. public const string S1S7Delivery = "S1S7_DELIVERY";
  33. /// <summary>生产异常(S2 工单开工 + S6 完工/质量)— 旧复合 scene,保留兼容。</summary>
  34. public const string S2S6Production = "S2S6_PRODUCTION";
  35. /// <summary>供应异常(S3 MRP套料 + S5 IQC/库存)— 旧复合 scene,保留兼容。</summary>
  36. public const string S3S5Supply = "S3S5_SUPPLY";
  37. /// <summary>采购执行异常(S4 PO跟单/收货/退货)— 旧复合 scene,保留兼容。</summary>
  38. public const string S4Purchase = "S4_PURCHASE";
  39. // 注:S2S6_QUALITY 是 dev DB 中存在但 C# 常量未定义的旧场景(demo rule 12 引用);
  40. // 通过 Label() / Modules() 字面值识别保留兼容,不新增常量以免被新代码引用。
  41. /// <summary>scene_code → 中文名称(双轨:S1-S7 业务名 + 旧复合保留)</summary>
  42. public static string Label(string sceneCode) => sceneCode switch
  43. {
  44. S1 => "S1 产销协同",
  45. S2 => "S2 制造协同",
  46. S3 => "S3 供应协同",
  47. S4 => "S4 采购执行",
  48. S5 => "S5 物料仓储",
  49. S6 => "S6 生产执行",
  50. S7 => "S7 成品仓储",
  51. S1S7Delivery => "交付异常",
  52. S2S6Production => "生产异常",
  53. "S2S6_QUALITY" => "质量异常",
  54. S3S5Supply => "供应异常",
  55. S4Purchase => "采购执行异常",
  56. _ => sceneCode
  57. };
  58. /// <summary>
  59. /// scene_code → 所属模块列表(双轨)。
  60. /// 新单模块 scene 1:1 自映射;旧复合 scene 沿用历史映射。
  61. /// </summary>
  62. public static string[] Modules(string sceneCode) => sceneCode switch
  63. {
  64. S1 => new[] { S1 },
  65. S2 => new[] { S2 },
  66. S3 => new[] { S3 },
  67. S4 => new[] { S4 },
  68. S5 => new[] { S5 },
  69. S6 => new[] { S6 },
  70. S7 => new[] { S7 },
  71. S1S7Delivery => new[] { "S1", "S7" },
  72. S2S6Production => new[] { "S2", "S6" },
  73. "S2S6_QUALITY" => new[] { "S2", "S6" },
  74. S3S5Supply => new[] { "S3", "S5" },
  75. S4Purchase => new[] { "S4" },
  76. _ => Array.Empty<string>()
  77. };
  78. /// <summary>新单模块 scene_code 列表(S1-S7)。新代码请使用此清单。</summary>
  79. public static readonly string[] ModuleSceneCodes = { S1, S2, S3, S4, S5, S6, S7 };
  80. /// <summary>旧复合 scene_code 列表(保留兼容;新代码请勿使用)。</summary>
  81. public static readonly string[] LegacyCompositeSceneCodes =
  82. {
  83. S1S7Delivery,
  84. S2S6Production,
  85. S3S5Supply,
  86. S4Purchase
  87. };
  88. /// <summary>
  89. /// 历史 scene_code 有序列表(仅含旧复合,保兼容外部遍历调用);
  90. /// 新代码请改用 <see cref="ModuleSceneCodes"/>。
  91. /// </summary>
  92. public static readonly string[] All =
  93. {
  94. S1S7Delivery,
  95. S2S6Production,
  96. S3S5Supply,
  97. S4Purchase
  98. };
  99. }
  100. /// <summary>
  101. /// S8 模块码常量(对应 S1-S7 业务模块)。
  102. /// </summary>
  103. public static class S8ModuleCode
  104. {
  105. public const string S1 = "S1";
  106. public const string S2 = "S2";
  107. public const string S3 = "S3";
  108. public const string S4 = "S4";
  109. public const string S5 = "S5";
  110. public const string S6 = "S6";
  111. public const string S7 = "S7";
  112. /// <summary>module_code → 业务名称(与侧栏菜单 S{N} 看板标题对齐,统一字面)</summary>
  113. public static string Label(string moduleCode) => moduleCode switch
  114. {
  115. S1 => "S1 产销协同",
  116. S2 => "S2 制造协同",
  117. S3 => "S3 供应协同",
  118. S4 => "S4 采购执行",
  119. S5 => "S5 物料仓储",
  120. S6 => "S6 生产执行",
  121. S7 => "S7 成品仓储",
  122. _ => moduleCode
  123. };
  124. /// <summary>
  125. /// module_code → 所属 scene_code。
  126. /// S8-SCENE-MIGRATE-CODE-DUALRAIL-1 起:优先返回 S1-S7 单模块 scene,
  127. /// 不再返回旧复合 scene;如需旧复合归属请直接引用 <see cref="S8SceneCode.S1S7Delivery"/> 等常量。
  128. /// </summary>
  129. public static string SceneOf(string moduleCode) => moduleCode switch
  130. {
  131. S1 => S8SceneCode.S1,
  132. S2 => S8SceneCode.S2,
  133. S3 => S8SceneCode.S3,
  134. S4 => S8SceneCode.S4,
  135. S5 => S8SceneCode.S5,
  136. S6 => S8SceneCode.S6,
  137. S7 => S8SceneCode.S7,
  138. _ => string.Empty
  139. };
  140. /// <summary>所有模块码有序列表</summary>
  141. public static readonly string[] All = { S1, S2, S3, S4, S5, S6, S7 };
  142. /// <summary>
  143. /// S8-EXCEPTION-CREATION-MODULE-CODE-FIX-1:合法 module_code 校验。
  144. /// 仅 S1-S7 完全匹配返回 true;空值 / 任何非 S1-S7 字符串(含 legacy 复合 scene)返回 false。
  145. /// </summary>
  146. public static bool IsValid(string? code) =>
  147. !string.IsNullOrWhiteSpace(code) && Array.IndexOf(All, code!) >= 0;
  148. /// <summary>
  149. /// 输入归一化:合法 S1-S7 原样返回,非法(含 legacy 复合 scene 字面量)返回 null。
  150. /// 用于建单链路,caller 可链式优先级派生 module_code。
  151. /// </summary>
  152. public static string? Normalize(string? code) => IsValid(code) ? code : null;
  153. /// <summary>
  154. /// S8-EXCEPTION-CREATION-MODULE-CODE-FIX-1:严格按 single-module scene 派生 module_code。
  155. /// 仅当 sceneCode ∈ {S1..S7} 时返回该值;
  156. /// 不接受 legacy 复合 scene(S1S7_DELIVERY / S2S6_PRODUCTION / S2S6_QUALITY / S3S5_SUPPLY / S4_PURCHASE)。
  157. /// 用于新建异常的 module_code 派生;与 <see cref="FromScene"/> 区别在于不做 legacy 映射。
  158. /// </summary>
  159. public static string? FromCanonicalScene(string? sceneCode) => Normalize(sceneCode);
  160. /// <summary>
  161. /// 场景码 → 代表模块码(双轨)。
  162. /// - 新 S1-S7 scene:返回自身(<see cref="S8SceneCode.Modules"/> 1:1 自映射);
  163. /// - 旧复合 scene:返回代表模块(取 <see cref="S8SceneCode.Modules"/> 首项),保留历史行为;
  164. /// 用于历史 process_node 等非 module_code 派生场景;新建异常 module_code 请改用
  165. /// <see cref="FromCanonicalScene"/>(严格版,禁止 legacy 映射)。
  166. /// 未识别 scene 返回 null(caller 自决:留空或兜底)。
  167. /// </summary>
  168. public static string? FromScene(string? sceneCode)
  169. {
  170. if (string.IsNullOrWhiteSpace(sceneCode)) return null;
  171. var modules = S8SceneCode.Modules(sceneCode);
  172. return modules.Length == 0 ? null : modules[0];
  173. }
  174. }