1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
-- ============================================================
-- 生产订单完整删除函数
-- 适用场景:待开始、进行中、已完成三种状态的生产订单删除
-- 生成日期:2026-06-11
-- ============================================================
 
DELIMITER $$
 
DROP FUNCTION IF EXISTS fn_delete_production_order$$
 
CREATE FUNCTION fn_delete_production_order(
    p_order_id BIGINT,
    p_force_delete TINYINT DEFAULT 0  -- 0=安全模式(已生产不允许删除), 1=强制删除
) RETURNS VARCHAR(500)
DETERMINISTIC
READS SQL DATA
BEGIN
    DECLARE v_order_status INT DEFAULT 0;
    DECLARE v_complete_quantity DECIMAL(20,4) DEFAULT 0;
    DECLARE v_quantity DECIMAL(20,4) DEFAULT 0;
    DECLARE v_nps_no VARCHAR(100) DEFAULT '';
    DECLARE v_has_pick_record INT DEFAULT 0;
    DECLARE v_has_product_main INT DEFAULT 0;
    DECLARE v_has_quality_inspect INT DEFAULT 0;
    DECLARE v_has_stock_record INT DEFAULT 0;
    DECLARE v_deleted_count INT DEFAULT 0;
    DECLARE v_result VARCHAR(500) DEFAULT '';
 
    -- 查询订单基本信息
    SELECT status, complete_quantity, quantity, nps_no
    INTO v_order_status, v_complete_quantity, v_quantity, v_nps_no
    FROM production_order
    WHERE id = p_order_id;
 
    -- 订单不存在
    IF v_order_status IS NULL THEN
        RETURN CONCAT('删除失败:生产订单不存在,ID=', p_order_id);
    END IF;
 
    -- 安全模式下检查是否允许删除
    IF p_force_delete = 0 THEN
        -- 状态检查:只有待开始(1)和已取消(4)允许删除
        IF v_order_status = 2 THEN
            RETURN CONCAT('删除失败:订单[', v_nps_no, ']正在进行中,不允许删除');
        END IF;
 
        IF v_order_status = 3 THEN
            RETURN CONCAT('删除失败:订单[', v_nps_no, ']已完成,不允许删除');
        END IF;
 
        IF v_order_status = 5 THEN
            RETURN CONCAT('删除失败:订单[', v_nps_no, ']已结束,不允许删除');
        END IF;
    END IF;
 
    -- ========== 第一步:检查关联数据是否存在 ==========
 
    -- 检查领料记录
    SELECT COUNT(*) INTO v_has_pick_record
    FROM production_order_pick_record
    WHERE production_order_id = p_order_id;
 
    -- 检查报工记录
    SELECT COUNT(*) INTO v_has_product_main
    FROM production_product_main ppm
    INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
    WHERE pot.production_order_id = p_order_id;
 
    -- 检查质检记录
    SELECT COUNT(*) INTO v_has_quality_inspect
    FROM quality_inspect qi
    INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
    INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
    WHERE pot.production_order_id = p_order_id;
 
    -- 检查库存记录(通过报工入库)
    SELECT COUNT(*) INTO v_has_stock_record
    FROM stock_in_record sir
    INNER JOIN production_product_main ppm ON sir.record_id = ppm.id
    INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
    WHERE pot.production_order_id = p_order_id
    AND sir.record_type IN ('2', '5');  -- 生产报工入库
 
    -- ========== 第二步:删除关联数据(从叶子到根) ==========
 
    -- 【第1层】删除质检附件
    DELETE FROM quality_inspect_file
    WHERE inspect_id IN (
        SELECT qi.id FROM quality_inspect qi
        INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第2层】删除质检参数
    DELETE FROM quality_inspect_param
    WHERE inspect_id IN (
        SELECT qi.id FROM quality_inspect qi
        INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第3层】删除不合格品记录
    DELETE FROM quality_unqualified
    WHERE inspect_id IN (
        SELECT qi.id FROM quality_inspect qi
        INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第4层】删除质检记录(过程检验、出厂检验)
    DELETE FROM quality_inspect
    WHERE product_main_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第5层】删除库存入库记录(生产报工入库、报废入库)
    DELETE FROM stock_in_record
    WHERE record_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    ) AND record_type IN ('2', '5', '7');  -- 生产报工入库、报废入库
 
    -- 删除质检入库记录
    DELETE FROM stock_in_record
    WHERE record_id IN (
        SELECT qi.id FROM quality_inspect qi
        INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    ) AND record_type = '6';  -- 质检入库
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第6层】删除库存出库记录(生产报工出库)
    DELETE FROM stock_out_record
    WHERE record_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    ) AND record_type = '13';  -- 生产报工出库
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第7层】删除报工产出
    DELETE FROM production_product_output
    WHERE production_product_main_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第8层】删除报工投入
    DELETE FROM production_product_input
    WHERE production_product_main_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第9层】删除生产核算
    DELETE FROM production_account
    WHERE production_product_main_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第10层】删除报工工序参数(通过production_product_main_id关联)
    DELETE FROM production_order_routing_operation_param
    WHERE production_product_main_id IN (
        SELECT ppm.id FROM production_product_main ppm
        INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
        WHERE pot.production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第11层】删除报工主表
    DELETE FROM production_product_main
    WHERE production_operation_task_id IN (
        SELECT id FROM production_operation_task
        WHERE production_order_id = p_order_id
    );
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第12层】删除领料记录
    DELETE FROM production_order_pick_record
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第13层】删除领料入库记录(退料)
    DELETE FROM stock_in_record
    WHERE record_id IN (
        SELECT id FROM production_order_pick
        WHERE production_order_id = p_order_id
    ) AND record_type IN ('20', '22');  -- 领料退料入库
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第14层】删除领料单
    DELETE FROM production_order_pick
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第15层】删除生产工单
    DELETE FROM production_operation_task
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第16层】删除工序参数(订单级别)
    DELETE FROM production_order_routing_operation_param
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第17层】删除工序
    DELETE FROM production_order_routing_operation
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第18层】删除工艺路线
    DELETE FROM production_order_routing
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第19层】删除BOM结构
    DELETE FROM production_bom_structure
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第20层】删除订单BOM
    DELETE FROM production_order_bom
    WHERE production_order_id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 【第21层】删除生产计划关联(回退计划已下发数量)
    -- 注意:这里需要根据业务逻辑回退production_plan的quantity_issued和status
    -- 由于production_plan_ids是JSON格式[1,2,3],需要特殊处理
    -- 此处仅删除订单,计划回退逻辑建议在应用层处理
 
    -- 【第22层】删除生产订单主表
    DELETE FROM production_order
    WHERE id = p_order_id;
    SET v_deleted_count = v_deleted_count + ROW_COUNT();
 
    -- 返回结果
    SET v_result = CONCAT(
        '删除成功:订单[', v_nps_no, '],',
        '状态=', CASE v_order_status
            WHEN 1 THEN '待开始'
            WHEN 2 THEN '进行中'
            WHEN 3 THEN '已完成'
            WHEN 4 THEN '已取消'
            WHEN 5 THEN '已结束'
            ELSE '未知'
        END, ',',
        '共删除', v_deleted_count, '条关联数据'
    );
 
    RETURN v_result;
 
END$$
 
DELIMITER ;
 
-- ============================================================
-- 批量删除生产订单存储过程
-- ============================================================
 
DELIMITER $$
 
DROP PROCEDURE IF EXISTS sp_batch_delete_production_order$$
 
CREATE PROCEDURE sp_batch_delete_production_order(
    IN p_order_ids TEXT,           -- 订单ID列表,逗号分隔,如 "1,2,3"
    IN p_force_delete TINYINT      -- 0=安全模式, 1=强制删除
)
BEGIN
    DECLARE v_order_id BIGINT;
    DECLARE v_done INT DEFAULT FALSE;
    DECLARE v_cursor CURSOR FOR
        SELECT CAST(TRIM(value) AS UNSIGNED)
        FROM JSON_TABLE(CONCAT('[', p_order_ids, ']'), '$[*]' COLUMNS(value VARCHAR(20) PATH '$')) AS jt;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
 
    DECLARE v_success_count INT DEFAULT 0;
    DECLARE v_fail_count INT DEFAULT 0;
    DECLARE v_result_msg VARCHAR(500);
 
    -- 创建临时表记录结果
    DROP TEMPORARY TABLE IF EXISTS tmp_delete_result;
    CREATE TEMPORARY TABLE tmp_delete_result (
        order_id BIGINT,
        result VARCHAR(500)
    );
 
    OPEN v_cursor;
 
    read_loop: LOOP
        FETCH v_cursor INTO v_order_id;
        IF v_done THEN
            LEAVE read_loop;
        END IF;
 
        -- 调用删除函数
        SET v_result_msg = fn_delete_production_order(v_order_id, p_force_delete);
 
        -- 记录结果
        INSERT INTO tmp_delete_result (order_id, result) VALUES (v_order_id, v_result_msg);
 
        -- 统计
        IF v_result_msg LIKE '删除成功%' THEN
            SET v_success_count = v_success_count + 1;
        ELSE
            SET v_fail_count = v_fail_count + 1;
        END IF;
 
    END LOOP;
 
    CLOSE v_cursor;
 
    -- 输出结果
    SELECT
        CONCAT('批量删除完成:成功', v_success_count, '个,失败', v_fail_count, '个') AS summary;
 
    SELECT * FROM tmp_delete_result;
 
    DROP TEMPORARY TABLE IF EXISTS tmp_delete_result;
 
END$$
 
DELIMITER ;
 
-- ============================================================
-- 使用示例
-- ============================================================
 
-- 示例1:安全模式删除单个订单(只能删除待开始/已取消状态)
-- SELECT fn_delete_production_order(123, 0);
 
-- 示例2:强制删除单个订单(忽略状态检查)
-- SELECT fn_delete_production_order(123, 1);
 
-- 示例3:批量删除订单
-- CALL sp_batch_delete_production_order('123,124,125', 0);
 
-- 示例4:批量强制删除
-- CALL sp_batch_delete_production_order('123,124,125', 1);