本章说明工作流如何确定任务的候选人或执行人,适用于【单人任务 → 任务设置 → 指派策略】中的“候选人范围”和【多人任务 → 任务设置 → 指派策略】中的“执行人范围”。【通知】节点的“接收人”也使用相同的人员选择方式。
如果您只想知道“多个用户 ID 怎么写”,可以先看下面的快速示例;如果人员来自 Python 脚本,请继续查看“Python 返回多个处理人的完整示例”。
人员固定时,直接选择【指定用户或组】,在选择框中选中多位用户即可,无需写表达式。
需要使用【表达式-用户ID】时,在表达式编辑器中填写:
["USER_ID_A", "USER_ID_B"]
这里表示两位用户。请把 USER_ID_A、USER_ID_B 替换为当前环境中真实的用户 ID;它们是示例占位值,不是用户姓名,也不一定等于登录账号或用户编码。
单个用户:表达式返回字符串,例如 "USER_ID_A"。
多个用户:表达式返回字符串数组,例如 ["USER_ID_A", "USER_ID_B"]。每个 ID 都要有引号,数组整体不要再加引号。
已有字符串数组全局变量 approver_ids:填写 wfv$approver_ids。
已有两个字符串变量 approver_a、approver_b:填写 [wfv$approver_a, wfv$approver_b]。
不要直接填写 "USER_ID_A,USER_ID_B" 来表示两个人。 这是一整段字符串,系统不会自动按逗号拆分。'["USER_ID_A", "USER_ID_B"]' 同样只是字符串,需要先用 JSON.parse 转成数组,具体见后文。
在单人任务中,以上两位用户共享一个任务;在多人任务中,以上两位用户各有一个任务。多人任务何时结束,还取决于并行/串行和完成规则。
单人任务的候选人:可以看到并参与处理该任务的人员范围。通常认领后成为执行人;配置多位候选人,仍然只生成一个任务。候选人和执行人具体能操作哪些按钮,由任务动作配置决定。
多人任务的执行人:直接获得各自任务的执行单位,无需先认领。最终有几个执行单位,就对应几个任务;并行时同时创建,串行时依次创建。完成规则可能提前结束节点,不代表所有人一定都要处理。
通知的接收人:接收消息的人员范围,不会因为选了多个人而生成审批任务。
例如,“张三、李四任意一人处理同一张待办”可使用单人任务;“张三、李四各自审批”应使用多人任务,并配置相应的完成规则。详见单人任务和多人任务。
选择用户组后,还需要决定按组派发还是按组内成员派发:
用户、用户组(组内成员均可完成该组任务):保留用户组作为执行单位。例如财务组有 3 位成员,多人任务给这个组生成 1 个组任务,组内成员均可按任务配置处理。
仅用户(用户组将换算为具体用户):计算指派范围时,将用户组展开为具体用户。同一个财务组有 3 位有效成员,多人任务会为这 3 人分别安排任务。
在单人任务中,这个选择影响候选人是“组”还是“具体用户”,不会让一个节点生成多个任务。
多人任务【完成任务】区域也有“执行人单位”设置,它决定组任务完成时以组还是个人的名义记录。它与【指派策略】中是否将组拆成个人,是两个不同的配置。
在范围配置中,点击【添加】可以新增一行,并为每一行选择不同的指派方式。

