|
@@ -588,6 +588,94 @@ public class ProcessInstanceServiceImpl implements ProcessInstanceService {
|
|
|
return USER_TYPE_SYSTEM.equals(userType) && task.getAssigneeId().equals(operatorId);
|
|
return USER_TYPE_SYSTEM.equals(userType) && task.getAssigneeId().equals(operatorId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional
|
|
|
|
|
+ public void migrateToDefinition(Long instanceId, Long targetDefinitionId) {
|
|
|
|
|
+ ProcessInstance instance = this.processInstanceMapper.selectById(instanceId);
|
|
|
|
|
+ if (instance == null) throw new BusinessException("流程实例不存在");
|
|
|
|
|
+ Long oldDefinitionId = instance.getProcessDefinitionId();
|
|
|
|
|
+ ProcessDefinition oldDef = this.processDefinitionMapper.selectById(oldDefinitionId);
|
|
|
|
|
+ ProcessDefinition newDef = this.processDefinitionMapper.selectById(targetDefinitionId);
|
|
|
|
|
+ if (oldDef == null || newDef == null) throw new BusinessException("流程定义不存在");
|
|
|
|
|
+ if (!Objects.equals(oldDef.getProcessCode(), newDef.getProcessCode())) {
|
|
|
|
|
+ throw new BusinessException("只能迁移到同一流程编码的不同版本");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 匹配当前节点在新定义中的位置(按节点名称)
|
|
|
|
|
+ FlowModel oldModel = this.flowEngineService.parseModel(oldDef.getModelJson());
|
|
|
|
|
+ FlowModel newModel = this.flowEngineService.parseModel(newDef.getModelJson());
|
|
|
|
|
+ String currentNodeId = instance.getCurrentNodeId();
|
|
|
|
|
+ if (currentNodeId != null) {
|
|
|
|
|
+ String currentNodeName = oldModel.getNodes().stream()
|
|
|
|
|
+ .filter(n -> n.getId().equals(currentNodeId))
|
|
|
|
|
+ .findFirst().map(FlowNode::getName).orElse(null);
|
|
|
|
|
+ if (currentNodeName != null) {
|
|
|
|
|
+ String newNodeId = newModel.getNodes().stream()
|
|
|
|
|
+ .filter(n -> currentNodeName.equals(n.getName())
|
|
|
|
|
+ && !com.qqflow.engine.domain.flow.enums.NodeType.START.getCode().equals(n.getType())
|
|
|
|
|
+ && !com.qqflow.engine.domain.flow.enums.NodeType.END.getCode().equals(n.getType()))
|
|
|
|
|
+ .findFirst().map(FlowNode::getId).orElse(null);
|
|
|
|
|
+ if (newNodeId == null) {
|
|
|
|
|
+ throw new BusinessException("当前节点 '" + currentNodeName + "' 在新流程定义中不存在,无法迁移");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 更新实例指向新定义
|
|
|
|
|
+ this.processInstanceMapper.update(null, Wrappers.<ProcessInstance>lambdaUpdate()
|
|
|
|
|
+ .eq(ProcessInstance::getId, instanceId)
|
|
|
|
|
+ .set(ProcessInstance::getProcessDefinitionId, targetDefinitionId)
|
|
|
|
|
+ .set(ProcessInstance::getVersion, newDef.getVersion())
|
|
|
|
|
+ .set(ProcessInstance::getCurrentNodeId, newNodeId));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 无当前节点(已结束),直接更新定义ID
|
|
|
|
|
+ this.processInstanceMapper.update(null, Wrappers.<ProcessInstance>lambdaUpdate()
|
|
|
|
|
+ .eq(ProcessInstance::getId, instanceId)
|
|
|
|
|
+ .set(ProcessInstance::getProcessDefinitionId, targetDefinitionId)
|
|
|
|
|
+ .set(ProcessInstance::getVersion, newDef.getVersion()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional
|
|
|
|
|
+ public int migrateAllToDefinition(Long fromDefinitionId, Long toDefinitionId) {
|
|
|
|
|
+ ProcessDefinition oldDef = this.processDefinitionMapper.selectById(fromDefinitionId);
|
|
|
|
|
+ ProcessDefinition newDef = this.processDefinitionMapper.selectById(toDefinitionId);
|
|
|
|
|
+ if (oldDef == null || newDef == null) throw new BusinessException("流程定义不存在");
|
|
|
|
|
+ if (!Objects.equals(oldDef.getProcessCode(), newDef.getProcessCode())) {
|
|
|
|
|
+ throw new BusinessException("只能迁移到同一流程编码的不同版本");
|
|
|
|
|
+ }
|
|
|
|
|
+ FlowModel oldModel = this.flowEngineService.parseModel(oldDef.getModelJson());
|
|
|
|
|
+ FlowModel newModel = this.flowEngineService.parseModel(newDef.getModelJson());
|
|
|
|
|
+ // 构建旧节点名 → 新节点ID映射
|
|
|
|
|
+ Map<String, String> nodeNameToNewId = newModel.getNodes().stream()
|
|
|
|
|
+ .filter(n -> n.getName() != null)
|
|
|
|
|
+ .collect(Collectors.toMap(FlowNode::getName, FlowNode::getId, (a, b) -> a));
|
|
|
|
|
+
|
|
|
|
|
+ List<ProcessInstance> instances = this.processInstanceMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<ProcessInstance>()
|
|
|
|
|
+ .eq(ProcessInstance::getProcessDefinitionId, fromDefinitionId)
|
|
|
|
|
+ .eq(ProcessInstance::getDeleted, 0)
|
|
|
|
|
+ .in(ProcessInstance::getStatus, 0, 1, 4)); // 待接收、运行中、已回退
|
|
|
|
|
+
|
|
|
|
|
+ int count = 0;
|
|
|
|
|
+ for (ProcessInstance pi : instances) {
|
|
|
|
|
+ String currentNodeId = pi.getCurrentNodeId();
|
|
|
|
|
+ String newNodeId = null;
|
|
|
|
|
+ if (currentNodeId != null) {
|
|
|
|
|
+ String nodeName = oldModel.getNodes().stream()
|
|
|
|
|
+ .filter(n -> n.getId().equals(currentNodeId))
|
|
|
|
|
+ .findFirst().map(FlowNode::getName).orElse(null);
|
|
|
|
|
+ if (nodeName != null) newNodeId = nodeNameToNewId.get(nodeName);
|
|
|
|
|
+ if (newNodeId == null) continue; // 节点不兼容,跳过
|
|
|
|
|
+ }
|
|
|
|
|
+ this.processInstanceMapper.update(null, Wrappers.<ProcessInstance>lambdaUpdate()
|
|
|
|
|
+ .eq(ProcessInstance::getId, pi.getId())
|
|
|
|
|
+ .set(ProcessInstance::getProcessDefinitionId, toDefinitionId)
|
|
|
|
|
+ .set(ProcessInstance::getVersion, newDef.getVersion())
|
|
|
|
|
+ .set(currentNodeId != null, ProcessInstance::getCurrentNodeId, newNodeId));
|
|
|
|
|
+ count++;
|
|
|
|
|
+ }
|
|
|
|
|
+ return count;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void fillBizValue(ProcessInstanceDTO dto, Long definitionId) {
|
|
private void fillBizValue(ProcessInstanceDTO dto, Long definitionId) {
|
|
|
if (definitionId == null || dto.getFormData() == null) return;
|
|
if (definitionId == null || dto.getFormData() == null) return;
|
|
|
try {
|
|
try {
|