苍穹工作流那些事 之 自由流程

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

苍穹工作流那些事 之 自由流程


企业内部在处理流程审批业务时,可能会遇到以下应用场景:无法预置工作流,在进行审批时才根据业务需要确定流程审批节点、审批人。


为此,苍穹工作流提供了对自由流程的支持。构建好的自由流程,处理过程被完整记录,流程实例纳入监控管理体系,既保障了灵活性,又确保了处理过程的严谨性、可追溯性



本期,小编就带大家详细了解苍穹工作流的自由流程功能。




1 业务场景


1、在发起流程时,由流程发起人确定当前业务单据要流转的审批流信息,包括有哪些审批节点和审批人。比如协同办公流程中,会出现发起人确定后续公文审批环节的情况。


2、在流程审批时,由审批人确认当前流程后续要流转的审批流信息,包括有哪些审批节点和审批人。

比如不同角色员工离职办理流程中,除一些通用处理节点,如直接上级审批、薪酬计算、离职证明等外,其他关键审批办理环节是不同的。一般由HR专员审批流程时,依据其职位、职级、部门、岗位类型等手动进行选择。


2 解决方案


苍穹工作流提供了自由流程接口样例代码,支持通过调用接口构建流程,通过项目化交付,最大程度满足用户对流程的自由审批需要,丰富了苍穹工作流的应用场景。


3 功能实现


那自由流程功能是如何实现的呢?小编这就带大家开启探索之旅~


步骤一:流程发起时,构建并启动自由流。相关代码示例如下:


private WFProcess createAndStartProcess() {
         String entityNumber = this.getModel().getDataEntityType().getName();
         QFilter filter = new QFilter(NUMBER, QCP.equals, entityNumber);
         DynamicObject billInfo = BusinessDataServiceHelper.loadSingle(BOS_FORMMETA, QUERY_FIELD, new QFilter[]{filter});
         //创建流程
         WFProcess wfProcess = initProcess(billInfo);
         //人工节点,如果不传人工节点,默认会创建一个
         WFUserTask wfUserTask = initWFUserTask(wfProcess);
         wfProcess.addNextNode(wfUserTask);
         //审批节点
         WFAuditTask wfAuditTask = initWFAuditTask(wfProcess,wfUserTask.getId());
         wfUserTask.addNextNode(wfAuditTask);
         //自动节点
         WFAutoTask wfAutoTask = initWFAutoTask(wfProcess);
         wfAuditTask.addNextNode(wfAutoTask);
         //会审节点
         WFJointAuditTask wfJointTask = initWFJointAuditTask(wfProcess,wfUserTask.getId(),wfAuditTask.getId());
         wfAutoTask.addNextNode(wfJointTask);
         Mapvariables = new HashMap<>();
         String businessKey = this.getModel().getDataEntity().getString("id");
         String operation = "submit";
         WorkflowServiceHelper.createProcessAndStart(businessKey , operation , entityNumber, variables, wfProcess);
         return wfProcess;
}


其中,流程的创建如下:


private WFProcess initProcess(DynamicObject billInfo) {
         WFProcess wfProcess = new WFProcess();
         wfProcess.setEntraBill(billInfo.getString(NUMBER));
         wfProcess.setEntraBillId(billInfo.getString("id"));
         wfProcess.setEntraBillName(new LocaleString(billInfo.getLocaleString("name").getLocaleValue()));
         //流程插件
         ListexecutionListeners = initExecutionListeners();
         wfProcess.setExecutionListeners(executionListeners);
         //单据例外
         ListbillExceptionOp = initBillexception();
         wfProcess.setBillExceptionOp(billExceptionOp);
         //扩展实现其他属性:比如业务申请人和审批人相同时自动审批
         MapextProps = new HashMap<>();
         extProps.put("autoAuditWhenSamePerson", true);
         wfProcess.setExtProps(extProps);
         return wfProcess;
}


人工节点的创建如下:


private WFUserTask initWFUserTask(WFProcess wfProcess) {
         WFUserTask wfUserTask = new WFUserTask(wfProcess);
         wfUserTask.setAllowCoordinate(true);
         wfUserTask.setAllowTransfer(true);
         WFParticipantModel participantModel = new WFParticipantModel();
         participantModel.getParticipant().add(getParticipant1());
         wfUserTask.setParticipant(participantModel);
         LocaleString name = new LocaleString();
         name.put(Lang.zh_CN.name(), ResManager.loadKDString("自由流人工节点", "FreeFlowPlugin_19", WF_UNITTEST));
         name.put(Lang.zh_TW.name(), ResManager.loadKDString("自由流人工节点", "FreeFlowPlugin_19", WF_UNITTEST));
         name.put(Lang.en_US.name(), "freeflowUserTask");
         wfUserTask.setName(name);
         ListdecisionOptions = initWFUserTaskDecisionOptions();
         wfUserTask.setDecisionOptions(decisionOptions);
         return wfUserTask;
}


