-- 修复内置工艺路线缺步骤(2026-10-22) -- 对齐 docs/superpowers/specs/2026-10-22-cc-builtin-route-steps-fix-design.md -- -- 现象:CC样本处理-BUILTIN 等内置路线仅有路线头、无 biz_process_route_step, -- 导致 B* 入库编码自动派发后任务显示「样本处理 0/0」。 -- 策略:对「内置 + 无有效步骤 + 源路线有步骤」的 *-BUILTIN 路线, -- 从源路线(route_code 去掉 -BUILTIN)深拷贝步骤及产出/数据采集等子表。 -- 幂等:仅当目标内置路线当前 0 条有效步骤时执行;已有步骤则跳过。 -- MySQL 5.7 -- 1) 需要修复的内置路线 ↔ 源路线 DROP TEMPORARY TABLE IF EXISTS tmp_builtin_route_fix; CREATE TEMPORARY TABLE tmp_builtin_route_fix ( dst_route_id VARCHAR(64) NOT NULL, src_route_id VARCHAR(64) NOT NULL, tenant_no VARCHAR(64) NOT NULL, PRIMARY KEY (dst_route_id) ) ENGINE=MEMORY; INSERT INTO tmp_builtin_route_fix (dst_route_id, src_route_id, tenant_no) SELECT b.id, ( SELECT s.id FROM biz_process_route s WHERE s.tenant_no = b.tenant_no AND s.route_code = REPLACE(b.route_code, '-BUILTIN', '') AND s.del_flag = 0 AND IFNULL(s.is_builtin, '0') = '0' ORDER BY CASE WHEN IFNULL(s.is_current, '0') = '1' THEN 0 ELSE 1 END, s.update_time DESC, s.create_time DESC LIMIT 1 ) AS src_route_id, b.tenant_no FROM biz_process_route b WHERE IFNULL(b.is_builtin, '0') = '1' AND b.del_flag = 0 AND b.route_code LIKE '%-BUILTIN' AND NOT EXISTS ( SELECT 1 FROM biz_process_route_step st WHERE st.route_id = b.id AND st.del_flag = 0 ); -- 去掉找不到源、或源也无步骤的行 DELETE FROM tmp_builtin_route_fix WHERE src_route_id IS NULL OR NOT EXISTS ( SELECT 1 FROM biz_process_route_step st WHERE st.route_id = tmp_builtin_route_fix.src_route_id AND st.del_flag = 0 ); -- 2) 源步骤 → 新步骤 ID 映射 DROP TEMPORARY TABLE IF EXISTS tmp_step_id_map; CREATE TEMPORARY TABLE tmp_step_id_map ( src_step_id VARCHAR(64) NOT NULL, dst_step_id VARCHAR(64) NOT NULL, dst_route_id VARCHAR(64) NOT NULL, tenant_no VARCHAR(64) NOT NULL, PRIMARY KEY (src_step_id) ) ENGINE=MEMORY; INSERT INTO tmp_step_id_map (src_step_id, dst_step_id, dst_route_id, tenant_no) SELECT ss.id, -- MD5+源步骤保证同语句多行不撞主键;前缀避免与历史 UUID 冲突 CONCAT('BF', UPPER(MD5(CONCAT('fix-builtin-step:', f.dst_route_id, ':', ss.id)))), f.dst_route_id, f.tenant_no FROM tmp_builtin_route_fix f INNER JOIN biz_process_route_step ss ON ss.route_id = f.src_route_id AND ss.del_flag = 0; -- 3) 拷贝步骤 INSERT INTO biz_process_route_step ( id, route_id, process_id, step_order, process_code, category_id, process_name, description, equipment_ids, equipment_name, estimated_duration, sop_ids, sop_content, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT m.dst_step_id, m.dst_route_id, ss.process_id, ss.step_order, ss.process_code, ss.category_id, ss.process_name, ss.description, ss.equipment_ids, ss.equipment_name, ss.estimated_duration, ss.sop_ids, ss.sop_content, ss.tenant_no, ss.order_num, ss.remark, ss.create_by, ss.create_dept_id, NOW(), ss.update_by, NOW(), 0 FROM tmp_step_id_map m INNER JOIN biz_process_route_step ss ON ss.id = m.src_step_id; -- 4) 试剂 INSERT INTO biz_process_route_step_reagent ( id, step_id, reagent_code, reagent_name, spec, standard_usage, unit, is_key_material, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT CONCAT('BF', UPPER(MD5(CONCAT('fix-builtin-reag:', m.dst_step_id, ':', r.id)))), m.dst_step_id, r.reagent_code, r.reagent_name, r.spec, r.standard_usage, r.unit, r.is_key_material, r.tenant_no, r.order_num, r.remark, r.create_by, r.create_dept_id, NOW(), r.update_by, NOW(), 0 FROM tmp_step_id_map m INNER JOIN biz_process_route_step_reagent r ON r.step_id = m.src_step_id AND r.del_flag = 0; -- 5) 耗材 INSERT INTO biz_process_route_step_consumable ( id, step_id, consumable_code, consumable_name, spec_model, standard_usage, unit, is_required, remark, tenant_no, order_num, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT CONCAT('BF', UPPER(MD5(CONCAT('fix-builtin-cons:', m.dst_step_id, ':', c.id)))), m.dst_step_id, c.consumable_code, c.consumable_name, c.spec_model, c.standard_usage, c.unit, c.is_required, c.remark, c.tenant_no, c.order_num, c.create_by, c.create_dept_id, NOW(), c.update_by, NOW(), 0 FROM tmp_step_id_map m INNER JOIN biz_process_route_step_consumable c ON c.step_id = m.src_step_id AND c.del_flag = 0; -- 6) 产出 INSERT INTO biz_process_route_step_output ( id, step_id, output_type_id, output_name, output_barcode, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT CONCAT('BF', UPPER(MD5(CONCAT('fix-builtin-out:', m.dst_step_id, ':', o.id)))), m.dst_step_id, o.output_type_id, o.output_name, o.output_barcode, o.tenant_no, o.order_num, o.remark, o.create_by, o.create_dept_id, NOW(), o.update_by, NOW(), 0 FROM tmp_step_id_map m INNER JOIN biz_process_route_step_output o ON o.step_id = m.src_step_id AND o.del_flag = 0; -- 7) 数据采集 INSERT INTO biz_process_route_step_data_collection ( id, step_id, collection_name, unit, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT CONCAT('BF', UPPER(MD5(CONCAT('fix-builtin-dc:', m.dst_step_id, ':', d.id)))), m.dst_step_id, d.collection_name, d.unit, d.tenant_no, d.order_num, d.remark, d.create_by, d.create_dept_id, NOW(), d.update_by, NOW(), 0 FROM tmp_step_id_map m INNER JOIN biz_process_route_step_data_collection d ON d.step_id = m.src_step_id AND d.del_flag = 0; -- 8) 校验(人工看结果) SELECT b.route_code, b.route_name, (SELECT COUNT(*) FROM biz_process_route_step st WHERE st.route_id = b.id AND st.del_flag = 0) AS step_count FROM biz_process_route b WHERE IFNULL(b.is_builtin, '0') = '1' AND b.del_flag = 0 AND b.route_code LIKE '%-BUILTIN' ORDER BY b.route_code; DROP TEMPORARY TABLE IF EXISTS tmp_step_id_map; DROP TEMPORARY TABLE IF EXISTS tmp_builtin_route_fix;