1. 概述
系统需要使用流程业务,首先需要根据业务的情况在系统中先进行流珵业务的建模,建模的过程我们称为新建流程定义。平台使用的是BPMN的流程模型定义,这时我们需要提供在线的BPMN的流程定义设计器,如下所示:

2. 存储设计
2.1. 流程定义表
平台采用activiti作为底层的流程引擎,因此,其设计的xml为activiti原生的流程定义bpmn文件,只需要在平台增加一表bpm_def进行保存流程定义基本属性:
| 是否主键 | 字段名 | 字段描述 | 数据类型 | 长度 | 可空 | 备注 |
|---|---|---|---|---|---|---|
| 是 | DEF_ID_ | DEF_ID_ | VARCHAR(64) | 64 | ||
| TREE_ID_ | ID | VARCHAR(64) | 64 | 是 | 分类Id | |
| SUBJECT_ | 标题 | VARCHAR(255) | 255 | 标题 | ||
| DESCP_ | 描述 | VARCHAR(1024) | 1024 | 是 | 描述 | |
| KEY_ | 标识Key | VARCHAR(255) | 255 | 标识Key | ||
| ACT_DEF_ID_ | Activiti流程定义ID | VARCHAR(255) | 255 | 是 | Activiti流程定义ID | |
| ACT_DEP_ID_ | ACT流程发布ID | VARCHAR(255) | 255 | 是 | ACT流程发布ID | |
| STATUS_ | 状态 | VARCHAR(20) | 20 | 状态 | ||
| VERSION_ | 版本号 | INT | 版本号 | |||
| IS_MAIN_ | 主版本 | VARCHAR(20) | 20 | 是 | 主版本 | |
| SETTING_ | 定义属性设置 | TEXT | 是 | 定义属性设置 | ||
| MODEL_ID_ | 设计模型ID | VARCHAR(64) | 64 | 设计模型ID,关联Activiti中的ACT_RE_MODEL表主键 | ||
| MAIN_DEF_ID_ | 主定义ID | VARCHAR(64) | 64 | 是 | 主定义ID | |
| TENANT_ID_ | 租用ID | VARCHAR(64) | 64 | 是 | 租用机构ID | |
| CREATE_BY_ | 公共 - 创建人ID | VARCHAR(64) | 64 | 是 | 创建人ID | |
| CREATE_TIME_ | 公共 - 创建时间 | DATETIME | 是 | 创建时间 | ||
| UPDATE_BY_ | 更新人ID | VARCHAR(64) | 64 | 是 | 更新人ID | |
| UPDATE_TIME_ | 公共 - 更新时间 | DATETIME | 是 | 更新时间 | ||
| CREATE_BY_ | 公共 - 创建人ID | VARCHAR(64) | 64 | 是 | 创建人ID | |
| CREATE_TIME_ | 公共 - 创建时间 | DATETIME | 是 | 创建时间 | ||
| UPDATE_BY_ | 更新人ID | VARCHAR(64) | 64 | 是 | 更新人ID | |
| UPDATE_TIME_ | 公共 - 更新时间 | DATETIME | 是 | 更新时间 | ||
| DATA_SAVE_MODE_ | 数据保存模式 | VARCHAR(10) | 10 | 是 | 数据保存模式(all,json,db) | |
| SUPPORT_MOBILE_ | 支持手机端 | INT | 是 | 支持手机端 | ||
| BO_DEF_ID_ | BO定义ID | VARCHAR(20) | 20 | 是 | BO定义ID | |
| BILL_NO_ | 单号 | VARCHAR(255) | 255 | 是 | 单号 | |
| START_DEP_ID_ | 发起部门ID | VARCHAR(64) | 64 | 是 | 发起部门ID | |
| START_DEP_FULL_ | 发起部门全名 | VARCHAR(300) | 300 | 是 | 发起部门全名 | |
| IS_LIVE_ | 是否复活 | VARCHAR(64) | 64 | 是 | 是否复活 | |
| LIVE_INST_ID_ | 复活的流程实例 | VARCHAR(64) | 64 | 是 | 复活的流程实例 |
- 编码
- 流程定义名称
- 是否发布
- 设计器存储的xml
- 流程属性配置
- 主版本Id
- 版本号
- Actviti的发布Id
- Activiti的流程定义Id
【说明】
- 编码是为作API接口发起流程的唯一标识。
- 是否发布状态,只有发布状态的流程才允许发起,发布状态代表流程定义xml需要发布至activiti原生的引擎中去,并且返回了流程定义与发布Id
- 版本号代表每次发布都会增加1,并且主版本Id相应发生变化
- 设计器的xml是为设计器原生产生的原始xml,最终发布的xml则代表转化后给activiti引擎运行的流程定义,与原始xml有小小变化差异,如命名空间不一样。
- 流程属性配置则用于存储流程属性,节点扩展各属性的配置
2.2. 流程定义扩展属性
流程定义的扩展属性存储于EXT_CONFS属性字段中,用于记录流程级别,任务级别,其他如网关,开始与结束节点等的属性配置,可根据业务的需要进行灵活扩展,如下所示,为其中一个节点的属性配置。
2.2.1. 流程级别属性扩展定义
2.2.1.1 JSON属性定义
流程级的json属性定义示例:
"Process": {"detailForm": {"formpc": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": ""}],"mobile": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": "{}","id": "1290175530450284546"}]},"boDefs": {"text": "采购单","value": "purchaseOrder"},"endProcessScript": "","subjectRuleData": [{"ruleSplitor": "processName","ruleType": true},{"ruleSplitor": "-由","ruleType": false},{"ruleSplitor": "createUser","ruleType": true},{"ruleSplitor": "创建于","ruleType": false},{"ruleSplitor": "createTime","ruleType": true}],"noticeTemplate": {},"id": "purchaseFlow","processEndCopyConfig": [],"events": [{"eventConfigs": [],"eventType": {"name": "流程启动","id": "PROCESS_STARTED"}},{"eventConfigs": [],"eventType": {"name": "流程完成","id": "PROCESS_COMPLETED"}},{"eventConfigs": [],"eventType": {"name": "全局任务创建","id": "GLOBAL_TASK_CREATE"}},{"eventConfigs": [],"eventType": {"name": "全局任务完成","id": "GLOBAL_TASK_COMPLETE"}}],"actDepId": "1290178520938364930","orderNo": 1,"isMain": "YES","processEndHandler": "","nodeType": "bpmn:Process","processEndHandlerName": "","version": 2,"defId": "1290178520925782017","treeId": "1273174971675750402","processStartAfterHandler": "","noticeTypes": "getui,weixin","actDefId": "purchaseFlow:2:1290178521089359874","name": "采购订单","varConfigs": [{"uid": "AFZZS9DL3HHLU1B09OPISH97IJT53X20","expression": "","field": "purchaseOrder.lx","datatype": "varchar","label": "类型","key": "lx"},{"uid": "GSG29FZ8UIN3WKF3VYI3LTPZ75I8E12P","expression": "","field": "purchaseOrder.je","datatype": "number","label": "金额","key": "je"}],"processStartPreHandlerName": "","status": "DEPLOYED","mainDefId": "1290178520925782017","subjectRule": "{流程方案名称}-由{创建人}创建于{创建时间}","pkId": "1290178520925782017","buttonConfigs": [],"processStartAfterHandlerName": "","startForm": {"formpc": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": ""}],"mobile": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": "{}","id": "1290175530450284546"}]},"globalForm": {"formpc": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": ""}],"mobile": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": "{}","id": "1290175530450284546"}]},"descp": "","startNodeOptions": ["skipFirstNode","startConfirm"],"bpmSolFvConfings": {"solFvData": {},"label": "全局节点","key": "globalForm"},"dataSetting": {},"updateBy": "1","taskCompleteCopyConfig": [],"key": "purchaseFlow","processStartPreHandler": "","tableFormula": {},"remindDefs": [],"updateTime": "2020-08-13 16:04:17","taskStartCopyConfig": [{"uid": "KXYTQ8FN0DB0V27WDOT3B4UVJQR50UEM","condition": "","name": "人员配置","infoTypes": "getui","configList": [{"display": "发起人","calcType": "no","logic": "or","type": "starter","config": "发起人","currentComponet": "starterEdit"}]}],"createBy": "1","jumpSkipOptions": {"expression": "","type": ["sameNode","noCondition"]},"createTime": "2020-08-03 14:48:46"},
关键属性作用描述
| 属性名 | 功能描述 | 示例值 |
|---|---|---|
| detailForm | 流程节点的明细表单,包括pc与mobile两端的表单的配置 | |
| startForm | 流程节点的开始表单,包括pc与mobile两端的表单的配置 | |
| globalForm | 流程全局的表单,包括pc与mobile两端的表单的配置 | |
| boDefs | 流程绑定的业务模型,流程中能使用哪些单据,即由其设置的业务对象来决定 | “boDefs”: { “text”: “采购单”, “value”: “purchaseOrder” }, |
| subjectRuleData | 流程的标题规则,可以设置流程事项的标题,可由固定值与单据字段或流程变量动态生成 | |
| noticeTemplate | 通知的消息模块 | |
| processEndCopyConfig | 流程结束的抄送配置 | |
| endProcessScript | 流程结束时调用的脚本(Groovy Script) | |
| events | 流程的调用事件,包括流程启动、流程完成,全局的任务创建,全局流程完成 | |
| varConfigs | 流程全局的变量配置,其值一般来自单据的字段 | |
| processEndHandler | 流程结束时调用的处理器,需要实现ProcessHandler的接口 | |
| processStartAfterHandler | 流程启动时调用的处理器,需要实现ProcessHandler的接口 | |
| noticeTypes | 消息通用类型,如短信,个推,企业微信 | getui,weixin |
| buttonConfigs | 流程启动界面的操作按钮配置 | |
| startNodeOptions | 流程启动的开关配置 | 跳过第一个节点=skipFirstNode 启动需要确认=startConfirm 启动可填写意见=fillOpinion 指定下一步用户=assignFlowUsers |
| dataSetting | 为流程操作单据时,可对单据的业务对象进行一些字段值的数据更改 | |
| taskCompleteCopyConfig | 流程任务完成后的抄送配置 | |
| taskStartCopyConfig | 流程任务开始时的抄送配置 | |
| tableFormula | 任务完成时执行的表间公式 | |
| remindDefs | 任务的催办配置 | |
| jumpSkipOptions | 任务跳过的配置 |
2.2.1.2. 获取配置类
通过流程定义Id可获取流程级的配置,如下所示:
ProcessConfig processConfig = bpmDefService.getProcessConfig(actDefId);
2.2.2. 任务节点属性配置:
2.2.2.1. JSON 属性定义
任务节点的属性配置定义示例如下所示:
"UserTask_0e0aixm": {"allowScript": "","backOptions": ["BACK","BACK_TO_STARTOR"],"allowTipInfo": "","dbclick": true,"taskAfterHandlerName": "","startCopyConfig": [],"bpmSolFvConfings": {"solFvData": {},"key": "UserTask_0e0aixm"},"dataSetting": {},"userConfigs": [{"uid": "I77W7P5W6SSBI0R28YGPMRPQF7FQQER4","condition": "","name": "人员配置","configList": [{"display": "智慧科技","calcType": "no","logic": "or","type": "group","config": "2","currentComponet": "groupEdit"}]}],"multipleType": "normal","noticeTemplate": {},"id": "UserTask_0e0aixm","taskPreHandler": "","key": "UserTask_0e0aixm","events": [],"taskAfterHandler": "","orderNo": 60,"buttons": [],"signConfig": {"finishCondition": "","votePrivileges": [],"calOption": "voteCount","voteCount": 1,"finishOption": "waitAllVoted","voteOption": "AGREE","completeType": "TICKETS","finishExecute": ""},"tableFormula": {},"remindDefs": [],"nodeType": "bpmn:UserTask","taskPreHandlerName": "","parentId": "purchaseFlow","noticeTypes": "","form": {},"jumpSkipOptions": {"expression": "","type": ""},"jumpRules": [],"completeCopyConfig": [],"name": "C","varConfigs": [],"switchOptions": []},
任务级属性定义说明:
| 属性名 | 功能描述 | 示例值 |
|---|---|---|
| allowScript | 检查当前的任务是否允许执行的判断脚本,Groovy脚本 | |
| backOptions | 回退选择项,即某个节点是否允许回退 | BACK 回退上一步 BACK_TO_STARTOR 回退至发起人 BACK_SPEC 回退至某审批节点 |
| taskPreHandlerName | 任务完成的前置处理器,实现ProcessHandler接口 | |
| taskAfterHandlerName | 任务完成的前置处理器,实现ProcessHandler接口 | |
| dataSetting | 为流程操作单据时,可对单据的业务对象进行一些字段值的数据更改 | 由界面进行配置 |
| userConfigs | 节点人员配置,可由多个人员配置组成,实现不同的人员查找 | |
| multipleType | 多实例类型 | normal为普通任务 parallel为并行 sequential为串行 |
| noticeTemplate | 通知模板 | |
| events | 事件调用配置,任务创建,任务完成事件 | |
| buttons | 审批单据的按钮配置 | |
| signConfig | 当multipleType为并行或串行任务时,才进行该属性的配置,具体参考会签的配置 | |
| tableFormula | 表间公式,流程任务在完成任务事项时触发表间公式的调用 | |
| remindDefs | 催办定义,定义节点的催办事项等 | |
| noticeTypes | 通知类型,可动态扩展,支持微信,邮件,内部消息,短信等 | |
| jumpSkipOptions | 跳过配置,支持动态的跳过配置管理 | sameFollowNodeUser=相邻节点相同用户审批 noCondition=不需要条件直接跳过 onceUserCheck=当前用户曾审批 checkedByFormVars=根据表单变量判断 |
| jumpRules | 任务的跳转规则,支持任务的跳过处理 | |
| varConfigs | 变量配置,支持在节点上进行一些任务级别的变量配置 | |
| switchOptions | 任务节点一些开关参数配置 | allowDefButtons=允许自定义审批按钮 allowPrintForm=允许打印表单 allowSelectExecutor=允许选择执行人 allowExecutorNull=允许执行人为空 |
2.2.2.2. 获取节点级的配置
UserTaskConfig userTaskConfig= (UserTaskConfig) bpmDefService.getNodeConfig(execution.getProcessDefinitionId(),execution.getCurrentActivityId());
2.3. 单据配置
单据的配置请参考流程级与任务级的,若任务配置了单据,则优先使用任务级的配置。其配置格式如下所示:
"detailForm": {"formpc": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": ""}],"mobile": [{"boAlias": "purchaseOrder","name": "采购单","alias": "purchaseOrder","permission": "{}","id": "1290175530450284546"}]}
说明:
boAlias:代表该单据绑定的BO实体的别名
alias:为单据的别名
name:为单据的名称
permission:单据在不同的地方有字段、按钮、子表的数据权限,其格式如下所示:
{"subtableRights": [{"name": "采购单明细","alias": "purchaseOrderItem","type": "all","setting": ""}],"tabBtn": {},"sub": {"purchaseOrderItem": {"subTabBtn": {"add": {"edit_name": "无权限","edit": "none","name": "添加","alias": "add","type": "default","openType": "inner"},"removeExist": {"edit_name": "所有人","edit": "everyone","name": "删除已添加","alias": "removeExist","type": "default"},"up": {"edit_name": "无权限","edit": "none","name": "上移","alias": "up","type": "default","openType": "inner"},"down": {"edit_name": "无权限","edit": "none","name": "下移","alias": "down","type": "default","openType": "inner"},"remove": {"edit_name": "无权限","edit": "none","name": "删除","alias": "remove","type": "default","openType": "inner"}},"subAttr": {"cpbm": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "产品编码","alias": "cpbm","require": "everyone","read_name": "所有人"},"mc": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "名称","alias": "mc","require": "everyone","read_name": "所有人"},"sl": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "数量","alias": "sl","require": "everyone","read_name": "所有人"},"jg": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "价格","alias": "jg","require": "everyone","read_name": "所有人"}}}},"main": {"dh": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "单号","alias": "dh","require": "everyone","read_name": "所有人"},"fj": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "附件","alias": "fj","require": "everyone","read_name": "所有人"},"bz": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "备注","alias": "bz","require": "everyone","read_name": "所有人"},"je": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "金额","alias": "je","require": "everyone","read_name": "所有人"},"lx": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "类型","alias": "lx","require": "everyone","read_name": "所有人"},"cgr": {"edit_name": "无权限","read": "everyone","require_name": "所有人","edit": "none","name": "采购人","alias": "cgr","require": "everyone","read_name": "所有人"}}}
2.4. 事件配置
平台扩展流程事件包括:
| 事件Key | 触发时机 | 备注 |
|---|---|---|
| TASK_CREATED | 任务创建 | 配置于任务节点属性,由任务创建时触发 |
| TASK_COMPLETED | 任务完成 | 配置于任务节点属性,由任务完成时触发 |
| PROCESS_STARTED | 流程启动 | 配置于流程属性,由流程启动时触发 |
| PROCESS_COMPLETED | 流程完成 | 配置于流程属性,由流程结束完成时触发 |
| GLOBAL_TASK_CREATE | 全局任务创建 | 配置于流程属性,配置后,即表示该节点所有的任务节点在创建时都会触发该事件调用 |
| GLOBAL_TASK_COMPLETE | 全局任务完成 | 配置于流程属性,配置后,即表示该节点所有的任务节点在完成时都会触发该事件调用 |
平台在每个级别上的事件允许用户定义不同的外部调用方式,包括有:
2.4.1. Activiti的流程事件:
扩展的流程事件需要由Activiti的流程事件来触发,因此需要在Activiti的对应的事件监听器中进行以上流程事件的配置与调用,平台提供了以下Activiti的流程事件监听处理器。
在Activiti的引擎构建入口中,加上注流程级的全局事件监听:
package com.redxun.bpm.config;/*** Activiti流程引擎构建配置入口* @author csx* @since 1.0*/@Configurationpublic class ActivitiConfig extends AbstractProcessEngineAutoConfiguration {@Bean@Primarypublic SpringProcessEngineConfiguration springProcessEngineConfiguration(PlatformTransactionManager transactionManager,SpringAsyncExecutor springAsyncExecutor,ActivitiProperties activitiProperties,@Autowired(required = false) DefaultActivityBehaviorFactoryMappingConfigurer processEngineConfigurationConfigurer,@Autowired(required = false) List<ProcessEngineConfigurator> processEngineConfigurators,UserGroupManager userGroupManager,@Qualifier(DataSourceUtil.GLOBAL_DATASOURCE) DataSource dataSource) throws IOException {SpringProcessEngineConfiguration conf = new SpringProcessEngineConfiguration();conf.setConfigurators(processEngineConfigurators);conf.setDataSource(dataSource);conf.setTransactionManager(transactionManager);//加入事件监听// 忽略部分代码...//加上全局事件的控制List<ActivitiEventListener> eventListeners=new ArrayList<>();eventListeners.add(new GlobalEventListener());conf.setEventListeners(eventListeners);return conf;}}
2.4.2. Activiti的全局事件监听器
通过全局的事件监听器实现不同的事件调用不同的处理器,在不同的事件处理器中,调用流程级或任务节点级的事件配置,执行不同的任务操作,如执行SQL,执行Groovy脚本,执行外部的WebService接口等。
package com.redxun.bpm.activiti.event;import com.redxun.bpm.activiti.event.handler.*;import org.activiti.engine.delegate.event.ActivitiEvent;import org.activiti.engine.delegate.event.ActivitiEventListener;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.HashMap;import java.util.Map;/*** 全局事件监听器* @author csx**/public class GlobalEventListener implements ActivitiEventListener {private Logger logger= LoggerFactory.getLogger(GlobalEventListener.class);//事件类型,处理器映射Map<String, EventHandler> eventTypes=new HashMap<>();public GlobalEventListener(){initEventHandlers();}@Overridepublic void onEvent(ActivitiEvent event) {String eventType=event.getType().name();//加上监听事件处理EventHandler handler=eventTypes.get(eventType);if(handler!=null){handler.handle(event);}}@Overridepublic boolean isFailOnException() {return true;}/*** 初始化事件处理器*/public void initEventHandlers(){//注册流程实例创建事件处理器eventTypes.put(EventType.PROCESS_STARTED.name(), new ProcessStartedEventHandler());//注册流程实例完成结束事件处理器eventTypes.put(EventType.PROCESS_COMPLETED.name(),new ProcessCompletedEventHandler());//注册流程任务创建事件处理器eventTypes.put(EventType.TASK_CREATED.name(),new TaskCreatedEventHandler());//注册流程任务完成事件处理器eventTypes.put(EventType.TASK_COMPLETED.name(),new TaskCompletedEventHandler());//注册流程活动开始事件处理器eventTypes.put(EventType.ACTIVITY_STARTED.name(),new ActivityStartedEventHandler());//注册流程活动结束事件处理器eventTypes.put(EventType.ACTIVITY_COMPLETED.name(),new ActivityCompletedEventHandler());}}
2.4.3. 流程级事件调用
流程级的事件调用指的是流程的创建事件与流程结束事件,在设计器中设计时,配置的界面如下:

添加流程级的事件

流程级的事件配置
2.4.3.1. JSON配置
"events": [{"eventConfigs": [{"async": "true","handerTypeName": "脚本","action": "AGREE","description": "调用脚本推送采购订单至SAP","handerType": "script","config": {"dsAlias": "","script": "processScript.doPurchaseOrder(purchaseOrder_lx,purchaseOrder_je,\r\npurchaseOrder_dh);"}}],"eventType": {"name": "流程启动","id": "PROCESS_STARTED"}},{"eventConfigs": [],"eventType": {"name": "流程完成","id": "PROCESS_COMPLETED"}},{"eventConfigs": [],"eventType": {"name": "全局任务创建","id": "GLOBAL_TASK_CREATE"}},{"eventConfigs": [],"eventType": {"name": "全局任务完成","id": "GLOBAL_TASK_COMPLETE"}}],
以上的事件配置调用的类型可以进行选择,如SQL,Groovy脚本,调用WebService接口。
不同类型的事件调用器扩展如下所示:

- ScriptEventHandler为脚本调用处理器
- SqlEventHandler为SQL执行调用处理器
- WebReqEventHandler为WebService的执行调用处理器
2.4.3.2. 节点级的事件调用
节点级的事件调用也类似流程级的事件调用,在线设计器选中某一任务节点时,也通过以下界面进行不同事件级的配置调用:

事件调用的方式也流程级的事件调用方式一致。
2.5. 按钮配置
按钮配置也分为流程级与任务级的按钮配置,分别代表流程启动时的功能按钮与任务办理的功能按钮。系统提供默认的功能配置,非默认的配置允许用户手工添加,但点击的事件代码则需要在单据与流程进行扩展定义。
2.5.1.JSON配置
系统对按钮的存储格式如下:
"buttons": [{"uid": "CKB1U75C2WLVP4OKB32B7HEZO7ZFT9UN","closeable": false,"editable": false,"name": "审批","icon": "icon-approve","jsMethod": "approve","id": "btnApprove","type": "primary"},{"uid": "ILQ5B600ETU7BJCTU10CCGLQNXLACMG9","closeable": true,"editable": false,"name": "锁定","icon": "icon-addSign","jsMethod": "doLock","id": "btnLock","type": "default"},{"uid": "3PCKZTW7C5A3S4R1O16IEXS6MJU7K82T","closeable": true,"editable": false,"name": "驳回","icon": "icon-reject","jsMethod": "reject","id": "btnReject","type": "default"},{"uid": "MMFT9A2GBWEZROOFO43MH33DOD27IQND","closeable": false,"editable": false,"name": "转办","icon": "icon-transfer","jsMethod": "doTransfer","id": "btnTransfer","type": "default"},{"uid": "8VKBQQ2WW1FEOHQOCJ0E5LLD47ONQ2TB","closeable": false,"editable": false,"name": "沟通","icon": "icon-communicate","jsMethod": "communicate","id": "btnCommu","type": "default"},{"uid": "KEKXKK5A6MVLBED8A31R3BXAG30PP84K","closeable": true,"editable": false,"name": "作废","icon": "icon-discard","jsMethod": "doDiscard","id": "btnDiscard","type": "danger"},{"uid": "3NDDULB0OY807UPV2KJ1YGHWQSRTYF9L","closeable": true,"editable": false,"name": "打印","icon": "icon-print","jsMethod": "doPrint","id": "btnPrint","type": "default"},{"uid": "VGYO15XW7A2OA9U0WI4CO9E57MPIAPLH","closeable": true,"editable": false,"name": "保存","icon": "icon-save","jsMethod": "doSaveData","id": "btnSave","type": "default"},{"uid": "P2KBWO2BSPWIKFTCKTL1LH7DWTI3HAXA","closeable": false,"editable": false,"name": "流程图","icon": "icon-flowImg","jsMethod": "doFlowImg","id": "btnFlowImg","type": "default"},{"uid": "12XF2LQ3N6JD05QUHFLJOCTOPXW86SDW","closeable": false,"editable": false,"name": "审批历史","icon": "icon-history","jsMethod": "doHistory","id": "btnHistory","type": "default"},{"uid": "BGA1SD5WC9APRZ9PQ3BC17NSKK2YC7YX","closeable": true,"editable": false,"name": "留言","icon": "icon-message","jsMethod": "doMessage","id": "btnMessage","type": "default"}],
以上的按钮的事件调用均定义于jpaas_bpm_desinger的前端项目TaskToolBar.vue与ProcessToolBar.vue中。
2.6. 催办配置
2.6.1. JSON配置
在流程任务节点中,配置存储格式如下所示:
"remindDefs": [{"sendInterval": {"hour": 0,"day": "2","minute": 0},"sendTimes": 2,"script": "SysFunApi.compareDays(SysFunApi.getCurDate(),checkDate)","uid": "NHCWV2NN7BTUBH90ZD9VVB4SQ7YN3T4B","condition": "purchaseOrder.je > 0","dateType": "CALENDAR","notifyType": "getui,weixin,mail","name": "定期1天催办","timeToSend": {"hour": 0,"day": "10","minute": 0},"timeLimitHandler": "","action": "approve","expireDate": {"hour": 0,"day": "1","minute": 0},"event": "TASK_CREATED"}],
界面配置如下:

2.6.2. 任务催办的后台逻辑处理

说明:
- 在全局的任务创建事件中,TaskCreatedEventHandler 中发布TaskCreateApplicationEvent事件
- ReminderListener监听该事件,根据节点催办配置实现催办实例的插入
- RemindJob通过BpmRemindInstService获取过期与未过期的任务,调用本身的办法发送消息进行相关人员的催办处理
2.7. 会签配置
会签是用于流程多实例的任务节点中,可实现同一任务多人同时办理或分步办理,平台可以设置会签的投标规则与跳出的条件设置,设置的格式如下所示:
2.7.1. JSON配置
"signConfig": {"finishCondition": "","votePrivileges": [],"calOption": "voteCount","voteCount": 1,"finishOption": "waitAllVoted","voteOption": "AGREE","completeType": "TICKETS","finishExecute": ""},
参数说明:
- finishCondition:完成的条件脚本
- calOption:计算选项,按票数还是百分比
- voteCount:投票数量值
- finishOption:完成选项,是等待所有投票,还是达到条件往下执行
- voteOption: 计算的投票类型
- completeType:完成计算的类型,
- finishExecute:完成后执行的脚本
2.8. 人员配置
人员配置是任务节点在创建时,需要动态根据配置项计算出来的人员,并且把人员分配给用户任务的配置信息,它支持:
- 按条件的人员查找规则
- 不同的用户集合进行与或非运算
- 支持不同的人员查找策略算法
- 支持用户组及是否计算到人员
2.8.1. 人员配置项定义
2.8.1.1. JSON配置
"userConfigs": [{"uid": "QXXDHCL4IQC1R1WKY6ZZ39WHIP6UIQ8B","condition": "","name": "人员配置","configList": [{"display": "发起人","calcType": "yes","logic": "or","type": "starter","config": "发起人","currentComponet": "starterEdit"},{"display": "郭靖,黄蓉","calcType": "yes","logic": "or","type": "user","config": "1273526648723415041,1273526443793915905","currentComponet": "userEdit"},{"display": "财务部,研发部","calcType": "yes","logic": "or","type": "group","config": "1273526190164353025,1273526098128740353","currentComponet": "groupEdit"}]}],
2.8.1.2. 界面展示

2.9. 跳转规则配置
用于处理流程非常规的任务跳转处理,如任务节点在满足一条件时,让任务直接跳至结束,尽管流程节点没有画连接至结束节点。它能让一些非正规流程任务的跳转变得灵活,而且不会对流程定义进行修改,影响了其他流程实例。
2.9.1. JSON存储
在定义上扩展如下所示:
"jumpRules": [{"destNodeId": "UserTask_0e0aixm","uid": "FXOF0HC9PMAO5FR20A2C7NE13VQ79E40","scriptConfig": "purchaseOrder.je > 2000","name": "跳至总经理","destNodeName": "总经理审批"}],
说明:
scriptConfig:为满足条件脚本则跳至目标节点destNodeId对应的节点
2.9.2. 配置界面:

2.10. 抄送配置
系统支持流程开始、结束、任务开始、结束时均可以产生对应的一些基于微信、邮件、内部消息、个推等消息的抄送。
2.10.1. JSON存储
"startCopyConfig": [{"uid": "QQ0U7AU0RX71US0BOQLU2AD0URGB1V9V","condition": "","name": "人员配置","configList": [{"display": "xxx","calcType": "no","logic": "or","type": "group","config": "1284391456728883201","currentComponet": "groupEdit"}]}],"completeCopyConfig": [{"uid": "53ZE6D9O5HWD44E8EE50KZFAZ5O26YUR","condition": "","name": "人员配置","infoTypes": "getui,weixin,mail","configList": [{"display": "黄蓉,郭芙蓉","calcType": "no","logic": "or","type": "user","config": "1273526443793915905,1273499857644363777","currentComponet": "userEdit"}]}],
2.10.2. 界面配置:
