-- ============================================================= -- 自定义审批流(租户侧 + 平台侧) -- -- 对应模型:go/models/approval.go -- -- 设计要点: -- 1. 配置侧与实例侧分离:flow/node 是配置(租户可编辑), -- instance/task 是运行时(提交后生成,不可编辑)。 -- 2. 节点表用 prev_keys / next_keys 存连线,当期顺序链只填 sort, -- 后续上拖拽图与条件分支无需改表。 -- 3. scope 区分租户侧(tenant)与平台侧(platform):平台账号不归属租户, -- 其流程不带 tid,实例用 biz_tid 标记申请来源租户。 -- -- 注意:不显式指定 COLLATE,沿用数据库默认排序规则,避免与既有表 -- (utf8mb4_0900_ai_ci)在 JOIN 比较字符串时报 Illegal mix of collations。 -- ============================================================= SET NAMES utf8mb4; -- ---------------- 1. 租户侧审批流程 ---------------- CREATE TABLE IF NOT EXISTS `yz_backend_approval_flow` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `tid` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '租户ID', `module_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '所属功能模块 code(yz_system_modules.code):oa/erp/crm/cms', `biz_type` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '适用单据类型:reimburse/bid/domain/...', `flow_code` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '审批流编号(自动生成、全局唯一,供各程序按编号发起):FL000007', `apply_dept_ids` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '适用部门ID列表 CSV(yz_backend_organization.id),空=全公司通用', `flow_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '流程名称', `description` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '流程说明', `is_default` TINYINT NOT NULL DEFAULT 0 COMMENT '是否该单据类型的默认流程:1是 0否', `status` TINYINT NOT NULL DEFAULT 1 COMMENT '1启用 0停用', `is_deleted` TINYINT NOT NULL DEFAULT 0, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `delete_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_tid` (`tid`), KEY `idx_tid_module` (`tid`,`module_code`), KEY `idx_tid_biz` (`tid`,`biz_type`), KEY `idx_tid_code` (`tid`,`flow_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OA-自定义审批流程(租户侧)'; -- ---------------- 2. 租户侧审批节点 ---------------- CREATE TABLE IF NOT EXISTS `yz_backend_approval_node` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `flow_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '所属流程ID', `tid` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '租户ID(冗余,便于按租户清理)', `node_key` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '节点唯一标识(流程内唯一)', `node_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '节点名称', `node_type` TINYINT NOT NULL DEFAULT 2 COMMENT '1开始 2审批 3结束 4条件分支', `approver_type` TINYINT NOT NULL DEFAULT 1 COMMENT '1指定用户 2指定角色 3部门主管 4指定职位 5发起人本人 6发起人主管', `approver_ids` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '审批人ID列表,逗号分隔(user=SystemTenantUser.uid / role=AdminRole.id / position=BackendPosition.id)', `multi_mode` TINYINT NOT NULL DEFAULT 1 COMMENT '多人审批方式:1或签(任一通过) 2会签(全部通过)', `allow_return` TINYINT NOT NULL DEFAULT 0 COMMENT '是否允许退回上一节点:1是 0否', `timeout_hours` INT NOT NULL DEFAULT 48 COMMENT '超时小时数,超时后自动通过', `prev_keys` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '前置节点 node_key 列表,逗号分隔(为条件分支预留)', `next_keys` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '后继节点 node_key 列表,逗号分隔(为条件分支预留)', `condition_expr` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '进入条件表达式,如 amount>5000(条件分支网关的出边条件)', `sort` INT NOT NULL DEFAULT 0 COMMENT '顺序号,顺序链按此升序流转', `pos_x` INT NOT NULL DEFAULT 0 COMMENT '画布X坐标(图编辑器回显)', `pos_y` INT NOT NULL DEFAULT 0 COMMENT '画布Y坐标(图编辑器回显)', `is_deleted` TINYINT NOT NULL DEFAULT 0, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `delete_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_flow` (`flow_id`), KEY `idx_tid` (`tid`), KEY `idx_flow_sort` (`flow_id`,`sort`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OA-自定义审批节点(租户侧)'; -- ---------------- 3. 平台侧审批流程 ---------------- CREATE TABLE IF NOT EXISTS `yz_platform_approval_flow` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `module_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '所属平台模块 code', `biz_type` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '适用单据类型:domain/tenant/...', `flow_code` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '审批流编号(自动生成、全局唯一):FL000007', `flow_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '流程名称', `description` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '流程说明', `is_default` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认流程:1是 0否', `status` TINYINT NOT NULL DEFAULT 1 COMMENT '1启用 0停用', `is_deleted` TINYINT NOT NULL DEFAULT 0, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `delete_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_module` (`module_code`), KEY `idx_biz` (`biz_type`), KEY `idx_code` (`flow_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='平台-自定义审批流程'; -- ---------------- 4. 平台侧审批节点 ---------------- CREATE TABLE IF NOT EXISTS `yz_platform_approval_node` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `flow_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '所属流程ID', `node_key` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '节点唯一标识(流程内唯一)', `node_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '节点名称', `node_type` TINYINT NOT NULL DEFAULT 2 COMMENT '1开始 2审批 3结束 4条件分支', `approver_type` TINYINT NOT NULL DEFAULT 1 COMMENT '1指定平台用户 2指定平台角色 5发起人本人', `approver_ids` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '审批人ID列表,逗号分隔(user=AdminUser.id / role=AdminRole.id)', `multi_mode` TINYINT NOT NULL DEFAULT 1 COMMENT '1或签 2会签', `allow_return` TINYINT NOT NULL DEFAULT 0 COMMENT '是否允许退回:1是 0否', `timeout_hours` INT NOT NULL DEFAULT 48 COMMENT '超时小时数', `prev_keys` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '前置节点(为条件分支预留)', `next_keys` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '后继节点(为条件分支预留)', `condition_expr` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '进入条件(条件分支网关出边条件)', `sort` INT NOT NULL DEFAULT 0 COMMENT '顺序号', `pos_x` INT NOT NULL DEFAULT 0 COMMENT '画布X坐标(图编辑器回显)', `pos_y` INT NOT NULL DEFAULT 0 COMMENT '画布Y坐标(图编辑器回显)', `is_deleted` TINYINT NOT NULL DEFAULT 0, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `delete_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_flow` (`flow_id`), KEY `idx_flow_sort` (`flow_id`,`sort`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='平台-自定义审批节点'; -- ---------------- 5. 审批实例(运行时,租户侧与平台侧共用) ---------------- CREATE TABLE IF NOT EXISTS `yz_approval_instance` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `scope` TINYINT NOT NULL DEFAULT 1 COMMENT '1租户侧 2平台侧', `tid` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '租户ID(租户侧=本租户;平台侧=发起申请的平台账号所属租户,平台账号通常为0)', `biz_tid` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '业务来源租户ID(平台侧审批必填:申请由哪个租户提交)', `flow_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '流程ID(配置可能被改,实例内节点快照为准)', `biz_type` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '单据类型:reimburse/bid/domain', `biz_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '单据ID', `biz_title` VARCHAR(200) NOT NULL DEFAULT '' COMMENT '单据标题快照', `submit_user_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '发起人ID', `submit_user_name` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '发起人姓名快照', `submit_dept_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '发起人部门ID快照(部门主管审批依赖)', `form_data` TEXT NULL COMMENT '发起表单数据快照(JSON),条件分支求值依据', `current_node` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '当前节点 node_key', `status` TINYINT NOT NULL DEFAULT 1 COMMENT '0草稿 1审批中 2已通过 3已驳回 4已撤回 5已取消', `submit_time` DATETIME DEFAULT NULL COMMENT '提交时间', `finish_time` DATETIME DEFAULT NULL COMMENT '完成时间', `is_deleted` TINYINT NOT NULL DEFAULT 0, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `delete_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_scope_tid` (`scope`,`tid`), KEY `idx_biz` (`biz_type`,`biz_id`), KEY `idx_biz_tid` (`scope`,`biz_tid`,`biz_type`), KEY `idx_status` (`status`), KEY `idx_flow` (`flow_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='审批实例(运行时)'; -- ---------------- 6. 审批任务(运行时,节点级待办) ---------------- CREATE TABLE IF NOT EXISTS `yz_approval_task` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `instance_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '实例ID', `scope` TINYINT NOT NULL DEFAULT 1 COMMENT '1租户侧 2平台侧', `tid` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '租户ID', `biz_type` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '单据类型(冗余,便于列表筛选)', `biz_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '单据ID(冗余)', `node_key` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '节点 node_key', `node_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '节点名称快照', `sort` INT NOT NULL DEFAULT 0 COMMENT '节点顺序号快照', `approver_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '审批人ID', `approver_name` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '审批人姓名快照', `multi_mode` TINYINT NOT NULL DEFAULT 1 COMMENT '1或签 2会签', `status` TINYINT NOT NULL DEFAULT 0 COMMENT '0待审批 1已通过 2已驳回 3已退回 4已跳过 5已超时', `action` TINYINT NOT NULL DEFAULT 0 COMMENT '1提交 2通过 3驳回 4退回 5撤回 6超时自动通过', `comment` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '审批意见', `deadline` DATETIME DEFAULT NULL COMMENT '超时时间点', `finish_time` DATETIME DEFAULT NULL COMMENT '处理时间', `is_deleted` TINYINT NOT NULL DEFAULT 0, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `delete_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_instance` (`instance_id`), KEY `idx_approver` (`scope`,`approver_id`,`status`), KEY `idx_biz` (`biz_type`,`biz_id`), KEY `idx_tid` (`tid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='审批任务(运行时·待办)'; -- ============================================================= -- 旧表迁移说明: -- yz_backend_approval_flows(扁平步骤行结构)仅被 OA 报销 Submit 读取。 -- 第一期接管报销后改走新引擎,旧表保留只读兼容,不再写入。 -- 如需保留历史配置,可按如下语句转换(按需执行): -- -- INSERT INTO yz_backend_approval_flow -- (tid, module_code, biz_type, flow_name, is_default, status) -- SELECT DISTINCT tid, 'oa', 'reimburse', flow_name, 1, 1 -- FROM yz_backend_approval_flows -- WHERE is_active = 1 AND is_deleted = 0 -- GROUP BY tid, flow_name; -- -- INSERT INTO yz_backend_approval_node -- (flow_id, tid, node_key, node_name, node_type, approver_type, approver_ids, timeout_hours, sort) -- SELECT f.id, f.tid, CONCAT('step_', s.step_order), s.flow_name, 2, 2, '', s.timeout_hours, s.step_order -- FROM yz_backend_approval_flows s -- JOIN yz_backend_approval_flow f -- ON f.tid = s.tid AND f.biz_type = 'reimburse' -- WHERE s.is_active = 1 AND s.is_deleted = 0; -- =============================================================