1.0.532.sql 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. -- =====================================================================================
  2. -- 1.0.532 · S8 Stage-2「产品设计」End Authority 与身份桥的中台补齐
  3. --
  4. -- ── 背景 ────────────────────────────────────────────────────────────────────────────
  5. -- Stage-2 的业务终点是「订单首次具备可执行日计划」,当前系统由
  6. -- POST /api/Production/daily-plan/release → UPDATE PeriodSequenceDet SET Status='Y'
  7. -- 表达。但该动作此前存在三个缺口:
  8. -- G1 不写 action log → 没有 LEVEL A 事件时间
  9. -- G2 只能退而用 UpdateTime → 会被后续任意一次 UPDATE 覆盖,不是稳定里程碑
  10. -- G3 Status 未进标准层 → S8 在中台里根本看不到「是否已下达」
  11. -- G5 WorkOrdMaster.BusinessID 未进标准层 → 计划→订单的 ID 桥在中台中断
  12. --
  13. -- 本脚本负责 G3 / G5 两个结构缺口;G1 / G2 由 ExecutableDailyPlanService 接入
  14. -- aidop_action_run_log(action_code = S2_DAILY_PLAN_RELEASE)解决。
  15. --
  16. -- ── BusinessID 语义实证(改名依据,2026-09-11 全库实测)────────────────────────────
  17. -- WorkOrdMaster 共 267 行:BusinessID IS NULL = 0,= 0 为 239 行,> 0 为 28 行;
  18. -- 28 行 >0 值 100% 命中【同租户】crm_seorderentry.Id,孤儿 0 行。
  19. -- 写入方 OrderWorkOrderGenerationService.cs:241 明确 `@BusinessId = entry.Id`,
  20. -- 读取方 FindOpenWorkOrderByEntryAsync 亦以 `BusinessID = @EntryId` 反查。
  21. -- 0 表示「该工单无关联订单明细行」(WorkOrderKittingCheckService.cs:53 注释),
  22. -- 不是另一种业务语义,故标准层用明确列名 sales_order_entry_id,并把 0 归一为 NULL。
  23. --
  24. -- ── 本脚本不做 ──────────────────────────────────────────────────────────────────────
  25. -- 不建 dwd_product_design_kpi;不把 sales_order_id 冗余进各 STD 表;
  26. -- 不回填历史下达事件(历史 Status='Y' 只能证明状态,无强时间 Authority)。
  27. -- =====================================================================================
  28. -- ---------------------------------------------------------------------------
  29. -- ① mdp_std_operation_schedule 补 status
  30. -- 语义 = PeriodSequenceDet.Status 原样投影:'Y' = 日计划已下达(可执行),
  31. -- '' / NULL = 未下达。仅 PeriodSequenceDet 来源的行有值;
  32. -- 同表另一来源 ScheduleResultOpMaster 无此概念,保持 NULL。
  33. -- ⚠️ 它只是「状态佐证」,Stage-2 End 的时间 Authority 一律取
  34. -- S2_DAILY_PLAN_RELEASE SUCCESS 的 end_time,禁止用 update_time 充当下达时间。
  35. -- ---------------------------------------------------------------------------
  36. SET @ddl := (SELECT IF(EXISTS(
  37. SELECT 1 FROM `information_schema`.`COLUMNS`
  38. WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_std_operation_schedule'
  39. AND `COLUMN_NAME` = 'status'),
  40. 'SELECT 1',
  41. 'ALTER TABLE `mdp_std_operation_schedule` ADD COLUMN `status` VARCHAR(20) NULL COMMENT ''日计划下达状态:Y=已下达(可执行),空/NULL=未下达;源 PeriodSequenceDet.Status'' AFTER `employee`'));
  42. PREPARE s FROM @ddl; EXECUTE s; DEALLOCATE PREPARE s;
  43. SET @ddl := (SELECT IF(EXISTS(
  44. SELECT 1 FROM `information_schema`.`STATISTICS`
  45. WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_std_operation_schedule'
  46. AND `INDEX_NAME` = 'idx_std_op_sched_status'),
  47. 'SELECT 1',
  48. 'ALTER TABLE `mdp_std_operation_schedule` ADD INDEX `idx_std_op_sched_status` (`tenant_id`, `status`, `work_order`)'));
  49. PREPARE s FROM @ddl; EXECUTE s; DEALLOCATE PREPARE s;
  50. -- ---------------------------------------------------------------------------
  51. -- ② mdp_std_work_order_schedule 补 sales_order_entry_id
  52. -- = WorkOrdMaster.BusinessID(>0 时恒等于 crm_seorderentry.Id,见上方实证)。
  53. -- 这是「日计划 → 工单 → 订单行 → 订单」在中台内唯一的 ID 级桥;
  54. -- 既有 sales_order_no 是 SalesJob 文本,**不得**作为归因 Authority。
  55. -- ---------------------------------------------------------------------------
  56. SET @ddl := (SELECT IF(EXISTS(
  57. SELECT 1 FROM `information_schema`.`COLUMNS`
  58. WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_std_work_order_schedule'
  59. AND `COLUMN_NAME` = 'sales_order_entry_id'),
  60. 'SELECT 1',
  61. 'ALTER TABLE `mdp_std_work_order_schedule` ADD COLUMN `sales_order_entry_id` BIGINT NULL COMMENT ''销售订单明细行Id = crm_seorderentry.Id(源 WorkOrdMaster.BusinessID;源值0表示无关联订单行,已归一为NULL)'' AFTER `sales_order_no`'));
  62. PREPARE s FROM @ddl; EXECUTE s; DEALLOCATE PREPARE s;
  63. SET @ddl := (SELECT IF(EXISTS(
  64. SELECT 1 FROM `information_schema`.`STATISTICS`
  65. WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_std_work_order_schedule'
  66. AND `INDEX_NAME` = 'idx_std_wo_sched_entry'),
  67. 'SELECT 1',
  68. 'ALTER TABLE `mdp_std_work_order_schedule` ADD INDEX `idx_std_wo_sched_entry` (`tenant_id`, `sales_order_entry_id`)'));
  69. PREPARE s FROM @ddl; EXECUTE s; DEALLOCATE PREPARE s;
  70. -- ---------------------------------------------------------------------------
  71. -- ③ 历史数据说明(不在此脚本手工回填)
  72. -- 两个新列由 S2MdpSyncTransformService 的标准层 upsert 在下一次跑批时统一投影,
  73. -- 走既有 mdp_stg_schedule → mdp_std_* 链路,不手工 UPDATE 标准层拼历史结果。
  74. -- 事件层不同:历史上不存在 S2_DAILY_PLAN_RELEASE,本批**不伪造历史 action log**,
  75. -- 历史已下达计划的 Stage-2 End 一律记 HISTORICAL_END_TIME_UNKNOWN。
  76. -- ---------------------------------------------------------------------------