Skip to main content

更新数据组件

更新数据组件(DbUpdate)用于按条件更新实体对象中已有记录。

概述​

更新数据组件按上游传入的记录与字段值批量更新目标实体。它先选择「操作对象」,再勾选需要更新的「更新字段」;执行时依据上游数据确定待更新记录,并写入所选字段。

组件支持「跳过操作权限校验」,并可通过「输出到最终结果」返回更新结果。

配置项​

配置项说明
操作对象要更新的实体对象,必填
更新字段需要更新的字段,可多选,来自操作对象的字段列表
跳过操作权限校验开启后不校验当前用户对目标对象的操作权限
输出到最终结果开启后该组件结果作为接口返回值

执行流程​

使用场景​

  • 状态流转后回写主表字段
  • 审批通过后更新单据状态
  • 根据计算结果批量修正数据

下一步​

属性明细​

以下内容面向技术实现与 AI 检索,说明更新数据组件的节点元数据。

节点元数据​

更新数据组件由 FlowCmpType.DbUpdate 标识:

属性名类型含义取值/存储值
typestring组件类型固定为 "DbUpdate"
MetaObjectIdstring(GUID)目标实体对象缺省取当前接口所属对象
UpdateFieldsstring更新字段编码列表逗号分隔,例 "Status,Remark"
SkipOperationPermissionstring(bool)是否跳过操作权限校验"true" / "false"
IsFinalResultstring(bool)是否输出到最终结果"true" / "false"
orderstring同级排序例:"3"

元数据存储示例​

{
"ID": "update1",
"type": "DbUpdate",
"MetaObjectId": "3f9c0b2e-2d3a-4e6f-9c11-0f7a5b8d2e10",
"UpdateFields": "Status,Remark",
"SkipOperationPermission": "false",
"IsFinalResult": "false",
"order": "3"
}

字段数据源​

「更新字段」下拉通过 POST /api/DataSource/GetMetaFieldDataSource 获取,请求时带 extend.IncludeLookup = "true",因此可选中关联(lookup)字段。切换操作对象后该下拉会重新请求。

服务端执行逻辑​

本组件在服务端的实现类为 DbUpdateComponentManager,组件类型为 FlowComponentTypeEnum.DbUpdate。本节说明服务端如何解析节点配置、取数、校验、做行级权限过滤与落库。

执行时机与场景​

  • 流程引擎分两个阶段调用组件:保存/发布时进入校验阶段(_VerifyAsync),运行期进入执行阶段(_ExecuteAsync)。
  • 组件基类为 TriggerComponentManagerBase(继承 InterfaceComponentManagerBase)。进入任阶段前会先做通用处理:节点 IsDisabled 为 "true" 时直接跳过;每次进入递增 RecursionDeep,超过 100 抛 ProcessCycleOrNodeMoreThanLimit。
  • 当链路运行在对象触发器场景时(上下文中存在追踪标记 _TriggerNodeCollector),ExecuteAsync 会额外记录该节点的耗时与成功/失败。

输入数据来源​

节点配置全部取自 context.CurrentNode.Meta,所有 meta 值均以字符串形式存储。本组件读取的 key 为 MetaObjectId、UpdateFields、IsFinalResult、SkipOperationPermission;type、IsDisabled 由基类读取。

待更新数据按以下优先级解析:

  1. 上游结果优先:context.CmpResult 为 List<ObjectData> 时直接使用;
  2. 否则回退请求数据:context.Request 深克隆后的 Request.List。

两者都为空时执行 ExecuteNextAsync(空操作)。与写入组件不同,更新要求每条记录都带 Id。

