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
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
-- ============================================================================
-- 新疆-新高力 项目:单据审核状态机改造 + 电力作业计划生成工单 待执行数据库变更
-- 目标库:mom-xgdl
-- 说明:本脚本幂等,可重复执行;已存在的字段/菜单会自动跳过。
--       开发库(192.168.197.128)已全部执行过,本脚本用于向其它环境(如测试/生产)同步。
-- 内容结构:
--   第一部分  20 张单据表的审核人四字段
--   第二部分  上述单据的「审核」按钮权限(system_menu type=3)
--   第三部分  电力作业计划生成工单编码规则说明(无需执行)
--   第四部分  通用审批配置表 + 26 个业务类型 + 审批配置页菜单
--             + 采购计划/采购订单审核字段与按钮 + 角色授权
--
-- 执行前置要求:必须用支持 DELIMITER 与存储过程的客户端整体执行
--   (mysql CLI:mysql -h<host> -P<port> -u<user> -p mom-xgdl < 本文件)。
--   多数图形化/在线 SQL 控制台按分号拆分语句,会把 DELIMITER $$ 段落拆坏。
--
-- 对应代码提交:
--   refactor(crm/erp/hrm/mes): 单据审核改为审批配置状态机
--   fix(mes): 电力作业计划生成工单补充编码规则取号
--   e347fd6e refactor(approval): 采购计划/采购订单审批由 BPM 改为轻量级状态机
-- ============================================================================
 
SET NAMES utf8mb4;
 
-- ============================================================================
-- 第一部分:20 张单据表新增审核人四字段
--   reviewer_id / reviewer_name / review_time / review_remark
-- ============================================================================
 
DROP TABLE IF EXISTS _tmp_xgdl_review_cols;
CREATE TABLE _tmp_xgdl_review_cols (
    tbl    VARCHAR(64)  NOT NULL,
    col    VARCHAR(64)  NOT NULL,
    coldef VARCHAR(255) NOT NULL
);
 