一行可以是一个人,也可以是多个人,例如一个字符串数组、一个用户组或一条角色方案查询。
多行的结果合并为人员范围,并非只取第一行,也不是要求同一个人同时满足每行条件。
同一用户重复出现会去重,不要通过重复填写同一个 ID 来安排多次审批。
串行多人任务按配置行的先后顺序处理;同一行内的人员顺序不能作为审批顺序保证。如果要求“张三先审批,李四后审批”,请分成两行,每行只配置一个人,并选择串行执行。
适用场景:任务始终由本次流程的发起人处理,例如审批结束后由申请人补充材料或确认结果。
配置步骤:
在候选人范围或执行人范围中选择【流程发起人】。
保留系统展示的 initiator_id,无需填写用户 ID。
如果只需要发起人处理,检查范围中是否还保留了其他不需要的配置行。
![]()
示例:张三发起报销流程,“补充发票”节点选择流程发起人,则该节点指向张三。李四发起同一个流程时,则指向李四。
注意:流程发起人与工作流的设计人、创建人、发布人不是同一个概念。定时或系统触发的流程,应先确认运行实例记录的发起人以及人员为空时的处理方式。
适用场景:人员固定,或者业务始终由某个固定用户组负责,例如财务共享组复核。
配置步骤:
选择【指定用户或组】。
打开选择框,选择一位或多位用户,也可以选择一个或多个用户组,或组合选择用户和组。
选了用户组时,检查“候选人单位”或“执行人单位”,确定是否展开为组内成员。
![]()
示例一:固定两人审批。多人任务中选择张三、李四,执行人单位选择“仅用户”,两人各有一个任务。人员数量固定时,这是最容易配置的方式。
示例二:固定财务组处理。多人任务中只选择财务组,执行人单位选择“用户、用户组”,生成一个财务组任务;如果要求组内每人分别审批,则改为“仅用户”。
注意:这里通过选择框选人,不需要手工拼接 ID。串行且要求固定先后顺序时,张三、李四应分别配置为两行。
适用场景:人员随单据、启动参数或前序节点计算结果变化,例如 Python 根据金额和组织返回审批人。
配置步骤:
选择【表达式-用户ID】,打开表达式编辑器。
输入返回用户 ID 的表达式;使用变量时,优先从编辑器左侧变量列表选取。
确认最终结果是一个字符串,或每项都是字符串的一维数组。
![]()
单人:
"USER_ID_A"
多人:
["USER_ID_A", "USER_ID_B"]
即使真实 ID 看起来全是数字,也按字符串写,例如 "00123",避免变成数字后丢失前导零。
假设全局变量编码为 approver_ids,类型为“字符 - string”,且已勾选“作为数组”,运行时值为 ["USER_ID_A", "USER_ID_B"],表达式直接填写:
wfv$approver_ids
如果是同名的启动参数,使用 wfi$approver_ids。如果只有一位审批人,也可以使用字符串变量 wfv$approver_id。
不要给变量引用加引号:"wfv$approver_ids" 表示字面文本,不会读取变量。也不要把已有数组再套一层方括号:[wfv$approver_ids] 会形成嵌套数组,不是要求的一维字符串数组。
假设 wfi$amount 是数字类型的申请金额,小于 10,000 元由张三审批,达到 10,000 元由张三和李四分别审批:
wfi$amount >= 10000 ? ["USER_ID_A", "USER_ID_B"] : ["USER_ID_A"]
示例两条分支都返回数组,便于后续统一作为字符串数组传递。只有当本例中的 ID 替换为真实用户 ID,并且金额参数已定义,才能在实际流程中使用。
如果字符变量 approver_ids_text 的实际内容是 USER_ID_A,USER_ID_B,先拆分并清理空格和空项:
(wfv$approver_ids_text || "").split(",").map(function (id) {
return id.trim();
}).filter(function (id) {
return id !== "";
})
这个示例使用英文逗号。中文逗号、分号、换行不会按上述写法自动拆分,需要先统一上游输出格式。
如果字符变量 approver_ids_json 的实际内容是 JSON 数组文本 ["USER_ID_A", "USER_ID_B"],使用:
JSON.parse(wfv$approver_ids_json)
JSON.parse 只用于合法的 JSON 文本。Python 的列表字符串 ['USER_ID_A', 'USER_ID_B'] 使用单引号,不是合法 JSON;已经是数组的变量也不要再次 JSON.parse。解析结果仍必须是一维字符串数组,不能是对象或数字数组。
表达式使用 JavaScript,建议沿用平台支持的 ES5 写法。多行表达式以最后一行计算结果为输出;如果前面做了循环或修改数组,最后一行要单独写出要返回的数组变量。不要直接把 Python 列表处理代码粘贴到这里。更多规则见表达式。
适用场景:负责处理的用户组随业务变化,例如不同公司交由不同财务组处理。
配置步骤:
选择【表达式-用户组ID】。
返回一个用户组 ID 字符串或一维字符串数组。
根据业务要求选择按组派发,或将用户组展开为具体用户。
![]()
单个组:
"GROUP_ID_FINANCE"
多个组:
["GROUP_ID_FINANCE", "GROUP_ID_RISK"]
如果全局变量 approver_group_ids 已是字符串数组,直接使用 wfv$approver_group_ids。逗号文本和 JSON 文本的转换方法与用户 ID 相同。
示例:财务组有 2 人,风控组有 3 人,两组成员不重叠。在多人任务中返回上述两个组,选择“用户、用户组”时对应 2 个组任务;选择“仅用户”时对应 5 个个人任务。如果两组有同一位成员,展开后该用户会去重。
注意:此处必须填写用户组 ID,不是组名称;用户 ID 应使用【表达式-用户ID】。如果同一范围需要用户和用户组,请分别添加两行,不要把两类 ID 混在同一个表达式中。
适用场景:审批职责已维护在角色方案中,需要根据公司、部门等维度找到相应角色的人员。
配置步骤:
选择【基于角色方案】,展开配置。
选择角色方案组件,再选择需要的角色或角色组。
按该角色方案的维度要求填写维度成员,可通过流程参数或变量动态提供。
确认角色方案在这个维度组合下已配置用户或用户组,并检查任务的人员单位设置。

