feat: 二期审批引擎扩展与会签/明细/回填/附件分类共享层(#46)

- ApprovalDocumentType SPI + 注册表:新增单据不再改引擎
- ApprovalApproverResolver:会签组、orgLeaderByCode/orgDeputyByCode、租户岗位解析器
- 会签:任务带 group_key/group_name/group_seq,一人多组一次通过,只取消同组待办
- 回填:节点 writableFields、BACKFILL 动作、approval_field_change 留痕
- 附件:新增 VOUCHER 分类并按单据类型校验必传
- 详情:document.fields/lines/lineColumns/groupProgress + permissions.writableFields
- 列表/导出:title/search_text 落库、flowCode 筛选、明细行数/合计金额/会签进度列、明细导出
- sql/05-approval_phase2.sql(可重复执行)
This commit is contained in:
weicw
2026-10-31 06:13:45 +08:00
parent 5018463005
commit d5001c981c
59 changed files with 3230 additions and 661 deletions
+107
View File
@@ -0,0 +1,107 @@
-- 二期审批引擎扩展(可重复执行)
-- 目标库:db_gxtyzx(master)
-- 执行顺序:01-approval.sql -> 02-approval_menu.sql -> 03-approval_orgs_roles.sql
-- -> 04-approval_role_grants.sql -> 05-approval_phase2.sql
--
-- 覆盖 ADR 0003(会签)、0004(明细行)、0006(回填)、0007(流程类型筛选)。
-- MySQL 8 不支持 ADD COLUMN IF NOT EXISTS,因此用 information_schema 判断后动态执行。
-- 老数据回填:一期实例没有 title/search_text(幂等,只补空值)
UPDATE approval_instance i
JOIN approval_completion_form f ON f.instance_id = i.id
SET i.title = f.name,
i.search_text = CONCAT_WS(' ', f.name, f.implement_org, f.service_content)
WHERE i.title IS NULL;
UPDATE approval_instance i
JOIN approval_coordination_form c ON c.instance_id = i.id
SET i.title = c.title,
i.search_text = CONCAT_WS(' ', c.title, c.content, c.remark)
WHERE i.title IS NULL;
DROP PROCEDURE IF EXISTS approval_phase2_add_column;
DROP PROCEDURE IF EXISTS approval_phase2_add_index;
DELIMITER $$
CREATE PROCEDURE approval_phase2_add_column(IN p_table VARCHAR(64), IN p_column VARCHAR(64),
IN p_definition TEXT)
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = p_table AND column_name = p_column
) THEN
SET @ddl = CONCAT('ALTER TABLE ', p_table, ' ADD COLUMN ', p_definition);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END$$
CREATE PROCEDURE approval_phase2_add_index(IN p_table VARCHAR(64), IN p_index VARCHAR(64),
IN p_definition TEXT)
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.statistics
WHERE table_schema = DATABASE() AND table_name = p_table AND index_name = p_index
) THEN
SET @ddl = CONCAT('ALTER TABLE ', p_table, ' ADD ', p_definition);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END$$
DELIMITER ;
-- 会签任务分组:非会签节点三列为空(ADR 0003)
CALL approval_phase2_add_column('approval_task', 'group_key',
'group_key VARCHAR(40) DEFAULT NULL COMMENT ''会签组标识'' AFTER opinion');
CALL approval_phase2_add_column('approval_task', 'group_name',
'group_name VARCHAR(100) DEFAULT NULL COMMENT ''会签组显示名'' AFTER group_key');
CALL approval_phase2_add_column('approval_task', 'group_seq',
'group_seq INT DEFAULT NULL COMMENT ''会签组展示顺序'' AFTER group_name');
-- 列表标题与检索文本:由单据实现计算落库,列表/检索不再按 doc_type 分支(ADR 0007)
CALL approval_phase2_add_column('approval_instance', 'title',
'title VARCHAR(200) DEFAULT NULL COMMENT ''列表显示标题'' AFTER biz_id');
CALL approval_phase2_add_column('approval_instance', 'search_text',
'search_text VARCHAR(500) DEFAULT NULL COMMENT ''关键词检索文本'' AFTER title');
-- 回填唯一性检索用:同类单据按 flow_code 过滤
CALL approval_phase2_add_index('approval_instance', 'idx_flow',
'KEY idx_flow (tenant_id, flow_code, status)');
-- 字段改值历史(ADR 0006)
CREATE TABLE IF NOT EXISTS approval_field_change (
id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id INT NOT NULL DEFAULT 10150,
instance_id BIGINT NOT NULL,
task_id BIGINT DEFAULT NULL,
node_key VARCHAR(40) DEFAULT NULL,
field_key VARCHAR(40) NOT NULL,
field_label VARCHAR(100) DEFAULT NULL,
old_value VARCHAR(500) DEFAULT NULL,
new_value VARCHAR(500) DEFAULT NULL,
operator_id INT NOT NULL,
operator_name VARCHAR(100) DEFAULT NULL,
round INT NOT NULL,
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_instance (instance_id, create_time),
KEY idx_field (tenant_id, field_key, new_value)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='审批字段改值历史';
-- 老数据回填:一期实例没有 title/search_text(幂等,只补空值)
UPDATE approval_instance i
JOIN approval_completion_form f ON f.instance_id = i.id
SET i.title = f.name,
i.search_text = CONCAT_WS(' ', f.name, f.implement_org, f.service_content)
WHERE i.title IS NULL;
UPDATE approval_instance i
JOIN approval_coordination_form c ON c.instance_id = i.id
SET i.title = c.title,
i.search_text = CONCAT_WS(' ', c.title, c.content, c.remark)
WHERE i.title IS NULL;
DROP PROCEDURE IF EXISTS approval_phase2_add_column;
DROP PROCEDURE IF EXISTS approval_phase2_add_index;