INSERT INTO _tmp_xgdl_review_cols (tbl, col, coldef) VALUES
-- CRM
('crm_cancellation',            'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('crm_cancellation',            'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('crm_cancellation',            'review_time',    'datetime COMMENT ''审核时间'''),
('crm_cancellation',            'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('crm_contract',                'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('crm_contract',                'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('crm_contract',                'review_time',    'datetime COMMENT ''审核时间'''),
('crm_contract',                'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('crm_invoice',                 'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('crm_invoice',                 'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('crm_invoice',                 'review_time',    'datetime COMMENT ''审核时间'''),
('crm_invoice',                 'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('crm_refund',                  'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('crm_refund',                  'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('crm_refund',                  'review_time',    'datetime COMMENT ''审核时间'''),
('crm_refund',                  'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
-- ERP
('erp_finance_payment',         'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('erp_finance_payment',         'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('erp_finance_payment',         'review_time',    'datetime COMMENT ''审核时间'''),
('erp_finance_payment',         'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('erp_purchase_request',        'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('erp_purchase_request',        'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('erp_purchase_request',        'review_time',    'datetime COMMENT ''审核时间'''),
('erp_purchase_request',        'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
-- HRM
('hrm_leave_application',       'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('hrm_leave_application',       'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('hrm_leave_application',       'review_time',    'datetime COMMENT ''审核时间'''),
('hrm_leave_application',       'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('hrm_regularize_application',  'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('hrm_regularize_application',  'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('hrm_regularize_application',  'review_time',    'datetime COMMENT ''审核时间'''),
('hrm_regularize_application',  'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('hrm_resignation_application', 'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('hrm_resignation_application', 'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('hrm_resignation_application', 'review_time',    'datetime COMMENT ''审核时间'''),
('hrm_resignation_application', 'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('hrm_transfer_application',    'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('hrm_transfer_application',    'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('hrm_transfer_application',    'review_time',    'datetime COMMENT ''审核时间'''),
('hrm_transfer_application',    'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('hrm_attendance_exception',    'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('hrm_attendance_exception',    'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('hrm_attendance_exception',    'review_time',    'datetime COMMENT ''审核时间'''),
('hrm_attendance_exception',    'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('hrm_performance_appraise',    'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('hrm_performance_appraise',    'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('hrm_performance_appraise',    'review_time',    'datetime COMMENT ''审核时间'''),
('hrm_performance_appraise',    'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
-- MES
('mes_pd_project',              'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_pd_project',              'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_pd_project',              'review_time',    'datetime COMMENT ''审核时间'''),
('mes_pd_project',              'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('product_tech_confirm',        'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('product_tech_confirm',        'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('product_tech_confirm',        'review_time',    'datetime COMMENT ''审核时间'''),
('product_tech_confirm',        'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('mes_wm_equipment_receipt',    'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_wm_equipment_receipt',    'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_wm_equipment_receipt',    'review_time',    'datetime COMMENT ''审核时间'''),
('mes_wm_equipment_receipt',    'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('mes_wm_item_receipt',         'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_wm_item_receipt',         'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_wm_item_receipt',         'review_time',    'datetime COMMENT ''审核时间'''),
('mes_wm_item_receipt',         'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('mes_wm_misc_issue',           'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_wm_misc_issue',           'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_wm_misc_issue',           'review_time',    'datetime COMMENT ''审核时间'''),
('mes_wm_misc_issue',           'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('mes_wm_misc_receipt',         'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_wm_misc_receipt',         'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_wm_misc_receipt',         'review_time',    'datetime COMMENT ''审核时间'''),
('mes_wm_misc_receipt',         'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('mes_wm_return_vendor',        'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_wm_return_vendor',        'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_wm_return_vendor',        'review_time',    'datetime COMMENT ''审核时间'''),
('mes_wm_return_vendor',        'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)'''),
('mes_wm_stock_taking_task',    'reviewer_id',    'bigint COMMENT ''审核人用户编号(提交审批时指定)'''),
('mes_wm_stock_taking_task',    'reviewer_name',  'varchar(64) COMMENT ''审核人姓名(冗余)'''),
('mes_wm_stock_taking_task',    'review_time',    'datetime COMMENT ''审核时间'''),
('mes_wm_stock_taking_task',    'review_remark',  'varchar(500) COMMENT ''审核意见(不通过时即不通过原因)''');
 
DROP PROCEDURE IF EXISTS xgdl_add_review_cols;
DELIMITER $$
CREATE PROCEDURE xgdl_add_review_cols()
BEGIN
    DECLARE v_done INT DEFAULT 0;
    DECLARE v_tbl VARCHAR(64);
    DECLARE v_col VARCHAR(64);
    DECLARE v_def VARCHAR(255);
    DECLARE cur CURSOR FOR SELECT tbl, col, coldef FROM _tmp_xgdl_review_cols;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = 1;
 
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO v_tbl, v_col, v_def;
        IF v_done = 1 THEN
            LEAVE read_loop;
        END IF;
        IF EXISTS (SELECT 1 FROM information_schema.tables
                   WHERE table_schema = DATABASE() AND table_name = v_tbl)
           AND NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_schema = DATABASE() AND table_name = v_tbl AND column_name = v_col)
        THEN
            SET @ddl = CONCAT('ALTER TABLE `', v_tbl, '` ADD COLUMN `', v_col, '` ', v_def);
            PREPARE stmt FROM @ddl;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;
        END IF;
    END LOOP;
    CLOSE cur;
END$$
DELIMITER ;
 
CALL xgdl_add_review_cols();
DROP PROCEDURE IF EXISTS xgdl_add_review_cols;
DROP TABLE IF EXISTS _tmp_xgdl_review_cols;
 
-- ============================================================================
-- 第二部分:审核按钮菜单(system_menu,type=3 按钮)
--   挂载位置:与同资源「修改」按钮同父级;已存在则跳过
-- ============================================================================
 
-- 逐条插入:名称、权限、锚点权限(同资源的 :update 按钮)
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '销户申请审核' AS name, 'crm:cancellation:audit' AS perm, 'crm:cancellation:update' AS anchor) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'crm:cancellation:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'crm:cancellation:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '合同审核' AS name, 'crm:contract:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'crm:contract:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'crm:contract:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '发票审核' AS name, 'crm:invoice:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'crm:invoice:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'crm:invoice:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '退费单审核' AS name, 'crm:refund:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'crm:refund:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'crm:refund:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '付款单审核' AS name, 'erp:finance-payment:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'erp:finance-payment:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'erp:finance-payment:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '采购申请审核' AS name, 'erp:purchase-request:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'erp:purchase-request:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'erp:purchase-request:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '请假申请审核' AS name, 'hrm:leave:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'hrm:leave:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'hrm:leave:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '转正申请审核' AS name, 'hrm:regularize:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'hrm:regularize:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'hrm:regularize:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '离职申请审核' AS name, 'hrm:resignation:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'hrm:resignation:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'hrm:resignation:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '调动申请审核' AS name, 'hrm:transfer:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'hrm:transfer:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'hrm:transfer:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '考勤异常审核' AS name, 'hrm:attendance-exception:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'hrm:attendance-exception:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'hrm:attendance-exception:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '项目审核' AS name, 'mes:pd-project:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:pd-project:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:pd-project:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '技术确认函审核' AS name, 'mes:pd-tech-confirm:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:pd-tech-confirm:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:pd-tech-confirm:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '采购入库单审核' AS name, 'mes:wm-item-receipt:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:wm-item-receipt:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:wm-item-receipt:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '杂项出库单审核' AS name, 'mes:wm-misc-issue:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:wm-misc-issue:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:wm-misc-issue:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '采购退货单审核' AS name, 'mes:wm-return-vendor:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:wm-return-vendor:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:wm-return-vendor:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '盘点任务审核' AS name, 'mes:wm-stock-taking-task:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:wm-stock-taking-task:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:wm-stock-taking-task:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '设备入库单审核' AS name, 'mes:wm:equipment-receipt:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:wm:equipment-receipt:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:wm:equipment-receipt:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '杂项入库单审核' AS name, 'mes:wm:misc-receipt:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:wm:misc-receipt:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:wm:misc-receipt:audit') m);
 
-- ============================================================================
-- 第三部分:电力作业计划生成工单 —— 工单编码取号规则(无变更,仅说明)
--   fix(mes) 使用 PRO_WORK_ORDER_CODE 编码规则自动生成工单编码。
--   该规则(WO_ + yyyyMMdd + 4 位循环流水号,规则组成 3 段)在
--   mes_md_auto_code_rule / mes_md_auto_code_part 中已存在,无需执行 SQL。
--   全新环境请执行 sql/mysql/mes_auto_code_rule_init.sql 初始化全部编码规则
--   (注意:该脚本会 TRUNC 式重建规则表,仅适用于首次初始化,勿在已有数据的环境执行)。
-- ============================================================================
 
-- ============================================================================
-- 第四部分:通用审批配置(审批引擎的地基)
--
-- 前三部分只加了「审核人字段」和「审核按钮权限」,但没有建审批配置表本身。
-- 只跑前三部分的话,所有单据的「提交」都会在 validateApprovalEnabledAndGetApprovers
-- 处失败(审批配置不存在 / 未启用 / 未配置审批人)。本部分补齐:
--   4.1 审批配置主表 + 审批人子表
--   4.2 26 个业务类型种子(默认未启用)
--   4.3 审批配置页面菜单与查询/保存按钮
--   4.4 采购计划、采购订单的审核人四字段
--   4.5 采购计划、采购订单的审核按钮权限
--   4.6 角色授权(本框架无「超管绕过权限」逻辑,不授权则 admin 也看不到按钮)
--
-- 对应代码提交:e347fd6e refactor(approval): 采购计划/采购订单审批由 BPM 改为轻量级状态机
-- ============================================================================
 
-- 4.1 审批配置主表 / 审批人子表
CREATE TABLE IF NOT EXISTS system_approval_config (
  id bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  biz_type varchar(64) NOT NULL COMMENT '业务类型编码,与各模块审批分类编码一致',
  biz_name varchar(100) NOT NULL COMMENT '业务类型名称',
  approval_enabled bit(1) NOT NULL DEFAULT b'0' COMMENT '是否启用审批',
  remark varchar(500) NULL DEFAULT NULL COMMENT '备注',
  creator varchar(64) NULL DEFAULT '' COMMENT '创建者',
  create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  updater varchar(64) NULL DEFAULT '' COMMENT '更新者',
  update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  PRIMARY KEY (id) USING BTREE,
  KEY idx_biz_type (biz_type) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '通用审批配置表';
 
CREATE TABLE IF NOT EXISTS system_approval_config_user (
  id bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  config_id bigint NOT NULL COMMENT '审批配置ID(关联 system_approval_config.id)',
  user_id bigint NOT NULL COMMENT '审批人用户ID(系统用户)',
  sort int NOT NULL DEFAULT 0 COMMENT '显示顺序',
  creator varchar(64) NULL DEFAULT '' COMMENT '创建者',
  create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  updater varchar(64) NULL DEFAULT '' COMMENT '更新者',
  update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  PRIMARY KEY (id) USING BTREE,
  KEY idx_config_id (config_id) USING BTREE,
  KEY idx_user_id (user_id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '通用审批配置-审批人表';
 
-- 4.2 业务类型种子:编码与各模块 *_APPROVE_* 常量一一对应,默认全部未启用
INSERT IGNORE INTO system_approval_config
  (biz_type, biz_name, approval_enabled, remark, creator, create_time, updater, update_time, deleted) VALUES
('purchase_plan_approve',        '采购计划审核',   b'0', 'ERP 采购计划', '1', NOW(), '1', NOW(), b'0'),
('purchase_request_approve',     '采购申请审核',   b'0', 'ERP 采购申请', '1', NOW(), '1', NOW(), b'0'),
('erp_purchase_order_approve',   '采购订单审核',   b'0', 'ERP 采购订单(原误用 purchase_request_approve,已改为独立编码)', '1', NOW(), '1', NOW(), b'0'),
('erp_purchase_invoice_approve', '采购来票审核',   b'0', 'ERP 采购来票', '1', NOW(), '1', NOW(), b'0'),
('erp_finance_payment_approve',  '付款单审核',     b'0', 'ERP 付款单', '1', NOW(), '1', NOW(), b'0'),
('contract_approve',             '合同审批',       b'0', 'CRM 合同', '1', NOW(), '1', NOW(), b'0'),
('refund_approve',               '退费审批',       b'0', 'CRM 退款', '1', NOW(), '1', NOW(), b'0'),
('cancellation_approve',         '销户审批',       b'0', 'CRM 销户', '1', NOW(), '1', NOW(), b'0'),
('crm_invoice_approve',          '开票审批',       b'0', 'CRM 发票', '1', NOW(), '1', NOW(), b'0'),
('sale_quotation_approve',       '销售报价审批',   b'0', 'CRM 销售报价', '1', NOW(), '1', NOW(), b'0'),
('hrm_leave_approve',            '请假审批',       b'0', 'HRM 请假申请', '1', NOW(), '1', NOW(), b'0'),
('hrm_regularize_approve',       '转正审批',       b'0', 'HRM 转正申请', '1', NOW(), '1', NOW(), b'0'),
('hrm_resignation_approve',      '离职审批',       b'0', 'HRM 离职申请', '1', NOW(), '1', NOW(), b'0'),
('hrm_transfer_approve',         '调动审批',       b'0', 'HRM 调动申请', '1', NOW(), '1', NOW(), b'0'),
('hrm_attendance_approve',       '考勤异常审批',   b'0', 'HRM 考勤异常', '1', NOW(), '1', NOW(), b'0'),
('performance_appraise_approve', '绩效考核审批',   b'0', 'HRM 绩效考核', '1', NOW(), '1', NOW(), b'0'),
('mes_pd_project_approve',       '产品项目审批',   b'0', 'MES 产品项目', '1', NOW(), '1', NOW(), b'0'),
('pd_tech_confirm_approve',      '技术确认函审批', b'0', 'MES 产品技术确认函', '1', NOW(), '1', NOW(), b'0'),
('item_receipt_approve',         '采购入库审批',   b'0', 'MES 采购入库单', '1', NOW(), '1', NOW(), b'0'),
('equipment_receipt_approve',    '设备入库审批',   b'0', 'MES 设备入库单', '1', NOW(), '1', NOW(), b'0'),
('misc_issue_approve',           '其他出库审批',   b'0', 'MES 其他出库单', '1', NOW(), '1', NOW(), b'0'),
('misc_receipt_approve',         '其他入库审批',   b'0', 'MES 其他入库单', '1', NOW(), '1', NOW(), b'0'),
('return_vendor_approve',        '退货审批',       b'0', 'MES 退货单', '1', NOW(), '1', NOW(), b'0'),
('stock_taking_result_approve',  '盘点结果审批',   b'0', 'MES 盘点单', '1', NOW(), '1', NOW(), b'0'),
('wms_approve',                  '仓库单据审核',   b'0', 'MES 仓储通用审批', '1', NOW(), '1', NOW(), b'0'),
('compensation_approve',         '赔付审批',       b'0', '售后赔偿单', '1', NOW(), '1', NOW(), b'0');
 
-- 4.3 审批配置页面菜单
--     父级锚定「系统管理」:取 system/user/index 的 parent_id,避免硬编码目录 ID
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT '审批配置', '', 2, 8, a.parent_id, 'approval-config', 'ep:stamp', 'system/approvalConfig/index', 'SystemApprovalConfig', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT MIN(m.parent_id) AS parent_id FROM system_menu m WHERE m.deleted = 0 AND m.component = 'system/user/index') a
WHERE a.parent_id IS NOT NULL
  AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND component = 'system/approvalConfig/index') x);
 
-- 4.3.1 审批配置查询按钮(父级 = 上面的页面菜单,按 component 反查)
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT '审批配置查询', 'system:approval-config:query', 3, 1, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT MIN(m.id) AS parent_id FROM system_menu m WHERE m.deleted = 0 AND m.component = 'system/approvalConfig/index') a
WHERE a.parent_id IS NOT NULL
  AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'system:approval-config:query') x);
 
-- 4.3.2 审批配置保存按钮
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT '审批配置保存', 'system:approval-config:update', 3, 2, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT MIN(m.id) AS parent_id FROM system_menu m WHERE m.deleted = 0 AND m.component = 'system/approvalConfig/index') a
WHERE a.parent_id IS NOT NULL
  AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'system:approval-config:update') x);
 