示例:角色方案“费用审批职责”有“公司”维度和“财务审核人”角色。A 公司该角色对应张三、李四,B 公司对应王五。节点选择该方案和角色,公司维度赋值为启动参数 wfi$company_code。A 公司发起时得到张三、李四,B 公司发起时得到王五。
如果角色方案返回多个人员,无需在节点中再把这些人拼成字符串;系统会按查询结果形成指派范围。如果返回的是用户组,是否展开为个人仍由人员单位决定。
注意:角色、角色组与用户组不是同一概念。选择了角色但没有维护当前维度组合下的人员,仍可能得到空结果;应先检查角色方案中的实际授权和传入的维度成员,而不是只检查节点是否选了方案。
适用场景:业务对象已经保存负责人或审批人的用户关联属性,例如报销单上的“审核人”。
配置步骤:
选择【基于用户对象】,展开配置。
在“基础对象”中选择业务对象,例如“报销单”。
在“过滤基础对象”中,通过业务主键定位本次流程对应的记录。此处目前仅支持基础对象的业务主键,不是任意条件查询。
选择“用户属性”,该属性必须关联用户对象 SystemUser。

示例:报销单业务主键为“单据编号”,单据 BX20260001 的“审核人”关联张三。流程启动参数 bill_no 保存此单据编号:基础对象选报销单,业务主键赋值为 wfi$bill_no,用户属性选“审核人”,即可得到张三。
如果该用户关联属性在业务模型中支持关联多个用户,且这条记录关联张三、李四,则按查询结果取得两人的用户 ID;如果业务模型只有单值负责人属性,选择该属性不会凭空得到多人。
注意:普通文本属性中写了“张三,李四”,或存了一段用户 ID 文本,并不等于用户关联属性。此类文本应先由前序节点取到变量,再用【表达式-用户ID】处理。业务主键没有匹配记录、属性未赋值或关联用户无效,都应按空结果排查。
适用场景:业务对象已保存负责处理的用户组,例如项目上的“复核组”。
配置步骤:
选择【基于用户组对象】。
选择基础对象,并通过业务主键定位当前记录。
选择“用户组属性”,该属性必须关联用户组对象 SystemGroup。
检查人员单位,决定按组创建任务还是展开为组内成员。

