EOS Low-Code Platform 8 EOS Low-Code Platform 8
产品简介
学习指南
更新说明
安装与集成
上线指南
初见EOS
低代码开发手册
专业代码开发手册
专题场景实战
公共服务框架
应用运行治理
最佳实践
运维指南
  • 流程参与者获取失败排查与解决手册
  • 现象一:启动流程或流转时,直接报错“The activity participant is null”
  • 1. 参与者配置为“角色”、“岗位”、“机构”等组织模型
  • 2. 参与者配置为“上一环节处理人”
  • 3. 参与者配置为“业务参与者规则(逻辑流)”
  • 4. 参与者配置为“自定义 Java 类”
  • 现象二:提交表单时指定了后续环节的参与者,但参与者未生效
  • 现象三:在组织机构树中搜索员工,提示“无数据”
  • 现象四:调用 API(如 getProbableParticipants)获取参与者时返回空列表
  • 预防措施:配置“未找到参与者”兜底策略
  • 终极排查清单(速查表)

# 流程参与者获取失败排查与解决手册

当流程卡住、报错“参与者为空”时,请根据您遇到的具体现象,直接查阅下方对应的章节,按照步骤操作。

# 现象一:启动流程或流转时,直接报错“The activity participant is null”

这是最常见的现象,表示引擎在某个环节完全没找到处理人。请根据该环节的参与者配置类型,选择下方对应的排查路径。

# 1. 参与者配置为“角色”、“岗位”、“机构”等组织模型

原因:指定的角色/岗位/机构下没有有效人员,或关联的人员已被禁用。

解决步骤:

  1. 确认具体配置:在流程设计器中,找到报错的人工活动,查看其参与者配置的具体对象(例如:角色编码 ROLE_ADMIN)。

  2. SQL排查-角色示例:在数据库中查询该角色下是否有关联的有效人员。

    -- 检查角色 'ROLE_ADMIN' 下是否有正常的人员
    SELECT
      r.CODE AS ROLE_CODE,
      r.NAME AS ROLE_NAME,
      p.PARTY_ID,
      -- 判断关联的是人员还是机构
      CASE p.PARTY_TYPE
        WHEN 'emp' THEN (SELECT NAME FROM afc_employee WHERE ID = p.PARTY_ID AND STATUS = 0)
        WHEN 'org' THEN (SELECT NAME FROM afc_org WHERE ID = p.PARTY_ID AND STATUS = 0)
      END AS PARTY_NAME
    FROM afc_role r
    JOIN afc_r_party_role p ON r.ID = p.ROLE_ID
    WHERE r.CODE = 'ROLE_ADMIN' -- 替换为您的角色编码
      AND r.STATUS = 0; -- 角色本身也要正常
    
    • 如果查询结果为空:说明组织模型数据不完整,需要去组织管理模块为该角色添加人员。
    • 如果查询结果中的 PARTY_NAME 为 NULL:说明关联的人员或机构已被禁用,需启用或重新关联。

# 2. 参与者配置为“上一环节处理人”

原因:当前环节期望由上一个环节的处理人来处理,但上一个环节可能没有处理人(例如是自动活动),或历史数据被清理。

解决步骤:

  1. 查看流程历史:在流程监控中查看该流程实例的历史记录,确认上一个人工环节是否有处理人。

  2. 数据兜底:这种配置方式风险较高,强烈建议为此活动配置 “未找到参与者时的处理策略”(见本文档【预防措施】章节),例如转交给流程管理员,防止流程卡死。

# 3. 参与者配置为“业务参与者规则(逻辑流)”

原因:用来获取参与者的逻辑流没有返回正确格式的数据,或逻辑流本身执行报错。

解决步骤:

  1. 确认逻辑流位置:该逻辑流必须位于当前应用下,跨应用调用会失败。

  2. 调试逻辑流:在逻辑流中添加调试输出,或在代码中打印日志,确认返回值。

  3. 检查返回值格式:逻辑流必须返回 WFParticipant 对象或 List<WFParticipant> 列表。

    // 正确示例:返回一个人员
    import com.eos.workflow.omservice.WFParticipant;
    
    def participant = new WFParticipant("12345", "张三", "emp"); // ID, 名称, 类型
    context.out = participant;
    
    // 正确示例:返回多个人员(用于会签)
    import com.eos.workflow.omservice.WFParticipant;
    
    def participants = [];
    participants.add(new WFParticipant("12345", "张三", "emp"));
    participants.add(new WFParticipant("67890", "李四", "emp"));
    context.out = participants.toArray(); // 注意要转为数组
    
    • 错误示例:返回了 null,返回了空列表 [],或返回的 WFParticipant 对象缺少 ID、Name、TypeCode 等必填字段。

# 4. 参与者配置为“自定义 Java 类”

原因:Java 类未加载、类上缺少注解、方法签名错误或返回值格式不对。

