批量字段赋值组件
批量字段赋值组件(DbBatchUpdateField)用于在一个节点内一次配置多条字段赋值,避免为每个字段单独放置一个字段赋值节点。
概述
批量字段赋值把多条「字段 + 赋值方式 + 值」的组合集中在一个组件里,执行时按配置顺序依次完成所有赋值。与字段赋值的单字段模式相比,它更适合字段较多、需要统一维护的初始化或联动更新场景。
组件以「赋值项」列表的方式编辑:添加一行赋值项,选择字段与赋值方式,再填写对应的值;同一字段只能被赋值一次。
配置项
| 配置项 | 说明 |
|---|---|
| 操作对象 | 要操作的实体对象,必填,赋值字段来源于该对象 |
| 赋值项 | 一组赋值配置,可添加多条 |
| 输出到最终结果 | 开启后该组件结果作为接口返回值 |
赋值项配置
每个赋值项包含:
| 配置项 | 说明 |
|---|---|
| 赋值字段 | 要赋值的字段,可搜索选择,同一字段不可重复添加 |
| 赋值方式 | 固定赋值 / 内置函数 / 动态计算 |
| 值 / 内置函数 / 计算表达式 | 随赋值方式变化的具体配置 |
赋值方式取值
| 界面名称 | 值(UpdateType) | 说明 |
|---|---|---|
| 固定赋值 | static | 直接设置一个固定值 |
| 内置函数 | method | 使用内置函数取值,支持「当前时间」「当前登录用户」 |
| 动态计算 | calculate | 通过 Razor 表达式计算值 |
内置函数取值:CurrentDateTime(当前时间)、LoginUserId(当前登录用户)。
编辑与执行说明
- 切换操作对象后,已配置的赋值项会被清空(字段编码属于上一个对象),需要重新配置。
- 每条赋值项以标签展示其赋值方式;动态计算的标签显示为「Razor」。
- 执行时按赋值项顺序依次赋值,动态计算可以读取到前面赋值项已写入的结果。
- 对同一字段重复配置时后配置覆盖先配置(界面已限制同一字段不可重复添加)。
执行流程
使用场景
- 初始化或联动更新多个字段
- 同时写入创建人、创建时间、状态等多个字段
- 根据已有字段批量计算并回填
下一步
属性明细
以下内容面向技术实现与 AI 检索,说明批量字段赋值组件的节点元数据。
节点元数据
批量字段赋值组件由 FlowCmpType.DbBatchUpdateField 标识。赋值项列表以 JSON 字符串存储在 Assignments 中:
| 属性名 | 类型 | 含义 | 取值/存储值 |
|---|---|---|---|
type | string | 组件类型 | 固定为 "DbBatchUpdateField" |
MetaObjectId | string(GUID) | 目标实体对象 | 缺省取当前接口所属对象 |
Assignments | string(JSON) | 赋值项列表 | JSON 数组字符串,缺省 "[]" |
IsFinalResult | string(bool) | 是否输出到最终结果 | "true" / "false" |
order | string | 同级排序 | 例:"1" |
赋值项结构
Assignments 数组中的每个元素结构如下:
| 属性名 | 类型 | 含义 | 取值/存储值 |
|---|---|---|---|
UpdateField | string | 赋值字段编码 | 字段的 Code |
UpdateType | string | 赋值方式 | "static" / "method" / "calculate" |
Method | string | 内置函数 | 仅 method 有效:"CurrentDateTime" / "LoginUserId" |
NewValue | string | 值 / 计算表达式 | static 为固定值,calculate 为 Razor 表达式 |
元数据存储示例
{
"ID": "batch1",
"type": "DbBatchUpdateField",
"MetaObjectId": "3f9c0b2e-2d3a-4e6f-9c11-0f7a5b8d2e10",
"Assignments": "[{\"UpdateField\":\"Status\",\"UpdateType\":\"static\",\"NewValue\":\"Approved\"},{\"UpdateField\":\"AuditTime\",\"UpdateType\":\"method\",\"Method\":\"CurrentDateTime\"}]",
"IsFinalResult": "false",
"order": "1"
}
字段数据源
赋值字段下拉通过 POST /api/DataSource/GetMetaFieldDataSource 获取(带 extend.IncludeLookup = "true"),在操作对象变化时统一加载并供所有赋值项复用。
服务端执行逻辑
本组件在服务端的实现类为 DbBatchUpdateFieldComponentManager,组件类型为 FlowComponentTypeEnum.DbBatchUpdateField。它取代了旧的单字段组件 字段赋值,本节说明服务端如何解析赋值项、取数与执行赋值。
执行时机与场景
- 流程引擎分两个阶段调用组件:保存/发布时进入校验阶段(
_VerifyAsync),运行期进入执行阶段(_ExecuteAsync)。 - 组件基类为
TriggerComponentManagerBase(继承InterfaceComponentManagerBase)。进入任阶段前会先做通用处理:节点IsDisabled为"true"时 直接跳过;每次进入递增RecursionDeep,超过 100 抛ProcessCycleOrNodeMoreThanLimit。 - 当链路运行在对象触发器场景时(上下文中存在追踪标记
_TriggerNodeCollector),ExecuteAsync会额外记录该节点的耗时与成功/失败。
输入数据来源
节点配置全部取自 context.CurrentNode.Meta,所有 meta 值均以字符串形式存储。本组件读取的 key 为 MetaObjectId、Assignments、IsFinalResult;type、IsDisabled 由基类读取。
Assignments 是 List<DbFieldAssignment> 的 JSON 字符串(缺省 "[]"),由 JsonConvert.DeserializeObject 解析为赋值项列表,元素结构见「赋值项结构」。
待赋值数据按以下优先级解析:
- 上游结果优先:
context.CmpResult为List<ObjectData>时直接就地赋值; - 否则处理请求数据:
context.Request?.List。
执行步骤
- 校验:
MetaObjectId为空抛OperationObjectNotFound;查询MetaObject不存在抛MetaObjectNotFoundById。 - 解析赋值项(
GetAssignments):Assignments为空抛AssignmentNotConfigured;JSON 反序列化失败抛AssignmentConfigFormatError(附MoreMessage = ex.Message);结果为空数组同样抛AssignmentNotConfigured。 - 逐条校验赋值项:
UpdateField为空抛UpdateFieldNotSet;UpdateType为空抛AssignmentModeNotSelected;UpdateType == "method"且Method为空抛AssignmentFunctionNotSelected。 - 模型解析:
GetMetaObjectByIdFromCacheAsync读取对象定义;GetMetaFieldsIncludeLookupByMetaObjectIdFromCacheAsync读取含 lookup 的字段列表。 - 字段校验:任一赋值项的
UpdateField不在字段编码内抛UpdateFieldNotInEntity。 - 顺序赋值(
ApplyAssignments):按赋值项配置顺序逐条调用metaFieldService.ApplyFieldAssignment(...),并传入context.SystemParam。由于是顺序执行,后一条赋值可读取到前一条在同一数据上写入的结果。 - 回写上下文后进入下游。
赋值语义与 SQL 形态
每条赋值项最终交由 ApplyFieldAssignment 处理,规则与单字段组件一致:
UpdateType | 行为 |
|---|---|
static | 直接 item[field] = 值;值若为 @LoginUserId / @CurrentDateTime 则先解析 |
method | CurrentDateTime → DateTimeOffset.UtcNow;LoginUserId → 当前登录用户;其他值忽略 |
calculate | 用 Razor 编译 NewValue,参数合并链路变量与当前行字段(同名字段优先),异常抛 DynamicAssignmentCalculationError |
重要:本组件不落库。
_ExecuteAsync只对List<ObjectData>做内存赋值,不调用任何IChameleonDbContext写方法。要让结果持久化,需在下游接 更新数据(DbUpdate)。
输出与上下文
context.CmpResult = result(赋值后的对象集合)。context.DicParam写入:BizDataIds(逗号拼接的_id)、MetaObjectCode、MetaObjectId;GetMetaObjectByIdFromCacheAsync另写入ChameleonMetaObjectId、ChameleonMetaObjectCode。IsFinalResult为"true"时:设置context.TransferResult.List/Total与context.Result = ResponseResult<List<ObjectData>>.Success(result).Total(result.Count),此处data为完整列表(未做Take(1))。
事务、批量阈值与限制
- 本组件不读取列表条数、无批量阈值限制(因为不落库)。
- 赋值项数量由节点配置决定;同一条数据上的赋值按配置顺序串行执行。
- 组件自身不涉及事务;递归深度上限 100。
权限校验
本组件不执行任何权限校验:不依赖 permissionService,也不读取 SkipOperationPermission / SkipMouPermission。
异常与校验
| 触发条件 | 错误常量 |
|---|---|
MetaObjectId 为空 | OperationObjectNotFound |
| 目标对象不存在 | MetaObjectNotFoundById |
Assignments 为空或为空数组 | AssignmentNotConfigured |
Assignments JSON 非法 | AssignmentConfigFormatError(附 MoreMessage) |
赋值项 UpdateField 为空 | UpdateFieldNotSet |
赋值项 UpdateType 为空 | AssignmentModeNotSelected |
UpdateType == "method" 且 Method 为空 | AssignmentFunctionNotSelected |
| 赋值字段不在对象字段内 | UpdateFieldNotInEntity |
| 动态计算表达式执行失败 | DynamicAssignmentCalculationError(附 MoreMessage) |
所有异常经 ErrorException 包装,附带组件类型、接口 id、节点 id 定位信息;文案取自 locale 资源。