最进根据公司需求,需要使用工作流工具实现一套复杂的审核流程,
审批业务流程图如下:
根据业务流程图绘制的BPMN图:
主要实现思想:
1.以vote变量为投票标识 1为通过,2为驳回
2.使用脚本任务作为业务相关的操作(审核楼层你以外的业务操作,例如当前两部驳回后会修改采购清单的业务状态为编制中)
3.通过监听器的方式实现消息的推送(例如审核通过发送站内信和短信通知下一步人员进行操作)
4.其中有一步是平台干涉的(配货定价这一步,此处是非审核人的操作,此时审核任务需挂起等待平台配货),此处选择使用接收 任务,当配货完成,调用任务的signal()激活任务使之继续向下流转
bpmn图对应的bpmn20.xml代码(可直接将代码保存为bpmn后缀然后查看对应bpmn图):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1516329136940" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema"> <process id="auditListPurchase" isClosed="false" isExecutable="true" name="auditListPurchase" processType="None"> <startEvent id="auditListPurchaseStartEvent" name="开始"/> <endEvent id="auditListPurchaseProcessEndEvent" name="结束"/> <userTask activiti:assignee="${startUser}" activiti:exclusive="true" id="startUser" name="提交采购需求"> <extensionElements> <activiti:taskListener class="com.sjgtw.business.service.workflow.ApprovalUserTaskListener" event="complete"> <activiti:field name="passSendFlag"> <activiti:string>0</activiti:string> </activiti:field> </activiti:taskListener> </extensionElements> </userTask> <userTask activiti:assignee="${auditPM}" activiti:exclusive="true" id="auditPM" name="项目经理审核"> <extensionElements> <activiti:taskListener class="com.sjgtw.business.service.workflow.ApprovalUserTaskListener" event="complete"> <activiti:field name="passSendFlag"> <activiti:string>1</activiti:string> </activiti:field> </activiti:taskListener> </extensionElements> </userTask> <userTask activiti:assignee="${auditMaterial}" activiti:exclusive="true" id="auditMaterial" name="物设部审核"> <extensionElements> <activiti:taskListener class="com.sjgtw.business.service.workflow.ApprovalUserTaskListener" event="complete"> <activiti:field name="passSendFlag"> <activiti:string>1</activiti:string> </activiti:field> </activiti:taskListener> </extensionElements> </userTask> <receiveTask activiti:exclusive="true" id="distributionPricing" name="配货定价"/> <userTask activiti:assignee="${auditMaterial1}" activiti:exclusive="true" id="auditMaterial1" name="物设部负责人审核"> <extensionElements> <activiti:taskListener class="com.sjgtw.business.service.workflow.ApprovalUserTaskListener" event="complete"> <activiti:field name="passSendFlag"> <activiti:string>1</activiti:string> </activiti:field> </activiti:taskListener> </extensionElements> </userTask> <userTask activiti:assignee="${auditMaterialManager}" activiti:exclusive="true" id="auditMaterialManager" name="物设部部长审核"> <extensionElements> <activiti:taskListener class="com.sjgtw.business.service.workflow.ApprovalUserTaskListener" event="complete"> <activiti:field name="passSendFlag"> <activiti:string>1</activiti:string> </activiti:field> </activiti:taskListener> </extensionElements> </userTask> <userTask activiti:assignee="${auditMaterialMajor}" activiti:exclusive="true" id="auditMaterialMajor" name="分管副总审核"> <extensionElements> <activiti:taskListener class="com.sjgtw.business.service.workflow.ApprovalUserTaskListener" event="complete"> <activiti:field name="passSendFlag"> <activiti:string>1</activiti:string> </activiti:field> </activiti:taskListener> </extensionElements> </userTask> <sequenceFlow id="_18" name="通过" sourceRef="startUser" targetRef="auditPM"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 1}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_19" name="通过" sourceRef="auditPM" targetRef="auditMaterial"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 1}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_20" sourceRef="distributionPricing" targetRef="auditMaterial1"/> <sequenceFlow id="_21" name="通过" sourceRef="auditMaterial1" targetRef="auditMaterialManager"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 1}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_22" name="通过" sourceRef="auditMaterialManager" targetRef="auditMaterialMajor"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 1}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_13" sourceRef="auditListPurchaseStartEvent" targetRef="startUser"/> <scriptTask activiti:exclusive="true" id="updateListPurchase2Edit" name="更新状态为编制中" scriptFormat="groovy"> <script><![CDATA[def listPurchaseService=com.gt.core.common.SpringContextUtil.getBean("listPurchaseServiceImpl"); java.lang.Long businessId = java.lang.Long.valueOf(businessId); java.lang.String userId = userId.toString(); listPurchaseService.updateListPurchaseState(businessId, 3,com.gt.util.common.DateUtils.getDateStr(new Date()), userId); ]]></script> </scriptTask> <sequenceFlow id="_17" name="驳回" sourceRef="auditMaterial" targetRef="updateListPurchase2Edit"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 0}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_23" name="驳回" sourceRef="auditPM" targetRef="updateListPurchase2Edit"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 0}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_24" sourceRef="updateListPurchase2Edit" targetRef="startUser"/> <scriptTask activiti:exclusive="true" id="updateListPurchase2Distribution" name="更新状态为配货" scriptFormat="groovy"> <extensionElements> <activiti:executionListener class="com.sjgtw.business.service.workflow.PriceExecutionListener" event="start"> <activiti:field name="orderFlag"> <activiti:string>0</activiti:string> </activiti:field> </activiti:executionListener> </extensionElements> <script><![CDATA[def listPurchaseService=com.gt.core.common.SpringContextUtil.getBean("listPurchaseServiceImpl"); java.lang.Long businessId = java.lang.Long.valueOf(businessId); java.lang.String userId = userId.toString(); listPurchaseService.updateListPurchaseState(businessId, 0,com.gt.util.common.DateUtils.getDateStr(new Date()), userId); ]]></script> </scriptTask> <sequenceFlow id="_27" name="通过" sourceRef="auditMaterial" targetRef="updateListPurchase2Distribution"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 1}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_28" name="驳回" sourceRef="auditMaterial1" targetRef="updateListPurchase2Distribution"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 0}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_29" name="驳回" sourceRef="auditMaterialManager" targetRef="updateListPurchase2Distribution"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vote == 0}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_30" name="驳回" sourceRef="auditMaterialMajor" targetRef="updateListPurchase2Distribution">