-- 4.4 采购计划 / 采购订单 审核人四字段
--     (第一部分只覆盖了另外 20 张表,这两张是采购计划/采购订单改造时补的)
DROP TABLE IF EXISTS _tmp_xgdl_po_review_cols;
CREATE TABLE _tmp_xgdl_po_review_cols (
    tbl    VARCHAR(64)  NOT NULL,
    col    VARCHAR(64)  NOT NULL,
    coldef VARCHAR(255) NOT NULL
);
 
INSERT INTO _tmp_xgdl_po_review_cols (tbl, col, coldef) VALUES
('erp_purchase_plan',  'reviewer_id',   'bigint COMMENT ''审核人编号(实际执行审核的用户)'''),
('erp_purchase_plan',  'reviewer_name', 'varchar(64) COMMENT ''审核人姓名(冗余记录,避免列表查询再查用户)'''),
('erp_purchase_plan',  'review_time',   'datetime COMMENT ''审核时间'''),
('erp_purchase_plan',  'review_remark', 'varchar(500) COMMENT ''审核意见(通过时的意见 / 不通过时的原因)'''),
('erp_purchase_order', 'reviewer_id',   'bigint COMMENT ''审核人编号(实际执行审核的用户)'''),
('erp_purchase_order', 'reviewer_name', 'varchar(64) COMMENT ''审核人姓名(冗余记录,避免列表查询再查用户)'''),
('erp_purchase_order', 'review_time',   'datetime COMMENT ''审核时间'''),
('erp_purchase_order', 'review_remark', 'varchar(500) COMMENT ''审核意见(通过时的意见 / 不通过时的原因)''');
 