解决步骤:

  1. 检查类注解:确认 Java 类上有 @ParticipantRuleFunctionClass 注解,方法上有 @ParticipantRuleFunction 注解。

  2. 检查方法签名:方法入参必须是 (Map<String, Object>, ProcessContext),出参必须是 WFParticipant 或 List<WFParticipant>。

  3. 检查类加载:

    • BPS 应用:确认 jar 包放在 [BPS_HOME]/lib 目录下。
    • 微服务应用:确认 jar 包通过 maven 依赖引入或放在应用的 lib 目录。
    • 排查命令:
      # 检查 BPS 启动时是否有类加载异常
      grep -i "classnotfound" bps.log | grep -i "您的类名"
      grep -i "noclassdeffound" bps.log
      
  4. 检查返回值:参考【现象一-第3点】中的返回值格式示例,确保返回的 WFParticipant 对象包含了 ID、Name、TypeCode 等必要信息,且 TypeCode 必须是 emp、org、role 三者之一。

# 现象二:提交表单时指定了后续环节的参与者,但参与者未生效

原因:在提交按钮的返回值中,指定参与者的 JSON 结构错误。

解决步骤:

  1. 检查 JSON 结构:确认返回值中 destActivityParticipant 为 true,并且 destParticipants 数组格式正确。

    // 正确示例:指定下一个环节 manualActivity2 的参与者为张三
    return {
      "destActivity": false, // false 表示按连线走
      "links": [{
        "id": "manualActivity2", // 目标活动ID
        "rule": {
          "destActivityParticipant": true, // 启用参与者指定
          "destParticipants": [{
            "id": "27",       // 参与者ID
            "name": "张三",   // 参与者名称
            "typeCode": "emp" // 参与者类型
          }]
        }
      }]
    };
    
  2. 添加调试代码:在提交按钮的脚本中,用 console.log 打印出最终返回的 JSON 字符串,复制到 JSON 在线校验工具中检查格式是否正确。

# 现象三:在组织机构树中搜索员工,提示“无数据”

原因:组织机构树的搜索功能是静态检索,它只过滤当前页面已加载出来的节点。如果目标机构节点没有展开,其下的人员就不会被加载,自然也搜索不到。

解决步骤:

  1. 手动展开:先手动点击展开组织机构树,一直展开到可能包含目标人员的机构层级,然后再进行搜索。

  2. 代码展开(前端):在页面加载后,自动将树展开到指定层级。

    // 示例:页面加载后,将树展开到第3级
    setTimeout(() => {
      const tree = this.Api.getElement('your_tree_component_id');
      if (tree) {
        tree.expandTreeToLevel(3, true);
      }
    }, 1000);
    
  3. 调用动态检索接口:如果需要真正的全局搜索,需要自行开发后端接口,根据关键字在数据库 afc_user 或 afc_employee 表中进行模糊查询。

# 现象四:调用 API(如 getProbableParticipants)获取参与者时返回空列表

原因:调用 API 时参数不正确,或该活动本身的参与者规则就无法解析出人员。

解决步骤:

  1. 检查参数类型:确认 processInstId 是 long 类型,activityId 是 String 类型。

    // 正确示例
    workFlowManager.getProbableParticipants(12345L, "manualActivity1");
    
  2. 验证流程实例和活动:确认 12345L 这个流程实例存在,并且 "manualActivity1" 确实是该流程定义中属于下一步的一个活动 ID。

  3. 根本原因排查:API 返回空列表只是结果,根本原因还是要回到【现象一】中,根据该活动的参与者配置类型进行排查。

# 预防措施:配置“未找到参与者”兜底策略

为了防止因参与者获取失败导致流程永久卡死,强烈建议为每一个重要的人工活动配置兜底策略。

配置位置:

流程设计器中,选中人工活动节点 -> 属性视图 -> “参与者”选项卡 -> “未找到参与者时的处理策略”。

配置建议:

  • 转交给指定人员:选择一个固定的流程管理员或业务主管,作为最后一道防线。这是最推荐的做法。
  • 进入异常状态:流程进入“异常”状态,需要管理员登录管理端手动处理。适用于需要严格管控的场景。
  • 监控异常:仅记录一条警告日志,流程继续向下流转。此选项风险较高,需谨慎使用。

# 终极排查清单(速查表)

步骤 检查项 一句话操作指引
1 看日志 搜索 bps.log,关键词 participant、null、activity is null、21040507。
2 定类型 确认报错环节的参与者配置类型(角色?逻辑流?自定义类?)。
3 查数据 如果是角色/岗位,用 SQL 检查关联关系是否正常,人员是否被禁用。
4 验逻辑 如果是逻辑流,确认它在当前应用下,并调试其返回值。
5 验类 如果是自定义类,检查注解、方法签名和 jar 包位置。
6 看结构 如果是动态指定,用 JSON 校验工具检查提交时的返回值结构。
7 配兜底 (长期建议) 为活动配置“未找到参与者”的兜底策略。

← 分支规则和分支聚合问题 回退失败 →