示例:项目 PROJECT_001 的“复核组”关联财务组。基础对象选“项目”,业务主键赋值为 wfi$project_code,用户组属性选“复核组”。多人任务选择“用户、用户组”时为财务组安排一个任务;选择“仅用户”时,为组内有效成员分别安排任务。
如果属性支持关联多个用户组,按实际关联结果取得多个组;后续的组展开规则与【表达式-用户组ID】一致。普通组名称文本或用户属性不能代替用户组关联属性。
业务场景:流程先通过 PY脚本计算处理人,再交给多人任务,张三、李四分别处理。
编排顺序为:PY脚本(同步调用)→ 数据映射到全局变量 → 多人任务。
假设 Python 输出字段为 approver_ids,对应脚本变量保存如下值:
approver_ids = ["USER_ID_A", "USER_ID_B"]
这是用于说明返回值形态的脚本片段。还需要在 Python 元素中启用“指定输出结果”,使用“自定义输出结构”,将这个变量配置为输出字段 approver_ids:基础类型为字符串,数组选项启用。仅在脚本中定义或 print 这个变量,不等于已配置工作流可读取的输出。
脚本实际输出应为字符串列表,不能只是将输出类型改成数组,而实际仍返回 "USER_ID_A,USER_ID_B"。推荐方式下也不要使用 str(approver_ids) 或 json.dumps(approver_ids),因为它们会把列表转成文本。
在工作流变量中新增全局变量:
编码:approver_ids。
类型:“字符 - string”。
“作为数组”:勾选,即 string[]。
初始值:可以为空数组,实际人员由前序 PY脚本返回后赋值。
只有一个人时也保持同一种返回形态,例如 ["USER_ID_A"]。不要让这个输出有时是字符串、有时是数组。
在 PY脚本节点中选择脚本,调用方式选择【同步】。
确认节点的脚本输出中可以看到 approver_ids,且类型为字符串数组。修改 Python 输出定义后,应重新检查该节点读取到的输出类型。
在 PY脚本节点结束时的数据映射中,将当前节点输出 acr$approver_ids 映射到全局变量 wfv$approver_ids。优先使用变量选择器,映射整个数组。
如果通过表达式映射,表达式为:
acr$approver_ids
这里源输出和目标变量都应是 string[];不要填写 [acr$approver_ids],也不要加引号。
acr$ 是当前节点的局部输出,后续多人任务应读取已映射的 wfv$approver_ids。异步 PY脚本不会等待脚本返回结果,不能直接照用这条编排。长耗时脚本需要异步配合等待消息传值,参见PY脚本。
“执行人单位”选择【仅用户】。
“执行人范围”选择【表达式-用户ID】。
填写下面的表达式,并移除示例中不需要的其他指派行,例如默认的流程发起人行。
wfv$approver_ids
如果希望张三、李四同时收到任务,选择并行;如果要求两人都应答后才结束,再选择适用的会签完成规则。数组决定派给谁,完成规则决定何时结束,两处都需要配置。
先使用真实用户 ID 测试,确认以下结果:
PY脚本运行成功,输出 approver_ids 的值确实为两项字符串列表。
PY脚本节点结束后,流程全局变量 approver_ids 的类型是 string[],值为两项用户 ID。
多人任务创建后,张三、李四分别看到自己的任务;如果只出现一位或额外出现发起人,检查 ID 是否有效以及是否保留了其他指派行。
不一定要同时修改 Python 和工作流为数组。可以让 Python 输出字段及目标全局变量都保持 string,在【表达式-用户ID】中再转换:
输出为英文逗号分隔的 USER_ID_A,USER_ID_B:使用前文的 split、trim、filter 示例。
输出为合法 JSON 数组文本 ["USER_ID_A", "USER_ID_B"]:使用 JSON.parse(wfv$approver_ids_json)。
例如,Python 要输出 JSON 文本时,先准备列表,再生成文本,并把 approver_ids_json 配置为非数组的字符串输出字段:
import json
approver_ids = ["USER_ID_A", "USER_ID_B"]
approver_ids_json = json.dumps(approver_ids)
此时工作流全局变量 approver_ids_json 也配置为 string,映射后在任务指派表达式中执行 JSON.parse。这条方式在传递阶段是字符串,在指派阶段才转换为数组;不要把 JSON 文本直接映射到 string[] 变量。
在“候选人为空处理”或“执行人为空时处理”中,按业务需要选择:
作为不可捕获异常抛出:暂停当前流程的后续执行,在流程监控中查看异常并处理。
指定用户:配置默认接手的流程发起人或具体用户;默认用户本身也不存在时,仍会进入异常处理。
表达式结果为空、ID 无效、用户组无有效成员、角色方案未匹配人员、业务对象未匹配记录或人员属性未赋值,都可能使最终人员范围为空。默认接手人应是业务认可的兜底人选,不能替代对上游数据的检查。
平台会过滤“企业所有用户”“所有用户”“空间所有用户”这三类特殊用户组,不能用它们批量给全部用户派任务。通过选择框、表达式、角色方案或对象属性配置时,都要注意这一限制。
先检查实际返回值。单个字符串 "USER_ID_A" 是合法输入;多个用户必须是 ["USER_ID_A", "USER_ID_B"],不能只在原字符串里加逗号。也要确认每个元素都是用户 ID 字符串,而不是数字、姓名或包含 user_id 的对象。
按发生位置逐步检查,而不是反复只改全局变量:
Python 输出:实际返回的是列表还是列表的文本?输出字段是否真的声明为字符串数组?
PY脚本节点输出:节点是否识别到了新的字段类型和数组标记?
数据映射:来源是否选到整个输出字段,目标是否为字符串数组?有没有多加引号或方括号?
任务表达式:使用的是否是已赋值的全局变量?最后计算结果是否为一维字符串数组?
运行版本:变量定义随工作流版本生效;修改设计后应使用包含这些配置的版本发起新的测试实例,不能仅凭旧实例判断新定义是否生效。
类型不匹配与“ID 对应不到有效用户”是不同问题。先让值的形态正确,再检查这些 ID 在当前环境中是否存在。
检查是否使用了单人任务;如果是多人任务,再检查是否按用户组派发、选择了串行执行、存在重复用户,或者完成规则已提前结束其他任务。
不要依赖同一行数组的顺序。将每位用户配置成单独的一行,再按需要调整行顺序,并将多人任务设为串行。某一行通过角色方案、用户组或数组解析出多人时,这一行内部的顺序仍不能保证。
进入【流程监控 → 异常信息】查看具体失败节点,并对照 PY脚本输出、数据映射和任务指派三个阶段检查。仅凭“节点信息异常”的截图,不能判断一定是数组格式或某个配置导致。排查时记录实际输入值、变量类型和运行版本,以便区分格式问题、人员为空及其他执行异常。
回到顶部
咨询热线
