工作流引擎是 IMS 系统的核心组件,负责处理各种审批流程的业务逻辑。本文将详细介绍工作流引擎的架构设计、流程定义、节点类型与审批逻辑实现。
工作流引擎整体架构
工作流引擎采用分层架构设计:
- 流程设计器 - 可视化设计审批流程
- 流程引擎 - 核心执行逻辑
- 任务调度 - 待办任务分配与超时处理
- 规则引擎 - 动态决定审批人与条件分支
- 历史记录 - 流程执行轨迹追踪
流程定义数据结构
流程定义采用 JSON 格式存储:
process-definition.js
// 流程定义结构 const ProcessDefinition = { id: 'leave_request', name: '请假申请流程', version: 1, // 流程变量定义 variables: [ { key: 'days', type: 'number', label: '请假天数' }, { key: 'reason', type: 'string', label: '请假原因' } ], // 节点定义 nodes: [ { id: 'start', type: 'start', name: '开始', next: 'apply' }, { id: 'apply', type: 'userTask', name: '提交申请', assigneeType: 'initiator', // 申请人自己 formKey: 'leave_form', next: 'decide' }, { id: 'decide', type: 'exclusiveGateway', name: '判断审批路径', conditions: [ { expr: '${days <= 3}', target: 'manager_approve' }, { expr: '${days > 3}', target: 'dept_approve' } ] }, { id: 'manager_approve', type: 'userTask', name: '部门经理审批', assigneeType: 'variable', assigneeExpr: '${manager}', // 会签设置 counterSign: { enabled: false, strategy: 'any' // 任意一人通过即可 }, next: 'end' }, { id: 'dept_approve', type: 'userTask', name: '部门经理审批', assigneeExpr: '${manager}', next: 'hr_approve' }, { id: 'hr_approve', type: 'userTask', name: 'HR审批', assigneeType: 'role', assigneeExpr: 'HR', next: 'end' }, { id: 'end', type: 'end', name: '结束' } ] };
流程引擎核心实现
流程引擎负责解析流程定义并执行:
workflow-engine.js
class WorkflowEngine { constructor(repository) { this.repository = repository; this.variableResolver = new VariableResolver(); } // 启动流程实例 async startProcess(definitionId, initiator, variables) { const definition = await this.repository.getDefinition(definitionId); // 创建流程实例 const instance = { id: generateId(), definitionId: definition.id, definitionKey: definition.key, version: definition.version, initiator: initiator, status: 'running', variables: { ...variables, initiator }, startTime: new Date(), currentNodeId: 'start' }; await this.repository.saveInstance(instance); // 自动流转到下一个节点 await this.moveToNextNode(instance, 'start'); return instance; } // 节点流转逻辑 async moveToNextNode(instance, currentNodeId) { const definition = await this.repository.getDefinition(instance.definitionKey); const currentNode = definition.nodes.find(n => n.id === currentNodeId); if (!currentNode.next) return; const nextNodeId = await this.resolveNextNode(definition, currentNode, instance); const nextNode = definition.nodes.find(n => n.id === nextNodeId); // 处理不同节点类型 switch (nextNode.type) { case 'userTask': await this.createTask(instance, nextNode); break; case 'end': instance.status = 'completed'; instance.endTime = new Date(); break; } instance.currentNodeId = nextNodeId; await this.repository.saveInstance(instance); } // 处理用户任务完成 async completeTask(taskId, userId, variables = {}) { const task = await this.repository.getTask(taskId); // 验证任务是否可办理 if (!this.canCompleteTask(task, userId)) { throw new Error('无权限办理此任务'); } // 更新流程变量 const instance = await this.repository.getInstance(task.instanceId); Object.assign(instance.variables, variables); // 记录任务历史 await this.repository.saveHistory({ taskId, userId, action: 'complete', variables, completedAt: new Date() }); // 完成任务 task.status = 'completed'; task.completedAt = new Date(); await this.repository.saveTask(task); // 流转到下一节点 await this.moveToNextNode(instance, task.nodeId); } }
审批人分配策略
支持多种审批人分配方式:
assignee-resolver.js
class AssigneeResolver { async resolve(assigneeType, assigneeExpr, instance) { switch (assigneeType) { case 'initiator': // 申请人自己 return instance.initiator; case 'user': // 指定用户 return assigneeExpr; case 'role': // 角色对应的用户 return await this.findUsersByRole(assigneeExpr); case 'deptLeader': // 申请人部门领导 const user = await this.getUser(instance.initiator); return user.department.leaderId; case 'variable': // 从变量获取 return instance.variables[assigneeExpr]; case 'script': // 脚本计算 return eval(assigneeExpr); default: throw new Error(`Unknown assignee type: ${assigneeType}`); } } }
会签与转交实现
支持多人审批场景:
counter-sign.js
// 会签处理逻辑 class CounterSignHandler { async handleTaskComplete(task, userId, instance) { const node = await this.getNodeDefinition(instance, task.nodeId); // 检查是否会签 if (!node.counterSign || !node.counterSign.enabled) { return true; } // 记录会签意见 await this.saveCounterSignVote(task.instanceId, task.nodeId, userId, task.comment); // 判断是否满足会签条件 const votes = await this.getVotes(task.instanceId, task.nodeId); const strategy = node.counterSign.strategy; switch (strategy) { case 'all': // 所有人同意 return votes.every(v => v.approved); case 'any': // 任意一人同意 return votes.some(v => v.approved); case 'majority': // 多数同意 return votes.filter(v => v.approved).length > votes.length / 2; } } // 转交任务 async transferTask(taskId, fromUserId, toUserId) { const task = await this.getTask(taskId); if (task.assigneeId !== fromUserId) { throw new Error('无权限转交此任务'); } task.assigneeId = toUserId; await this.saveTask(task); } }
流程监控与催办
流程运行状态的监控与超时提醒:
- 超时检测 - 定时扫描待办任务,对超时任务发送提醒
- 流程追踪 - 记录每个节点的开始/结束时间
- 催办功能 - 支持手动触发催办通知
- 流程挂起 - 特殊情况下暂停流程执行
总结
工作流引擎是企业级 IMS 系统的核心。良好的架构设计需要考虑流程定义的灵活性、审批人分配的多样性、会签转交等复杂场景,以及流程执行的可靠性和可追溯性。