审批节点的创建如下:


private WFAuditTask initWFAuditTask(WFProcess wfProcess, String id) {
         WFAuditTask wfAuditTask = new WFAuditTask(wfProcess);
         LocaleString name = new LocaleString();
         name.put(Lang.zh_CN.name(), ResManager.loadKDString("自由流审批节点", "FreeFlowPlugin_13", WF_UNITTEST));
         name.put(Lang.zh_TW.name(), ResManager.loadKDString("自由流审批节点", "FreeFlowPlugin_13", WF_UNITTEST));
         name.put(Lang.en_US.name(), "freeflowAuditTask");
         wfAuditTask.setName(name);
         //协办
         wfAuditTask.setAllowCoordinate(true);
         //转交
         wfAuditTask.setAllowTransfer(true);
         //加签
         wfAuditTask.setCountersigned(true);
         //参与人
         WFParticipantModel participantModel = new WFParticipantModel();
         participantModel.getParticipant().add(getParticipant1());
         participantModel.getParticipant().add(getParticipant2());
         //participantModel.getParticipant().add(getParticipant3());
         //participantModel.getParticipant().add(getParticipant4());
         wfAuditTask.setParticipant(participantModel);
         //决策项
         ListrejectNodeIds = new ArrayList<>();
         if(WfUtils.isNotEmpty(id)){
                   rejectNodeIds.add(id);
         }
         ListdecisionOptions = initWFDecisionOptions(rejectNodeIds);
         wfAuditTask.setDecisionOptions(decisionOptions);
         //单据设置
         WFBillSetting billSetting = new WFBillSetting();
         billSetting.setFormKey(getView().getFormShowParameter().getFormId());
         billSetting.setMobilFormKey("anquan$");
         wfAuditTask.setBillSetting(billSetting);
         //自动审批
         WFAutoAudit wfAutoAudit = getAutoAudit(wfAuditTask.getId());
         wfAuditTask.setAutoAudit(wfAutoAudit);
         //自动跳过
         WFConditionalRule skipCondition = initSkipCondition(wfAuditTask.getId());
         wfAuditTask.setSkipCondition(skipCondition);
         //扩展实现其他属性:比如扩展业务按钮
         MapextProps = initBtnModel();
         wfAuditTask.setExtProps(extProps);
         return wfAuditTask;
}


会审节点的创建如下:


private WFJointAuditTask initWFJointAuditTask(WFProcess wfProcess,String id1,String id2) {
         WFJointAuditTask wfJointTask = new WFJointAuditTask(wfProcess);
         LocaleString name = new LocaleString();
         name.put(Lang.zh_CN.name(), ResManager.loadKDString("自由流会审节点", "FreeFlowPlugin_10", WF_UNITTEST));
         name.put(Lang.zh_TW.name(), ResManager.loadKDString("自由流会审节点", "FreeFlowPlugin_10", WF_UNITTEST));
         name.put(Lang.en_US.name(), "freeflowWFJointAuditTask");
         wfJointTask.setName(name);
         //协办
         wfJointTask.setAllowCoordinate(true);
         //转交
         wfJointTask.setAllowTransfer(true);
         //加签
         wfJointTask.setCountersigned(true);
         //参与人
         WFParticipantModel participantModel = new WFParticipantModel();
         participantModel.getParticipant().add(getParticipant1());
         participantModel.getParticipant().add(getParticipant2());
         participantModel.getParticipant().add(getParticipant3());
         participantModel.getParticipant().add(getParticipant4());
         wfJointTask.setParticipant(participantModel);
         //决策项
         ListrejectNodeNumbers = new ArrayList<>();
         if(WfUtils.isNotEmpty(id1)){
                   rejectNodeNumbers.add(id1);
         }
         if(WfUtils.isNotEmpty(id2)){
                   rejectNodeNumbers.add(id2);
         }
         ListdecisionOptions = initWFDecisionOptions(rejectNodeNumbers);
         wfJointTask.setDecisionOptions(decisionOptions);
         //单据设置
         WFBillSetting billSetting = new WFBillSetting();
         billSetting.setMobilFormKey("anquan$");
         billSetting.setFormKey(getView().getFormShowParameter().getFormId());
         wfJointTask.setBillSetting(billSetting);
         //一票通过
         wfJointTask.setBusinessModel("passByOne");
         return wfJointTask;
}


自动节点的创建如下:


