提交 f832715e 编写于 作者: zhouweidong's avatar zhouweidong

同步动态版工作流能力:

1、支持流程启动表单、流程辅助功能表单配置。
2、支持工作流超时配置。
3、支持流程版本启用配置。
4、优化计算待办任务处理页逻辑。
5、支持流程跳转、流程重启、流程撤回。
上级 77a4786c
...@@ -5,19 +5,18 @@ import cn.ibizlab.core.workflow.extensions.domain.FlowUser; ...@@ -5,19 +5,18 @@ import cn.ibizlab.core.workflow.extensions.domain.FlowUser;
import cn.ibizlab.core.workflow.extensions.service.WFCoreService; import cn.ibizlab.core.workflow.extensions.service.WFCoreService;
import cn.ibizlab.core.workflow.extensions.service.WFModelService; import cn.ibizlab.core.workflow.extensions.service.WFModelService;
import cn.ibizlab.util.errors.BadRequestAlertException; import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.service.RemoteService; import cn.ibizlab.util.service.RemoteService;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FormProperty; import org.flowable.bpmn.model.FormProperty;
import org.flowable.bpmn.model.UserTask; import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListener; import org.flowable.common.engine.api.delegate.event.*;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventType;
import org.flowable.common.engine.impl.event.FlowableEntityEventImpl; import org.flowable.common.engine.impl.event.FlowableEntityEventImpl;
import org.flowable.engine.TaskService; import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.event.FlowableProcessEngineEvent;
import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl; import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl;
import org.flowable.engine.delegate.event.impl.FlowableEntityWithVariablesEventImpl; import org.flowable.engine.delegate.event.impl.FlowableEntityWithVariablesEventImpl;
import org.flowable.engine.delegate.event.impl.FlowableMultiInstanceActivityEventImpl; import org.flowable.engine.delegate.event.impl.FlowableMultiInstanceActivityEventImpl;
...@@ -25,9 +24,11 @@ import org.flowable.engine.delegate.event.impl.FlowableProcessStartedEventImpl; ...@@ -25,9 +24,11 @@ import org.flowable.engine.delegate.event.impl.FlowableProcessStartedEventImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.identitylink.api.IdentityLinkType; import org.flowable.identitylink.api.IdentityLinkType;
import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntity; import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntity;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.api.Task; import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl; import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.flowable.ui.common.service.exception.BadRequestException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.expression.MapAccessor; import org.springframework.context.expression.MapAccessor;
...@@ -46,7 +47,6 @@ import java.util.*; ...@@ -46,7 +47,6 @@ import java.util.*;
@Component @Component
public class ProcessInstanceListener extends AbstractFlowableEventListener { public class ProcessInstanceListener extends AbstractFlowableEventListener {
@Autowired @Autowired
@Lazy @Lazy
private WFModelService wfModelService; private WFModelService wfModelService;
...@@ -138,7 +138,7 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener { ...@@ -138,7 +138,7 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener {
} }
} }
} }
else if (evt instanceof org.flowable.engine.delegate.event.impl.FlowableMultiInstanceActivityEventImpl){ else if (evt instanceof FlowableMultiInstanceActivityEventImpl){
try { try {
FlowableMultiInstanceActivityEventImpl event = (FlowableMultiInstanceActivityEventImpl) evt; FlowableMultiInstanceActivityEventImpl event = (FlowableMultiInstanceActivityEventImpl) evt;
// 多实例(会签) // 多实例(会签)
...@@ -319,7 +319,6 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener { ...@@ -319,7 +319,6 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener {
String token=curUser.getToken(); String token=curUser.getToken();
remoteService.getClient(cloudServiceid).put(entity + "/" + businessKey, token,callbackArg); remoteService.getClient(cloudServiceid).put(entity + "/" + businessKey, token,callbackArg);
} }
System.out.println("流程结束");
} }
} }
...@@ -395,6 +394,52 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener { ...@@ -395,6 +394,52 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener {
} }
} }
} }
//超时处理
else if (evt instanceof FlowableEngineEntityEvent && FlowableEngineEventType.TIMER_FIRED == evt.getType()) {
FlowableEngineEntityEvent event = (FlowableEngineEntityEvent) evt;
if(event.getEntity() == null || !(event.getEntity() instanceof JobEntity)){
throw new BadRequestException("执行工作流超时发生错误,超时作业参数格式不正确");
}
JobEntity jobEntity = (JobEntity) event.getEntity();
String strTenantId = jobEntity.getTenantId();
if(StringUtils.isEmpty(strTenantId)){
throw new BadRequestException(String.format("执行超时作业[%s]发生异常,超时作业未配置租户标识",jobEntity.getId()));
}
DelegateExecution delegateExecution = getDelegateExecution(event, false);
Object systemId = delegateExecution.getVariable("system");
if(ObjectUtils.isEmpty(systemId)){
throw new BadRequestException("执行超时作业[%s]发生异常,未能从流程实例变量中获取系统标识",jobEntity.getId());
}
//构造超时用户身份
AuthenticationUser user = AuthenticationUser.setAuthenticationUser("SYSTEM","内置用户");
user.setSrfsystemid(systemId.toString());
user.setSrfdcid(strTenantId);
}
}
/**
* 获取流程执行器
* @param evt
* @param bTryMode
* @return
*/
protected DelegateExecution getDelegateExecution(FlowableEvent evt, boolean bTryMode) {
DelegateExecution delegateExecution = null;
if (evt instanceof FlowableProcessEngineEvent) {
delegateExecution = ((FlowableProcessEngineEvent) evt).getExecution();
if (delegateExecution != null) {
return delegateExecution;
}
}
if(bTryMode) {
return null;
}
throw new BadRequestException(String.format("上下文执行对象无效"));
} }
@Override @Override
...@@ -402,5 +447,4 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener { ...@@ -402,5 +447,4 @@ public class ProcessInstanceListener extends AbstractFlowableEventListener {
return true; return true;
} }
} }
\ No newline at end of file
...@@ -35,6 +35,7 @@ import org.flowable.engine.history.HistoricProcessInstance; ...@@ -35,6 +35,7 @@ import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.ProcessInstanceHistoryLog; import org.flowable.engine.history.ProcessInstanceHistoryLog;
import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentBuilder; import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment; import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLink; import org.flowable.identitylink.api.IdentityLink;
...@@ -45,6 +46,7 @@ import org.flowable.task.api.history.HistoricTaskInstance; ...@@ -45,6 +46,7 @@ import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity; import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.ui.common.security.SecurityUtils; import org.flowable.ui.common.security.SecurityUtils;
import org.flowable.ui.common.service.exception.BadRequestException;
import org.flowable.ui.modeler.domain.AbstractModel; import org.flowable.ui.modeler.domain.AbstractModel;
import org.flowable.ui.modeler.domain.AppModelDefinition; import org.flowable.ui.modeler.domain.AppModelDefinition;
import org.flowable.ui.modeler.domain.Model; import org.flowable.ui.modeler.domain.Model;
...@@ -54,6 +56,7 @@ import org.flowable.ui.modeler.model.ModelKeyRepresentation; ...@@ -54,6 +56,7 @@ import org.flowable.ui.modeler.model.ModelKeyRepresentation;
import org.flowable.ui.modeler.model.ModelRepresentation; import org.flowable.ui.modeler.model.ModelRepresentation;
import org.flowable.ui.modeler.serviceapi.AppDefinitionService; import org.flowable.ui.modeler.serviceapi.AppDefinitionService;
import org.flowable.ui.modeler.serviceapi.ModelService; import org.flowable.ui.modeler.serviceapi.ModelService;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.expression.MapAccessor; import org.springframework.context.expression.MapAccessor;
...@@ -87,7 +90,6 @@ import java.util.stream.Collectors; ...@@ -87,7 +90,6 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
public class WFCoreService public class WFCoreService
{ {
@Autowired @Autowired
private RepositoryService repositoryService; private RepositoryService repositoryService;
...@@ -137,6 +139,11 @@ public class WFCoreService ...@@ -137,6 +139,11 @@ public class WFCoreService
private final ExpressionParser parser = new SpelExpressionParser(); private final ExpressionParser parser = new SpelExpressionParser();
/**
* 流程辅助功能移动端表单配置
*/
public static List<ProcFunction> ProcFuncFormParams = new ArrayList(Arrays.asList(ProcFunction.ADDSTEPBEFORE,ProcFunction.ADDSTEPAFTER , ProcFunction.REASSIGN));
private AuthenticationContext createAuthenticationContext() private AuthenticationContext createAuthenticationContext()
{ {
UserIdAuthenticationContext context=new UserIdAuthenticationContext(); UserIdAuthenticationContext context=new UserIdAuthenticationContext();
...@@ -210,10 +217,63 @@ public class WFCoreService ...@@ -210,10 +217,63 @@ public class WFCoreService
return StringUtils.isEmpty(dynaModelId)? new ArrayList<>() : wfModelService.getDynamicWorkflow(dynaModelId,system,entity); return StringUtils.isEmpty(dynaModelId)? new ArrayList<>() : wfModelService.getDynamicWorkflow(dynaModelId,system,entity);
} }
public List<WFProcessDefinition> getWorkflow(String system,String appname,String entity) { /**
* 获取流程定义
* @param system
* @param appname
* @param entity
* @return
*/
public List<WFProcessDefinition> getWorkflow2(String system,String appname,String entity) {
return wfModelService.getWorkflow(system,entity); return wfModelService.getWorkflow(system,entity);
} }
/**
* 获取流程定义(含启动表单等配置)
* @param system
* @param appname
* @param entity
* @return
*/
public List<WFProcessDefinition> getWorkflow(String system,String appname,String entity) {
List<WFProcessDefinition> processDefinitions = getWorkflow2(system, appname, entity);
//填充流程启动表单
processDefinitions.forEach(processDefinition ->{
String processDefinitionKey = processDefinition.getDefinitionkey();
if(StringUtils.isEmpty(processDefinitionKey)){
return;
}
List<ProcessDefinition> definitionList = repositoryService.createProcessDefinitionQuery().
processDefinitionKey(processDefinitionKey).
orderByProcessDefinitionVersion()
.desc().list();
if(ObjectUtils.isEmpty(definitionList)){
return;
}
ProcessDefinition lastProcessDefinition = definitionList.get(0);
repositoryService.getBpmnModel(lastProcessDefinition.getId()).getMainProcess().getFlowElements().forEach(element ->
{
if (element instanceof StartEvent)
{
Map<String,String> wfStartFormParams = getAllParam(element , "form");
if(!ObjectUtils.isEmpty(wfStartFormParams))
{
for(Map.Entry<String,String> entry: wfStartFormParams.entrySet()){
processDefinition.set(entry.getKey(),entry.getValue());
}
}
}
});
});
return processDefinitions;
}
public List<String> getWorkflowKey(String system,String appname,String entity) { public List<String> getWorkflowKey(String system,String appname,String entity) {
List<String> definitionKeys=new ArrayList<>(); List<String> definitionKeys=new ArrayList<>();
for(WFProcessDefinition wfdef:wfModelService.getWorkflow(system,entity)) for(WFProcessDefinition wfdef:wfModelService.getWorkflow(system,entity))
...@@ -556,7 +616,7 @@ public class WFCoreService ...@@ -556,7 +616,7 @@ public class WFCoreService
Integer version=1; Integer version=1;
String processDefinitionKey=instance.getProcessdefinitionkey(); String processDefinitionKey=instance.getProcessdefinitionkey();
if(StringUtils.isEmpty(processDefinitionKey)){ if(StringUtils.isEmpty(processDefinitionKey)){
List<WFProcessDefinition> definitions=this.getWorkflow(system,appname,entity); List<WFProcessDefinition> definitions=this.getWorkflow2(system,appname,entity);
if(definitions.size()==0) if(definitions.size()==0)
throw new BadRequestAlertException("未找到对应的工作流配置",entity,businessKey); throw new BadRequestAlertException("未找到对应的工作流配置",entity,businessKey);
processDefinitionKey=definitions.get(0).getDefinitionkey(); processDefinitionKey=definitions.get(0).getDefinitionkey();
...@@ -597,58 +657,134 @@ public class WFCoreService ...@@ -597,58 +657,134 @@ public class WFCoreService
return instance; return instance;
} }
public List<WFTaskWay> getWFLink(String system,String appname, public List<WFTaskWay> getWFLink(String system, String appname,String entity, String businessKey, String taskDefinitionKey) {
String entity, String businessKey,String taskDefinitionKey) {
List<WFTaskWay> taskWays=new ArrayList<>(); List<WFTaskWay> taskWays = new ArrayList<>();
String processInstanceBusinessKey=system+":"+entity+":k-"+businessKey; String processInstanceBusinessKey = system + ":" + entity + ":k-" + businessKey;
String userId=AuthenticationUser.getAuthenticationUser().getUserid(); String userId = AuthenticationUser.getAuthenticationUser().getUserid();
if(StringUtils.isEmpty(userId)) if (StringUtils.isEmpty(userId))
return taskWays; return taskWays;
TaskQuery query=taskService.createTaskQuery().taskCandidateOrAssigned(userId).processInstanceBusinessKey(processInstanceBusinessKey);
if(!StringUtils.isEmpty(taskDefinitionKey)) TaskQuery query = taskService.createTaskQuery().taskCandidateOrAssigned(userId).processInstanceBusinessKey(processInstanceBusinessKey);
if (!StringUtils.isEmpty(taskDefinitionKey))
query.taskDefinitionKey(taskDefinitionKey); query.taskDefinitionKey(taskDefinitionKey);
List<Task> list=query.orderByTaskCreateTime().desc().listPage(0,1);
if(list.size()==0) List<Task> list = query.orderByTaskCreateTime().desc().listPage(0, 1);
if (list.size() == 0)
return taskWays; return taskWays;
Task task=list.get(0);
if((!StringUtils.isEmpty(task.getProcessDefinitionId()))&&(!StringUtils.isEmpty(task.getTaskDefinitionKey()))) { Task task = list.get(0);
if ((!StringUtils.isEmpty(task.getProcessDefinitionId())) && (!StringUtils.isEmpty(task.getTaskDefinitionKey()))) {
UserTask userTask = wfModelService.getModelStepById(task.getProcessDefinitionId()).get(task.getTaskDefinitionKey()); UserTask userTask = wfModelService.getModelStepById(task.getProcessDefinitionId()).get(task.getTaskDefinitionKey());
//设置流程表单 //设置流程表单
setProcessForm(userTask); setProcessForm(userTask);
if(userTask!=null&&userTask.getOutgoingFlows()!=null) {
if (userTask != null && userTask.getOutgoingFlows() != null) {
//加签逻辑 //加签逻辑
String procFuncs = getParam(userTask,"form","procfunc"); String procFuncs = getParam(userTask, "form", "procfunc");
if(DelegationState.PENDING == task.getDelegationState() && userId.equals(task.getAssignee()) if (DelegationState.PENDING == task.getDelegationState() && userId.equals(task.getAssignee())&& !StringUtils.isEmpty(procFuncs) && procFuncs.contains(ProcFunction.ADDSTEPBEFORE.value))
&& !StringUtils.isEmpty(procFuncs) && procFuncs.contains(ProcFunction.ADDSTEPBEFORE.value)){ {
WFTaskWay way = getFuncWay(task,ProcFunction.FINISH.value); WFTaskWay taskWay = new WFTaskWay();
if(way!=null) taskWay.setTaskid(task.getId());
taskWays.add(way); taskWay.setTaskdefinitionkey(task.getTaskDefinitionKey());
taskWay.set("type", ProcFunction.FINISH.value);
taskWay.setSequenceflowname(ProcFunction.FINISH.text);
setProFuncFormParams(taskWay, userTask);
taskWays.add(taskWay);
return taskWays; return taskWays;
} }
//流程辅助功能
List<WFTaskWay> functions = getProcessFunc(task,userTask); //流程交互连接
if (functions.size() > 0) { for (SequenceFlow sequenceFlow : userTask.getOutgoingFlows()) {
taskWays.addAll(functions); WFTaskWay way = new WFTaskWay();
}
for(SequenceFlow sequenceFlow:userTask.getOutgoingFlows()) {
WFTaskWay way=new WFTaskWay();
way.setSequenceflowid(sequenceFlow.getId()); way.setSequenceflowid(sequenceFlow.getId());
way.setSequenceflowname(sequenceFlow.getName()); way.setSequenceflowname(sequenceFlow.getName());
if(task.getProcessDefinitionId().indexOf(":")>0) if (task.getProcessDefinitionId().indexOf(":") > 0)
way.setProcessdefinitionkey(task.getProcessDefinitionId().split(":")[0]); way.setProcessdefinitionkey(task.getProcessDefinitionId().split(":")[0]);
way.setTaskid(task.getId()); way.setTaskid(task.getId());
way.setProcessinstanceid(task.getProcessInstanceId()); way.setProcessinstanceid(task.getProcessInstanceId());
way.setTaskdefinitionkey(task.getTaskDefinitionKey()); way.setTaskdefinitionkey(task.getTaskDefinitionKey());
way.setProcessinstancebusinesskey(processInstanceBusinessKey); way.setProcessinstancebusinesskey(processInstanceBusinessKey);
//设置流程交互表单 //设置流程交互表单
setTaskWayForm(sequenceFlow,way); setTaskWayForm(sequenceFlow, way);
taskWays.add(way); taskWays.add(way);
} }
//流程辅助功能
if (!StringUtils.isEmpty(procFuncs)) {
for (String strProcFunc : procFuncs.split(";")) {
if(!StringUtils.isEmpty(strProcFunc)){
ProcFunction procFunction = ProcFunction.valueOf(strProcFunc.toUpperCase());
if (procFunction == null) {
throw new BadRequestException(String.format("获取流程辅助功能[%s]配置失败",strProcFunc));
}
WFTaskWay taskWay = new WFTaskWay();
taskWay.setTaskid(task.getId());
taskWay.setTaskdefinitionkey(task.getTaskDefinitionKey());
taskWay.set("type", procFunction.value);
taskWay.setSequenceflowname(procFunction.text);
setProFuncFormParams(taskWay, userTask);
taskWays.add(taskWay);
}
}
}
} }
} }
return taskWays; return taskWays;
} }
/**
* 设置流程辅助功能表单
* @param way
* @param userTask
*/
protected void setProFuncFormParams(WFTaskWay way, UserTask userTask) {
Object profuncType = way.get("type");
if(ObjectUtils.isEmpty(profuncType)){
throw new BadRequestException("未能获取辅助功能类型");
}
ProcFunction procFunction = ProcFunction.valueOf(profuncType.toString().toUpperCase());
if (procFunction == null) {
throw new BadRequestException(String.format("获取流程辅助功能[%1$s]配置失败",profuncType.toString()));
}
Map<String, String> userTaskParams = getAllParam(userTask, "form");
//尝试获取流程表单配置
if(ProcFuncFormParams.contains(procFunction)){
int index = ProcFuncFormParams.indexOf(procFunction);
String strIndex = index == 0 ? "" : String.valueOf(index+1);
String webFormId = String.format("process-util%1$sform",strIndex);
String webFormName = String.format("process-util%1$sformname",strIndex);
String mobFormId = String.format("process-mobutil%1$sform",strIndex);
String mobFormName = String.format("process-mobutil%1$sformname",strIndex);
if(userTaskParams.containsKey(webFormId))
way.set("sequenceFlowForm",userTaskParams.get(webFormId));
if(userTaskParams.containsKey(webFormName)){
way.set("sequenceFlowFormName",userTaskParams.get(webFormName));
way.setSequenceflowname(webFormName);
}
if(userTaskParams.containsKey(mobFormId))
way.set("sequenceFlowMobForm",userTaskParams.get(mobFormId));
if(userTaskParams.containsKey(mobFormName)) {
way.set("sequenceFlowMobFormName", userTaskParams.get(mobFormName));
way.setSequenceflowname(mobFormName);
}
}
}
public List<WFTaskWay> getTaskLink(String system,String appname, String entity, String businessKey,String taskId) { public List<WFTaskWay> getTaskLink(String system,String appname, String entity, String businessKey,String taskId) {
List<WFTaskWay> taskWays=new ArrayList<>(); List<WFTaskWay> taskWays=new ArrayList<>();
String processInstanceBusinessKey=system+":"+entity+":k-"+businessKey; String processInstanceBusinessKey=system+":"+entity+":k-"+businessKey;
...@@ -714,7 +850,7 @@ public class WFCoreService ...@@ -714,7 +850,7 @@ public class WFCoreService
ProcFunction function = ProcFunction.valueOf(funcType.toUpperCase()); ProcFunction function = ProcFunction.valueOf(funcType.toUpperCase());
if(function!=null){ if(function!=null){
if(function == ProcFunction.ADDSTEPAFTER){ if(function == ProcFunction.ADDSTEPAFTER){
function = ProcFunction.TRANSFER; function = ProcFunction.REASSIGN;
} }
way = new WFTaskWay(); way = new WFTaskWay();
way.set("type",function.value); way.set("type",function.value);
...@@ -1041,6 +1177,7 @@ public class WFCoreService ...@@ -1041,6 +1177,7 @@ public class WFCoreService
String bookings=""; String bookings="";
String refgroups=""; String refgroups="";
String dynainstid = getDynainstId(); String dynainstid = getDynainstId();
int isValid = 1;
if(!curProcess.getExtensionElements().containsKey("field")) if(!curProcess.getExtensionElements().containsKey("field"))
{ {
log.error(bpmnFileName+"没有实体订阅"); log.error(bpmnFileName+"没有实体订阅");
...@@ -1056,6 +1193,9 @@ public class WFCoreService ...@@ -1056,6 +1193,9 @@ public class WFCoreService
bookings=field.getChildElements().get("string").get(0).getElementText(); bookings=field.getChildElements().get("string").get(0).getElementText();
if("refgroups".equals(field.getAttributes().get("name").get(0).getValue())) if("refgroups".equals(field.getAttributes().get("name").get(0).getValue()))
refgroups=field.getChildElements().get("string").get(0).getElementText(); refgroups=field.getChildElements().get("string").get(0).getElementText();
if ("isvalid".equals(field.getAttributes().get("name").get(0).getValue())) {
isValid = Integer.valueOf(field.getChildElements().get("string").get(0).getElementText());
}
if(field.getAttributes().get("name").get(0).getValue().startsWith("bookingapps_")) if(field.getAttributes().get("name").get(0).getValue().startsWith("bookingapps_"))
{ {
...@@ -1153,7 +1293,7 @@ public class WFCoreService ...@@ -1153,7 +1293,7 @@ public class WFCoreService
wfProcessDefinition.setDefinitionkey(processDefinitionKey); wfProcessDefinition.setDefinitionkey(processDefinitionKey);
wfProcessDefinition.setDeploykey(processDefinitionKey); wfProcessDefinition.setDeploykey(processDefinitionKey);
wfProcessDefinition.setPssystemid(system); wfProcessDefinition.setPssystemid(system);
wfProcessDefinition.setModelenable(1); wfProcessDefinition.setModelenable(isValid);
wfProcessDefinition.setModelversion(version); wfProcessDefinition.setModelversion(version);
wfProcessDefinition.setDefinitionname(curProcess.getName()); wfProcessDefinition.setDefinitionname(curProcess.getName());
if(bookingapps.containsKey(booking)) if(bookingapps.containsKey(booking))
...@@ -1384,7 +1524,7 @@ public class WFCoreService ...@@ -1384,7 +1524,7 @@ public class WFCoreService
public Timestamp getnow() public Timestamp getnow()
{ {
return new Timestamp(new java.util.Date().getTime()); return new Timestamp(new Date().getTime());
} }
public boolean test(Object finalObject,String option,Object exp) public boolean test(Object finalObject,String option,Object exp)
...@@ -1608,7 +1748,7 @@ public class WFCoreService ...@@ -1608,7 +1748,7 @@ public class WFCoreService
* @param taskId * @param taskId
* @param taskWay * @param taskWay
*/ */
public boolean afterSign(String system,String appname, public boolean reassign(String system,String appname,
String entity,String businessKey,String taskId,WFTaskWay taskWay){ String entity,String businessKey,String taskId,WFTaskWay taskWay){
String userId=AuthenticationUser.getAuthenticationUser().getUserid(); String userId=AuthenticationUser.getAuthenticationUser().getUserid();
if (StringUtils.isEmpty(userId)) if (StringUtils.isEmpty(userId))
...@@ -2144,4 +2284,158 @@ public class WFCoreService ...@@ -2144,4 +2284,158 @@ public class WFCoreService
} }
return businessKeys; return businessKeys;
} }
/**
* 流程撤回
* @param taskId
* @param taskWay
* @return
*/
public boolean withDraw(String taskId , WFTaskWay taskWay) {
String processInstanceId = taskWay.getProcessinstanceid();
String taskDefinitionKey = taskWay.getTaskdefinitionkey();
if(StringUtils.isEmpty(processInstanceId) || StringUtils.isEmpty(taskDefinitionKey)){
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
if(historicTaskInstance != null){
taskDefinitionKey = historicTaskInstance.getTaskDefinitionKey();
processInstanceId = historicTaskInstance.getProcessInstanceId();
}
}
if (StringUtils.isEmpty(taskDefinitionKey)) {
log.debug("taskDefinitionKey不存在");
return false;
}
if (StringUtils.isEmpty(processInstanceId)) {
log.debug("processInstanceId不存在");
return false;
}
List<HistoricTaskInstance> history = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricTaskInstanceEndTime()
.desc()
.list();
if(ObjectUtils.isEmpty(history)){
throw new BadRequestException(String.format("未找到[%1$s]流程实例",processInstanceId));
}
HistoricTaskInstance sourceRef = history.get(0);
// 执行撤回
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(processInstanceId)
.moveActivityIdTo(taskDefinitionKey, sourceRef.getTaskDefinitionKey())
.changeState();
return true;
}
/**
* 流程跳转
* @param instance
* @return
*/
public boolean jump(WFProcessInstance instance) {
Object taskDefinitionKey = instance.get("taskdefinitionkey") ;
if(ObjectUtils.isEmpty(taskDefinitionKey)){
throw new BadRequestException("未传入目标步骤");
}
String userIds = getStringValue(instance.get("wfusers"));
if(ObjectUtils.isEmpty(userIds)){
throw new BadRequestException("未传入流程步骤用户");
}
UserTask userTask = wfModelService.getModelStepByKey(instance.getProcessdefinitionkey()).get(taskDefinitionKey);
if(ObjectUtils.isEmpty(userTask)){
throw new BadRequestException("未能获取目标步骤信息");
}
Map activeData = new LinkedHashMap();
activeData.put("srfwfpredefinedusers",userIds);
// 查询跳转下所有同节点实例,执行跳转
List<String> executionIds = new ArrayList<>();
runtimeService.createExecutionQuery().parentId(instance.getId()).list().forEach(item ->{
executionIds.add(item.getId());
});
if(ObjectUtils.isEmpty(executionIds)){
throw new BadRequestException("未能获取当前流程实例的执行器信息");
}
runtimeService.createChangeActivityStateBuilder().
processVariable("activedata",activeData).
moveExecutionsToSingleActivityId(executionIds, userTask.getId()).
changeState();
return true;
}
/**
* 重启流程
* @param system
* @param entity
* @param businessKey
* @param instance
* @return
*/
public boolean restart(String system, String entity, String businessKey, WFProcessInstance instance) {
String processInstanceId = instance.getId();
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if(processInstance == null){
throw new BadRequestException("未查询到流程实例信息");
}
Object activeData = null;
if(!ObjectUtils.isEmpty(processInstance.getEndTime())) { //流程中
activeData = runtimeService.getVariable(processInstanceId, "activedata");
}
else{
HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName("activedata").singleResult();
if(variableInstance != null){
activeData = variableInstance.getValue();
}
}
if(activeData == null || !(activeData instanceof Map)){
throw new BadRequestException("未能获取流程上下文参数");
}
Object appName = ((Map)activeData).get("appname");
if(StringUtils.isEmpty(appName)){
throw new BadRequestException("未能获取当前实例应用标识");
}
if(ObjectUtils.isEmpty(processInstance.getEndTime())){ //删除流程中的数据
runtimeService.deleteProcessInstance(processInstanceId,"重启流程");
}
instance.set("activedata",activeData);
wfStart(system,appName.toString(),entity,businessKey,instance);
return true;
}
public boolean sendCopy(String taskId, WFTaskWay taskWay) {
throw new BadRequestException("暂未实现");
}
/**
* 字符串处理
* @param value
* @return
*/
protected String getStringValue(Object value){
if(ObjectUtils.isEmpty(value)){
return null;
}
return value.toString();
}
} }
...@@ -297,7 +297,7 @@ public class WFCoreResource ...@@ -297,7 +297,7 @@ public class WFCoreResource
if(StringUtils.isEmpty(path)) if(StringUtils.isEmpty(path))
throw new BadRequestAlertException("未找到待办任务处理页","",""); throw new BadRequestAlertException("未找到待办任务处理页","","");
return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY).header(HttpHeaders.LOCATION, path).build(); return ResponseEntity.status(HttpStatus.OK).body(path);
} }
@RequestMapping(method = RequestMethod.POST, value = "/deploybpmn") @RequestMapping(method = RequestMethod.POST, value = "/deploybpmn")
...@@ -305,6 +305,27 @@ public class WFCoreResource ...@@ -305,6 +305,27 @@ public class WFCoreResource
return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.wfdeploybpmns(bpmnfiles)); return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.wfdeploybpmns(bpmnfiles));
} }
@ApiOperation(value = "withDraw", tags = {"withDraw" }, notes = "根据实例将流程撤回前一步")
@RequestMapping(method = RequestMethod.POST, value = "/{system}-app-{appname}/{entity}/{businessKey}/tasks/{taskId}/withdraw")
public ResponseEntity<Boolean> withDraw(@PathVariable("taskId") String taskId ,@RequestBody WFTaskWay taskWay){
return ResponseEntity.ok(wfCoreService.withDraw(taskId , taskWay));
}
@ApiOperation(value = "dataAccessMode", tags = {"流程跳转" }, notes = "流程跳转")
@RequestMapping(method = RequestMethod.POST, value = "/{system}-{entity}/{businessKey}/process-instances/{processInstanceId}/jump")
public ResponseEntity<Boolean> jump(@PathVariable("processInstanceId") String processInstanceId, @RequestBody WFProcessInstance instance) {
instance.setId(processInstanceId);
return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.jump(instance));
}
@ApiOperation(value = "restartwf", tags = {"重启流程" }, notes = "重启流程")
@RequestMapping(method = RequestMethod.POST, value = "/{system}-{entity}/{businessKey}/process-instances/{processInstanceId}/restart")
public ResponseEntity<Boolean> restart(@PathVariable("system") String system, @PathVariable("entity") String entity, @PathVariable("businessKey") String businessKey,
@PathVariable("processInstanceId") String processInstanceId, @RequestBody WFProcessInstance instance) {
instance.setId(processInstanceId);
return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.restart(system,entity,businessKey,instance));
}
@ApiOperation(value = "前加签任务", tags = {"工作流前加签任务" } ,notes = "前加签任务") @ApiOperation(value = "前加签任务", tags = {"工作流前加签任务" } ,notes = "前加签任务")
@RequestMapping(method = RequestMethod.POST, value = "/{system}-app-{appname}/{entity}/{businessKey}/tasks/{taskId}/beforesign") @RequestMapping(method = RequestMethod.POST, value = "/{system}-app-{appname}/{entity}/{businessKey}/tasks/{taskId}/beforesign")
public ResponseEntity<Boolean> beforeSign(@PathVariable("system") String system,@PathVariable("appname") String appname, public ResponseEntity<Boolean> beforeSign(@PathVariable("system") String system,@PathVariable("appname") String appname,
...@@ -314,15 +335,22 @@ public class WFCoreResource ...@@ -314,15 +335,22 @@ public class WFCoreResource
return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.beforeSign(system,appname,entity,businessKey,taskId,taskWay)); return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.beforeSign(system,appname,entity,businessKey,taskId,taskWay));
} }
@ApiOperation(value = "后加签任务", tags = {"工作流后加签任务" }, notes = "前加签任务") @ApiOperation(value = "转办任务", tags = {"工作流转办任务" }, notes = "转办任务")
@RequestMapping(method = RequestMethod.POST, value = "/{system}-app-{appname}/{entity}/{businessKey}/tasks/{taskId}/transfer") @RequestMapping(method = RequestMethod.POST, value = "/{system}-app-{appname}/{entity}/{businessKey}/tasks/{taskId}/transfer")
public ResponseEntity<Boolean> afterSign(@PathVariable("system") String system,@PathVariable("appname") String appname, public ResponseEntity<Boolean> reassign(@PathVariable("system") String system,@PathVariable("appname") String appname,
@PathVariable("entity") String entity, @PathVariable("entity") String entity,
@PathVariable("businessKey") String businessKey,@PathVariable("taskId") String taskId, @PathVariable("businessKey") String businessKey,@PathVariable("taskId") String taskId,
@RequestBody WFTaskWay taskWay) { @RequestBody WFTaskWay taskWay) {
return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.afterSign(system,appname,entity,businessKey,taskId,taskWay)); return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.reassign(system,appname,entity,businessKey,taskId,taskWay));
}
@ApiOperation(value = "将文件抄送给选定人员", tags = {"将文件抄送给选定人员" } ,notes = "将文件抄送给选定人员")
@RequestMapping(method = RequestMethod.POST, value = "/{system}-app-{appname}/{entity}/{businessKey}/tasks/{taskId}/sendcopy")
public ResponseEntity<Boolean> sendCopy(@PathVariable("taskId") String taskId,@RequestBody WFTaskWay taskWay) {
return ResponseEntity.status(HttpStatus.OK).body(wfCoreService.sendCopy(taskId,taskWay));
} }
/** /**
* 将流程表单设置到响应头中 * 将流程表单设置到响应头中
*/ */
......
...@@ -6,13 +6,17 @@ package cn.ibizlab.util.enums; ...@@ -6,13 +6,17 @@ package cn.ibizlab.util.enums;
public enum ProcFunction { public enum ProcFunction {
SENDBACK("sendback","退回"), SENDBACK("sendback","退回"),
WITHDRAW("withdraw","撤回"),
SUPPLYINFO("supplyinfo","补充信息"), SUPPLYINFO("supplyinfo","补充信息"),
ADDSTEPBEFORE("addstepbefore","前加签"), ADDSTEPBEFORE("addstepbefore","前加签"),
ADDSTEPAFTER("addstepafter","后加签"), ADDSTEPAFTER("addstepafter","后加签"),
TAKEADVICE("takeadvice","征求意见"), TAKEADVICE("takeadvice","征求意见"),
SENDCOPY("sendcopy","抄送"), SENDCOPY("sendcopy","抄送"),
TRANSFER("transfer","转办"), REASSIGN("reassign","转办"),
FINISH("finish","完成"); FINISH("finish","完成"),
JUMP("jump","跳转"),
TIMEOUT("timeout","超时"),
RESTART("restart","重启流程");
ProcFunction(String value, String text) { ProcFunction(String value, String text) {
this.value = value; this.value = value;
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册