DROP PROCEDURE IF EXISTS xgdl_add_po_review_cols;
DELIMITER $$
CREATE PROCEDURE xgdl_add_po_review_cols()
BEGIN
    DECLARE v_done INT DEFAULT 0;
    DECLARE v_tbl VARCHAR(64);
    DECLARE v_col VARCHAR(64);
    DECLARE v_def VARCHAR(255);
    DECLARE cur CURSOR FOR SELECT tbl, col, coldef FROM _tmp_xgdl_po_review_cols;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = 1;
 
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO v_tbl, v_col, v_def;
        IF v_done = 1 THEN
            LEAVE read_loop;
        END IF;
        IF EXISTS (SELECT 1 FROM information_schema.tables
                   WHERE table_schema = DATABASE() AND table_name = v_tbl)
           AND NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_schema = DATABASE() AND table_name = v_tbl AND column_name = v_col)
        THEN
            SET @ddl = CONCAT('ALTER TABLE `', v_tbl, '` ADD COLUMN `', v_col, '` ', v_def);
            PREPARE stmt FROM @ddl;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;
        END IF;
    END LOOP;
    CLOSE cur;
END$$
DELIMITER ;
 
CALL xgdl_add_po_review_cols();
DROP PROCEDURE IF EXISTS xgdl_add_po_review_cols;
DROP TABLE IF EXISTS _tmp_xgdl_po_review_cols;
 
