工作流引擎是 IMS 系统的核心组件,负责管理和自动化业务流程。本文详细介绍工作流引擎的设计、节点类型、流转规则和实现方案。
工作流基本概念
工作流由节点和连线组成,支持复杂的业务流程建模:
/* 工作流定义 */
interface WorkflowDefinition {
id: string;
name: string;
version: number;
nodes: NodeDefinition[];
connections: Connection[];
variables: VariableDefinition[];
}
/* 节点定义 */
interface NodeDefinition {
id: string;
name: string;
type: NodeType; // start/end/task/gateway
position: { x: number; y: number };
config: NodeConfig;
}
/* 流程实例 */
interface ProcessInstance {
id: string;
workflowId: string;
status: ProcessStatus; // running/completed/terminated
currentNodes: string[];
variables: Record<string, any>;
startTime: Date;
endTime?: Date;
}
节点类型实现
工作流引擎支持多种节点类型:
/* 节点类型枚举 */
enum NodeType {
START = 'start',
END = 'end',
TASK = 'task',
USER_TASK = 'user_task',
SERVICE_TASK = 'service_task',
GATEWAY = 'gateway',
PARALLEL_GATEWAY = 'parallel_gateway',
EXCLUSIVE_GATEWAY = 'exclusive_gateway'
}
/* 节点执行器 */
class NodeExecutor {
execute(node, context) {
switch (node.type) {
case NodeType.USER_TASK:
return this.executeUserTask(node, context);
case NodeType.SERVICE_TASK:
return this.executeServiceTask(node, context);
case NodeType.GATEWAY:
return this.evaluateGateway(node, context);
default:
return nextNodes;
}
}
/* 用户任务:创建审批任务 */
async executeUserTask(node, context) {
const task = {
id: generateId(),
nodeId: node.id,
processId: context.instance.id,
assignee: node.config.assignee,
candidateUsers: node.config.candidateUsers,
candidateGroups: node.config.candidateGroups,
dueDate: calculateDueDate(node.config.duration),
status: 'pending'
};
await taskService.create(task);
return { status: 'waiting' };
}
/* 服务任务:自动执行逻辑 */
async executeServiceTask(node, context) {
const handler = getServiceHandler(node.config.handler);
const result = await handler.execute(context.variables);
/* 更新流程变量 */
if (node.config.outputVar) {
context.variables[node.config.outputVar] = result;
}
return { status: 'completed' };
}
}
审批流转规则
支持多种审批模式和条件分支:
/* 审批模式 */
enum ApprovalMode {
ONE = 'one', // 单人审批
ALL = 'all', // 全部通过
ANY = 'any', // 任一通过
COUNTERSIGN = 'countersign' // 会签
}
/* 审批人分配策略 */
class ApproverStrategy {
static getApprovers(nodeConfig, context) {
switch (nodeConfig.assigneeType) {
case 'user':
return [nodeConfig.assignee];
case 'role':
return userService.getUsersByRole(nodeConfig.assignee);
case 'manager':
return [orgService.getManager(context.initiator)];
case 'expression':
return evaluateExpression(nodeConfig.assigneeExpr, context);
case 'form_selector':
return [context.variables[nodeConfig.formField]];
}
}
}
/* 条件分支网关 */
class ExclusiveGateway {
evaluate(node, context) {
const connections = getOutgoingConnections(node.id);
for (const conn of connections) {
if (!conn.condition) return conn.targetId;
const result = evaluateExpression(conn.condition, context);
if (result) return conn.targetId;
}
return null;
}
}
任务管理与通知
处理待办任务和消息通知:
/* 任务服务 */
class TaskService {
/* 处理任务审批 */
async complete(taskId, userId, result, comment) {
const task = await getTaskById(taskId);
/* 验证审批权限 */
await verifyPermission(task, userId);
/* 记录审批历史 */
await saveApprovalRecord({
taskId, userId, result, comment, timestamp: now()
});
/* 继续流程 */
await workflowEngine.continueProcess(task.processId);
}
/* 任务提醒 */
async sendReminder(task) {
const overdue = isOverdue(task);
const template = overdue ? 'task_overdue' : 'task_reminder';
await notificationService.send({
userId: task.assignee,
template,
data: { taskName: task.name, dueDate: task.dueDate }
});
}
/* 任务转交 */
async transfer(taskId, fromUser, toUser, reason) {
await db.update('task', { id: taskId }, { assignee: toUser });
await saveTransferRecord({ taskId, fromUser, toUser, reason });
}
}
流程监控与统计
- 实时监控流程执行状态
- 统计各节点的平均处理时间
- 分析流程效率瓶颈
- 导出流程报表
流程设计建议
- 合理设置审批时限,避免流程卡顿
- 使用并行网关提高审批效率
- 重要节点配置加签机制
- 预留流程调整的灵活性
总结
- 节点类型:支持用户任务、服务任务、网关等多种类型
- 审批模式:单人、多人、会签等多种模式
- 条件分支:支持表达式判断的排他网关
- 任务管理:待办、提醒、转交、催办完整支持
- 监控分析:流程执行监控和统计分析