Skip to Content

扩展动作处理器

当 Entity Engine 内置的动作无法满足特定业务需求时,您可以创建自定义动作处理器。动作处理器让您能够实现复杂的业务逻辑、外部系统集成和自定义操作流程。

什么是动作处理器

动作处理器是用于处理特定业务操作的组件。它们可以响应用户操作、系统事件或定时任务,执行相应的业务逻辑。

常见的动作处理器场景

  • 邮件通知:发送系统通知和提醒邮件
  • 数据导出:将实体数据导出为各种格式
  • 外部集成:与第三方API和服务集成
  • 业务流程:实现复杂的业务规则和工作流
  • 数据处理:批量处理和转换数据

每个动作处理器需要实现 IEntityActionHandler 接口,定义支持的动作名称和处理逻辑。

实现动作处理器

基本结构

所有自定义动作处理器都需要实现 IEntityActionHandler 接口:

import { IEntityActionHandler, EntityAction, EntityActionResult, IEntityEnginePrimitive } from '@scenemesh/entity-engine'; class EmailActionHandler implements IEntityActionHandler { actionNames = ['send-email', 'email-notification']; async handle( action: EntityAction, context: { engine: IEntityEnginePrimitive } ): Promise<EntityActionResult> { try { // 验证参数 if (!action.parameter.to || !action.parameter.subject) { return { success: false, message: '收件人和主题为必填项', payload: { type: 'error' } }; } // 执行邮件发送逻辑 const result = await this.sendEmail(action.parameter); return { success: true, message: '邮件发送成功', payload: { type: 'email-sent', data: { messageId: result.messageId, recipients: result.accepted } } }; } catch (error) { return { success: false, message: `邮件发送失败: ${error.message}`, payload: { type: 'error', data: error } }; } } private async sendEmail(params: any) { // 实现邮件发送逻辑 return { messageId: 'msg_' + Date.now(), accepted: [params.to] }; } }

核心要素

动作名称:通过 actionNames 数组定义处理器支持的动作名称 处理方法:通过 handle 方法实现具体的业务逻辑
类型安全:使用TypeScript接口确保正确的参数和返回类型 错误处理:返回统一的 EntityActionResult 类型,包含成功状态和消息

实现示例:数据导出处理器

让我们创建一个数据导出动作处理器,展示核心实现模式:

class DataExportHandler implements IEntityActionHandler { actionNames = ['export-data', 'export-csv', 'export-json']; async handle(action: EntityAction, context): Promise<EntityActionResult> { try { // 验证参数和权限 if (!action.modelName) { return { success: false, message: '模型名称为必填项' }; } // 查询数据 const records = await context.engine.dataService.list({ modelName: action.modelName, ...action.parameter.query }); // 格式化并导出数据 const exportData = this.formatData(records, action.parameter.format); return { success: true, message: `成功导出 ${records.length} 条记录`, payload: { type: 'export-completed', data: exportData } }; } catch (error) { return { success: false, message: `导出失败: ${error.message}` }; } } }

这个处理器支持多种数据导出格式,并提供了完整的错误处理机制。

注册动作处理器

创建好动作处理器后,需要将其注册到 Entity Engine 的动作注册表中:

// 注册自定义动作处理器 engine.actionRegistry.registerActionHandler(new EmailActionHandler()); engine.actionRegistry.registerActionHandler(new DataExportHandler());

注册后,系统会自动识别并路由到相应的动作处理器。

执行动作

注册后,您可以通过动作注册表执行自定义动作:

// 执行数据导出动作 const exportAction: EntityAction = { name: 'export-data', modelName: 'Product', parameter: { format: 'csv', query: { limit: 100, filter: { status: 'active' } } } }; const handler = engine.actionRegistry.getActionHandler('export-data'); if (handler) { const result = await handler.handle(exportAction, { engine }); console.log(result.success ? '导出成功' : result.message); }

获取动作处理器

您可以查询已注册的动作处理器来了解系统中可用的操作:

// 获取特定的动作处理器 const exportHandler = engine.actionRegistry.getActionHandler('export-data'); if (exportHandler) { console.log('数据导出功能可用'); }

这些方法可以帮助您在运行时检查可用的动作,并动态决定执行哪些操作。

常见使用模式

条件执行

根据不同的动作名称执行不同的逻辑:

class NotificationHandler implements IEntityActionHandler { actionNames = ['send-notification', 'send-email', 'send-sms']; async handle(action: EntityAction, context: any): Promise<EntityActionResult> { switch (action.name) { case 'send-email': return this.handleEmail(action, context); case 'send-sms': return this.handleSms(action, context); default: return { success: false, message: `不支持的动作: ${action.name}` }; } } }

异步处理

对于耗时较长的操作,可以返回任务ID并在后台处理:

class AsyncHandler implements IEntityActionHandler { actionNames = ['process-large-dataset']; async handle(action: EntityAction, context: any): Promise<EntityActionResult> { const taskId = `task_${Date.now()}`; // 启动后台处理 this.processInBackground(taskId, action.parameter); return { success: true, message: '任务已启动', payload: { type: 'task-started', data: { taskId } } }; } }

最佳实践

命名规范

类名:使用 PascalCase,以 Handler 结尾(如 EmailNotificationHandler动作名称:使用 kebab-case(如 send-email
描述性:动作名称应该清晰描述其功能

错误处理

统一格式:始终返回 EntityActionResult 类型 错误信息:提供清晰的错误描述和上下文
异常捕获:妥善处理所有可能的异常情况 日志记录:记录关键操作和错误信息

性能考虑

异步处理:对于耗时操作,考虑使用异步模式 参数验证:在处理开始时验证输入参数
资源管理:及时释放不需要的资源和连接 重试机制:对于网络请求等可能失败的操作,实现适当的重试逻辑

下一步

掌握了自定义动作处理器后,您可以继续学习:

Last updated on