15 changed files with 2859 additions and 0 deletions
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<parent> |
||||
<artifactId>common</artifactId> |
||||
<groupId>apelet</groupId> |
||||
<version>1.0.0</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>common-flow-online</artifactId> |
||||
<version>1.0.0</version> |
||||
<name>common-flow-online</name> |
||||
<packaging>jar</packaging> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>apelet</groupId> |
||||
<artifactId>common-flow</artifactId> |
||||
<version>1.0.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>apelet</groupId> |
||||
<artifactId>common-online</artifactId> |
||||
<version>1.0.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>apelet</groupId> |
||||
<artifactId>common-orm</artifactId> |
||||
<version>1.0.0</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
package apelet.common.flow.online.aop; |
||||
|
||||
import apelet.common.core.object.TokenData; |
||||
import apelet.common.core.util.AopTargetUtil; |
||||
import apelet.common.core.util.MyDateUtil; |
||||
import apelet.common.flow.dao.FlowTransProducerMapper; |
||||
import apelet.common.flow.model.FlowTaskComment; |
||||
import apelet.common.flow.model.FlowTransProducer; |
||||
import apelet.common.flow.online.object.TransactionalFlowBusinessData; |
||||
import cn.hutool.core.bean.BeanUtil; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.annotation.Pointcut; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.ApplicationEventPublisher; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* 拦截流程业务多数据库数据写入的AOP对象。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Aspect |
||||
@Component |
||||
@Slf4j |
||||
public class FlowMultiDatabaseWriteAspect { |
||||
|
||||
@Autowired |
||||
private ApplicationEventPublisher eventPublisher; |
||||
@Autowired |
||||
private FlowTransProducerMapper flowTransProducerMapper; |
||||
|
||||
@Pointcut("execution(public * apelet.common.flow..service.impl..*(..)) " + |
||||
"&& @annotation(apelet.common.core.annotation.MultiDatabaseWriteMethod)") |
||||
public void multiDatabaseWriteMethodPointCut() { |
||||
// 空注释,避免sonar警告
|
||||
} |
||||
|
||||
@Around("multiDatabaseWriteMethodPointCut()") |
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
String initMethod = AopTargetUtil.getFullMethodName(joinPoint); |
||||
TransactionalFlowBusinessData data = TransactionalFlowBusinessData.getOrCreateFromRequestAttribute(); |
||||
if (data.getInitMethod() == null) { |
||||
data.setInitMethod(initMethod); |
||||
} |
||||
try { |
||||
// 调用原来的方法
|
||||
Object result = joinPoint.proceed(); |
||||
if (StrUtil.equals(initMethod, data.getInitMethod()) && CollUtil.isNotEmpty(data.getSqlDataList())) { |
||||
this.fillupTransactionalBusinessData(); |
||||
FlowTransProducer producerData = BeanUtil.copyProperties(data, FlowTransProducer.class); |
||||
producerData.setAppCode(TokenData.takeFromRequest().getAppCode()); |
||||
producerData.setTryTimes(1); |
||||
String sqlData = JSON.toJSONStringWithDateFormat( |
||||
data.getSqlDataList(), MyDateUtil.COMMON_SHORT_DATETIME_FORMAT); |
||||
producerData.setSqlData(sqlData); |
||||
flowTransProducerMapper.insert(producerData); |
||||
eventPublisher.publishEvent(data); |
||||
} |
||||
return result; |
||||
} catch (Exception e) { |
||||
TransactionalFlowBusinessData.removeFromRequestAttribute(); |
||||
throw e; |
||||
} finally { |
||||
if (StrUtil.equals(initMethod, data.getInitMethod())) { |
||||
TransactionalFlowBusinessData.removeFromRequestAttribute(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void fillupTransactionalBusinessData() { |
||||
FlowTaskComment comment = FlowTaskComment.getFromRequest(); |
||||
TransactionalFlowBusinessData data = TransactionalFlowBusinessData.getFromRequestAttribute(); |
||||
if (comment != null) { |
||||
data.setProcessInstanceId(comment.getProcessInstanceId()); |
||||
data.setTaskId(comment.getTaskId()); |
||||
data.setTaskKey(comment.getTaskKey()); |
||||
data.setTaskName(comment.getTaskName()); |
||||
data.setTaskComment(comment.getTaskComment()); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
package apelet.common.flow.online.aop; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.annotation.Pointcut; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* 主要用于拦截FlowTransactionBusinessDataListener监听器类抛出的异常。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Aspect |
||||
@Component |
||||
@Order(1) |
||||
@Slf4j |
||||
public class FlowMultiDatabaseWriteExAspect { |
||||
|
||||
@Pointcut("execution(public * apelet.common.flow.online.service.impl..*(..)) " + |
||||
"&& @annotation(apelet.common.core.annotation.MultiDatabaseWriteMethod)") |
||||
public void multiDatabaseWriteMethodPointCut() { |
||||
// 空注释,避免sonar警告
|
||||
} |
||||
|
||||
@Around("multiDatabaseWriteMethodPointCut()") |
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
try { |
||||
return joinPoint.proceed(); |
||||
} catch (Exception e) { |
||||
log.error("FlowMultiDatabaseWriteExAspect throw", e); |
||||
throw e; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
package apelet.common.flow.online.config; |
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
|
||||
/** |
||||
* common-flow-online模块的自动配置引导类。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@EnableConfigurationProperties({FlowOnlineProperties.class}) |
||||
public class FlowOnlineAutoConfig { |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
package apelet.common.flow.online.config; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
||||
/** |
||||
* 在线表单工作流模块的配置对象。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Data |
||||
@ConfigurationProperties(prefix = "common-flow-online") |
||||
public class FlowOnlineProperties { |
||||
|
||||
/** |
||||
* 在线表单的URL前缀。 |
||||
*/ |
||||
private String urlPrefix; |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
package apelet.common.flow.online.listener; |
||||
|
||||
import apelet.common.core.util.ApplicationContextHolder; |
||||
import apelet.common.flow.model.FlowEntry; |
||||
import apelet.common.flow.model.FlowNodeTasks; |
||||
import apelet.common.flow.model.FlowWorkOrder; |
||||
import apelet.common.flow.service.FlowEntryService; |
||||
import apelet.common.flow.service.FlowNodeTasksService; |
||||
import apelet.common.flow.service.FlowWorkOrderService; |
||||
import apelet.common.online.dto.OnlinePluginExecuteDto; |
||||
import apelet.common.online.model.OnlineForm; |
||||
import apelet.common.online.service.OnlineFormService; |
||||
import apelet.common.online.service.OnlineOperationService; |
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import org.flowable.engine.RuntimeService; |
||||
import org.flowable.engine.delegate.TaskListener; |
||||
import org.flowable.engine.runtime.ProcessInstance; |
||||
import org.flowable.task.service.delegate.DelegateTask; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 审批设置插件by创建事件 |
||||
*/ |
||||
public class ApprovalSettingsByCreateListener implements TaskListener { |
||||
|
||||
private final transient FlowNodeTasksService flowNodeTasksService = |
||||
ApplicationContextHolder.getBean(FlowNodeTasksService.class); |
||||
private final transient FlowEntryService flowEntryService = |
||||
ApplicationContextHolder.getBean(FlowEntryService.class); |
||||
private final transient OnlineFormService onlineFormService = |
||||
ApplicationContextHolder.getBean(OnlineFormService.class); |
||||
private final transient FlowWorkOrderService flowWorkOrderService = |
||||
ApplicationContextHolder.getBean(FlowWorkOrderService.class); |
||||
private final transient OnlineOperationService onlineOperationService = |
||||
ApplicationContextHolder.getBean(OnlineOperationService.class); |
||||
|
||||
private final transient RuntimeService runtimeService = |
||||
ApplicationContextHolder.getBean(RuntimeService.class); |
||||
@Override |
||||
public void notify(DelegateTask delegateTask) { |
||||
|
||||
String eventName = delegateTask.getEventName(); |
||||
List<Integer> setList = new ArrayList<>(); |
||||
if (eventName.equals("create")) { |
||||
setList.add(1); |
||||
} else if (eventName.equals("assignment")) { |
||||
setList.add(2); |
||||
} else if (eventName.equals("complete")) { |
||||
String operationType = (String)delegateTask.getVariable("operationType"); |
||||
if(operationType != null){ |
||||
if(operationType.equals("agree")){ |
||||
setList.add(5); |
||||
}else if(operationType.equals("reject")) { |
||||
setList.add(6); |
||||
}else if(operationType.equals("refuse")){ |
||||
} |
||||
} |
||||
setList.add(3); |
||||
} else if (eventName.equals("delete")) { |
||||
setList.add(4); |
||||
} |
||||
String taskKey = delegateTask.getTaskDefinitionKey(); |
||||
String processDefinitionId = delegateTask.getProcessDefinitionId(); |
||||
LambdaQueryWrapper<FlowNodeTasks> wrapper = new LambdaQueryWrapper<>(); |
||||
// wrapper.eq(FlowNodeTasks::getFlowId, processDefinitionId);
|
||||
wrapper.eq(FlowNodeTasks::getTaskKey, taskKey); |
||||
wrapper.in(FlowNodeTasks::getExecutionTiming, setList); |
||||
List<FlowNodeTasks> list = flowNodeTasksService.list(wrapper); |
||||
if (list != null && list.size() > 0) { |
||||
for (FlowNodeTasks flowNodeTasks : list) { |
||||
LambdaQueryWrapper<FlowEntry> wrapperFlowEntry = new LambdaQueryWrapper<>(); |
||||
wrapperFlowEntry.eq(FlowEntry::getEntryId, flowNodeTasks.getFlowId()); |
||||
FlowEntry flowEntry = flowEntryService.getById(flowNodeTasks.getFlowId()); |
||||
OnlineForm form = onlineFormService.getOnlineFormFromCache(flowEntry.getDefaultFormId()); |
||||
Long formId = form.getFormId(); |
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() |
||||
.processInstanceId(delegateTask.getProcessInstanceId()) |
||||
.singleResult(); |
||||
String billId = processInstance.getBusinessKey(); |
||||
if (billId != null && formId > 0) { |
||||
OnlinePluginExecuteDto onlinePluginExecuteDto = new OnlinePluginExecuteDto(); |
||||
onlinePluginExecuteDto.setBillId(String.valueOf(billId)); |
||||
onlinePluginExecuteDto.setFormId(formId); |
||||
onlinePluginExecuteDto.setButtonName(flowNodeTasks.getOperation()); |
||||
onlineOperationService.executePlugin(onlinePluginExecuteDto, null, null); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
package apelet.common.flow.online.object; |
||||
|
||||
import apelet.common.core.util.ContextUtil; |
||||
import apelet.common.online.object.TransactionalBusinessData; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
/** |
||||
* 跨库存储工作流的业务数据的事物性事件数据。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@Data |
||||
public class TransactionalFlowBusinessData extends TransactionalBusinessData { |
||||
|
||||
/** |
||||
* 流程实例Id。 |
||||
*/ |
||||
private String processInstanceId; |
||||
/** |
||||
* 流程任务Id。 |
||||
*/ |
||||
private String taskId; |
||||
/** |
||||
* 流程任务定义标识。 |
||||
*/ |
||||
private String taskKey; |
||||
/** |
||||
* 流程任务定义名称。 |
||||
*/ |
||||
private String taskName; |
||||
/** |
||||
* 审批注释。 |
||||
*/ |
||||
private String taskComment; |
||||
|
||||
private static final ThreadLocal<TransactionalFlowBusinessData> FLOW_BUSINESS_DATA_THREAD_LOCAL = new ThreadLocal<>(); |
||||
|
||||
public TransactionalFlowBusinessData() { |
||||
super(); |
||||
} |
||||
|
||||
public TransactionalFlowBusinessData(HttpServletRequest request) { |
||||
super(request); |
||||
} |
||||
|
||||
/** |
||||
* 获取HttpServletRequest属性中的事物性时间对象。如果没有情趣对象,则从线程本地存储中获取。 |
||||
* |
||||
* @return 返回设置在当前请求属性中的事务性时间对象。如果不存在则返回NULL。 |
||||
*/ |
||||
public static TransactionalFlowBusinessData getFromRequestAttribute() { |
||||
HttpServletRequest request = ContextUtil.getHttpRequest(); |
||||
if (request != null) { |
||||
return (TransactionalFlowBusinessData) request.getAttribute(BUSINESS_DATA_ATTR_KEY); |
||||
} |
||||
return FLOW_BUSINESS_DATA_THREAD_LOCAL.get(); |
||||
} |
||||
|
||||
/** |
||||
* 获取HttpServletRequest属性中的事物性时间对象。如果存在直接返回,否则创建新对象,并设置到当前请求的指定属性中。 |
||||
* 如果没有情趣对象,则从线程本地存储中创建。 |
||||
* |
||||
* @return 返回设置在当前请求属性中的事务性时间对象。 |
||||
*/ |
||||
public static TransactionalFlowBusinessData getOrCreateFromRequestAttribute() { |
||||
HttpServletRequest request = ContextUtil.getHttpRequest(); |
||||
TransactionalFlowBusinessData data; |
||||
if (request != null) { |
||||
data = (TransactionalFlowBusinessData) request.getAttribute(BUSINESS_DATA_ATTR_KEY); |
||||
if (data != null) { |
||||
return data; |
||||
} |
||||
data = new TransactionalFlowBusinessData(request); |
||||
request.setAttribute(BUSINESS_DATA_ATTR_KEY, data); |
||||
} else { |
||||
data = FLOW_BUSINESS_DATA_THREAD_LOCAL.get(); |
||||
if (data != null) { |
||||
return data; |
||||
} |
||||
data = new TransactionalFlowBusinessData(); |
||||
FLOW_BUSINESS_DATA_THREAD_LOCAL.set(data); |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
/** |
||||
* 移除该对象。 |
||||
*/ |
||||
public static void removeFromRequestAttribute() { |
||||
if (ContextUtil.hasRequestContext()) { |
||||
ContextUtil.getHttpRequest().removeAttribute(BUSINESS_DATA_ATTR_KEY); |
||||
} else { |
||||
FLOW_BUSINESS_DATA_THREAD_LOCAL.remove(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
package apelet.common.flow.online.service; |
||||
|
||||
import apelet.common.flow.model.FlowEntry; |
||||
|
||||
import javax.xml.stream.XMLStreamException; |
||||
|
||||
public interface FlowEntryOnlineService { |
||||
|
||||
void publish(FlowEntry flowEntry, String initTaskInfo) throws XMLStreamException; |
||||
|
||||
|
||||
void processFlowTaskExtList(FlowEntry flowEntry, String taskInfo) throws XMLStreamException; |
||||
} |
||||
@ -0,0 +1,163 @@
@@ -0,0 +1,163 @@
|
||||
package apelet.common.flow.online.service; |
||||
|
||||
import apelet.common.flow.model.FlowTaskComment; |
||||
import apelet.common.flow.model.FlowTransProducer; |
||||
import apelet.common.flow.model.FlowWorkOrder; |
||||
import apelet.common.online.model.OnlineDatasource; |
||||
import apelet.common.online.model.OnlineDatasourceRelation; |
||||
import apelet.common.online.model.OnlineTable; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import org.flowable.engine.runtime.ProcessInstance; |
||||
import org.flowable.task.api.Task; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 流程操作服务接口。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
public interface FlowOnlineOperationService { |
||||
|
||||
/** |
||||
* 启动流程实例,并将业务主键Id传给新启动的流程实例。 |
||||
* |
||||
* @param processDefinitionId 流程实例Id。 |
||||
* @param dataId 业务主键Id。 |
||||
*/ |
||||
ProcessInstance startWithBusinessKey(String processDefinitionId, String dataId); |
||||
|
||||
|
||||
/** |
||||
* 启动流程实例,并将业务主键Id传给新启动的流程实例。 |
||||
* |
||||
* @param processDefinitionId 流程实例Id。 |
||||
* @param dataId 业务主键Id。 |
||||
*/ |
||||
void startWithBusinessKeyExt(String processDefinitionId, String dataId,Long formId); |
||||
|
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时启动流程。如果当前用户是第一个用户任务的Assignee, |
||||
* 或者第一个用户任务的Assignee是流程发起人变量,该方法还会自动Take第一个任务。 |
||||
* |
||||
* @param processDefinitionId 流程定义Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param table 表对象。 |
||||
* @param data 表数据。 |
||||
*/ |
||||
void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data); |
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时启动流程。如果当前用户是第一个用户任务的Assignee, |
||||
* 或者第一个用户任务的Assignee是流程发起人变量,该方法还会自动Take第一个任务。 |
||||
* |
||||
* @param processDefinitionId 流程定义Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param masterTable 主表对象。 |
||||
* @param masterData 主表数据。 |
||||
* @param slaveDataListMap 关联从表数据Map。 |
||||
*/ |
||||
void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap); |
||||
|
||||
/** |
||||
* 保存在线表单的草稿数据,同时启动一个流程实例。 |
||||
* |
||||
* @param processDefinitionId 流程定义Id。 |
||||
* @param tableId 在线表单主表Id。 |
||||
* @param masterData 主表数据。 |
||||
* @param slaveData 所有关联从表数据。 |
||||
* @return 流程工单对象。 |
||||
*/ |
||||
FlowWorkOrder saveNewDraftAndStartProcess( |
||||
String processDefinitionId, Long tableId, JSONObject masterData, JSONObject slaveData); |
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时Take用户任务。 |
||||
* |
||||
* @param processInstanceId 流程实例Id。 |
||||
* @param taskId 流程任务Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param table 表对象。 |
||||
* @param data 表数据。 |
||||
*/ |
||||
void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data); |
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时Take用户任务。 |
||||
* |
||||
* @param processInstanceId 流程实例Id。 |
||||
* @param taskId 流程任务Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param masterTable 主表对象。 |
||||
* @param masterData 主表数据。 |
||||
* @param slaveDataListMap 关联从表数据Map。 |
||||
*/ |
||||
void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap); |
||||
|
||||
/** |
||||
* 保存业务表数据,同时接收流程任务。 |
||||
* |
||||
* @param task 流程任务。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param datasource 主表所在数据源。 |
||||
* @param masterData 主表数据。 |
||||
* @param masterDataId 主表数据主键。 |
||||
* @param slaveDataListMap 从表数据。 |
||||
*/ |
||||
void updateAndTakeTask( |
||||
Task task, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineDatasource datasource, |
||||
JSONObject masterData, |
||||
String masterDataId, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap); |
||||
|
||||
/** |
||||
* 修复业务数据。 |
||||
* |
||||
* @param flowTransProducer 流程操作流水生产者对象。 |
||||
*/ |
||||
void fixBusinessData(FlowTransProducer flowTransProducer); |
||||
|
||||
/** |
||||
* 获取在线表单工作流Id所关联的权限数据,包括权限字列表和权限资源列表。 |
||||
* |
||||
* @param onlineFormEntryIds 在线表单工作流Id集合。 |
||||
* @return 参数中在线表单工作流Id集合所关联的权限数据。 |
||||
*/ |
||||
List<Map<String, Object>> calculatePermData(Set<Long> onlineFormEntryIds); |
||||
} |
||||
@ -0,0 +1,319 @@
@@ -0,0 +1,319 @@
|
||||
package apelet.common.flow.online.service.impl; |
||||
|
||||
import apelet.common.core.object.TokenData; |
||||
import apelet.common.core.util.MyModelUtil; |
||||
import apelet.common.flow.constant.FlowConstant; |
||||
import apelet.common.flow.dao.FlowEntryMapper; |
||||
import apelet.common.flow.dao.FlowEntryPublishMapper; |
||||
import apelet.common.flow.dao.FlowEntryPublishVariableMapper; |
||||
import apelet.common.flow.listener.*; |
||||
import apelet.common.flow.model.*; |
||||
import apelet.common.flow.model.constant.FlowEntryStatus; |
||||
import apelet.common.flow.object.*; |
||||
import apelet.common.flow.online.listener.ApprovalSettingsByCreateListener; |
||||
import apelet.common.flow.online.service.FlowEntryOnlineService; |
||||
import apelet.common.flow.service.*; |
||||
import apelet.common.flow.util.BaseFlowIdentityExtHelper; |
||||
import apelet.common.flow.util.FlowCustomExtFactory; |
||||
import apelet.common.flow.util.FlowRedisKeyUtil; |
||||
import apelet.common.redis.util.CommonRedisUtil; |
||||
import apelet.common.sequence.wrapper.IdGeneratorWrapper; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.lang.Assert; |
||||
import cn.hutool.core.util.BooleanUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.Cleanup; |
||||
import org.flowable.bpmn.converter.BpmnXMLConverter; |
||||
import org.flowable.bpmn.model.*; |
||||
import org.flowable.engine.RepositoryService; |
||||
import org.flowable.engine.repository.Deployment; |
||||
import org.flowable.engine.repository.ProcessDefinition; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import javax.xml.stream.XMLInputFactory; |
||||
import javax.xml.stream.XMLStreamException; |
||||
import javax.xml.stream.XMLStreamReader; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
@Service("flowEntryOnlineService") |
||||
public class FlowEntryOnlineServiceImpl implements FlowEntryOnlineService { |
||||
|
||||
@Autowired |
||||
private FlowEntryMapper flowEntryMapper; |
||||
@Autowired |
||||
private FlowEntryPublishMapper flowEntryPublishMapper; |
||||
@Autowired |
||||
private FlowEntryPublishVariableMapper flowEntryPublishVariableMapper; |
||||
@Autowired |
||||
private FlowEntryVariableService flowEntryVariableService; |
||||
@Autowired |
||||
private FlowCategoryService flowCategoryService; |
||||
@Autowired |
||||
private FlowTaskExtService flowTaskExtService; |
||||
@Autowired |
||||
private FlowApiService flowApiService; |
||||
@Autowired |
||||
private FlowCustomExtFactory flowCustomExtFactory; |
||||
@Autowired |
||||
private RepositoryService repositoryService; |
||||
@Autowired |
||||
private IdGeneratorWrapper idGenerator; |
||||
@Autowired |
||||
private CommonRedisUtil commonRedisUtil; |
||||
|
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void publish(FlowEntry flowEntry, String initTaskInfo) throws XMLStreamException { |
||||
commonRedisUtil.evictFormCache( |
||||
FlowRedisKeyUtil.makeFlowEntryKey(flowEntry.getProcessDefinitionKey())); |
||||
FlowCategory flowCategory = flowCategoryService.getById(flowEntry.getCategoryId()); |
||||
InputStream xmlStream = new ByteArrayInputStream( |
||||
flowEntry.getBpmnXml().getBytes(StandardCharsets.UTF_8)); |
||||
@Cleanup XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(xmlStream); |
||||
BpmnXMLConverter converter = new BpmnXMLConverter(); |
||||
BpmnModel bpmnModel = converter.convertToBpmnModel(reader); |
||||
bpmnModel.getMainProcess().setName(flowEntry.getProcessDefinitionName()); |
||||
bpmnModel.getMainProcess().setId(flowEntry.getProcessDefinitionKey()); |
||||
flowApiService.addProcessInstanceEndListener(bpmnModel, FlowFinishedListener.class); |
||||
List<FlowTaskExt> flowTaskExtList = flowTaskExtService.buildTaskExtList(bpmnModel); |
||||
if (StrUtil.isNotBlank(flowEntry.getExtensionData())) { |
||||
FlowEntryExtensionData flowEntryExtensionData = |
||||
JSON.parseObject(flowEntry.getExtensionData(), FlowEntryExtensionData.class); |
||||
this.mergeTaskNotifyData(flowEntryExtensionData, flowTaskExtList); |
||||
this.processFlowTaskRevive(flowEntryExtensionData, bpmnModel); |
||||
} |
||||
this.processFlowTaskExtList(flowTaskExtList, bpmnModel); |
||||
TokenData tokenData = TokenData.takeFromRequest(); |
||||
Deployment deploy = repositoryService.createDeployment() |
||||
.addBpmnModel(flowEntry.getProcessDefinitionKey() + ".bpmn", bpmnModel) |
||||
.tenantId(tokenData.getTenantId() != null ? tokenData.getTenantId().toString() : tokenData.getAppCode()) |
||||
.name(flowEntry.getProcessDefinitionName()) |
||||
.key(flowEntry.getProcessDefinitionKey()) |
||||
.category(flowCategory.getCode()) |
||||
.deploy(); |
||||
ProcessDefinition processDefinition = flowApiService.getProcessDefinitionByDeployId(deploy.getId()); |
||||
FlowEntryPublish flowEntryPublish = new FlowEntryPublish(); |
||||
flowEntryPublish.setEntryPublishId(idGenerator.nextLongId()); |
||||
flowEntryPublish.setEntryId(flowEntry.getEntryId()); |
||||
flowEntryPublish.setProcessDefinitionId(processDefinition.getId()); |
||||
flowEntryPublish.setDeployId(processDefinition.getDeploymentId()); |
||||
flowEntryPublish.setPublishVersion(processDefinition.getVersion()); |
||||
flowEntryPublish.setActiveStatus(true); |
||||
flowEntryPublish.setMainVersion(flowEntry.getStatus().equals(FlowEntryStatus.UNPUBLISHED)); |
||||
flowEntryPublish.setCreateUserId(TokenData.takeFromRequest().getUserId()); |
||||
flowEntryPublish.setPublishTime(new Date()); |
||||
flowEntryPublish.setInitTaskInfo(initTaskInfo); |
||||
flowEntryPublish.setExtensionData(flowEntry.getExtensionData()); |
||||
flowEntryPublish.setStartConditions(flowEntry.getStartConditions()); |
||||
AnalyzedNode rootNode = flowApiService.analyzeBpmnRoads(processDefinition.getId()); |
||||
flowEntryPublish.setAnalyzedNodeJson(JSON.toJSONString(rootNode)); |
||||
flowEntryPublishMapper.insert(flowEntryPublish); |
||||
FlowEntry updatedFlowEntry = new FlowEntry(); |
||||
updatedFlowEntry.setEntryId(flowEntry.getEntryId()); |
||||
updatedFlowEntry.setStatus(FlowEntryStatus.PUBLISHED); |
||||
updatedFlowEntry.setLatestPublishTime(new Date()); |
||||
// 对于从未发布过的工作,第一次发布的时候会将本地发布置位主版本。
|
||||
if (flowEntry.getStatus().equals(FlowEntryStatus.UNPUBLISHED)) { |
||||
updatedFlowEntry.setMainEntryPublishId(flowEntryPublish.getEntryPublishId()); |
||||
} |
||||
flowEntryMapper.updateById(updatedFlowEntry); |
||||
FlowEntryVariable flowEntryVariableFilter = new FlowEntryVariable(); |
||||
flowEntryVariableFilter.setEntryId(flowEntry.getEntryId()); |
||||
List<FlowEntryVariable> flowEntryVariableList = |
||||
flowEntryVariableService.getFlowEntryVariableList(flowEntryVariableFilter, null); |
||||
if (CollUtil.isNotEmpty(flowTaskExtList)) { |
||||
flowTaskExtList.forEach(t -> t.setProcessDefinitionId(processDefinition.getId())); |
||||
flowTaskExtService.saveBatch(flowTaskExtList); |
||||
} |
||||
this.insertEntryPublishVariables(flowEntryVariableList, flowEntryPublish.getEntryPublishId()); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void processFlowTaskExtList(FlowEntry flowEntry,String taskInfo) throws XMLStreamException { |
||||
|
||||
InputStream xmlStream = new ByteArrayInputStream( |
||||
flowEntry.getBpmnXml().getBytes(StandardCharsets.UTF_8)); |
||||
@Cleanup XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(xmlStream); |
||||
BpmnXMLConverter converter = new BpmnXMLConverter(); |
||||
BpmnModel bpmnModel = converter.convertToBpmnModel(reader); |
||||
bpmnModel.getMainProcess().setName(flowEntry.getProcessDefinitionName()); |
||||
bpmnModel.getMainProcess().setId(flowEntry.getProcessDefinitionKey()); |
||||
|
||||
List<FlowTaskExt> flowTaskExtList = flowTaskExtService.buildTaskExtList(bpmnModel); |
||||
|
||||
List<FlowElement> elementList = new LinkedList<>(); |
||||
this.calculateAllElementList(bpmnModel.getMainProcess().getFlowElements(), elementList); |
||||
|
||||
Map<String, FlowElement> elementMap = elementList.stream() |
||||
.filter(UserTask.class::isInstance).collect(Collectors.toMap(FlowElement::getId, c -> c)); |
||||
for (FlowTaskExt t : flowTaskExtList) { |
||||
UserTask userTask = (UserTask) elementMap.get(t.getTaskId()); |
||||
// create 创建
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "create"); |
||||
// assignment 分配/指派
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "assignment"); |
||||
// complete 完成
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "complete"); |
||||
// delete 删除
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "delete"); |
||||
} |
||||
} |
||||
|
||||
private void calculateAllElementList(Collection<FlowElement> elements, List<FlowElement> resultList) { |
||||
resultList.addAll(elements); |
||||
for (FlowElement element : elements) { |
||||
if (element instanceof SubProcess) { |
||||
this.calculateAllElementList(((SubProcess) element).getFlowElements(), resultList); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void mergeTaskNotifyData(FlowEntryExtensionData flowEntryExtensionData, List<FlowTaskExt> flowTaskExtList) { |
||||
if (CollUtil.isEmpty(flowEntryExtensionData.getNotifyTypes())) { |
||||
return; |
||||
} |
||||
List<String> flowTaskNotifyTypes = |
||||
flowEntryExtensionData.getNotifyTypes().stream().filter(StrUtil::isNotBlank).collect(Collectors.toList()); |
||||
if (CollUtil.isEmpty(flowTaskNotifyTypes)) { |
||||
return; |
||||
} |
||||
for (FlowTaskExt flowTaskExt : flowTaskExtList) { |
||||
if (flowTaskExt.getExtraDataJson() == null) { |
||||
JSONObject o = new JSONObject(); |
||||
o.put(FlowConstant.USER_TASK_NOTIFY_TYPES_KEY, flowTaskNotifyTypes); |
||||
flowTaskExt.setExtraDataJson(o.toJSONString()); |
||||
} else { |
||||
FlowUserTaskExtData taskExtData = |
||||
JSON.parseObject(flowTaskExt.getExtraDataJson(), FlowUserTaskExtData.class); |
||||
if (CollUtil.isEmpty(taskExtData.getFlowNotifyTypeList())) { |
||||
taskExtData.setFlowNotifyTypeList(flowTaskNotifyTypes); |
||||
} else { |
||||
Set<String> notifyTypesSet = taskExtData.getFlowNotifyTypeList() |
||||
.stream().filter(StrUtil::isNotBlank).collect(Collectors.toSet()); |
||||
notifyTypesSet.addAll(flowTaskNotifyTypes); |
||||
taskExtData.setFlowNotifyTypeList(new LinkedList<>(notifyTypesSet)); |
||||
} |
||||
flowTaskExt.setExtraDataJson(JSON.toJSONString(taskExtData)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void processFlowTaskRevive(FlowEntryExtensionData flowEntryExtensionData, BpmnModel bpmnModel) { |
||||
if (BooleanUtil.isTrue(flowEntryExtensionData.getSupportRevive())) { |
||||
List<UserTask> mainProcessUserTasks = bpmnModel.getMainProcess().getFlowElements() |
||||
.stream().filter(UserTask.class::isInstance).map(t -> (UserTask) t).collect(Collectors.toList()); |
||||
mainProcessUserTasks.forEach(t -> flowApiService.addTaskCreateListener(t, FlowTaskReviveListener.class)); |
||||
} |
||||
} |
||||
|
||||
private void processFlowTaskExtList(List<FlowTaskExt> flowTaskExtList, BpmnModel bpmnModel) { |
||||
List<FlowElement> elementList = new LinkedList<>(); |
||||
this.calculateAllElementList(bpmnModel.getMainProcess().getFlowElements(), elementList); |
||||
this.doAddLatestApprovalStatusListener(elementList); |
||||
Map<String, FlowElement> elementMap = elementList.stream() |
||||
.filter(UserTask.class::isInstance).collect(Collectors.toMap(FlowElement::getId, c -> c)); |
||||
BaseFlowIdentityExtHelper flowIdentityExtHelper = flowCustomExtFactory.getFlowIdentityExtHelper(); |
||||
for (FlowTaskExt t : flowTaskExtList) { |
||||
UserTask userTask = (UserTask) elementMap.get(t.getTaskId()); |
||||
flowApiService.addTaskCreateListener(userTask, FlowUserTaskListener.class); |
||||
// create 创建
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "create"); |
||||
// assignment 分配/指派
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "assignment"); |
||||
// complete 完成
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "complete"); |
||||
// delete 删除
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "delete"); |
||||
|
||||
Map<String, List<ExtensionAttribute>> attributes = userTask.getAttributes(); |
||||
if (CollUtil.isNotEmpty(attributes.get(FlowConstant.USER_TASK_AUTO_SKIP_KEY))) { |
||||
flowApiService.addTaskCreateListener(userTask, AutoSkipTaskListener.class); |
||||
} |
||||
// 如果流程图中包含部门领导审批和上级部门领导审批的选项,就需要注册 FlowCustomExtFactory 工厂中的
|
||||
// BaseFlowIdentityExtHelper 对象,该注册操作需要业务模块中实现。
|
||||
if (StrUtil.equals(t.getGroupType(), FlowConstant.GROUP_TYPE_UP_DEPT_POST_LEADER)) { |
||||
userTask.setCandidateGroups( |
||||
CollUtil.newArrayList("${" + FlowConstant.GROUP_TYPE_UP_DEPT_POST_LEADER_VAR + "}")); |
||||
Assert.notNull(flowIdentityExtHelper); |
||||
flowApiService.addTaskCreateListener(userTask, flowIdentityExtHelper.getUpDeptPostLeaderListener()); |
||||
} else if (StrUtil.equals(t.getGroupType(), FlowConstant.GROUP_TYPE_DEPT_POST_LEADER)) { |
||||
userTask.setCandidateGroups( |
||||
CollUtil.newArrayList("${" + FlowConstant.GROUP_TYPE_DEPT_POST_LEADER_VAR + "}")); |
||||
Assert.notNull(flowIdentityExtHelper); |
||||
flowApiService.addTaskCreateListener(userTask, flowIdentityExtHelper.getDeptPostLeaderListener()); |
||||
} else if (StrUtil.equals(t.getGroupType(), FlowConstant.GROUP_TYPE_POST)) { |
||||
Assert.notNull(t.getDeptPostListJson()); |
||||
List<FlowTaskPostCandidateGroup> groupDataList = |
||||
JSON.parseArray(t.getDeptPostListJson(), FlowTaskPostCandidateGroup.class); |
||||
List<String> candidateGroupList = |
||||
FlowTaskPostCandidateGroup.buildCandidateGroupList(groupDataList); |
||||
userTask.setCandidateGroups(candidateGroupList); |
||||
} |
||||
this.processFlowTaskExtListener(userTask, t); |
||||
} |
||||
} |
||||
|
||||
private void insertEntryPublishVariables(List<FlowEntryVariable> entryVariableList, Long entryPublishId) { |
||||
if (CollUtil.isEmpty(entryVariableList)) { |
||||
return; |
||||
} |
||||
List<FlowEntryPublishVariable> entryPublishVariableList = |
||||
MyModelUtil.copyCollectionTo(entryVariableList, FlowEntryPublishVariable.class); |
||||
for (FlowEntryPublishVariable variable : entryPublishVariableList) { |
||||
variable.setVariableId(idGenerator.nextLongId()); |
||||
variable.setEntryPublishId(entryPublishId); |
||||
} |
||||
flowEntryPublishVariableMapper.insertList(entryPublishVariableList); |
||||
} |
||||
|
||||
private void doAddLatestApprovalStatusListener(Collection<FlowElement> elementList) { |
||||
List<FlowElement> sequenceFlowList = |
||||
elementList.stream().filter(SequenceFlow.class::isInstance).collect(Collectors.toList()); |
||||
for (FlowElement sequenceFlow : sequenceFlowList) { |
||||
FlowElementExtProperty extProperty = flowTaskExtService.buildFlowElementExt(sequenceFlow); |
||||
if (extProperty != null && extProperty.getLatestApprovalStatus() != null) { |
||||
List<FieldExtension> fieldExtensions = new LinkedList<>(); |
||||
FieldExtension fieldExtension = new FieldExtension(); |
||||
fieldExtension.setFieldName(FlowConstant.LATEST_APPROVAL_STATUS_KEY); |
||||
fieldExtension.setStringValue(extProperty.getLatestApprovalStatus().toString()); |
||||
fieldExtensions.add(fieldExtension); |
||||
flowApiService.addExecutionListener( |
||||
sequenceFlow, UpdateLatestApprovalStatusListener.class, "start", fieldExtensions); |
||||
} |
||||
} |
||||
List<SubProcess> subProcesseList = elementList.stream() |
||||
.filter(SubProcess.class::isInstance).map(SubProcess.class::cast).collect(Collectors.toList()); |
||||
for (SubProcess subProcess : subProcesseList) { |
||||
this.doAddLatestApprovalStatusListener(subProcess.getFlowElements()); |
||||
} |
||||
} |
||||
|
||||
private void processFlowTaskExtListener(UserTask userTask, FlowTaskExt taskExt) { |
||||
if (StrUtil.isBlank(taskExt.getExtraDataJson())) { |
||||
return; |
||||
} |
||||
FlowUserTaskExtData userTaskExtData = |
||||
JSON.parseObject(taskExt.getExtraDataJson(), FlowUserTaskExtData.class); |
||||
if (CollUtil.isNotEmpty(userTaskExtData.getFlowNotifyTypeList())) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowTaskNotifyListener.class); |
||||
} |
||||
if (userTaskExtData.getRejectType().equals(FlowUserTaskExtData.REJECT_TYPE_BACK_TO_SOURCE)) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowTaskRejectBackListener.class); |
||||
} |
||||
if (StrUtil.isNotBlank(userTaskExtData.getTimeoutHandleWay())) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowTaskTimeoutListener.class); |
||||
} |
||||
if (StrUtil.isNotBlank(userTaskExtData.getEmptyUserHandleWay())) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowEmptyUserHandleListener.class); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
package apelet.common.flow.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MyDataSource; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.flow.base.service.BaseFlowOnlineService; |
||||
import apelet.common.flow.model.FlowWorkOrder; |
||||
import apelet.common.flow.online.object.TransactionalFlowBusinessData; |
||||
import apelet.common.flow.util.FlowCustomExtFactory; |
||||
import apelet.common.online.exception.OnlineRuntimeException; |
||||
import apelet.common.online.model.*; |
||||
import apelet.common.online.model.constant.FieldKind; |
||||
import apelet.common.online.service.*; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import javax.annotation.PostConstruct; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 在线表单和流程监听器进行数据对接时的服务实现类。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Slf4j |
||||
@MyDataSource(ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("flowOnlineBusinessService") |
||||
public class FlowOnlineBusinessServiceImpl implements BaseFlowOnlineService { |
||||
|
||||
@Autowired |
||||
private FlowCustomExtFactory flowCustomExtFactory; |
||||
@Autowired |
||||
private OnlineTableService onlineTableService; |
||||
@Autowired |
||||
private OnlineDatasourceService onlineDatasourceService; |
||||
@Autowired |
||||
private OnlineDatasourceRelationService onlineDatasourceRelationService; |
||||
@Autowired |
||||
private OnlineOperationService onlineOperationService; |
||||
|
||||
@PostConstruct |
||||
public void doRegister() { |
||||
flowCustomExtFactory.getOnlineBusinessDataExtHelper().setOnlineBusinessService(this); |
||||
} |
||||
|
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void updateFlowStatus(FlowWorkOrder workOrder) { |
||||
OnlineTable onlineTable = onlineTableService.getOnlineTableFromCache(workOrder.getOnlineTableId()); |
||||
if (onlineTable == null) { |
||||
log.error("OnlineTableId [{}] doesn't exist while calling FlowOnlineBusinessServiceImpl.updateFlowStatus", |
||||
workOrder.getOnlineTableId()); |
||||
return; |
||||
} |
||||
String dataId = workOrder.getBusinessKey(); |
||||
this.handleTransactionalFlowBusinessData(workOrder, "FlowOnlineBusinessServiceImpl.updateFlowStatus"); |
||||
for (OnlineColumn column : onlineTable.getColumnMap().values()) { |
||||
if (ObjectUtil.equals(column.getFieldKind(), FieldKind.FLOW_FINISHED_STATUS)) { |
||||
onlineOperationService.updateColumn(onlineTable, dataId, column, workOrder.getFlowStatus()); |
||||
} |
||||
if (ObjectUtil.equals(column.getFieldKind(), FieldKind.FLOW_APPROVAL_STATUS)) { |
||||
onlineOperationService.updateColumn(onlineTable, dataId, column, workOrder.getLatestApprovalStatus()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void deleteBusinessData(FlowWorkOrder workOrder) { |
||||
OnlineTable onlineTable = onlineTableService.getOnlineTableFromCache(workOrder.getOnlineTableId()); |
||||
if (onlineTable == null) { |
||||
log.error("OnlineTableId [{}] doesn't exist while calling FlowOnlineBusinessServiceImpl.deleteBusinessData", |
||||
workOrder.getOnlineTableId()); |
||||
return; |
||||
} |
||||
OnlineDatasource datasource = |
||||
onlineDatasourceService.getOnlineDatasourceByMasterTableId(onlineTable.getTableId()); |
||||
List<OnlineDatasourceRelation> relationList = |
||||
onlineDatasourceRelationService.getOnlineDatasourceRelationListFromCache(CollUtil.newHashSet(datasource.getDatasourceId())); |
||||
String dataId = workOrder.getBusinessKey(); |
||||
for (OnlineDatasourceRelation relation : relationList) { |
||||
OnlineTable slaveTable = onlineTableService.getOnlineTableFromCache(relation.getSlaveTableId()); |
||||
if (slaveTable == null) { |
||||
throw new OnlineRuntimeException("数据验证失败,数据源关联 [" + relation.getRelationName() + "] 的从表Id不存在!"); |
||||
} |
||||
relation.setSlaveTable(slaveTable); |
||||
} |
||||
this.handleTransactionalFlowBusinessData(workOrder, "FlowOnlineBusinessServiceImpl.deleteBusinessData"); |
||||
onlineOperationService.delete(onlineTable, relationList, dataId); |
||||
} |
||||
|
||||
private void handleTransactionalFlowBusinessData(FlowWorkOrder workOrder, String desc) { |
||||
TransactionalFlowBusinessData eventData = TransactionalFlowBusinessData.getFromRequestAttribute(); |
||||
if (eventData != null) { |
||||
eventData.setProcessInstanceId(workOrder.getProcessInstanceId()); |
||||
eventData.setOperationDesc(desc); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,434 @@
@@ -0,0 +1,434 @@
|
||||
package apelet.common.flow.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MultiDatabaseWriteMethod; |
||||
import apelet.common.core.annotation.MyDataSource; |
||||
import apelet.common.core.config.CoreProperties; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.core.object.CallResult; |
||||
import apelet.common.core.object.ObjectValue; |
||||
import apelet.common.dbutil.provider.DataSourceProvider; |
||||
import apelet.common.dbutil.provider.PostgreSqlProvider; |
||||
import apelet.common.flow.config.FlowProperties; |
||||
import apelet.common.flow.constant.FlowApprovalType; |
||||
import apelet.common.flow.constant.FlowConstant; |
||||
import apelet.common.flow.constant.FlowTaskStatus; |
||||
import apelet.common.flow.dao.FlowTransProducerMapper; |
||||
import apelet.common.flow.exception.FlowOperationException; |
||||
import apelet.common.flow.model.*; |
||||
import apelet.common.flow.online.object.TransactionalFlowBusinessData; |
||||
import apelet.common.flow.online.service.FlowOnlineOperationService; |
||||
import apelet.common.flow.service.FlowApiService; |
||||
import apelet.common.flow.service.FlowEntryService; |
||||
import apelet.common.flow.service.FlowWorkOrderService; |
||||
import apelet.common.generator.utils.OrmGenDataSourceUtil; |
||||
import apelet.common.online.config.OnlineProperties; |
||||
import apelet.common.online.exception.OnlineRuntimeException; |
||||
import apelet.common.online.model.*; |
||||
import apelet.common.online.object.TransactionalBusinessData; |
||||
import apelet.common.online.service.*; |
||||
import apelet.common.online.util.OnlineDataSourceUtil; |
||||
import apelet.common.orm.impl.Selector; |
||||
import apelet.common.orm.impl.SelectorItem; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.lang.Assert; |
||||
import cn.hutool.core.map.MapUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.flowable.engine.runtime.ProcessInstance; |
||||
import org.flowable.task.api.Task; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
import org.springframework.transaction.event.TransactionPhase; |
||||
import org.springframework.transaction.event.TransactionalEventListener; |
||||
|
||||
import java.sql.Connection; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
@Slf4j |
||||
@MyDataSource(ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("flowOnlineOperationService") |
||||
public class FlowOnlineOperationServiceImpl implements FlowOnlineOperationService { |
||||
|
||||
@Autowired |
||||
private FlowApiService flowApiService; |
||||
@Autowired |
||||
private FlowWorkOrderService flowWorkOrderService; |
||||
@Autowired |
||||
private FlowEntryService flowEntryService; |
||||
@Autowired |
||||
private OnlineOperationService onlineOperationService; |
||||
@Autowired |
||||
private OnlineDatasourceService onlineDatasourceService; |
||||
@Autowired |
||||
private OnlineProperties onlineProperties; |
||||
@Autowired |
||||
private FlowProperties flowProperties; |
||||
@Autowired |
||||
private CoreProperties coreProperties; |
||||
@Autowired |
||||
private OnlineDataSourceUtil dataSourceUtil; |
||||
@Autowired |
||||
private FlowTransProducerMapper flowTransProducerMapper; |
||||
@Autowired |
||||
private OnlineFormService onlineFormService; |
||||
@Autowired |
||||
private OnlineTableService onlineTableService; |
||||
|
||||
@Autowired |
||||
private OrmGenDataSourceUtil ormGenDataSourceUtil; |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public ProcessInstance startWithBusinessKey(String processDefinitionId, String dataId) { |
||||
ProcessInstance instance = flowApiService.start(processDefinitionId, dataId); |
||||
flowWorkOrderService.saveNew(instance, dataId, null, null); |
||||
return instance; |
||||
} |
||||
|
||||
@Override |
||||
public void startWithBusinessKeyExt(String processDefinitionId, String dataId, Long formId) { |
||||
OnlineForm OnlineForm = onlineFormService.getOnlineFormFromCache(formId); |
||||
OnlineTable onlineTable = onlineTableService.getOnlineTableFromCache(OnlineForm.getMasterTableId()); |
||||
Selector selector = new Selector(); |
||||
selector.getList().add(new SelectorItem("billstatus")); |
||||
ObjectValue objectValue = ormGenDataSourceUtil.queryOne(onlineTable.getTableName(),Long.valueOf(dataId),selector); |
||||
if(objectValue == null){ |
||||
String errorMessage = "无效数据!"; |
||||
throw new RuntimeException(errorMessage); |
||||
} |
||||
if(!objectValue.get("billstatus").equals("A")){ |
||||
throw new RuntimeException("只有保存状态才能提交"); |
||||
} |
||||
objectValue.put("billstatus","B"); |
||||
try { |
||||
ormGenDataSourceUtil.update(onlineTable.getTableName(),objectValue,selector); |
||||
}catch (Exception e){ |
||||
e.printStackTrace(); |
||||
String errorMessage = "更新失败!错误信息:"+e.getMessage(); |
||||
throw new RuntimeException(errorMessage); |
||||
} |
||||
if(processDefinitionId != null){ |
||||
JSONObject taskVariableData = new JSONObject(); |
||||
ProcessInstance instance = this.startWithBusinessKey(processDefinitionId,dataId); |
||||
FlowTaskComment flowTaskComment = new FlowTaskComment(); |
||||
flowTaskComment.setApprovalType("agree"); |
||||
flowTaskComment.setTaskComment("发起人"); |
||||
flowApiService.takeFirstTask(instance.getProcessInstanceId(), flowTaskComment, taskVariableData); |
||||
} |
||||
|
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data) { |
||||
this.saveNewAndStartProcess(processDefinitionId, flowTaskComment, taskVariableData, table, data, null); |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
Object dataId = onlineOperationService.saveNewWithRelation(masterTable, masterData, slaveDataListMap); |
||||
Assert.notNull(dataId); |
||||
if (taskVariableData == null) { |
||||
taskVariableData = new JSONObject(); |
||||
} |
||||
taskVariableData.put(FlowConstant.MASTER_DATA_KEY, masterData); |
||||
taskVariableData.put(FlowConstant.SLAVE_DATA_KEY, this.normailizeSlaveDataListMap(slaveDataListMap)); |
||||
taskVariableData.put(FlowConstant.MASTER_TABLE_KEY, masterTable); |
||||
ProcessInstance instance = flowApiService.start(processDefinitionId, dataId); |
||||
flowWorkOrderService.saveNew(instance, dataId, masterTable.getTableId(), null); |
||||
flowApiService.takeFirstTask(instance.getProcessInstanceId(), flowTaskComment, taskVariableData); |
||||
// 这里需要在创建工单后再次更新一下工单状态,在flowApiService.completeTask中的更新,
|
||||
// 因为当时没有创建工单对象,更新会不起任何作用,所以这里要补偿一下。
|
||||
Integer approvalStatus = MapUtil.getInt(taskVariableData, FlowConstant.LATEST_APPROVAL_STATUS_KEY); |
||||
flowWorkOrderService.updateLatestApprovalStatusByProcessInstanceId(instance.getId(), approvalStatus); |
||||
} |
||||
|
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public FlowWorkOrder saveNewDraftAndStartProcess( |
||||
String processDefinitionId, Long tableId, JSONObject masterData, JSONObject slaveData) { |
||||
ProcessInstance instance = flowApiService.start(processDefinitionId, null); |
||||
return flowWorkOrderService.saveNewWithDraft( |
||||
instance, tableId, null, JSON.toJSONString(masterData), JSON.toJSONString(slaveData)); |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data) { |
||||
this.saveNewAndTakeTask( |
||||
processInstanceId, taskId, flowTaskComment, taskVariableData, table, data, null); |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
Object dataId = onlineOperationService.saveNewWithRelation(masterTable, masterData, slaveDataListMap); |
||||
Assert.notNull(dataId); |
||||
Task task = flowApiService.getProcessInstanceActiveTask(processInstanceId, taskId); |
||||
flowApiService.setBusinessKeyForProcessInstance(processInstanceId, dataId); |
||||
Map<String, Object> variables = |
||||
flowApiService.initAndGetProcessInstanceVariables(task.getProcessDefinitionId()); |
||||
if (taskVariableData == null) { |
||||
taskVariableData = new JSONObject(); |
||||
} |
||||
taskVariableData.putAll(variables); |
||||
taskVariableData.put(FlowConstant.MASTER_DATA_KEY, masterData); |
||||
taskVariableData.put(FlowConstant.SLAVE_DATA_KEY, this.normailizeSlaveDataListMap(slaveDataListMap)); |
||||
taskVariableData.put(FlowConstant.MASTER_TABLE_KEY, masterTable); |
||||
flowApiService.completeTask(task, flowTaskComment, taskVariableData, null); |
||||
ProcessInstance instance = flowApiService.getProcessInstance(processInstanceId); |
||||
FlowWorkOrder flowWorkOrder = |
||||
flowWorkOrderService.getFlowWorkOrderByProcessInstanceId(instance.getProcessInstanceId()); |
||||
if (flowWorkOrder == null) { |
||||
flowWorkOrderService.saveNew(instance, dataId, masterTable.getTableId(), null); |
||||
} else { |
||||
flowWorkOrder.setBusinessKey(dataId.toString()); |
||||
flowWorkOrder.setUpdateTime(new Date()); |
||||
flowWorkOrder.setFlowStatus(FlowTaskStatus.SUBMITTED); |
||||
flowWorkOrderService.updateById(flowWorkOrder); |
||||
} |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void updateAndTakeTask( |
||||
Task task, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineDatasource datasource, |
||||
JSONObject masterData, |
||||
String masterDataId, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
int flowStatus = FlowTaskStatus.APPROVING; |
||||
if (flowTaskComment.getApprovalType().equals(FlowApprovalType.REFUSE)) { |
||||
flowStatus = FlowTaskStatus.REFUSED; |
||||
} else if (flowTaskComment.getApprovalType().equals(FlowApprovalType.STOP)) { |
||||
flowStatus = FlowTaskStatus.FINISHED; |
||||
} |
||||
OnlineTable masterTable = datasource.getMasterTable(); |
||||
Long datasourceId = datasource.getDatasourceId(); |
||||
flowWorkOrderService.updateFlowStatusByProcessInstanceId(task.getProcessInstanceId(), flowStatus); |
||||
this.updateMasterData(masterTable, masterData, masterDataId); |
||||
if (slaveDataListMap != null) { |
||||
for (Map.Entry<OnlineDatasourceRelation, List<JSONObject>> relationEntry : slaveDataListMap.entrySet()) { |
||||
Long relationId = relationEntry.getKey().getRelationId(); |
||||
onlineOperationService.updateRelationData( |
||||
masterTable, masterData, masterDataId, datasourceId, relationId, relationEntry.getValue()); |
||||
} |
||||
} |
||||
if (flowTaskComment.getApprovalType().equals(FlowApprovalType.STOP)) { |
||||
Integer s = MapUtil.getInt(taskVariableData, FlowConstant.LATEST_APPROVAL_STATUS_KEY); |
||||
flowWorkOrderService.updateLatestApprovalStatusByProcessInstanceId(task.getProcessInstanceId(), s); |
||||
CallResult stopResult = flowApiService.stopProcessInstance( |
||||
task.getProcessInstanceId(), flowTaskComment.getTaskComment(), flowStatus); |
||||
if (!stopResult.isSuccess()) { |
||||
throw new FlowOperationException(stopResult.getErrorMessage()); |
||||
} |
||||
} else { |
||||
if (taskVariableData == null) { |
||||
taskVariableData = new JSONObject(); |
||||
} |
||||
taskVariableData.put(FlowConstant.MASTER_DATA_KEY, masterData); |
||||
taskVariableData.put(FlowConstant.SLAVE_DATA_KEY, this.normailizeSlaveDataListMap(slaveDataListMap)); |
||||
taskVariableData.put(FlowConstant.MASTER_TABLE_KEY, masterTable); |
||||
flowApiService.completeTask(task, flowTaskComment, taskVariableData, null); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void fixBusinessData(FlowTransProducer flowTransProducer) { |
||||
try { |
||||
String sql = "SELECT * FROM zz_flow_trans_consumer WHERE trans_id = " + flowTransProducer.getTransId(); |
||||
List<Map<String, Object>> dataList = dataSourceUtil.query(flowTransProducer.getDblinkId(), sql); |
||||
if (CollUtil.isNotEmpty(dataList)) { |
||||
return; |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("Failed to call dataSourceUtil.query", e); |
||||
throw new OnlineRuntimeException(e.getMessage()); |
||||
} |
||||
TransactionalFlowBusinessData businessData = new TransactionalFlowBusinessData(); |
||||
businessData.setTransId(flowTransProducer.getTransId()); |
||||
businessData.setDblinkId(flowTransProducer.getDblinkId()); |
||||
List<TransactionalBusinessData.BusinessSqlData> sqlDataList = |
||||
JSON.parseArray(flowTransProducer.getSqlData(), TransactionalBusinessData.BusinessSqlData.class); |
||||
businessData.setSqlDataList(sqlDataList); |
||||
try { |
||||
this.doHandle(businessData); |
||||
} catch (Exception e) { |
||||
log.error(e.getMessage(), e); |
||||
throw new OnlineRuntimeException(e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public List<Map<String, Object>> calculatePermData(Set<Long> onlineFormEntryIds) { |
||||
if (CollUtil.isEmpty(onlineFormEntryIds)) { |
||||
return new LinkedList<>(); |
||||
} |
||||
List<Map<String, Object>> permDataList = new LinkedList<>(); |
||||
List<FlowEntry> flowEntries = flowEntryService.getInList(onlineFormEntryIds); |
||||
Set<Long> pageIds = flowEntries.stream().map(FlowEntry::getPageId).collect(Collectors.toSet()); |
||||
Map<Long, String> pageAndVariableNameMap = |
||||
onlineDatasourceService.getPageIdAndVariableNameMapByPageIds(pageIds); |
||||
for (FlowEntry flowEntry : flowEntries) { |
||||
JSONObject permData = new JSONObject(); |
||||
permData.put("entryId", flowEntry.getEntryId()); |
||||
String key = StrUtil.upperFirst(flowEntry.getProcessDefinitionKey()); |
||||
List<String> permCodeList = new LinkedList<>(); |
||||
String formPermCode = "form" + key; |
||||
permCodeList.add(formPermCode); |
||||
permCodeList.add(formPermCode + ":fragment" + key); |
||||
permData.put("permCodeList", permCodeList); |
||||
String flowUrlPrefix = flowProperties.getUrlPrefix(); |
||||
String onlineUrlPrefix = onlineProperties.getUrlPrefix(); |
||||
List<String> permList = CollUtil.newLinkedList( |
||||
onlineUrlPrefix + "/onlineForm/view", |
||||
onlineUrlPrefix + "/onlineForm/render", |
||||
onlineUrlPrefix + "/onlineOperation/listByOneToManyRelationId/" + pageAndVariableNameMap.get(flowEntry.getPageId()), |
||||
flowUrlPrefix + "/flowOperation/viewInitialHistoricTaskInfo", |
||||
flowUrlPrefix + "/flowOperation/startOnly", |
||||
flowUrlPrefix + "/flowOperation/viewInitialTaskInfo", |
||||
flowUrlPrefix + "/flowOperation/viewRuntimeTaskInfo", |
||||
flowUrlPrefix + "/flowOperation/viewProcessBpmn", |
||||
flowUrlPrefix + "/flowOperation/viewHighlightFlowData", |
||||
flowUrlPrefix + "/flowOperation/listFlowTaskComment", |
||||
flowUrlPrefix + "/flowOperation/cancelWorkOrder", |
||||
flowUrlPrefix + "/flowOperation/listRuntimeTask", |
||||
flowUrlPrefix + "/flowOperation/listHistoricProcessInstance", |
||||
flowUrlPrefix + "/flowOperation/listHistoricTask", |
||||
flowUrlPrefix + "/flowOperation/freeJumpTo", |
||||
flowUrlPrefix + "/flowOnlineOperation/startPreview", |
||||
flowUrlPrefix + "/flowOnlineOperation/viewUserTask", |
||||
flowUrlPrefix + "/flowOnlineOperation/viewHistoricProcessInstance", |
||||
flowUrlPrefix + "/flowOnlineOperation/submitUserTask", |
||||
flowUrlPrefix + "/flowOnlineOperation/upload", |
||||
flowUrlPrefix + "/flowOnlineOperation/download", |
||||
flowUrlPrefix + "/flowOperation/submitConsign", |
||||
flowUrlPrefix + "/flowOnlineOperation/startAndTakeUserTask/" + flowEntry.getProcessDefinitionKey(), |
||||
flowUrlPrefix + "/flowOnlineOperation/startAndSaveDraft/" + flowEntry.getProcessDefinitionKey(), |
||||
flowUrlPrefix + "/flowOnlineOperation/listWorkOrder/" + flowEntry.getProcessDefinitionKey(), |
||||
flowUrlPrefix + "/flowOnlineOperation/printWorkOrder/" + flowEntry.getProcessDefinitionKey() |
||||
); |
||||
permData.put("permList", permList); |
||||
permDataList.add(permData); |
||||
} |
||||
return permDataList; |
||||
} |
||||
|
||||
// @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
|
||||
// public void bulkHandleBusinessData(TransactionalFlowBusinessData businessData) {
|
||||
// try {
|
||||
// this.doHandle(businessData);
|
||||
// // 这里会切换回原有的在线表单表所在的数据库上线文。
|
||||
// flowTransProducerMapper.deleteById(businessData.getTransId());
|
||||
// } catch (Exception e) {
|
||||
// log.error("Failed to commit online business data [** " + JSON.toJSONString(businessData) + " **]", e);
|
||||
// FlowTransProducer transProducer = flowTransProducerMapper.selectById(businessData.getTransId());
|
||||
// transProducer.setErrorReason(e.getMessage());
|
||||
// flowTransProducerMapper.updateById(transProducer);
|
||||
// businessData.setErrorReason(e.getMessage());
|
||||
// throw new OnlineRuntimeException(e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
private void doHandle(TransactionalFlowBusinessData businessData) throws Exception { |
||||
Connection conn = null; |
||||
try { |
||||
conn = dataSourceUtil.getConnection(businessData.getDblinkId()); |
||||
conn.setAutoCommit(false); |
||||
for (TransactionalBusinessData.BusinessSqlData s : businessData.getSqlDataList()) { |
||||
List<Object> paramList = null; |
||||
if (CollUtil.isNotEmpty(s.getColumnValueList())) { |
||||
paramList = s.getColumnValueList().stream().map(Object.class::cast).collect(Collectors.toList()); |
||||
} |
||||
dataSourceUtil.execute(conn, s.getSql(), paramList); |
||||
} |
||||
this.insertFlowConsumerTrans(conn, businessData); |
||||
conn.commit(); |
||||
} catch (Exception e) { |
||||
if (conn != null) { |
||||
conn.rollback(); |
||||
} |
||||
log.error(e.getMessage(), e); |
||||
throw new OnlineRuntimeException(e.getMessage()); |
||||
} finally { |
||||
if (conn != null) { |
||||
conn.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void insertFlowConsumerTrans(Connection conn, TransactionalFlowBusinessData businessData) { |
||||
DataSourceProvider provider = dataSourceUtil.getProvider(businessData.getDblinkId()); |
||||
Long transId = businessData.getTransId(); |
||||
String sql = "INSERT INTO zz_flow_trans_consumer VALUES(?,?)"; |
||||
if (provider instanceof PostgreSqlProvider) { |
||||
dataSourceUtil.execute(conn, sql, CollUtil.newArrayList(transId, new java.sql.Date(System.currentTimeMillis()))); |
||||
} else { |
||||
dataSourceUtil.execute(conn, sql, CollUtil.newArrayList(transId, new Date())); |
||||
} |
||||
} |
||||
|
||||
private void updateMasterData(OnlineTable masterTable, JSONObject masterData, String dataId) { |
||||
if (masterData == null) { |
||||
return; |
||||
} |
||||
// 如果存在主表数据,就执行主表数据的更新。
|
||||
Map<String, Object> originalMasterData = |
||||
onlineOperationService.getMasterData(masterTable, null, null, dataId); |
||||
for (Map.Entry<String, Object> entry : originalMasterData.entrySet()) { |
||||
masterData.putIfAbsent(entry.getKey(), entry.getValue()); |
||||
} |
||||
if (!onlineOperationService.update(masterTable, masterData)) { |
||||
throw new FlowOperationException("主表数据不存在!"); |
||||
} |
||||
} |
||||
|
||||
private Map<String, List<JSONObject>> normailizeSlaveDataListMap( |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
if (slaveDataListMap == null || slaveDataListMap.size() == 0) { |
||||
return null; |
||||
} |
||||
Map<String, List<JSONObject>> resultMap = new HashMap<>(slaveDataListMap.size()); |
||||
for (Map.Entry<OnlineDatasourceRelation, List<JSONObject>> entry : slaveDataListMap.entrySet()) { |
||||
resultMap.put(entry.getKey().getSlaveTable().getTableName(), entry.getValue()); |
||||
} |
||||
return resultMap; |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
||||
apelet.common.flow.online.config.FlowOnlineAutoConfig |
||||
Loading…
Reference in new issue