
16 changed files with 681 additions and 8 deletions
@ -0,0 +1,93 @@ |
|||||
|
package com.yxt.supervise.flowable.biz.flow2; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder; |
||||
|
import com.yxt.common.base.utils.StringUtils; |
||||
|
import com.yxt.common.core.result.ResultBean; |
||||
|
import com.yxt.supervise.flowable.api.flow.UpdateFlowFieldVo; |
||||
|
import com.yxt.supervise.flowable.sqloperationsymbol.BusinessVariables; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import org.apache.tomcat.util.threads.ThreadPoolExecutor; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.*; |
||||
|
|
||||
|
/** |
||||
|
* @description: |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2023/11/28 |
||||
|
**/ |
||||
|
@RestController |
||||
|
@RequestMapping("v2/flow") |
||||
|
public class FlowRest { |
||||
|
|
||||
|
Logger log = LoggerFactory.getLogger(FlowRest.class); |
||||
|
|
||||
|
@Autowired |
||||
|
private FlowService flowService; |
||||
|
|
||||
|
@ApiOperation(value = "启动流程") |
||||
|
@PostMapping(value = "/startProcess") |
||||
|
public ResultBean<UpdateFlowFieldVo> startProcess(BusinessVariables bv) { |
||||
|
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail(); |
||||
|
//获取表单中的参数
|
||||
|
Map<String, Object> formVariables = bv.getFormVariables(); |
||||
|
formVariables = formVariables == null ? new HashMap<>() : formVariables; |
||||
|
//发起人的组织全路径
|
||||
|
String orgPath = bv.getOrgSidPath(); |
||||
|
formVariables.put("createrOrgPath", orgPath); |
||||
|
formVariables.put("businessSid", bv.getBusinessSid()); |
||||
|
//获取下一环节待办人
|
||||
|
if (StringUtils.isBlank(bv.getNextNodeUserSids())) { |
||||
|
ResultBean<String> userResultBean = flowService.getNextNodeUser(bv); |
||||
|
if(userResultBean.getSuccess()){ |
||||
|
return rb.setMsg(userResultBean.getMsg()); |
||||
|
} |
||||
|
bv.setNextNodeUserSids(userResultBean.getData()); |
||||
|
} |
||||
|
//启动流程实例
|
||||
|
ResultBean<UpdateFlowFieldVo> startResultBean = flowService.businessStartProcessInstanceById(bv); |
||||
|
return startResultBean; |
||||
|
} |
||||
|
|
||||
|
public ResultBean<UpdateFlowFieldVo> handleProsess(BusinessVariables bv) { |
||||
|
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail(); |
||||
|
ResultBean<UpdateFlowFieldVo> updateFlowFieldVoResultBean = flowService.handleProsess(bv, true); |
||||
|
//添加抄送
|
||||
|
log.info("流程返回:{}", JSONObject.toJSONString(updateFlowFieldVoResultBean)); |
||||
|
//需要判断办结后再执行 TODO
|
||||
|
if (updateFlowFieldVoResultBean.getSuccess()) { |
||||
|
log.info("流程返回:{}", JSONObject.toJSONString(updateFlowFieldVoResultBean)); |
||||
|
if ("Event_end".equals(updateFlowFieldVoResultBean.getData().getTaskDefKey())) { |
||||
|
try { |
||||
|
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() |
||||
|
.setNameFormat("demo-pool-%d").build(); |
||||
|
ExecutorService pool = new ThreadPoolExecutor(2, 100, |
||||
|
0L, TimeUnit.MILLISECONDS, |
||||
|
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); |
||||
|
|
||||
|
Future future1 = pool.submit(() -> { |
||||
|
HashMap<String, Object> map = new HashMap<>(); |
||||
|
map.put("bv", bv); |
||||
|
UpdateFlowFieldVo ufVo = updateFlowFieldVoResultBean.getData(); |
||||
|
ufVo.setTaskId(bv.getTaskId()); |
||||
|
map.put("uff", ufVo); |
||||
|
// flowService.cc(map, bv.getTaskDefKey());
|
||||
|
}); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
return rb.setMsg("抄送失败"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return updateFlowFieldVoResultBean; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,506 @@ |
|||||
|
package com.yxt.supervise.flowable.biz.flow2; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.alibaba.fastjson.JSONArray; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.yxt.common.base.utils.StringUtils; |
||||
|
import com.yxt.common.core.result.ResultBean; |
||||
|
import com.yxt.supervise.flowable.api.flow.UpdateFlowFieldVo; |
||||
|
import com.yxt.supervise.flowable.api.flowcomment.FlowComment; |
||||
|
import com.yxt.supervise.flowable.api.flowtask.LatestTaskVo; |
||||
|
import com.yxt.supervise.flowable.biz.flowtask.FlowTaskService; |
||||
|
import com.yxt.supervise.flowable.biz.process.ExpressionCmd; |
||||
|
import com.yxt.supervise.flowable.common.ProcessConstants; |
||||
|
import com.yxt.supervise.flowable.sqloperationsymbol.BusinessVariables; |
||||
|
import com.yxt.supervise.system.sysuser.SysUserFeign; |
||||
|
import com.yxt.supervise.system.sysuser.SysUserVo; |
||||
|
import com.yxt.supervise.system.sysuser.UserQuery; |
||||
|
import com.yxt.supervise.system.sysuser.UserssQuery; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.flowable.bpmn.model.*; |
||||
|
import org.flowable.common.engine.impl.identity.Authentication; |
||||
|
import org.flowable.engine.*; |
||||
|
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; |
||||
|
import org.flowable.engine.repository.ProcessDefinition; |
||||
|
import org.flowable.engine.runtime.ProcessInstance; |
||||
|
import org.flowable.task.api.DelegationState; |
||||
|
import org.flowable.task.api.Task; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* @description: |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2023/11/28 |
||||
|
**/ |
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class FlowService { |
||||
|
|
||||
|
@Autowired |
||||
|
private SysUserFeign sysUserFeign; |
||||
|
@Autowired |
||||
|
RepositoryService repositoryService; |
||||
|
@Autowired |
||||
|
ManagementService managementService; |
||||
|
@Autowired |
||||
|
RuntimeService runtimeService; |
||||
|
@Autowired |
||||
|
ProcessEngineConfigurationImpl processEngineConfiguration; |
||||
|
@Autowired |
||||
|
protected IdentityService identityService; |
||||
|
@Autowired |
||||
|
protected TaskService taskService; |
||||
|
@Autowired |
||||
|
private FlowTaskService flowTaskService; |
||||
|
|
||||
|
public ResultBean<String> getNextNodeUser(BusinessVariables bv) { |
||||
|
ResultBean<String> rb = ResultBean.fireFail(); |
||||
|
//根据业务参数取流程流转的环节 信息
|
||||
|
List<Map<String, Object>> list = (List<Map<String, Object>>) getProcessCirculationNodesByMap(bv).getData(); |
||||
|
if (list == null || list.size() < 2) { |
||||
|
return rb.setMsg("流程设计问题"); |
||||
|
} |
||||
|
//取第二个环节的配置角色
|
||||
|
Object o = list.get(1).get("candidateGroups"); |
||||
|
if (o == null) { |
||||
|
return rb.setMsg("流程设计问题"); |
||||
|
} |
||||
|
JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(o)); |
||||
|
String roleSid = jsonArray.get(0).toString(); |
||||
|
//根据组织架构、角色两个参数取相关符合条件的用户信息
|
||||
|
UserQuery userQuery = new UserQuery(); |
||||
|
userQuery.setRoleSid(roleSid); |
||||
|
userQuery.setProjectSid(bv.getProjectSid()); |
||||
|
String nextNodeUserSids_ = ""; |
||||
|
List<SysUserVo> sysUserVos = sysUserFeign.getUserByRoleAndProject(userQuery).getData(); |
||||
|
if (sysUserVos == null || sysUserVos.size() < 1) { |
||||
|
return rb.setMsg("下一环节无用户"); |
||||
|
} else { |
||||
|
StringBuilder nextNodeUserSids = new StringBuilder(); |
||||
|
for (SysUserVo su : sysUserVos) { |
||||
|
nextNodeUserSids.append(su.getSid()).append(","); |
||||
|
} |
||||
|
//符合条件的用户的sid,拼接的字符串
|
||||
|
nextNodeUserSids_ = nextNodeUserSids.toString(); |
||||
|
nextNodeUserSids_ = nextNodeUserSids_.substring(0, nextNodeUserSids_.length() - 1); |
||||
|
} |
||||
|
return rb.success().setData(nextNodeUserSids_); |
||||
|
} |
||||
|
|
||||
|
private ResultBean getProcessCirculationNodesByMap(BusinessVariables bv) { |
||||
|
ResultBean<List<Map<String, Object>>> rb = new ResultBean<List<Map<String, Object>>>(); |
||||
|
String modelId = bv.getModelId(); |
||||
|
List<FlowElement> flowElements = calApprovePath(modelId, bv.getFormVariables()); |
||||
|
List<Map<String, Object>> list = new ArrayList<>(); |
||||
|
for (FlowElement f : flowElements) { |
||||
|
Map<String, Object> map = new HashMap<>(); |
||||
|
map.put("name", f.getName()); |
||||
|
map.put("id", f.getId()); |
||||
|
String s = JSON.toJSONString(f); |
||||
|
JSONObject jsonObject = JSONObject.parseObject(s); |
||||
|
log.info("item:{}", jsonObject); |
||||
|
Object candidateGroups = jsonObject.get("candidateGroups"); |
||||
|
map.put("candidateGroups", candidateGroups); |
||||
|
list.add(map); |
||||
|
} |
||||
|
return rb.setData(list); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 1. 首先拿到BpmnModel,所有流程定义信息都可以通过BpmnModel获取;若流程尚未发起,则用modelId查询最新部署的流程定义数据; |
||||
|
* 若流程已经发起,可以通过流程实例的processDefinitionId查询流程定义的历史数据。 |
||||
|
* |
||||
|
* @param variableMap 流程变量,用于计算条件分支 |
||||
|
*/ |
||||
|
public List<FlowElement> calApprovePath(String modelId, Map<String, Object> variableMap) { |
||||
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(modelId); |
||||
|
Collection<FlowElement> flowElements = new ArrayList<>(); |
||||
|
Collection<FlowElement> flowElements2 = bpmnModel.getMainProcess().getFlowElements(); |
||||
|
flowElements.addAll(flowElements2); |
||||
|
List<FlowElement> passElements = new ArrayList<>(); |
||||
|
dueStartElement(passElements, flowElements, variableMap); |
||||
|
return passElements; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 2. 找到开始节点,通过它的目标节点,然后再不断往下找。 |
||||
|
*/ |
||||
|
private void dueStartElement(List<FlowElement> passElements, Collection<FlowElement> flowElements, Map<String, Object> variableMap) { |
||||
|
Optional<FlowElement> startElementOpt = flowElements.stream().filter(flowElement -> flowElement instanceof StartEvent).findFirst(); |
||||
|
startElementOpt.ifPresent(startElement -> { |
||||
|
flowElements.remove(startElement); |
||||
|
List<SequenceFlow> outgoingFlows = ((StartEvent) startElement).getOutgoingFlows(); |
||||
|
String targetRef = outgoingFlows.get(0).getTargetRef(); |
||||
|
// 根据ID找到FlowElement
|
||||
|
FlowElement targetElementOfStartElement = getFlowElement(flowElements, targetRef); |
||||
|
if (targetElementOfStartElement instanceof UserTask) { |
||||
|
this.getPassElementList(passElements, flowElements, targetElementOfStartElement, variableMap); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 3. 我只用到了UserTask、ExclusiveGateway、ParallelGateway,所以代码里只列举了这三种,如果用到了其他的,可以再自己补充 |
||||
|
*/ |
||||
|
private void getPassElementList(List<FlowElement> passElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) { |
||||
|
// 任务节点
|
||||
|
if (curFlowElement instanceof UserTask) { |
||||
|
this.dueUserTaskElement(passElements, flowElements, curFlowElement, variableMap); |
||||
|
return; |
||||
|
} |
||||
|
// 排他网关
|
||||
|
if (curFlowElement instanceof ExclusiveGateway) { |
||||
|
this.dueExclusiveGateway(passElements, flowElements, curFlowElement, variableMap); |
||||
|
return; |
||||
|
} |
||||
|
// 并行网关
|
||||
|
if (curFlowElement instanceof ParallelGateway) { |
||||
|
this.dueParallelGateway(passElements, flowElements, curFlowElement, variableMap); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private FlowElement getFlowElement(Collection<FlowElement> flowElements, String targetRef) { |
||||
|
return flowElements.stream().filter(flowElement -> targetRef.equals(flowElement.getId())).findFirst().orElse(null); |
||||
|
} |
||||
|
|
||||
|
private void dueUserTaskElement(List<FlowElement> passElements, Collection<FlowElement> flowElements, |
||||
|
FlowElement curFlowElement, Map<String, Object> variableMap) { |
||||
|
passElements.add(curFlowElement); |
||||
|
List<SequenceFlow> outgoingFlows = ((UserTask) curFlowElement).getOutgoingFlows(); |
||||
|
String targetRef = outgoingFlows.get(0).getTargetRef(); |
||||
|
if (outgoingFlows.size() > 1) { |
||||
|
// 找到表达式成立的sequenceFlow
|
||||
|
SequenceFlow sequenceFlow = getSequenceFlow(variableMap, outgoingFlows); |
||||
|
targetRef = sequenceFlow.getTargetRef(); |
||||
|
} |
||||
|
// 根据ID找到FlowElement
|
||||
|
FlowElement targetElement = getFlowElement(flowElements, targetRef); |
||||
|
this.getPassElementList(passElements, flowElements, targetElement, variableMap); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private void dueExclusiveGateway(List<FlowElement> passElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) { |
||||
|
// 获取符合条件的sequenceFlow的目标FlowElement
|
||||
|
List<SequenceFlow> exclusiveGatewayOutgoingFlows = ((ExclusiveGateway) curFlowElement).getOutgoingFlows(); |
||||
|
flowElements.remove(curFlowElement); |
||||
|
// 找到表达式成立的sequenceFlow
|
||||
|
SequenceFlow sequenceFlow = getSequenceFlow(variableMap, exclusiveGatewayOutgoingFlows); |
||||
|
// 根据ID找到FlowElement
|
||||
|
FlowElement targetElement = getFlowElement(flowElements, sequenceFlow.getTargetRef()); |
||||
|
this.getPassElementList(passElements, flowElements, targetElement, variableMap); |
||||
|
} |
||||
|
|
||||
|
private void dueParallelGateway(List<FlowElement> passElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) { |
||||
|
FlowElement targetElement; |
||||
|
List<SequenceFlow> parallelGatewayOutgoingFlows = ((ParallelGateway) curFlowElement).getOutgoingFlows(); |
||||
|
for (SequenceFlow sequenceFlow : parallelGatewayOutgoingFlows) { |
||||
|
targetElement = getFlowElement(flowElements, sequenceFlow.getTargetRef()); |
||||
|
this.getPassElementList(passElements, flowElements, targetElement, variableMap); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 4. 根据传入的变量,计算出表达式成立的那一条SequenceFlow |
||||
|
* |
||||
|
* @param variableMap |
||||
|
* @param outgoingFlows |
||||
|
* @return |
||||
|
*/ |
||||
|
private SequenceFlow getSequenceFlow(Map<String, Object> variableMap, List<SequenceFlow> outgoingFlows) { |
||||
|
Optional<SequenceFlow> sequenceFlowOpt = outgoingFlows.stream().filter(item -> { |
||||
|
try { |
||||
|
return this.getElValue(item.getConditionExpression(), variableMap); |
||||
|
} catch (Exception e) { |
||||
|
log.error(e.getMessage(), e); |
||||
|
return false; |
||||
|
} |
||||
|
}).findFirst(); |
||||
|
return sequenceFlowOpt.orElse(outgoingFlows.get(0)); |
||||
|
} |
||||
|
|
||||
|
private boolean getElValue(String exp, Map<String, Object> variableMap) { |
||||
|
return managementService.executeCommand(new ExpressionCmd(runtimeService, processEngineConfiguration, null, exp, variableMap)); |
||||
|
} |
||||
|
|
||||
|
public ResultBean<UpdateFlowFieldVo> businessStartProcessInstanceById(BusinessVariables bv) { |
||||
|
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail(); |
||||
|
UpdateFlowFieldVo updateFlowFieldVo = new UpdateFlowFieldVo(); |
||||
|
String procDefId = bv.getModelId(); |
||||
|
String userSid = bv.getUserSid(); |
||||
|
String nextNodeUserSids = bv.getNextNodeUserSids(); |
||||
|
Map<String, Object> variables = bv.getFormVariables(); |
||||
|
Map<String, Object> variablesSeconds = bv.getFormVariables(); |
||||
|
//根据流程定义id查询
|
||||
|
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId) |
||||
|
.latestVersion().singleResult(); |
||||
|
if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) { |
||||
|
return rb.setMsg("流程已被挂起,请先激活流程"); |
||||
|
} |
||||
|
// 设置流程发起人Id到流程中
|
||||
|
ResultBean<SysUserVo> sysUserVoResultBean = sysUserFeign.fetchBySid(userSid); |
||||
|
SysUserVo sysUser = sysUserVoResultBean.getData(); |
||||
|
identityService.setAuthenticatedUserId(sysUser.getSid()); |
||||
|
variables.put(ProcessConstants.PROCESS_INITIATOR, userSid); |
||||
|
variables.put(ProcessConstants.USER_TYPE_ASSIGNEE, userSid); |
||||
|
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables); |
||||
|
// 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题?
|
||||
|
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult(); |
||||
|
if (Objects.nonNull(task)) { |
||||
|
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.START.getType(), |
||||
|
sysUser.getName() + "发起流程申请"); |
||||
|
taskService.setAssignee(task.getId(), userSid); |
||||
|
taskService.complete(task.getId(), variables); |
||||
|
} |
||||
|
//根据流程实例的id查询最新的待办环节
|
||||
|
ResultBean<List<LatestTaskVo>> latestTasksNew = flowTaskService.getLatestTasksNew(processInstance.getId()); |
||||
|
List<LatestTaskVo> data = latestTasksNew.getData(); |
||||
|
LatestTaskVo latestTaskVo = data.get(0); |
||||
|
String id_ = latestTaskVo.getId_(); |
||||
|
String task_def_key_ = latestTaskVo.getTask_def_key_(); |
||||
|
//查询下一环节是否有转办并添加评论
|
||||
|
// nextNodeUserSids = change(nextNodeUserSids, processInstance.getProcessInstanceId());
|
||||
|
taskService.setAssignee(id_, nextNodeUserSids); |
||||
|
taskService.setVariablesLocal(id_, variables); |
||||
|
if (bv.getUserSid().equals(nextNodeUserSids)) { |
||||
|
//如果申请人与下一环节审批人相同,则自动审批
|
||||
|
bv.setModelId(procDefId); |
||||
|
bv.setInstanceId(task.getProcessInstanceId()); |
||||
|
bv.setTaskId(id_); |
||||
|
bv.setUserSid(nextNodeUserSids); |
||||
|
bv.setBusinessSid(bv.getBusinessSid()); |
||||
|
bv.setTaskDefKey(task_def_key_); |
||||
|
bv.setFormVariables(variables); |
||||
|
bv.setOrgSidPath(bv.getOrgSidPath()); |
||||
|
bv.setFormVariables(variablesSeconds); |
||||
|
bv.setComment("因与申请人相同,系统自动处理,需以下一级审批人审批意见为准!"); |
||||
|
bv.setNextNodeUserSids(""); |
||||
|
ResultBean<UpdateFlowFieldVo> updateFlowFieldVoResultBean = handleProsess(bv, false); |
||||
|
if (updateFlowFieldVoResultBean.getSuccess() && updateFlowFieldVoResultBean.getData() != null) { |
||||
|
UpdateFlowFieldVo vo = updateFlowFieldVoResultBean.getData(); |
||||
|
updateFlowFieldVo.setProcInsId(vo.getProcInsId()); |
||||
|
updateFlowFieldVo.setNodeState(vo.getNodeState()); |
||||
|
updateFlowFieldVo.setTaskId(vo.getTaskId()); |
||||
|
updateFlowFieldVo.setTaskDefKey(vo.getTaskDefKey()); |
||||
|
updateFlowFieldVo.setProcDefId(bv.getModelId()); |
||||
|
updateFlowFieldVo.setSid(bv.getBusinessSid()); |
||||
|
return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功"); |
||||
|
} |
||||
|
} |
||||
|
updateFlowFieldVo.setProcInsId(task.getProcessInstanceId()); |
||||
|
updateFlowFieldVo.setNodeState(latestTaskVo.getName_()); |
||||
|
updateFlowFieldVo.setTaskId(id_); |
||||
|
updateFlowFieldVo.setTaskDefKey(task_def_key_); |
||||
|
updateFlowFieldVo.setProcDefId(bv.getModelId()); |
||||
|
updateFlowFieldVo.setSid(bv.getBusinessSid()); |
||||
|
return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 办理 |
||||
|
* |
||||
|
* @param bv |
||||
|
* @param b |
||||
|
* @return |
||||
|
*/ |
||||
|
public ResultBean<UpdateFlowFieldVo> handleProsess(BusinessVariables bv, boolean b) { |
||||
|
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail(); |
||||
|
UpdateFlowFieldVo vo = new UpdateFlowFieldVo(); |
||||
|
//获取表单中的参数
|
||||
|
Map<String, Object> formVariables = bv.getFormVariables(); |
||||
|
formVariables = formVariables == null ? new HashMap<>() : formVariables; |
||||
|
formVariables.put("businessSid", bv.getBusinessSid()); |
||||
|
String nextUserSid = bv.getNextNodeUserSids(); |
||||
|
String taskId = bv.getTaskId(); |
||||
|
String userSid = bv.getUserSid(); |
||||
|
String instanceId = bv.getInstanceId(); |
||||
|
String comment = bv.getComment(); |
||||
|
String nodeState = ""; |
||||
|
String taskDefKey = ""; |
||||
|
String projectSid = bv.getProjectSid(); |
||||
|
//设置下一环节审批人是否自动审批通过,默认否
|
||||
|
boolean contains = false; |
||||
|
//设置是否是管理员自动审批,默认否
|
||||
|
boolean adminContains = false; |
||||
|
if (StringUtils.isBlank(nextUserSid)) { |
||||
|
ResultBean<String> stringResultBean = getNextNodeUserSidsOfSubmit(bv); |
||||
|
if (!stringResultBean.getSuccess()) { |
||||
|
//下一环节用户为空的情况
|
||||
|
return rb.setMsg("下一环节无用户"); |
||||
|
} else { |
||||
|
nextUserSid = stringResultBean.getData(); |
||||
|
} |
||||
|
} |
||||
|
//查询任务id为taskId的任务是否存在
|
||||
|
Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); |
||||
|
if (Objects.isNull(task)) { |
||||
|
return rb.setMsg("任务不存在"); |
||||
|
} |
||||
|
String assignee = task.getAssignee(); |
||||
|
if (b && (StringUtils.isNotBlank(assignee) && assignee.indexOf(userSid) < 0)) { |
||||
|
return rb.setMsg("当前用户不是环节的待办人,不能进行办理操作!"); |
||||
|
} |
||||
|
|
||||
|
if (DelegationState.PENDING.equals(task.getDelegationState())) { |
||||
|
//加签
|
||||
|
Authentication.setAuthenticatedUserId(userSid); |
||||
|
taskService.addComment(taskId, instanceId, |
||||
|
FlowComment.DELEGATE.getType(), comment); |
||||
|
taskService.resolveTask(taskId, formVariables); |
||||
|
nodeState = task.getName(); |
||||
|
taskDefKey = task.getTaskDefinitionKey(); |
||||
|
} else { |
||||
|
//当前环节办理通过,且将下一环节用户放入流程中
|
||||
|
taskService.addComment(taskId, instanceId, FlowComment.NORMAL.getType(), comment); |
||||
|
log.error("taskid:{},userSid:{}", taskId, userSid); |
||||
|
log.error("formVariables:{}", JSON.toJSONString(formVariables)); |
||||
|
taskService.setAssignee(taskId, userSid); |
||||
|
taskService.complete(taskId, formVariables);//当前用户办理通过
|
||||
|
//根据流程实例的id取最新的待办环节,给环节设置上用户sid
|
||||
|
ResultBean<List<LatestTaskVo>> ll = flowTaskService.getLatestTasksNew(instanceId); |
||||
|
if (ll.getData().size() > 0) { |
||||
|
LatestTaskVo latestTaskVo = ll.getData().get(0); |
||||
|
String id_ = latestTaskVo.getId_(); |
||||
|
//查询下一环节用户是否有转办人
|
||||
|
// nextUserSid = change(nextUserSid, bv.getInstanceId());
|
||||
|
taskService.setAssignee(id_, nextUserSid);//将下一环节用户放入流程中
|
||||
|
vo.setTaskId(id_); |
||||
|
//在act_ru_variable表中增加环节上的业务参数的变量
|
||||
|
taskService.setVariablesLocal(id_, formVariables); |
||||
|
nodeState = latestTaskVo.getName_(); |
||||
|
taskDefKey = latestTaskVo.getTask_def_key_(); |
||||
|
} else { |
||||
|
nodeState = FlowComment.SETTLE.getRemark(); |
||||
|
taskDefKey = "Event_end"; |
||||
|
vo.setNodeState(FlowComment.SETTLE.getRemark()); |
||||
|
} |
||||
|
} |
||||
|
/* //设置管理员是否自动审批的字段是否是是。//若下一环节用户与系统管理员一致,则自动审批
|
||||
|
if (adminContains) { |
||||
|
bv.setUserSid(nextUserSid); |
||||
|
bv.setTaskId(vo.getTaskId()); |
||||
|
bv.setTaskDefKey(taskDefKey); |
||||
|
bv.setComment("系统自动跳过"); |
||||
|
bv.setNextNodeUserSids(""); |
||||
|
return handleProsess(bv, false); |
||||
|
}*/ |
||||
|
//获取该流程所有要走的环节节点
|
||||
|
List<FlowElement> flowElements = calApprovePath(bv.getModelId(), |
||||
|
bv.getFormVariables()); |
||||
|
for (int i = 0; i < flowElements.size(); i++) { |
||||
|
FlowElement flowElement = flowElements.get(i); |
||||
|
String id = flowElement.getId(); |
||||
|
if (taskDefKey.equals(id) && i + 1 < flowElements.size()) { |
||||
|
//获取下下一环节
|
||||
|
FlowElement flowElement1 = flowElements.get(i + 1); |
||||
|
List<SysUserVo> sysUserVoLists2 = new ArrayList<>(); |
||||
|
if (i + 2 < flowElements.size()) { |
||||
|
//获取下下下一环节用户
|
||||
|
FlowElement flowElement2 = flowElements.get(i + 2); |
||||
|
if (flowElement2 instanceof UserTask) { |
||||
|
UserTask userTask = (UserTask) flowElement2; |
||||
|
List<String> candidateGroups = userTask.getCandidateGroups(); |
||||
|
UserssQuery userssQuery = new UserssQuery(); |
||||
|
userssQuery.setCandidateGroups(candidateGroups); |
||||
|
userssQuery.setProjectSid(projectSid); |
||||
|
sysUserVoLists2 = sysUserFeign.getUserByRoleAndProject2(userssQuery).getData(); |
||||
|
if (sysUserVoLists2 == null) { |
||||
|
sysUserVoLists2 = new ArrayList<>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (flowElement1 instanceof UserTask) { |
||||
|
UserTask userTask = (UserTask) flowElement1; |
||||
|
List<String> candidateGroups = userTask.getCandidateGroups(); |
||||
|
List<SysUserVo> sysUserVoLists = new ArrayList<>(); |
||||
|
UserssQuery userssQuery = new UserssQuery(); |
||||
|
userssQuery.setCandidateGroups(candidateGroups); |
||||
|
userssQuery.setProjectSid(projectSid); |
||||
|
sysUserVoLists = sysUserFeign.getUserByRoleAndProject2(userssQuery).getData(); |
||||
|
if (sysUserVoLists == null) { |
||||
|
sysUserVoLists = new ArrayList<>(); |
||||
|
} |
||||
|
//当前环节运营部总经理 刘丽艳 点击同意 下一环节 事业部副总经理 (nextUserSid) 和事业部总经理(sysUserVoLists.get(0).getSid())
|
||||
|
//判断查询回来的用户的集合size是1 并且用户的sid和下一环节的用户的sid相同。
|
||||
|
if (sysUserVoLists.size() == 1 && sysUserVoLists.get(0).getSid().equals(nextUserSid)) { |
||||
|
contains = true; |
||||
|
break; |
||||
|
} |
||||
|
//如果下下一环节无用户,下下下一环节用户与下一环节用户相同且只有一个,则下一环节用户自动审批。
|
||||
|
if (sysUserVoLists.size() == 0 && sysUserVoLists2.size() == 1 && sysUserVoLists2.get(0).getSid().equals(nextUserSid)) { |
||||
|
contains = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (contains) { |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (contains) { |
||||
|
bv.setUserSid(nextUserSid); |
||||
|
bv.setTaskId(vo.getTaskId()); |
||||
|
bv.setTaskDefKey(taskDefKey); |
||||
|
bv.setComment("因与下一级审批人相同,系统自动处理,需以下一级审批人审批意见为准!"); |
||||
|
return handleProsess(bv, false); |
||||
|
} |
||||
|
vo.setProcInsId(instanceId); |
||||
|
vo.setProcDefId(bv.getModelId()); |
||||
|
vo.setNodeState(nodeState); |
||||
|
vo.setTaskDefKey(taskDefKey); |
||||
|
vo.setSid(bv.getBusinessSid()); |
||||
|
return rb.success().setData(vo); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取下一环节用户 |
||||
|
* |
||||
|
* @param bv |
||||
|
* @return |
||||
|
*/ |
||||
|
public ResultBean<String> getNextNodeUserSidsOfSubmit(BusinessVariables bv) { |
||||
|
ResultBean<String> rb = ResultBean.fireFail(); |
||||
|
String projectSid = bv.getProjectSid(); |
||||
|
String taskDefKey = bv.getTaskDefKey(); |
||||
|
//根据业务参数取流程流转的环节 信息
|
||||
|
List<Map<String, Object>> list = (List<Map<String, Object>>) getProcessCirculationNodesByMap(bv).getData(); |
||||
|
Map<String, Object> task_map = new HashMap<>(); |
||||
|
boolean endTask = true; |
||||
|
for (int i = 0; i < list.size(); i++) { |
||||
|
String id = list.get(i).get("id").toString(); |
||||
|
if (id.equals(taskDefKey) && i + 1 < list.size()) { |
||||
|
task_map = list.get(i + 1); |
||||
|
endTask = false; |
||||
|
} |
||||
|
} |
||||
|
if (endTask) { |
||||
|
task_map.put("name", "结束"); |
||||
|
return rb.success(); |
||||
|
} else { |
||||
|
Object o = task_map.get("candidateGroups"); |
||||
|
JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(o)); |
||||
|
String roleSid = jsonArray.get(0).toString(); |
||||
|
//根据组织架构、角色两个参数取相关符合条件的用户信息
|
||||
|
UserQuery userQuery = new UserQuery(); |
||||
|
userQuery.setRoleSid(roleSid); |
||||
|
userQuery.setProjectSid(projectSid); |
||||
|
String nextNodeUserSids_ = ""; |
||||
|
List<SysUserVo> sysUserVos = sysUserFeign.getUserByRoleAndProject(userQuery).getData(); |
||||
|
if (sysUserVos == null || sysUserVos.size() < 1) { |
||||
|
return rb; |
||||
|
} else { |
||||
|
StringBuilder nextNodeUserSids = new StringBuilder(); |
||||
|
for (SysUserVo su : sysUserVos) { |
||||
|
nextNodeUserSids.append(su.getSid()).append(","); |
||||
|
} |
||||
|
//符合条件的用户的sid,拼接的字符串
|
||||
|
nextNodeUserSids_ = nextNodeUserSids.toString(); |
||||
|
nextNodeUserSids_ = nextNodeUserSids_.substring(0, nextNodeUserSids_.length() - 1); |
||||
|
} |
||||
|
return rb.success().setData(nextNodeUserSids_); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
package com.yxt.supervise.system.sysuser; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @description: |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2023/11/28 |
||||
|
**/ |
||||
|
@Data |
||||
|
public class UserssQuery { |
||||
|
|
||||
|
private List<String> candidateGroups = new ArrayList<>(); |
||||
|
|
||||
|
private String projectSid; |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
package com.yxt.supervise.system.sysuser; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @description: |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2023/11/28 |
||||
|
**/ |
||||
|
@Data |
||||
|
public class UserssQuery { |
||||
|
|
||||
|
private List<String> candidateGroups = new ArrayList<>(); |
||||
|
|
||||
|
private String projectSid; |
||||
|
} |
Loading…
Reference in new issue