private WFAutoTask initWFAutoTask(WFProcess wfProcess) {
         WFAutoTask wfAutoTask = new WFAutoTask(wfProcess);
         LocaleString name = new LocaleString();
         name.put(Lang.zh_CN.name(), ResManager.loadKDString("自由流自动节点", "FreeFlowPlugin_11", WF_UNITTEST));
         name.put(Lang.zh_TW.name(), ResManager.loadKDString("自由流自动节点", "FreeFlowPlugin_11", WF_UNITTEST));
         name.put(Lang.en_US.name(), "freeflowWFAutoTask");
         wfAutoTask.setName(name);
         WFAutoTaskExtItf service = new WFAutoTaskExtItf();
         ListextItf = new ArrayList<>();
         JSONObject plugin1 = new JSONObject();
         plugin1.put("type", CLASS);
         plugin1.put(VALUE, "kd.bos.workflow.design.demo.FreeFlowExtItf");
         extItf.add(plugin1.toString());
         JSONObject plugin2 = new JSONObject();
         plugin2.put("type", OPERATION);
         JSONObject pluginValue = new JSONObject();
         pluginValue.put("forward_name", ResManager.loadKDString("保存", "FreeFlowPlugin_12", WF_UNITTEST));
         pluginValue.put("forward", "save");
         plugin2.put(VALUE, pluginValue);
         extItf.add(plugin2.toString());
         service.setExtItf(extItf);
         wfAutoTask.setService(service);
         return wfAutoTask;
}



其中参与人的创建有4种,如下:


//关系
private WFParticipantEntity getParticipant1() {
         WFParticipantEntity paritcipant = new WFParticipantEntity();
         paritcipant.setReferencePerson("ENTI_creator");
         paritcipant.setType("relation");
         paritcipant.setPersonRelation("self");
         paritcipant.setReportType("admin_org");
         return paritcipant;
}
//指定人
private WFParticipantEntity getParticipant2() {
         WFParticipantEntity paritcipant = new WFParticipantEntity();
         paritcipant.setType("person");
         paritcipant.setValue("3032311,101493");
         return paritcipant;
}
//角色
private WFParticipantEntity getParticipant3() {
         WFParticipantEntity paritcipant = new WFParticipantEntity();
         paritcipant.setRoleId("887560420028580864");
         paritcipant.setType("role");
         paritcipant.setValue("wyrtest");
         paritcipant.setBusinessOrgField("ENTI_creator.entryentity.dpt");
         return paritcipant;
}
//插件
private WFParticipantEntity getParticipant4() {
         WFParticipantEntity paritcipant = new WFParticipantEntity();
         paritcipant.setType("plugin");
         JSONObject plugin = new JSONObject();
         plugin.put("type", CLASS);
         plugin.put(VALUE, "kd.bos.workflow.design.demo.FreeFlowDynParticipantPlugin");
         paritcipant.setValue(plugin.toString());
         return paritcipant;
}


发起流程时,构建的自由流运行效果如下:



步骤二:流程审批中,向指定节点后插入多个节点。


在进入流程节点时,注册插件。在插件里构建自由流对象,放入流程变量中,如下图所示:



相关代码示例如下:


public class FreeFlowTestPlugin1 implements IWorkflowPlugin{
     @Override
     public void notify(AgentExecution execution) {
              WFProcess wfProcess = initWfProcess(execution);
      execution.setVariable(getFreeFlowNodeKey(execution.getCurrentFlowElement().getId()),SerializationUtils.toJsonString(wfProcess));
     }
}



运行效果如下:



4 常见问题


Q1苍穹工作流自由流程,是否提供界面化的配置功能?


A1目前标准产品不提供,有项目化的实施方案可供参考。


Q2基于苍穹工作流构建一条标准的自由流程,需要多少实施成本?


A2:熟悉苍穹工作流的技术人员,可在3个工作日内构建出一个节点不超过15个的中等复杂度流程。


5 相关链接


更多苍穹工作流自由流程相关资料,可参考如下链接:


自由流接口规范

工作流平台特性汇总

工作流常见问题汇总




#往期推荐#



#  五分钟新建流程攻略

#  让你一次看通透,流程参与人那些事

 苍穹工作流那些事 之 流程节点

#  苍穹工作流那些事 之 流程启动

 刚柔并济,流程动态配置方案详解

 苍穹工作流那些事 之 流程线

#  快速掌握流程变量的用法


更多精彩内容,“码”上了解!↓





苍穹工作流那些事 之 自由流程

企业内部在处理流程审批业务时,可能会遇到以下应用场景:无法预置工作流,在进行审批时才根据业务需要确定流程审批节点、审批人。为此,苍...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息