执行步骤​

  1. 校验:MetaObjectId 为空抛 OperationObjectNotFound;按 id 查询 MetaObject,不存在抛 MetaObjectNotFoundById。
  2. 取数:按优先级解析列表,为空则跳过;条数 > BatchOperationThreshold(100)抛 SingleOperationDataCannotMorethanXCount。
  3. Id 校验:任一条目 Id == Guid.Empty 抛 DataIdCanNotBeEmpty。
  4. 模型解析:GetMetaObjectByIdFromCacheAsync 读取缓存中的对象定义。
  5. 权限校验:操作权限与 MOU 行级权限,见「权限校验」。
  6. 计算可更新列:UpdateFields 非空时按逗号拆分并与对象字段编码取交集;为空时视为全部字段;始终加入 _id。若除 _id 外无可更新列(columns.Count <= 1)则直接 ExecuteNextAsync。
  7. 数据校验:metaFieldService.DataVerificationAsync(metaObjectId, list, isImport: false, update: true)。
  8. 字段过滤与必要字段:移除 Fields 中不在可更新列内的 key;写入 modifiedby = ChameleonContext.Current.UserId、modifiedtime = DateTimeOffset.UtcNow。
  9. 落库:见「数据操作与 SQL 形态」。
  10. 回写上下文后进入下游。

数据操作与 SQL 形态​

按 MetaObject.Code 分支持久化:

条件处理
System.UserInformationuserInformationService.BatchUpdateAsync(list)
System.OrganizationorganizationService.BatchUpdateAsync(list)
其他chameleonDbContext.BatchUpdateAsync(metaObject.Code, list)

即以实体编码为集合名、通过 IChameleonDbContext.BatchUpdateAsync 按 _id 批量更新。

输出与上下文​

  • context.CmpResult = list(MOU 过滤后、实际更新的对象集合)。
  • context.DicParam 写入:BizDataIds(逗号拼接的 _id)、MetaObjectCode、MetaObjectId;GetMetaObjectByIdFromCacheAsync 另写入 ChameleonMetaObjectId、ChameleonMetaObjectCode。
  • IsFinalResult 为 "true" 时:context.TransferResult.List = list、context.TransferResult.Total = list.Count,并设置 context.Result = ResponseResult<List<ObjectData>>.Success([.. list.Take(1)]).Total(list.Count),最终结果只返回第一条记录、total 为更新条数。

事务、批量阈值与限制​

  • 批量阈值:单次列表条数不得超过 CommonConst.BatchOperationThreshold = 100,超出抛 SingleOperationDataCannotMorethanXCount。
  • 若未配置任何有效更新字段,组件会提前返回,不会执行任何写库操作。
  • 组件自身不显式开启事务,批量更新由 IChameleonDbContext 执行;是否处于事务中以 IChameleonDbContext.InTransaction 为准。

权限校验​

  • 操作权限:未跳过时调用 permissionService.VerifyPermissionAsync(PermissionRequest.CreateMetaObjectDataOperation(metaObject._id, MetaObjectDataOperationType.Update))。
  • MOU/行级权限:未跳过时调用 permissionService.CombineDataPermissionFilterAsync(context, metaObject, FilterBuilder.In(CommonConst._id, ids), MouPermissionStageEnum.Edit) 生成过滤条件,再用 chameleonDbContext.GetListAsync(metaObject.Code, filter, ["_id"]) 取回有权限的 _id,与入参取交集;交集为空抛 NoPermissionOperateData。
  • 跳过标志:GetSkipOperationPermission(context) 判定节点 meta SkipOperationPermission 或 DicParam["SkipOperationPermission"] 任一为 "true";GetSkipMouPermission(context) 仅读取 DicParam["SkipMouPermission"](非节点 meta)。

异常与校验​

触发条件错误常量
MetaObjectId 为空OperationObjectNotFound
目标对象不存在MetaObjectNotFoundById
条数超过 100SingleOperationDataCannotMorethanXCount
记录 Id 为空DataIdCanNotBeEmpty
MOU 过滤后无可操作数据NoPermissionOperateData

所有异常经 ErrorException 包装,附带组件类型、接口 id、节点 id 定位信息;文案取自 locale 资源。