ScriptCallActivity
分类: 通用步骤
命名空间: CMS.Plugin.FlowManagement.Domain.FlowBusiness.Activitys
基类: ActionActivity
模块: FlowManagement.Domain
概述
ScriptCallActivity(自动化脚本)是用于在流程中调用基座脚本管理中定义的脚本的节点。它继承自 ActionActivity,支持调用系统中预先配置的自动化脚本,并将脚本执行的状态码写入流程上下文。该节点支持同步和异步调用模式,可以灵活地执行各种自动化任务。
ScriptCallActivity 是流程自动化的重要组件,通过它可以执行复杂的业务逻辑、数据处理、系统集成等任务,而无需在流程节点中编写代码。
业务场景
适用场景
- 数据处理: 执行复杂的数据转换、计算、验证等操作
- 系统集成: 调用外部系统接口或执行系统命令
- 业务逻辑: 执行复杂的业务规则和判断逻辑
- 批量操作: 执行批量数据处理或文件操作
- 定时任务: 配合定时触发执行周期性任务
在系统中的作用
ScriptCallActivity 在 LMES 流程系统中扮演着脚本执行器的角色:
- 调用基座脚本管理中配置的脚本
- 支持同步和异步执行模式
- 处理脚本执行结果和异常
- 将执行状态写入流程上下文
与其他节点的协作
- BusinessActivity: 在脚本调用前准备参数,在脚本调用后处理结果
- ActionActivity: 作为动作节点,可以配置执行时机
- ApiCallActivity: 可以与 API 调用配合,实现复杂的集成场景
- PythonScriptActivity: 如需内联脚本,可使用 Python 脚本节点
配置说明
基本配置
| 属性名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| ScriptId | string | 是 | - | 关联脚本,调用基座脚本管理中定义的脚本 |
| Wait | bool | 否 | true | 是否等待执行结束 |
| Authorization | string | 否 | - | 授权信息(请求 Token) |
| Action | ActionType | 否 | Execute | 执行时机(继承自 ActionActivity) |
| IsSynchronous | bool | 否 | true | 是否同步执行(继承自 ActionActivity) |
配置项详解
ScriptId
说明: 关联脚本的编号,指定要调用的脚本。该脚本必须在基座脚本管理模块中预先配置。
取值范围: 字符串,对应脚本管理中配置的脚本名称或编号
注意事项:
- 必须确保指定的脚本在系统中存在
- 脚本必须已启用且配置正确
- 脚本内容会通过 API 获取并执行
Wait
说明: 是否等待脚本执行完成。当设置为 true 时,流程会等待脚本执行完成;设置为 false 时,流程会立即继续执行,不等待脚本完成。
取值范围: true 或 false
注意事项:
- Wait=true(默认): 适用于需要确保脚本执行完成的场景
- Wait=false: 适用于只需要触发脚本执行,不关心执行结果的场景
- 异步执行(Wait=false)可以提高流程执行效率
Authorization
说明: 授权信息,用于脚本执行请求的身份验证。通常是 Bearer Token 或其他认证令牌。
取值范围: 字符串,格式取决于系统的认证方式
注意事项:
- 如果脚本执行需要认证,必须提供正确的授权信息
- 可以从流程上下文中动态获取 Token
流程上下文
输入参数
| 参数名 | 类型 | 说明 |
|---|---|---|
| ScriptId | string | 可以从流程上下文动态获取脚本编号 |
| Authorization | string | 可以从流程上下文动态获取授权信息 |
输出参数
| 参数名 | 类型 | 说明 |
|---|---|---|
| {节点名}_StatusCode | int | 脚本执行后的响应状态码 |
数据流转说明
-
执行前:
- 初始化状态码为 200(OK)
- 获取 IInternalApi 服务
- 通过 ScriptId 获取脚本内容
-
脚本执行:
- 调用 IInternalApi.ExecutScriptsAsync 执行脚本
- 传递脚本内容、等待标志和授权信息
-
执行后:
- 将 HTTP 状态码写入
{节点名}_StatusCode(节点名为节点的 Name 属性值) - 记录执行日志
- 将 HTTP 状态码写入
业务逻辑说明
处理流程
ScriptCallActivity 的执行流程如下:
-
初始化:
- 设置默认状态码为 200(OK)
- 获取 IInternalApi 服务
-
获取脚本:
- 调用
internalApi.GetScriptsByNameAsync(ScriptId)获取脚本信息 - 如果脚本不存在,记录警告日志并返回
- 调用
-
执行脚本:
- 记录执行参数日志
- 调用
internalApi.ExecutScriptsAsync执行脚本 - 传递脚本内容、Wait 标志、ScriptId 和 Authorization
-
异常处理:
- 捕获 HttpRequestException 异常
- 处理 ApiResponseStatusException 异常
- 记录错误日志和状态码
-
完成:
- 记录最终状态码日志
依赖服务
| 服务接口 | 用途 | 说明 |
|---|---|---|
| IInternalApi | 脚本执行服务 | 负责获取脚本内容和执行脚本 |
| IJsonSerializer | JSON 序列化 | 解析错误响应 |
| Flow.ServiceProvider | 服务提供者 | 获取依赖注入的服务 |
| Flow.Logger | 日志记录器 | 记录脚本执行日志 |
异常处理
| 异常类型 | 处理方式 | 说明 |
|---|---|---|
| HttpRequestException | 记录错误日志,设置状态码 | HTTP 请求失败 |
| ApiResponseStatusException | 解析错误消息,记录日志,设置状态码 | API 返回错误状态码 |
日志记录
ScriptCallActivity 记录以下关键日志:
- 脚本不存在:
ScriptId={ScriptId} 不存在! - 执行前:
ScriptId={ScriptId},Wait={Wait} - 执行后:
ScriptId={ScriptId},StatusCode={StatusCode} - 异常: 完整的错误消息
使用示例
基本示例
{
"Type": "ScriptCallActivity",
"Name": "执行数据处理脚本",
"Alias": "DataProcessScript",
"ScriptId": "DataProcessing",
"Wait": true
}
异步执行示例
{
"Type": "ScriptCallActivity",
"Name": "触发后台任务",
"Alias": "BackgroundTask",
"ScriptId": "BackgroundJob",
"Wait": false,
"Action": "Exit"
}
带授权信息示例
{
"Type": "ScriptCallActivity",
"Name": "执行安全脚本",
"Alias": "SecureScript",
"ScriptId": "SecureOperation",
"Wait": true,
"Authorization": "Bearer {AccessToken}"
}
完整流程示例
{
"Name": "数据处理流程",
"Activities": [
{
"Type": "BusinessActivity",
"Name": "准备数据",
"Alias": "PrepareData"
},
{
"Type": "ScriptCallActivity",
"Name": "执行数据转换",
"Alias": "TransformData",
"ScriptId": "DataTransform",
"Wait": true
},
{
"Type": "BusinessActivity",
"Name": "检查执行结果",
"Alias": "CheckResult"
}
]
}
处理脚本执行结果示例
[Serializable]
[Design("检查脚本结果", "检查脚本执行结果", Sort = 1)]
[Category("自定义")]
public class CheckScriptResultActivity : BusinessActivity
{
public override async Task ProcessAsync(ProcessflowEventArgs args)
{
var statusCode = (int)Flow.DataItems["TransformData_StatusCode"];
if (statusCode == 200)
{
Flow.Logger.LogMessage("脚本执行成功", Name);
Flow.DataItems["ScriptResult_Value"] = "Success";
}
else
{
Flow.Logger.LogErrorMessage($"脚本执行失败: StatusCode={statusCode}");
Flow.DataItems["ScriptResult_Value"] = "Failed";
}
await base.ProcessAsync(args);
}
}
扩展开发指南
继承层次
Activity (SYC.Flow.Kernel)
└── BusinessActivity
└── ActionActivity
└── ScriptCallActivity
可重写方法
| 方法名 | 用途 | 何时重写 |
|---|---|---|
| ExecuteActionAsync | 执行脚本调用 | 需要自定义脚本调用逻辑 |
自定义脚本调用节点示例
[Serializable]
[Design("增强脚本调用", "带重试的脚本调用节点", Sort = 1)]
[Category("自定义")]
public class EnhancedScriptCallActivity : ScriptCallActivity
{
[Design("重试次数", "脚本执行失败时的重试次数", Sort = 10)]
[Category("脚本配置")]
public int RetryCount { get; set; } = 3;
protected override async Task ExecuteActionAsync(ProcessflowEventArgs args)
{
for (int i = 0; i < RetryCount; i++)
{
await base.ExecuteActionAsync(args);
var statusCode = (int)Flow.DataItems[$"{Name}_StatusCode"];
if (statusCode == 200)
{
return;
}
Flow.Logger.LogWarningMessage($"脚本执行失败,重试 {i + 1}/{RetryCount}", Name);
await Task.Delay(1000 * (i + 1));
}
}
}
注意事项
- 脚本配置: 必须先在基座脚本管理模块中配置脚本,才能在流程中使用
- 状态码检查: 调用后应检查状态码,确保脚本执行成功
- 异步执行: Wait=false 时无法确认脚本是否执行成功
- 授权信息: 如果脚本执行需要认证,必须提供正确的 Authorization
- 脚本不存在: 如果 ScriptId 对应的脚本不存在,节点会记录警告并跳过执行
- 开发建议:
- 在脚本调用后检查状态码,处理失败情况
- 为脚本调用添加日志,便于问题排查
- 复杂逻辑建议使用脚本而非流程节点
- 敏感信息应从配置或流程上下文动态获取
相关节点
- ActionActivity: 脚本调用节点的基类
- ApiCallActivity: API 调用节点
- PythonScriptActivity: Python 脚本节点(内联脚本)
- MethodCallActivity: C# 方法调用节点
更新历史
| 日期 | 版本 | 说明 |
|---|---|---|
| 2025-11-28 | 1.0 | 初始版本 |
本文档最后更新时间: 2025-11-28