mes_product_record_plan.sql 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. -- 生产记录关联生产计划(订单-计划-产品-记录 全链路 / 无计划拦截)
  2. -- 背景:
  3. -- 1) mes_product_record(生产记录/工位结果)没有计划字段,工位结果层面无法追溯订单与计划;
  4. -- 2) 提交工位结果时没有"无计划"校验,无计划工件照样可以过站;
  5. -- 3) 生产记录列表/导出无法按订单、计划查询。
  6. -- 本脚本负责:加字段 + 加索引 + 存量回填 + 拦截总开关。
  7. -- 说明:结构补齐脚本,字段必须先执行本脚本再发布应用,否则生产记录相关查询会报错。
  8. -- ---------- 1. 生产记录表增加生产计划字段 ----------
  9. SET @col_exists = (SELECT COUNT(1) FROM information_schema.COLUMNS
  10. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'mes_product_record' AND COLUMN_NAME = 'plan_id');
  11. SET @ddl = IF(@col_exists = 0,
  12. 'ALTER TABLE `mes_product_record` ADD COLUMN `plan_id` VARCHAR(64) DEFAULT NULL COMMENT ''生产计划'' AFTER `cate_sn`',
  13. 'SELECT ''mes_product_record.plan_id 已存在'' AS message');
  14. PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
  15. -- ---------- 2. 索引:按计划/订单查记录 ----------
  16. SET @idx_exists = (SELECT COUNT(1) FROM information_schema.STATISTICS
  17. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'mes_product_record' AND INDEX_NAME = 'idx_mpr_plan_id');
  18. SET @ddl = IF(@idx_exists = 0,
  19. 'CREATE INDEX `idx_mpr_plan_id` ON `mes_product_record` (`plan_id`)',
  20. 'SELECT ''idx_mpr_plan_id 已存在'' AS message');
  21. PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
  22. -- ---------- 2.1 索引:按工件码查记录(无计划拦截回退查询用)----------
  23. -- 注意:mes_product_record 数据量较大时建索引耗时较长,可在低峰期执行
  24. SET @idx_exists = (SELECT COUNT(1) FROM information_schema.STATISTICS
  25. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'mes_product_record' AND COLUMN_NAME = 'sn');
  26. SET @ddl = IF(@idx_exists = 0,
  27. 'CREATE INDEX `idx_mpr_sn` ON `mes_product_record` (`sn`)',
  28. 'SELECT ''mes_product_record.sn 已有索引,跳过'' AS message');
  29. PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
  30. -- ---------- 3. 存量数据回填:工件有计划 -> 回填到该工件的所有记录 ----------
  31. UPDATE `mes_product_record` r
  32. JOIN `mes_product` p ON p.`sn` = r.`sn`
  33. SET r.`plan_id` = p.`plan_id`
  34. WHERE (r.`plan_id` IS NULL OR r.`plan_id` = '')
  35. AND p.`plan_id` IS NOT NULL AND p.`plan_id` <> '';
  36. -- ---------- 4. 拦截总开关 ----------
  37. -- 0=不拦截(应急/灰度),1=拦截(提交工位结果时工件必须关联有效生产计划)
  38. -- 注意:直插 js_sys_config 后需重启服务,或在"系统配置"页面重新保存一次触发缓存刷新
  39. DELETE FROM `js_sys_config` WHERE `config_key` = 'mes.plan.intercept';
  40. INSERT INTO `js_sys_config`
  41. (`id`, `config_name`, `config_key`, `config_value`, `is_sys`, `create_by`, `create_date`, `update_by`, `update_date`, `remarks`)
  42. VALUES
  43. ('2026102110000001','生产计划无计划拦截','mes.plan.intercept','1','0','system',NOW(),'system',NOW(),
  44. '提交工位结果时校验工件是否关联有效生产计划;0=关闭拦截,1=开启拦截');
  45. -- ---------- 5. 验证 ----------
  46. -- 5.1 字段与索引
  47. SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_COMMENT FROM information_schema.COLUMNS
  48. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'mes_product_record' AND COLUMN_NAME = 'plan_id';
  49. -- 5.2 仍有记录未回填(这些工件在生产但没有计划,发布后会拦截)
  50. SELECT r.sn, r.cate_sn, p.plan_id AS product_plan_id
  51. FROM mes_product_record r
  52. LEFT JOIN mes_product p ON p.sn = r.sn
  53. WHERE (r.plan_id IS NULL OR r.plan_id = '') AND r.content <> 'UDF'
  54. LIMIT 100;
  55. -- 5.3 记录与工件计划不一致(应为 0 行)
  56. SELECT r.id, r.sn, r.plan_id AS record_plan, p.plan_id AS product_plan
  57. FROM mes_product_record r
  58. JOIN mes_product p ON p.sn = r.sn
  59. WHERE IFNULL(r.plan_id,'') <> IFNULL(p.plan_id,'')
  60. LIMIT 100;
  61. -- 5.4 未关联订单的计划(应为 0 行)
  62. SELECT id, order_id, day, shift_id, nums FROM mes_product_plan
  63. WHERE order_id IS NULL OR order_id = '';
  64. -- 5.5 开关
  65. SELECT config_key, config_value FROM js_sys_config WHERE config_key = 'mes.plan.intercept';
  66. SELECT '生产记录关联生产计划脚本执行完成' AS message;