-- 4.5 采购计划 / 采购订单 审核按钮权限(锚点同第一部分:各自资源的 :update 按钮)
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '采购计划审核' AS name, 'erp:purchase-plan:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'erp:purchase-plan:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'erp:purchase-plan:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '采购订单审核' AS name, 'erp:purchase-order:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'erp:purchase-order:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'erp:purchase-order:audit') m);
 
-- 4.6 补漏:代码里已使用、但第二部分未创建的 3 个审核按钮权限
--     对账方式:grep -rhoE "'[a-z]+:[a-z0-9-]+:audit'" --include=*.java
--     缺失会导致对应页面的审核按钮对任何人都不显示(含 admin)。
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '故障赔付审核' AS name, 'aftersales:compensation:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'aftersales:compensation:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'aftersales:compensation:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '绩效考核审核' AS name, 'hrm:performance-appraise:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'hrm:performance-appraise:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'hrm:performance-appraise:audit') m);
 
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
SELECT t.name, t.perm, 3, 99, a.parent_id, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'
FROM (SELECT '产品项目审核' AS name, 'mes:pd-product:audit' AS perm) t
JOIN (SELECT MIN(x.parent_id) AS parent_id FROM system_menu x WHERE x.deleted = 0 AND x.permission = 'mes:pd-product:update') a ON 1 = 1
WHERE a.parent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM system_menu WHERE deleted = 0 AND permission = 'mes:pd-product:audit') m);
 
