Browse Source

优化未售买断提交和办理

zhanglei
dimengzhe 2 years ago
parent
commit
a1953ad303
  1. 82
      anrui-base/anrui-base-biz/src/main/java/com/yxt/anrui/base/biz/basevehicleactualsales/BaseVehicleActualSalesService.java
  2. 5
      anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flow2/FlowFeign.java
  3. 14
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow2/FlowRest.java
  4. 199
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow2/FlowService.java

82
anrui-base/anrui-base-biz/src/main/java/com/yxt/anrui/base/biz/basevehicleactualsales/BaseVehicleActualSalesService.java

@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.yxt.anrui.base.api.basemanufacturer.BaseManufacturer;
import com.yxt.anrui.base.api.basevehicle.BaseVehicle;
import com.yxt.anrui.base.api.basevehicle.BaseVehicleUpdateQuery;
@ -22,6 +23,7 @@ import com.yxt.anrui.base.api.basevehicleactualsales.flow.ActualGetNodeQuery;
import com.yxt.anrui.base.api.basevehicleactualsales.flow.ActualGetNodeVo;
import com.yxt.anrui.base.api.basevehicleactualsales.flow.BaseActualSalesTaskQuery;
import com.yxt.anrui.base.api.basevehicleactualsales.flow.SubmitActualSalesDto;
import com.yxt.anrui.base.api.busvehicleapply.BusVehicleApply;
import com.yxt.anrui.base.biz.basemanufacturer.BaseManufacturerService;
import com.yxt.anrui.base.biz.basevehicle.BaseVehicleService;
import com.yxt.anrui.base.biz.basevehicleactualdetails.BaseVehicleActualDetailsService;
@ -59,6 +61,7 @@ import com.yxt.messagecenter.api.message.MessageFeign;
import com.yxt.messagecenter.api.message.MessageFlowVo;
import com.yxt.messagecenter.api.message.MessageFlowableQuery;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -66,6 +69,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
@ -473,7 +477,7 @@ public class BaseVehicleActualSalesService extends MybatisBaseService<BaseVehicl
bv.setFormVariables(variables);
bv.setModelId(ProcDefEnum.BASEVEHICLEACTUALSALES.getProDefId());
if (r == 1) {
ResultBean<UpdateFlowFieldVo> voResultBean = flowableFeign.startProcess(bv);
ResultBean<UpdateFlowFieldVo> voResultBean = flowFeign.startProcess(bv);
if (!voResultBean.getSuccess()) {
return rb.setMsg(voResultBean.getMsg());
}
@ -489,18 +493,32 @@ public class BaseVehicleActualSalesService extends MybatisBaseService<BaseVehicl
baseVehicle.setSettlementStatusValue(VehicleState.BuyoutEnum.PRE_BUYOUT.getRemarks());
baseVehicleService.updateVeh(baseVehicle);
}
//极光推送
baseVehicleActualSales = fetchBySid(businessSid);
MessageFlowableQuery messageFlowableQuery = new MessageFlowableQuery();
MessageFlowVo messageFlowVo = new MessageFlowVo();
BeanUtil.copyProperties(ufVo, messageFlowVo);
messageFlowableQuery.setUfVo(messageFlowVo);
messageFlowableQuery.setAppMap(appMap);
messageFlowableQuery.setBusinessSid(businessSid);
messageFlowableQuery.setModuleName("未售买断申请");
messageFlowableQuery.setMsgContent(baseVehicleActualSales.getApplicationName() + "提交的" + messageFlowableQuery.getModuleName() + ",请审批");
messageFlowableQuery.setMsgTitle("未售买断");
ResultBean<String> stringResultBean = messageFeign.pushMessage(messageFlowableQuery);
//==================================添加线程
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());
BaseVehicleActualSales finalBaseVehicleActualSales = baseVehicleActualSales;
Future future1 = pool.submit(() -> {
//极光推送
MessageFlowableQuery messageFlowableQuery = new MessageFlowableQuery();
MessageFlowVo messageFlowVo = new MessageFlowVo();
BeanUtil.copyProperties(ufVo, messageFlowVo);
messageFlowableQuery.setUfVo(messageFlowVo);
messageFlowableQuery.setAppMap(appMap);
messageFlowableQuery.setBusinessSid(businessSid);
messageFlowableQuery.setModuleName("未售买断申请");
messageFlowableQuery.setMsgContent(finalBaseVehicleActualSales.getApplicationName() + "提交的" + messageFlowableQuery.getModuleName() + ",请审批");
messageFlowableQuery.setMsgTitle("未售买断");
ResultBean<String> stringResultBean = messageFeign.pushMessage(messageFlowableQuery);
});
} catch (Exception e) {
e.printStackTrace();
}
//==================================添加线程
return voResultBean;
}
if (r == 2) {
@ -569,27 +587,39 @@ public class BaseVehicleActualSalesService extends MybatisBaseService<BaseVehicl
variables.put("app", appMap);
bv.setFormVariables(variables);
bv.setOrgSidPath(baseVehicleActualSales.getOrgSidPath());
ResultBean<UpdateFlowFieldVo> resultBean = flowableFeign.handleProsess(bv);
ResultBean<UpdateFlowFieldVo> resultBean = flowFeign.handleProsess(bv);
if (!resultBean.getSuccess()) {
return rb.setMsg(resultBean.getMsg());
}
UpdateFlowFieldVo ufVo = resultBean.getData();
updateFlowFiled(BeanUtil.beanToMap(resultBean.getData()));
if (!"Event_end".equals(ufVo.getTaskDefKey())) {
//极光推送
baseVehicleActualSales = fetchBySid(bv.getBusinessSid());
MessageFlowableQuery messageFlowableQuery = new MessageFlowableQuery();
MessageFlowVo messageFlowVo = new MessageFlowVo();
BeanUtil.copyProperties(ufVo, messageFlowVo);
messageFlowVo.setProcDefId(baseVehicleActualSales.getProcDefId());
messageFlowVo.setProcInsId(baseVehicleActualSales.getProcInstId());
messageFlowableQuery.setUfVo(messageFlowVo);
messageFlowableQuery.setAppMap(appMap);
messageFlowableQuery.setBusinessSid(bv.getBusinessSid());
messageFlowableQuery.setModuleName("未售买断申请");
messageFlowableQuery.setMsgContent(baseVehicleActualSales.getApplicationName() + "提交的" + messageFlowableQuery.getModuleName() + ",请审批");
messageFlowableQuery.setMsgTitle("未售买断");
ResultBean<String> stringResultBean = messageFeign.pushMessage(messageFlowableQuery);
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());
BaseVehicleActualSales finalBaseVehicleActualSales = baseVehicleActualSales;
Future future1 = pool.submit(() -> {
//极光推送
MessageFlowableQuery messageFlowableQuery = new MessageFlowableQuery();
MessageFlowVo messageFlowVo = new MessageFlowVo();
BeanUtil.copyProperties(ufVo, messageFlowVo);
messageFlowVo.setProcDefId(finalBaseVehicleActualSales.getProcDefId());
messageFlowVo.setProcInsId(finalBaseVehicleActualSales.getProcInstId());
messageFlowableQuery.setUfVo(messageFlowVo);
messageFlowableQuery.setAppMap(appMap);
messageFlowableQuery.setBusinessSid(bv.getBusinessSid());
messageFlowableQuery.setModuleName("未售买断申请");
messageFlowableQuery.setMsgContent(finalBaseVehicleActualSales.getApplicationName() + "提交的" + messageFlowableQuery.getModuleName() + ",请审批");
messageFlowableQuery.setMsgTitle("未售买断");
ResultBean<String> stringResultBean = messageFeign.pushMessage(messageFlowableQuery);
});
} catch (Exception e) {
e.printStackTrace();
}
} else {
if ("1".equals(baseVehicleActualSales.getIsPay())) {
List<BaseVehicleActualPayVo> voPayList = baseVehicleActualPayService.detailsList(baseVehicleActualSales.getSid());

5
anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flow2/FlowFeign.java

@ -31,9 +31,4 @@ public interface FlowFeign {
@PostMapping(value = "/handleProsess")
@ResponseBody
ResultBean<UpdateFlowFieldVo> handleProsess(@RequestBody BusinessVariables bv);
@ApiOperation(value = "撤回流程")
@PostMapping(value = "/revokeProcess")
@ResponseBody
ResultBean<UpdateFlowFieldVo> revokeProcess(@RequestBody com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl);
}

14
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow2/FlowRest.java

@ -46,9 +46,6 @@ public class FlowRest implements FlowFeign {
@Autowired
private FlowService flowService;
@Autowired
private SysUserFeign sysUserFeign;
@Override
public ResultBean<UpdateFlowFieldVo> startProcess(BusinessVariables bv) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
@ -103,16 +100,5 @@ public class FlowRest implements FlowFeign {
return updateFlowFieldVoResultBean;
}
@Override
public ResultBean<UpdateFlowFieldVo> revokeProcess(FlowTaskVo fl) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
//获取表单中的参数
Map<String, Object> formVariables = fl.getValues();
formVariables = formVariables == null ? new HashMap<>() : formVariables;
formVariables.put("businessSid", fl.getBusinessSid());
ResultBean<UpdateFlowFieldVo> updateFlowFieldVoResultBean = flowService.revokeProcess(fl);
return null;
}
}

199
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow2/FlowService.java

@ -96,8 +96,6 @@ public class FlowService extends MybatisBaseService<FlowMapper, Flowable> {
private MessageFeign messageFeign;
@Autowired
private SysFlowccFeign sysFlowccFeign;
@Autowired
private FlowTaskMapper flowTaskMapper;
public ResultBean<String> getNextNodeUser(BusinessVariables bv) {
ResultBean<String> rb = ResultBean.fireFail();
@ -747,202 +745,5 @@ public class FlowService extends MybatisBaseService<FlowMapper, Flowable> {
return rb.success().setMsg("抄送" + userName.toString() + "成功!");
}
public ResultBean<UpdateFlowFieldVo> revokeProcess(FlowTaskVo flowTaskVo) {
ResultBean<UpdateFlowFieldVo> rb =ResultBean.fireFail();
String userSid = flowTaskVo.getUserSid();
//获取当前环节信息
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(flowTaskVo.getTaskId()).singleResult();
Execution execution = runtimeService.createExecutionQuery().executionId(historicTaskInstance.getExecutionId()).singleResult();
DelegateExecution delegateExecution = (DelegateExecution) execution;
if (delegateExecution == null) {
return rb.setMsg("流程已办结或终止,不能撤回");
}
// 获取当前节点的activityId,即xml中每个标签的ID
String currentActivityId = delegateExecution.getCurrentActivityId();
String taskId = getTaskId(currentActivityId, historicTaskInstance.getProcessInstanceId(), historicTaskInstance.getProcessDefinitionId());
if (StringUtils.isBlank(taskId)) {
return rb.setMsg("流程找不到上一环节,撤回操作失败!");
}
//获取上一环节操作信息
HistoricTaskInstance historicTaskInstance1 = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
//上一环节操作人
String assignee = historicTaskInstance1.getAssignee();
return null;
}
private String getTaskId(String currentActivityId, String processInstanceId, String processDefinitionId) {
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(currentActivityId);
List<SequenceFlow> list=flowNode.getIncomingFlows();
if(list.size()==0){
return "";
}
List<HistoricActivityInstance> list1=new ArrayList<>();
for( SequenceFlow sequenceFlow:list){
String sourceRef = sequenceFlow.getSourceRef();
list1= historyService.createHistoricActivityInstanceQuery().activityId(sourceRef)
.processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().desc().list();
if(list1.size()>0){
break;
}
}
// 获取上一个节点的activityId
HistoricActivityInstance historicActivityInstance = list1.get(0);
String activityType = historicActivityInstance.getActivityType();
String historicActivityInstanceActivityId = historicActivityInstance.getActivityId();
if (!"userTask".equals(activityType)) {
return getTaskId(historicActivityInstanceActivityId, processInstanceId, processDefinitionId);
}
return historicActivityInstance.getTaskId();
}
private ResultBean<List<LatestTaskVo>> revokeProcess_( String processInstanceId,
String assignee ) {
// 流程回退到上一个节点,审批人继续审批
// 获取流程定义信息
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
ProcessDefinition processDefinition = repositoryService
.createProcessDefinitionQuery()
.processDefinitionId(task.getProcessDefinitionId()).singleResult();
// 获取所有节点信息
Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0);
// 获取全部节点列表,包含子节点
Collection<FlowElement> allElements =
FlowableUtils.getAllElements(process.getFlowElements(), null);
// 获取当前任务节点元素
FlowElement source = null;
if (allElements != null) {
for (FlowElement flowElement : allElements) {
//类型为用户节点
if (flowElement.getId().equals(task.getTaskDefinitionKey())) {
//获取节点信息
source = flowElement;
}
}
}
// 目的获取所有跳转到的节点 targetIds
// 获取当前节点的所有父级用户任务节点
// 深度优先算法思想:延边迭代深入
//申请人申请后,销售经理审批同意,随后销售经理再撤回,申请人再撤回。 申请人->网关->销售经理->销售支持部经理
List<UserTask> parentUserTaskList = FlowableUtils.iteratorFindParentUserTasks(source, null, null);
if (parentUserTaskList == null || parentUserTaskList.size() == 0) {
// throw new CustomException("当前节点为");
return new ResultBean<List<LatestTaskVo>>().fail().setMsg("当前节点为").setData(new ArrayList<>());
}
// 如果流程已经结束,则得到结束节点
if (historyService.createHistoricProcessInstanceQuery().finished()
.processInstanceId(processInstanceId).count() > 0) {
return new ResultBean<List<LatestTaskVo>>().fail().setMsg("当前已经结束不能撤回").setData(new ArrayList<>());
}
// 获取活动 ID 即节点 Key
List<String> parentUserTaskKeyList = new ArrayList<>();
parentUserTaskList.forEach(item -> parentUserTaskKeyList.add(item.getId()));
// 获取全部历史节点活动实例,即已经走过的节点历史,数据采用开始时间升序
List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricTaskInstanceStartTime().asc().list();
HistoricTaskInstance historicTaskInstance = historicTaskInstanceList.get(historicTaskInstanceList.size() - 1);
Map<String, Object> actHiVarinstForOrgPath = flowTaskMapper.getActHiVarinstForOrgPath(historicTaskInstance.getId());
String orgPath = MapUtil.getStr(actHiVarinstForOrgPath,"TEXT_");
// 数据清洗,将回滚导致的脏数据清洗掉
List<String> lastHistoricTaskInstanceList = FlowableUtils.historicTaskInstanceClean(allElements, historicTaskInstanceList);
// 此时历史任务实例为倒序,获取最后走的节点
List<String> targetIds = new ArrayList<>();
int number = 0;
StringBuilder parentHistoricTaskKey = new StringBuilder();
for (String historicTaskInstanceKey : lastHistoricTaskInstanceList) {
// 当会签时候会出现特殊的,连续都是同一个节点历史数据的情况,这种时候跳过
if (parentHistoricTaskKey.toString().equals(historicTaskInstanceKey)) {
continue;
}
parentHistoricTaskKey = new StringBuilder(historicTaskInstanceKey);
if (historicTaskInstanceKey.equals(task.getTaskDefinitionKey())) {
number++;
}
// 在数据清洗后,历史节点就是唯一一条从起始到当前节点的历史记录,理论上每个点只会出现一次
// 在流程中如果出现循环,那么每次循环中间的点也只会出现一次,再出现就是下次循环
// number == 1,第一次遇到当前节点
// number == 2,第二次遇到,代表最后一次的循环范围
if (number == 2) {
break;
}
// 如果当前历史节点,属于父级的节点,说明最后一次经过了这个点,需要退回这个点
if (parentUserTaskKeyList.contains(historicTaskInstanceKey)) {
targetIds.add(historicTaskInstanceKey);
}
}
// 目的获取所有需要被跳转的节点 currentIds
// 取其中一个父级任务,因为后续要么存在公共网关,要么就是串行公共线路
UserTask oneUserTask = parentUserTaskList.get(0);
// 获取所有正常进行的任务节点 Key,这些任务不能直接使用,需要找出其中需要撤回的任务
List<Task> runTaskList = taskService.createTaskQuery()
.processInstanceId(processInstanceId).list();
List<String> runTaskKeyList = new ArrayList<>();
runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey()));
// 需驳回任务列表
List<String> currentIds = new ArrayList<>();
// 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务
List<UserTask> currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(oneUserTask, runTaskKeyList, null, null);
currentUserTaskList.forEach(item -> currentIds.add(item.getId()));
// 规定:并行网关之前节点必须需存在唯一用户任务节点,
// 如果出现多个任务节点,则并行网关节点默认为结束节点,原因为不考虑多对多情况
if (targetIds.size() > 1 && currentIds.size() > 1) {
return new ResultBean<List<LatestTaskVo>>().fail().setMsg("任务出现多对多情况,无法撤回").setData(new ArrayList<>());
}
// 循环获取那些需要被撤回的节点的ID,用来设置驳回原因
List<String> currentTaskIds = new ArrayList<>();
currentIds.forEach(currentId -> runTaskList.forEach(runTask -> {
if (currentId.equals(runTask.getTaskDefinitionKey())) {
currentTaskIds.add(runTask.getId());
}
}));
// 设置撤回意见
currentTaskIds.forEach(item -> {
taskService.addComment(item, processInstanceId,FlowComment.RECALL.getType(), "撤回办理");
// 设置实际办理人
taskService.setAssignee(item, assignee);
});
// 最近环节
List<LatestTaskVo> latestTaskList = new ArrayList<>();
try {
// 如果父级任务多于 1 个,说明当前节点不是并行节点,原因为不考虑多对多情况
if (targetIds.size() > 1) {
// 1 对 多任务跳转,currentIds 当前节点(1),targetIds 跳转到的节点(多)
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(processInstanceId).
moveSingleActivityIdToActivityIds(currentIds.get(0), targetIds).changeState();
}
// 如果父级任务只有一个,因此当前任务可能为网关中的任务
if (targetIds.size() == 1) {
// 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetIds.get(0) 跳转到的节点(1)
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(processInstanceId)
.moveActivityIdsToSingleActivityId(currentIds, targetIds.get(0)).changeState();
}
// 最近环节
parentUserTaskList.forEach(item -> {
LatestTaskVo latestTaskVo = new LatestTaskVo();
latestTaskVo.setASSIGNEE_(item.getAssignee());
latestTaskVo.setName_(item.getName());
latestTaskVo.setTask_def_key_(item.getId());
latestTaskVo.setIncomingSourceRef(item.getIncomingFlows().get(0).getSourceRef());
latestTaskVo.setOrgPath(orgPath);
Map<String, Object> task_map = flowTaskMapper.getTaskByDefKey(processInstanceId, item.getId());
if(task_map!=null){
taskService.setAssignee(task_map.get("id_").toString(), assignee);
latestTaskVo.setId_(task_map.get("id_").toString());
latestTaskList.add(latestTaskVo);
}
});
} catch (FlowableObjectNotFoundException e) {
throw new CustomException("未找到流程实例,流程可能已发生变化");
} catch (FlowableException e) {
throw new CustomException("无法取消或开始活动");
}
return new ResultBean<List<LatestTaskVo>>().success().setData(latestTaskList);
}
}

Loading…
Cancel
Save