1.0.536.sql 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. -- ============================================================================
  2. -- 1.0.536 · API_INBOUND WP-A:入站 6 表 + mdp_entity 扩列 + 联调种子(号段避让远端已占用的 1.0.527)
  3. --
  4. -- 幂等:CREATE TABLE IF NOT EXISTS;扩列 information_schema + PREPARE 自包含;
  5. -- 种子 INSERT ... WHERE NOT EXISTS。AutoVersionUpdate 按 ; 拆句、无事务。
  6. -- ============================================================================
  7. CREATE TABLE IF NOT EXISTS mdp_inbound_grant (
  8. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  9. tenant_id BIGINT NOT NULL COMMENT '凭证绑定租户(冗余自 SysOpenAccess.BindTenantId)',
  10. access_key VARCHAR(64) NOT NULL COMMENT 'SysOpenAccess.AccessKey',
  11. entity_code VARCHAR(100) NOT NULL COMMENT 'mdp_entity.entity_code 白名单',
  12. factory_id BIGINT NULL COMMENT '可选绑定工厂',
  13. source_code VARCHAR(50) NOT NULL COMMENT 'mdp_source.source_code(source_type=API_INBOUND)',
  14. rate_limit_per_min INT NOT NULL DEFAULT 60,
  15. batch_row_limit INT NOT NULL DEFAULT 500 COMMENT '主数据快照类可放宽到 2000',
  16. ip_allowlist VARCHAR(1000) NULL COMMENT '逗号分隔;空=不限制',
  17. status TINYINT NOT NULL DEFAULT 1 COMMENT '1启用 0停用',
  18. remark VARCHAR(500) NULL,
  19. create_time DATETIME NOT NULL,
  20. update_time DATETIME NOT NULL,
  21. UNIQUE KEY uk_inbound_grant (access_key, entity_code)
  22. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='第三方推数入站授权';
  23. CREATE TABLE IF NOT EXISTS mdp_inbound_request (
  24. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  25. tenant_id BIGINT NOT NULL,
  26. access_key VARCHAR(64) NOT NULL,
  27. entity_code VARCHAR(100) NOT NULL,
  28. idempotency_key VARCHAR(128) NOT NULL,
  29. request_hash CHAR(64) NOT NULL COMMENT 'sha256(原始请求体字节) hex',
  30. sync_batch_id VARCHAR(64) NOT NULL COMMENT 'INB_yyyyMMdd_{id 零填充}',
  31. snapshot_id VARCHAR(64) NULL,
  32. status VARCHAR(16) NOT NULL DEFAULT 'RECEIVED' COMMENT 'RECEIVED/COMMITTED/FAILED',
  33. http_status INT NOT NULL DEFAULT 0,
  34. result_code INT NOT NULL DEFAULT 0 COMMENT '回执 code:0 ok / 2 partial',
  35. accepted INT NOT NULL DEFAULT 0,
  36. rejected INT NOT NULL DEFAULT 0,
  37. stale_rejected INT NOT NULL DEFAULT 0,
  38. equal_ts_override INT NOT NULL DEFAULT 0,
  39. receipt_json MEDIUMTEXT NULL,
  40. error_msg VARCHAR(1000) NULL,
  41. client_ip VARCHAR(64) NULL,
  42. elapsed_ms INT NOT NULL DEFAULT 0,
  43. create_time DATETIME NOT NULL,
  44. update_time DATETIME NOT NULL,
  45. UNIQUE KEY uk_inbound_idem (tenant_id, access_key, entity_code, idempotency_key),
  46. KEY idx_inbound_req_batch (sync_batch_id),
  47. KEY idx_inbound_req_entity_time (entity_code, create_time)
  48. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='第三方推数入站请求(幂等状态机+审计)';
  49. CREATE TABLE IF NOT EXISTS mdp_inbound_envelope (
  50. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  51. request_id BIGINT NOT NULL COMMENT 'mdp_inbound_request.id',
  52. tenant_id BIGINT NOT NULL,
  53. access_key VARCHAR(64) NOT NULL,
  54. entity_code VARCHAR(100) NOT NULL,
  55. path VARCHAR(300) NOT NULL,
  56. headers_json TEXT NULL COMMENT '脱敏后头集合',
  57. body MEDIUMTEXT NOT NULL,
  58. body_sha256 CHAR(64) NOT NULL,
  59. create_time DATETIME NOT NULL,
  60. UNIQUE KEY uk_inbound_envelope_req (request_id),
  61. KEY idx_inbound_envelope_time (create_time)
  62. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='入站原始信封归档(重放用)';
  63. CREATE TABLE IF NOT EXISTS mdp_inbound_snapshot (
  64. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  65. snapshot_id VARCHAR(64) NOT NULL,
  66. tenant_id BIGINT NOT NULL,
  67. access_key VARCHAR(64) NOT NULL,
  68. entity_code VARCHAR(100) NOT NULL,
  69. status VARCHAR(16) NOT NULL DEFAULT 'OPEN' COMMENT 'OPEN/COMMITTED/EXPIRED/DIFF_BLOCKED',
  70. last_seq INT NOT NULL DEFAULT 0,
  71. row_count INT NOT NULL DEFAULT 0,
  72. diff_missing INT NULL,
  73. diff_ratio DECIMAL(6,4) NULL,
  74. opened_at DATETIME NOT NULL,
  75. expire_at DATETIME NOT NULL,
  76. committed_at DATETIME NULL,
  77. create_time DATETIME NOT NULL,
  78. update_time DATETIME NOT NULL,
  79. UNIQUE KEY uk_inbound_snapshot (snapshot_id),
  80. KEY idx_inbound_snap_entity (tenant_id, entity_code, status)
  81. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='入站全量快照批次';
  82. CREATE TABLE IF NOT EXISTS mdp_inbound_conflict (
  83. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  84. tenant_id BIGINT NOT NULL,
  85. entity_code VARCHAR(100) NOT NULL,
  86. biz_key VARCHAR(300) NOT NULL,
  87. source_system VARCHAR(50) NOT NULL,
  88. incoming_raw MEDIUMTEXT NOT NULL,
  89. mirror_table VARCHAR(64) NOT NULL,
  90. conflict_type VARCHAR(40) NOT NULL,
  91. status VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING/RESOLVED',
  92. resolution VARCHAR(500) NULL,
  93. create_time DATETIME NOT NULL,
  94. update_time DATETIME NOT NULL,
  95. KEY idx_inbound_conflict (tenant_id, entity_code, status)
  96. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='主数据镜像键冲突待裁决';
  97. CREATE TABLE IF NOT EXISTS mdp_field_map (
  98. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  99. tenant_id BIGINT NOT NULL,
  100. entity_code VARCHAR(100) NOT NULL,
  101. access_key VARCHAR(64) NOT NULL DEFAULT '*' COMMENT '精确对接方优先;*=该实体默认映射',
  102. contract_field VARCHAR(200) NOT NULL,
  103. raw_key VARCHAR(200) NOT NULL,
  104. is_required TINYINT NOT NULL DEFAULT 0,
  105. status TINYINT NOT NULL DEFAULT 1,
  106. create_time DATETIME NOT NULL,
  107. update_time DATETIME NOT NULL,
  108. UNIQUE KEY uk_field_map (tenant_id, entity_code, access_key, contract_field)
  109. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='入站对外契约字段两层映射';
  110. SET @exist := (SELECT COUNT(1) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='mdp_entity' AND COLUMN_NAME='inbound_enabled');
  111. SET @sql := IF(@exist=0, "ALTER TABLE mdp_entity ADD COLUMN inbound_enabled TINYINT NOT NULL DEFAULT 0 COMMENT '入站开通开关'", 'SELECT 1');
  112. PREPARE s FROM @sql;
  113. EXECUTE s;
  114. DEALLOCATE PREPARE s;
  115. SET @exist := (SELECT COUNT(1) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='mdp_entity' AND COLUMN_NAME='inbound_max_rows');
  116. SET @sql := IF(@exist=0, "ALTER TABLE mdp_entity ADD COLUMN inbound_max_rows INT NOT NULL DEFAULT 500 COMMENT '单请求行数上限(快照类 2000)'", 'SELECT 1');
  117. PREPARE s FROM @sql;
  118. EXECUTE s;
  119. DEALLOCATE PREPARE s;
  120. SET @exist := (SELECT COUNT(1) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='mdp_entity' AND COLUMN_NAME='stale_guard_enabled');
  121. SET @sql := IF(@exist=0, "ALTER TABLE mdp_entity ADD COLUMN stale_guard_enabled TINYINT NOT NULL DEFAULT 1 COMMENT '乱序 stale 守卫'", 'SELECT 1');
  122. PREPARE s FROM @sql;
  123. EXECUTE s;
  124. DEALLOCATE PREPARE s;
  125. SET @exist := (SELECT COUNT(1) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='mdp_entity' AND COLUMN_NAME='silence_alert_hours');
  126. SET @sql := IF(@exist=0, "ALTER TABLE mdp_entity ADD COLUMN silence_alert_hours INT NULL COMMENT '沉默告警阈值(小时);NULL=不告警'", 'SELECT 1');
  127. PREPARE s FROM @sql;
  128. EXECUTE s;
  129. DEALLOCATE PREPARE s;
  130. SET @exist := (SELECT COUNT(1) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='mdp_entity' AND COLUMN_NAME='silence_calendar');
  131. SET @sql := IF(@exist=0, "ALTER TABLE mdp_entity ADD COLUMN silence_calendar VARCHAR(20) NULL COMMENT '逗号分隔星期 1-7;空=每天'", 'SELECT 1');
  132. PREPARE s FROM @sql;
  133. EXECUTE s;
  134. DEALLOCATE PREPARE s;
  135. INSERT INTO mdp_source
  136. (tenant_id, source_code, source_name, source_type, status, remark, create_time, update_time)
  137. SELECT 797403760988229, 'TEST_INBOUND_ERP', '联调入站源 API_INBOUND', 'API_INBOUND', 1,
  138. 'WP-A 联调种子;正式对接方另签发', NOW(), NOW()
  139. WHERE NOT EXISTS (SELECT 1 FROM mdp_source WHERE source_code='TEST_INBOUND_ERP');
  140. INSERT INTO SysOpenAccess (Id, AccessKey, AccessSecret, BindTenantId, BindUserId, CreateTime, UpdateTime)
  141. SELECT 910000000000001, 'TESTKPARTNER', 'TESTKPARTNER_SECRET_DO_NOT_USE_IN_PROD',
  142. 797403760988229, 797403762421829, NOW(), NOW()
  143. WHERE NOT EXISTS (SELECT 1 FROM SysOpenAccess WHERE AccessKey='TESTKPARTNER');
  144. INSERT INTO mdp_entity
  145. (tenant_id, source_id, entity_code, entity_name, entity_type, source_table_name, target_table_name,
  146. sync_mode, batch_size, biz_key_expr, status, inbound_enabled, inbound_max_rows, stale_guard_enabled,
  147. remark, create_time, update_time)
  148. SELECT e.tenant_id, s.id, 'S1_SALES_ORDER_ENTRY', '销售订单行(入站草案)', e.entity_type, e.source_table_name, e.target_table_name,
  149. e.sync_mode, e.batch_size, e.biz_key_expr, 1, 1, 500, 1,
  150. 'v1-draft 对外码,贴源/转换复用 S1_SEORDER_ENTRY', NOW(), NOW()
  151. FROM mdp_entity e
  152. JOIN mdp_source s ON s.source_code='TEST_INBOUND_ERP'
  153. WHERE e.entity_code='S1_SEORDER_ENTRY'
  154. AND NOT EXISTS (SELECT 1 FROM mdp_entity x WHERE x.entity_code='S1_SALES_ORDER_ENTRY');
  155. INSERT INTO mdp_entity
  156. (tenant_id, source_id, entity_code, entity_name, entity_type, source_table_name, target_table_name,
  157. sync_mode, batch_size, biz_key_expr, status, inbound_enabled, inbound_max_rows, stale_guard_enabled,
  158. remark, create_time, update_time)
  159. SELECT e.tenant_id, s.id, 'MDM_ITEM', '物料主数据(入站草案)', e.entity_type, e.source_table_name, e.target_table_name,
  160. e.sync_mode, e.batch_size, e.biz_key_expr, 1, 1, 500, 1,
  161. 'v1-draft 对外码,贴源/转换复用 S3_ITEM_ERP', NOW(), NOW()
  162. FROM mdp_entity e
  163. JOIN mdp_source s ON s.source_code='TEST_INBOUND_ERP'
  164. WHERE e.entity_code='S3_ITEM_ERP'
  165. AND NOT EXISTS (SELECT 1 FROM mdp_entity x WHERE x.entity_code='MDM_ITEM');
  166. UPDATE mdp_entity
  167. SET inbound_enabled=1, inbound_max_rows=500, stale_guard_enabled=1, update_time=NOW()
  168. WHERE entity_code IN ('S1_SALES_ORDER_ENTRY', 'S1_SEORDER_ENTRY', 'MDM_ITEM');
  169. INSERT INTO mdp_inbound_grant
  170. (tenant_id, access_key, entity_code, factory_id, source_code, rate_limit_per_min, batch_row_limit, status, remark, create_time, update_time)
  171. SELECT 797403760988229, 'TESTKPARTNER', 'S1_SALES_ORDER_ENTRY', NULL, 'TEST_INBOUND_ERP', 60, 500, 1, 'WP-A 联调', NOW(), NOW()
  172. WHERE NOT EXISTS (SELECT 1 FROM mdp_inbound_grant WHERE access_key='TESTKPARTNER' AND entity_code='S1_SALES_ORDER_ENTRY');
  173. INSERT INTO mdp_inbound_grant
  174. (tenant_id, access_key, entity_code, factory_id, source_code, rate_limit_per_min, batch_row_limit, status, remark, create_time, update_time)
  175. SELECT 797403760988229, 'TESTKPARTNER', 'MDM_ITEM', NULL, 'TEST_INBOUND_ERP', 60, 500, 1, 'WP-A 联调', NOW(), NOW()
  176. WHERE NOT EXISTS (SELECT 1 FROM mdp_inbound_grant WHERE access_key='TESTKPARTNER' AND entity_code='MDM_ITEM');