-- 4.7 角色授权
--     重要:本框架 SecurityFrameworkServiceImpl 没有「超级管理员绕过权限校验」的短路逻辑,
--     权限一律走 system_role_menu。不授权的话连 admin 都看不到审批配置菜单和审核按钮。
--     开发库实测:全部 :audit 均已授予 super_admin(1) 与 common(2),
--     仅 mes:pd-product:audit 与 mes:pd-tech-confirm:audit 漏授 super_admin ——
--     下面这条语句会顺带把这两个缺口补齐。
--     其余角色请在「角色管理」页面按需勾选。
INSERT INTO system_role_menu (role_id, menu_id, creator, create_time, updater, update_time, deleted)
SELECT r.id, m.id, '1', NOW(), '1', NOW(), b'0'
FROM system_role r
CROSS JOIN system_menu m
WHERE r.code IN ('super_admin', 'common')
  AND r.deleted = 0
  AND m.deleted = 0
  AND ( m.component = 'system/approvalConfig/index'
        OR m.permission IN ('system:approval-config:query', 'system:approval-config:update')
        OR m.permission LIKE '%:audit' )
  AND NOT EXISTS (
      SELECT 1 FROM system_role_menu rm
      WHERE rm.role_id = r.id AND rm.menu_id = m.id AND rm.deleted = 0
  );
 
-- 完成。可执行以下语句校验:
-- SELECT table_name, column_name FROM information_schema.columns
--  WHERE table_schema = DATABASE() AND column_name = 'reviewer_id';
-- SELECT permission FROM system_menu WHERE deleted = 0 AND permission LIKE '%:audit';
-- SELECT COUNT(*) FROM system_approval_config WHERE deleted = 0;                     -- 期望 26
-- SELECT id, name, permission, parent_id FROM system_menu                            -- 必须回读三项,勿只看行数
--  WHERE deleted = 0 AND (component = 'system/approvalConfig/index'
--    OR permission LIKE 'system:approval-config:%'
--    OR permission IN ('erp:purchase-plan:audit','erp:purchase-order:audit'));
-- SELECT r.code, COUNT(*) FROM system_role_menu rm JOIN system_role r ON r.id = rm.role_id
--  JOIN system_menu m ON m.id = rm.menu_id
--  WHERE rm.deleted = 0 AND (m.component = 'system/approvalConfig/index'
--    OR m.permission LIKE 'system:approval-config:%'
--    OR m.permission IN ('erp:purchase-plan:audit','erp:purchase-order:audit'))
--  GROUP BY r.code;                                                                  -- 期望每角色 5 条