@@ -0,0 +1,100 @@ | |||||
package com.hz.pm.api.common.helper; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.flowable.bpmn.model.BpmnModel; | |||||
import org.flowable.bpmn.model.Process; | |||||
import org.flowable.bpmn.model.UserTask; | |||||
import org.flowable.engine.HistoryService; | |||||
import org.flowable.engine.RepositoryService; | |||||
import org.flowable.engine.history.HistoricActivityInstance; | |||||
import org.flowable.engine.history.HistoricProcessInstance; | |||||
import org.flowable.variable.api.history.HistoricVariableInstance; | |||||
import org.springframework.stereotype.Component; | |||||
import java.util.List; | |||||
import java.util.Set; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* <p> | |||||
* WflowHelper | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 16:00 2024/3/11 | |||||
*/ | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class WflowHelper { | |||||
private final HistoryService historyService; | |||||
private final RepositoryService repositoryService; | |||||
/** | |||||
* 所有流程是否完成(审核通过) | |||||
* | |||||
* @param instCodes \ | |||||
* @return \ | |||||
*/ | |||||
public boolean allInstancesFinished(Set<String> instCodes) { | |||||
List<HistoricProcessInstance> finishedInstances = historyService.createHistoricProcessInstanceQuery() | |||||
.processInstanceIds(instCodes) | |||||
.finished() | |||||
.list(); | |||||
if (finishedInstances.size() != instCodes.size()) { | |||||
return Boolean.FALSE; | |||||
} | |||||
for (HistoricProcessInstance instance : finishedInstances) { | |||||
String processDefinitionId = instance.getProcessDefinitionId(); | |||||
UserTask userTaskDefineNode = getLastUserTaskDefineNode(processDefinitionId); | |||||
List<HistoricActivityInstance> finishedTasks = historyService.createHistoricActivityInstanceQuery() | |||||
.activityType("userTask") | |||||
.activityId(userTaskDefineNode.getId()) | |||||
.processInstanceId(instance.getId()) | |||||
.orderByHistoricActivityInstanceEndTime() | |||||
.desc() | |||||
.list(); | |||||
if (finishedTasks.isEmpty()) { | |||||
return Boolean.FALSE; | |||||
} | |||||
List<HistoricVariableInstance> variableInstances = finishedTasks.stream() | |||||
.map(w -> { | |||||
String variableName = "approve_" + w.getTaskId(); | |||||
return historyService.createHistoricVariableInstanceQuery() | |||||
.processInstanceId(instance.getId()) | |||||
.variableName(variableName) | |||||
.singleResult(); | |||||
}).filter(w -> w != null && "PASS".equals(w.getValue().toString())) | |||||
.collect(Collectors.toList()); | |||||
if (userTaskDefineNode.getLoopCharacteristics().isSequential()) { | |||||
if (variableInstances.isEmpty()) { | |||||
return Boolean.FALSE; | |||||
} | |||||
} else { | |||||
if (variableInstances.size() != finishedTasks.size()) { | |||||
return Boolean.FALSE; | |||||
} | |||||
} | |||||
} | |||||
return Boolean.TRUE; | |||||
} | |||||
/** | |||||
* 获取流程定义的最后一个用户任务节点 | |||||
* | |||||
* @param processDefinitionId processDefinitionId | |||||
* @return \ | |||||
*/ | |||||
public UserTask getLastUserTaskDefineNode(String processDefinitionId) { | |||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); | |||||
List<Process> processes = bpmnModel.getProcesses(); | |||||
if (!processes.isEmpty()) { | |||||
List<UserTask> userTasks = processes.get(0).findFlowElementsOfType(UserTask.class); | |||||
if (!userTasks.isEmpty()) { | |||||
return userTasks.get(userTasks.size() - 1); | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.toolkit.Assert; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.google.common.collect.Sets; | import com.google.common.collect.Sets; | ||||
import com.hz.pm.api.common.enumeration.ProjectProcessStageEnum; | import com.hz.pm.api.common.enumeration.ProjectProcessStageEnum; | ||||
import com.hz.pm.api.common.helper.WflowHelper; | |||||
import com.hz.pm.api.common.model.constant.BizConst; | import com.hz.pm.api.common.model.constant.BizConst; | ||||
import com.hz.pm.api.common.model.constant.TypeReferenceConst; | import com.hz.pm.api.common.model.constant.TypeReferenceConst; | ||||
import com.hz.pm.api.common.statemachine.util.StateMachineUtil; | import com.hz.pm.api.common.statemachine.util.StateMachineUtil; | ||||
@@ -56,11 +57,15 @@ import com.wflow.workflow.service.ProcessInstanceService; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.flowable.bpmn.model.BpmnModel; | |||||
import org.flowable.bpmn.model.UserTask; | |||||
import org.flowable.engine.HistoryService; | import org.flowable.engine.HistoryService; | ||||
import org.flowable.engine.RepositoryService; | |||||
import org.flowable.engine.RuntimeService; | import org.flowable.engine.RuntimeService; | ||||
import org.flowable.engine.TaskService; | import org.flowable.engine.TaskService; | ||||
import org.flowable.engine.history.HistoricActivityInstance; | import org.flowable.engine.history.HistoricActivityInstance; | ||||
import org.flowable.engine.history.HistoricProcessInstance; | import org.flowable.engine.history.HistoricProcessInstance; | ||||
import org.flowable.engine.repository.ProcessDefinition; | |||||
import org.flowable.engine.task.Comment; | import org.flowable.engine.task.Comment; | ||||
import org.flowable.variable.api.history.HistoricVariableInstance; | import org.flowable.variable.api.history.HistoricVariableInstance; | ||||
import org.springframework.beans.BeanUtils; | import org.springframework.beans.BeanUtils; | ||||
@@ -102,6 +107,7 @@ public class HandlerManage { | |||||
private final IPurchaseService purchaseService; | private final IPurchaseService purchaseService; | ||||
private final IPurchaseInstService purchaseInstService; | private final IPurchaseInstService purchaseInstService; | ||||
private final TenderStateMachineUtil tenderStateMachineUtil; | private final TenderStateMachineUtil tenderStateMachineUtil; | ||||
private final WflowHelper wflowHelper; | |||||
@Value("${spring.profiles.active}") | @Value("${spring.profiles.active}") | ||||
private String active; | private String active; | ||||
@@ -253,41 +259,12 @@ public class HandlerManage { | |||||
if (instCodes.size() != purchases.size()) { | if (instCodes.size() != purchases.size()) { | ||||
return; | return; | ||||
} | } | ||||
if (allInstancesFinished(instCodes)) { | |||||
if (wflowHelper.allInstancesFinished(instCodes)) { | |||||
stateMachineUtil.pass(project); | stateMachineUtil.pass(project); | ||||
projectService.updateById(project); | projectService.updateById(project); | ||||
} | } | ||||
} | } | ||||
public boolean allInstancesFinished(Set<String> instCodes) { | |||||
long finishedCount = historyService.createHistoricProcessInstanceQuery() | |||||
.processInstanceIds(instCodes) | |||||
.finished() | |||||
.count(); | |||||
if (finishedCount != instCodes.size()) { | |||||
return Boolean.FALSE; | |||||
} | |||||
for (String instCode : instCodes) { | |||||
HistoricActivityInstance task = historyService.createHistoricActivityInstanceQuery() | |||||
.activityType("userTask") | |||||
.processInstanceId(instCode) | |||||
.orderByHistoricActivityInstanceEndTime() | |||||
.desc() | |||||
.singleResult(); | |||||
if (task == null) { | |||||
return Boolean.FALSE; | |||||
} | |||||
HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery() | |||||
.processInstanceId(instCode) | |||||
.variableName("approve_" + task.getTaskId()) | |||||
.singleResult(); | |||||
if (variableInstance == null || !"PASS".equals(variableInstance.getValue())) { | |||||
return Boolean.FALSE; | |||||
} | |||||
} | |||||
return Boolean.TRUE; | |||||
} | |||||
private void purchaseRejectedCallback(Project project, String instanceId) { | private void purchaseRejectedCallback(Project project, String instanceId) { | ||||
PurchaseInst purchaseInst = purchaseInstService.getByProjectIdAndInstCode(project.getId(), instanceId); | PurchaseInst purchaseInst = purchaseInstService.getByProjectIdAndInstCode(project.getId(), instanceId); | ||||
Assert.notNull(purchaseInst, "该标段对应的流程不存在"); | Assert.notNull(purchaseInst, "该标段对应的流程不存在"); | ||||
@@ -1,27 +1,16 @@ | |||||
package com.hz.pm.api.todocenter; | package com.hz.pm.api.todocenter; | ||||
import cn.hutool.core.bean.BeanUtil; | |||||
import cn.hutool.json.JSONUtil; | import cn.hutool.json.JSONUtil; | ||||
import cn.hutool.poi.excel.ExcelUtil; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.hz.pm.api.AppTests; | import com.hz.pm.api.AppTests; | ||||
import com.hz.pm.api.common.model.constant.BizConst; | |||||
import com.hz.pm.api.user.helper.MhUnitCache; | |||||
import com.hz.pm.api.user.model.entity.MhUnit; | |||||
import com.hz.pm.api.user.service.IMhUnitService; | |||||
import com.hz.pm.api.common.helper.WflowHelper; | |||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.wflow.bean.entity.WflowCcTasks; | import com.wflow.bean.entity.WflowCcTasks; | ||||
import com.wflow.bean.entity.WflowModelHistorys; | |||||
import com.wflow.bean.entity.WflowModels; | |||||
import com.wflow.mapper.WflowCcTasksMapper; | import com.wflow.mapper.WflowCcTasksMapper; | ||||
import com.wflow.utils.CodeUtil; | import com.wflow.utils.CodeUtil; | ||||
import com.wflow.workflow.bean.dto.ReqProcessHandlerDTO; | import com.wflow.workflow.bean.dto.ReqProcessHandlerDTO; | ||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | import com.wflow.workflow.enums.ProcessHandlerEnum; | ||||
import com.wflow.workflow.mapper.CustomHisActInstMapper; | import com.wflow.workflow.mapper.CustomHisActInstMapper; | ||||
import com.wflow.workflow.service.ProcessModelHistorysService; | |||||
import com.wflow.workflow.service.ProcessModelService; | |||||
import com.wflow.workflow.utils.ProcessTaskUtils; | import com.wflow.workflow.utils.ProcessTaskUtils; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.assertj.core.util.Lists; | import org.assertj.core.util.Lists; | ||||
@@ -37,6 +26,7 @@ import org.flowable.task.api.Task; | |||||
import org.flowable.task.api.history.HistoricTaskInstance; | import org.flowable.task.api.history.HistoricTaskInstance; | ||||
import org.flowable.variable.api.history.HistoricVariableInstance; | import org.flowable.variable.api.history.HistoricVariableInstance; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.mockito.internal.util.collections.Sets; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import java.util.Date; | import java.util.Date; | ||||
@@ -321,31 +311,11 @@ public class FlowableTest extends AppTests { | |||||
} | } | ||||
@Autowired | @Autowired | ||||
private IMhUnitService mhUnitService; | |||||
@Autowired | |||||
private MhUnitCache mhUnitCache; | |||||
@Autowired | |||||
private ProcessModelService processModelService; | |||||
@Autowired | |||||
private ProcessModelHistorysService processModelHistorysService; | |||||
private WflowHelper wflowHelper; | |||||
@Test | @Test | ||||
public void test() { | public void test() { | ||||
List<WflowModels> wflowModels = processModelService.list(Wrappers.lambdaQuery(WflowModels.class) | |||||
.ne(WflowModels::getRegionCode, "1")); | |||||
for (WflowModels model : wflowModels) { | |||||
WflowModelHistorys history = BeanUtil.copyProperties(model, WflowModelHistorys.class); | |||||
processModelHistorysService.save(history); | |||||
} | |||||
} | |||||
public static void main(String[] args) { | |||||
String path = "/Users/wendy/Desktop/项目下达资金-评审金额 - 副本.xls"; | |||||
List<Map<String, Object>> maps = ExcelUtil.getReader(path).readAll(); | |||||
for (Map<String, Object> map : maps) { | |||||
String format = "update mh_project set total_money = %s where project_name = '%s' and total_money is null;"; | |||||
System.out.println(String.format(format, map.get("评审金额"), map.get("项目名称"))); | |||||
} | |||||
wflowHelper.allInstancesFinished(Sets.newSet("dd21cb84-dfb8-11ee-a578-02426daa406d")); | |||||
} | } | ||||
} | } |