commit:支持flowable工作流

This commit is contained in:
Jerry
2021-09-27 15:37:18 +08:00
parent d8831c7598
commit a2fbe479d8
849 changed files with 217544 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
<?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>com.flow.demo</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>com.flow.demo</groupId>
<artifactId>common-flow</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.flow.demo</groupId>
<artifactId>common-online</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>

View File

@@ -0,0 +1,13 @@
package com.flow.demo.common.flow.online.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* common-flow-online模块的自动配置引导类。
*
* @author Jerry
* @date 2021-06-06
*/
@EnableConfigurationProperties({FlowOnlineProperties.class})
public class FlowOnlineAutoConfig {
}

View File

@@ -0,0 +1,20 @@
package com.flow.demo.common.flow.online.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 在线表单工作流模块的配置对象。
*
* @author Jerry
* @date 2021-06-06
*/
@Data
@ConfigurationProperties(prefix = "common-flow-online")
public class FlowOnlineProperties {
/**
* 在线表单的URL前缀。
*/
private String urlPrefix;
}

View File

@@ -0,0 +1,698 @@
package com.flow.demo.common.flow.online.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.page.PageMethod;
import com.flow.demo.common.core.annotation.MyRequestBody;
import com.flow.demo.common.core.constant.ErrorCodeEnum;
import com.flow.demo.common.core.object.*;
import com.flow.demo.common.core.util.MyModelUtil;
import com.flow.demo.common.core.util.MyPageUtil;
import com.flow.demo.common.flow.dto.FlowWorkOrderDto;
import com.flow.demo.common.flow.vo.FlowEntryVo;
import com.flow.demo.common.flow.vo.FlowWorkOrderVo;
import com.flow.demo.common.online.dto.OnlineFilterDto;
import com.flow.demo.common.online.model.*;
import com.flow.demo.common.online.model.constant.FieldFilterType;
import com.flow.demo.common.online.model.constant.RelationType;
import com.flow.demo.common.online.object.ColumnData;
import com.flow.demo.common.online.service.OnlineFormService;
import com.flow.demo.common.online.service.OnlinePageService;
import com.flow.demo.common.online.service.OnlineOperationService;
import com.flow.demo.common.online.service.OnlineTableService;
import com.flow.demo.common.online.util.OnlineOperationHelper;
import com.flow.demo.common.flow.online.service.FlowOnlineOperationService;
import com.flow.demo.common.flow.constant.FlowApprovalType;
import com.flow.demo.common.flow.util.FlowOperationHelper;
import com.flow.demo.common.flow.constant.FlowTaskStatus;
import com.flow.demo.common.flow.dto.FlowTaskCommentDto;
import com.flow.demo.common.flow.exception.FlowOperationException;
import com.flow.demo.common.flow.model.*;
import com.flow.demo.common.flow.service.*;
import com.flow.demo.common.flow.vo.TaskInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
/**
* 流程操作接口类
*
* @author Jerry
* @date 2021-06-06
*/
@Slf4j
@RestController
@RequestMapping("${common-flow.urlPrefix}/flowOnlineOperation")
public class FlowOnlineOperationController {
@Autowired
private FlowEntryService flowEntryService;
@Autowired
private FlowApiService flowApiService;
@Autowired
private FlowOperationHelper flowOperationHelper;
@Autowired
private FlowOnlineOperationService flowOnlineOperationService;
@Autowired
private FlowWorkOrderService flowWorkOrderService;
@Autowired
private OnlineFormService onlineFormService;
@Autowired
private OnlinePageService onlinePageService;
@Autowired
private OnlineOperationService onlineOperationService;
@Autowired
private OnlineTableService onlineTableService;
@Autowired
private OnlineOperationHelper onlineOperationHelper;
/**
* 根据指定流程的主版本,发起一个流程实例,同时作为第一个任务节点的执行人,执行第一个用户任务。
*
* @param processDefinitionKey 流程定义标识。
* @param flowTaskCommentDto 审批意见。
* @param taskVariableData 流程任务变量数据。
* @param masterData 流程审批相关的主表数据。
* @param slaveData 流程审批相关的多个从表数据。
* @return 应答结果对象。
*/
@PostMapping("/startAndTakeUserTask/{processDefinitionKey}")
public ResponseResult<Void> startAndTakeUserTask(
@PathVariable("processDefinitionKey") String processDefinitionKey,
@MyRequestBody(required = true) FlowTaskCommentDto flowTaskCommentDto,
@MyRequestBody JSONObject taskVariableData,
@MyRequestBody(required = true) JSONObject masterData,
@MyRequestBody JSONObject slaveData) {
String errorMessage;
// 1. 验证流程数据的合法性。
ResponseResult<FlowEntry> flowEntryResult = flowOperationHelper.verifyAndGetFlowEntry(processDefinitionKey);
if (!flowEntryResult.isSuccess()) {
return ResponseResult.errorFrom(flowEntryResult);
}
// 2. 验证流程一个用户任务的合法性。
FlowEntryPublish flowEntryPublish = flowEntryResult.getData().getMainFlowEntryPublish();
if (!flowEntryPublish.getActiveStatus()) {
errorMessage = "数据验证失败,当前流程发布对象已被挂起,不能启动新流程!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
ResponseResult<TaskInfoVo> taskInfoResult =
flowOperationHelper.verifyAndGetInitialTaskInfo(flowEntryPublish, true);
if (!taskInfoResult.isSuccess()) {
return ResponseResult.errorFrom(taskInfoResult);
}
TaskInfoVo taskInfo = taskInfoResult.getData();
// 3. 验证在线表单及其关联数据源的合法性。
ResponseResult<OnlineDatasource> datasourceResult = this.verifyAndGetOnlineDatasource(taskInfo.getFormId());
if (!datasourceResult.isSuccess()) {
return ResponseResult.errorFrom(datasourceResult);
}
OnlineDatasource datasource = datasourceResult.getData();
OnlineTable masterTable = datasource.getMasterTable();
// 4. 为本次流程操作构建数据。
ResponseResult<List<ColumnData>> columnDataListResult =
onlineOperationHelper.buildTableData(masterTable, masterData, false, null);
if (!columnDataListResult.isSuccess()) {
return ResponseResult.errorFrom(columnDataListResult);
}
FlowTaskComment flowTaskComment = BeanUtil.copyProperties(flowTaskCommentDto, FlowTaskComment.class);
// 5. 保存在线表单提交的数据,同时启动流程和自动完成第一个用户任务。
if (slaveData == null) {
flowOnlineOperationService.saveNewAndStartProcess(
flowEntryPublish.getProcessDefinitionId(),
flowTaskComment,
taskVariableData,
masterTable,
columnDataListResult.getData());
} else {
// 如果本次请求中包含从表数据,则一同插入。
ResponseResult<Map<OnlineDatasourceRelation, List<List<ColumnData>>>> slaveDataListResult =
onlineOperationHelper.buildSlaveDataList(datasource.getDatasourceId(), slaveData);
if (!slaveDataListResult.isSuccess()) {
return ResponseResult.errorFrom(slaveDataListResult);
}
flowOnlineOperationService.saveNewAndStartProcess(
flowEntryPublish.getProcessDefinitionId(),
flowTaskComment,
taskVariableData,
masterTable,
columnDataListResult.getData(),
slaveDataListResult.getData());
}
return ResponseResult.success();
}
/**
* 提交流程的用户任务。
*
* @param processInstanceId 流程实例Id。
* @param taskId 流程任务Id。
* @param flowTaskCommentDto 流程审批数据。
* @param taskVariableData 流程任务变量数据。
* @param masterData 流程审批相关的主表数据。
* @param slaveData 流程审批相关的多个从表数据。
* @return 应答结果对象。
*/
@PostMapping("/submitUserTask")
public ResponseResult<Void> submitUserTask(
@MyRequestBody(required = true) String processInstanceId,
@MyRequestBody(required = true) String taskId,
@MyRequestBody(required = true) FlowTaskCommentDto flowTaskCommentDto,
@MyRequestBody JSONObject taskVariableData,
@MyRequestBody JSONObject masterData,
@MyRequestBody JSONObject slaveData) {
String errorMessage;
// 验证流程任务的合法性。
Task task = flowApiService.getProcessInstanceActiveTask(processInstanceId, taskId);
ResponseResult<TaskInfoVo> taskInfoResult = flowOperationHelper.verifyAndGetRuntimeTaskInfo(task);
if (!taskInfoResult.isSuccess()) {
return ResponseResult.errorFrom(taskInfoResult);
}
TaskInfoVo taskInfo = taskInfoResult.getData();
// 验证在线表单及其关联数据源的合法性。
ResponseResult<OnlineDatasource> datasourceResult = this.verifyAndGetOnlineDatasource(taskInfo.getFormId());
if (!datasourceResult.isSuccess()) {
return ResponseResult.errorFrom(datasourceResult);
}
CallResult assigneeVerifyResult = flowApiService.verifyAssigneeOrCandidateAndClaim(task);
if (!assigneeVerifyResult.isSuccess()) {
return ResponseResult.errorFrom(assigneeVerifyResult);
}
OnlineDatasource datasource = datasourceResult.getData();
OnlineTable masterTable = datasource.getMasterTable();
Long datasourceId = datasource.getDatasourceId();
ProcessInstance instance = flowApiService.getProcessInstance(processInstanceId);
String dataId = instance.getBusinessKey();
FlowTaskComment flowTaskComment = BeanUtil.copyProperties(flowTaskCommentDto, FlowTaskComment.class);
if (StrUtil.isBlank(dataId)) {
return this.submitNewTask(processInstanceId, taskId,
flowTaskComment, taskVariableData, masterTable, masterData, slaveData, datasourceId);
}
try {
if (StrUtil.equals(flowTaskComment.getApprovalType(), FlowApprovalType.TRANSFER)) {
if (StrUtil.isBlank(flowTaskComment.getDelegateAssginee())) {
errorMessage = "数据验证失败,加签或转办任务指派人不能为空!!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
}
flowOnlineOperationService.updateAndTakeTask(
task, flowTaskComment, taskVariableData, masterTable, masterData, dataId, slaveData, datasourceId);
} catch (FlowOperationException e) {
log.error("Failed to call [FlowOnlineOperationService.updateAndTakeTask]", e);
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, e.getMessage());
}
return ResponseResult.success();
}
/**
* 获取当前流程实例的详情数据。包括主表数据、一对一从表数据、一对多从表数据列表等。
*
* @param processInstanceId 当前运行时的流程实例Id。
* @param taskId 流程任务Id。
* @return 当前流程实例的详情数据。
*/
@GetMapping("/viewUserTask")
public ResponseResult<JSONObject> viewUserTask(@RequestParam String processInstanceId, @RequestParam String taskId) {
String errorMessage;
// 验证流程任务的合法性。
Task task = flowApiService.getProcessInstanceActiveTask(processInstanceId, taskId);
ProcessInstance instance = flowApiService.getProcessInstance(processInstanceId);
// 如果业务主数据为空,则直接返回。
if (StrUtil.isBlank(instance.getBusinessKey())) {
return ResponseResult.success(null);
}
ResponseResult<TaskInfoVo> taskInfoResult = flowOperationHelper.verifyAndGetRuntimeTaskInfo(task);
if (!taskInfoResult.isSuccess()) {
return ResponseResult.errorFrom(taskInfoResult);
}
TaskInfoVo taskInfo = taskInfoResult.getData();
// 验证在线表单及其关联数据源的合法性。
ResponseResult<OnlineDatasource> datasourceResult = this.verifyAndGetOnlineDatasource(taskInfo.getFormId());
if (!datasourceResult.isSuccess()) {
return ResponseResult.errorFrom(datasourceResult);
}
OnlineDatasource datasource = datasourceResult.getData();
ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
onlineOperationHelper.verifyAndGetRelationList(datasource.getDatasourceId(), null);
if (!relationListResult.isSuccess()) {
return ResponseResult.errorFrom(relationListResult);
}
JSONObject jsonData = this.buildUserTaskData(
instance.getBusinessKey(), datasource.getMasterTable(), relationListResult.getData());
return ResponseResult.success(jsonData);
}
/**
* 获取已经结束的流程实例的详情数据。包括主表数据、一对一从表数据、一对多从表数据列表等。
*
* @param processInstanceId 历史流程实例Id。
* @param taskId 历史任务Id。如果该值为null仅有发起人可以查看当前流程数据否则只有任务的指派人才能查看。
* @return 历史流程实例的详情数据。
*/
@GetMapping("/viewHistoricProcessInstance")
public ResponseResult<JSONObject> viewHistoricProcessInstance(
@RequestParam String processInstanceId, @RequestParam(required = false) String taskId) {
String errorMessage;
// 验证流程实例的合法性。
HistoricProcessInstance instance = flowApiService.getHistoricProcessInstance(processInstanceId);
if (instance == null) {
errorMessage = "数据验证失败指定的流程实例Id并不存在请刷新后重试";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
String loginName = TokenData.takeFromRequest().getLoginName();
if (StrUtil.isBlank(taskId)) {
if (!StrUtil.equals(loginName, instance.getStartUserId())) {
errorMessage = "数据验证失败,指定历史流程的发起人与当前用户不匹配!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
} else {
HistoricTaskInstance taskInstance = flowApiService.getHistoricTaskInstance(processInstanceId, taskId);
if (taskInstance == null) {
errorMessage = "数据验证失败指定的任务Id并不存在请刷新后重试";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
if (!StrUtil.equals(loginName, taskInstance.getAssignee())) {
errorMessage = "数据验证失败,历史任务的指派人与当前用户不匹配!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
}
if (StrUtil.isBlank(instance.getBusinessKey())) {
// 对于没有提交过任何用户任务的场景,可直接返回空数据。
return ResponseResult.success(new JSONObject());
}
FlowEntryPublish flowEntryPublish =
flowEntryService.getFlowEntryPublishList(CollUtil.newHashSet(instance.getProcessDefinitionId())).get(0);
TaskInfoVo taskInfoVo = JSON.parseObject(flowEntryPublish.getInitTaskInfo(), TaskInfoVo.class);
// 验证在线表单及其关联数据源的合法性。
ResponseResult<OnlineDatasource> datasourceResult = this.verifyAndGetOnlineDatasource(taskInfoVo.getFormId());
if (!datasourceResult.isSuccess()) {
return ResponseResult.errorFrom(datasourceResult);
}
OnlineDatasource datasource = datasourceResult.getData();
ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
onlineOperationHelper.verifyAndGetRelationList(datasource.getDatasourceId(), null);
if (!relationListResult.isSuccess()) {
return ResponseResult.errorFrom(relationListResult);
}
JSONObject jsonData = this.buildUserTaskData(
instance.getBusinessKey(), datasource.getMasterTable(), relationListResult.getData());
return ResponseResult.success(jsonData);
}
/**
* 工作流工单列表。
*
* @param processDefinitionKey 流程标识名。
* @param flowWorkOrderDtoFilter 过滤对象。
* @param pageParam 分页参数。
* @return 查询结果。
*/
@PostMapping("/listWorkOrder/{processDefinitionKey}")
public ResponseResult<MyPageData<FlowWorkOrderVo>> listWorkOrder(
@PathVariable("processDefinitionKey") String processDefinitionKey,
@MyRequestBody FlowWorkOrderDto flowWorkOrderDtoFilter,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
FlowWorkOrder flowWorkOrderFilter =
flowOperationHelper.makeWorkOrderFilter(flowWorkOrderDtoFilter, processDefinitionKey);
MyOrderParam orderParam = new MyOrderParam();
orderParam.add(new MyOrderParam.OrderInfo("workOrderId", false, null));
String orderBy = MyOrderParam.buildOrderBy(orderParam, FlowWorkOrder.class);
List<FlowWorkOrder> flowWorkOrderList = flowWorkOrderService.getFlowWorkOrderList(flowWorkOrderFilter, orderBy);
MyPageData<FlowWorkOrderVo> resultData =
MyPageUtil.makeResponseData(flowWorkOrderList, FlowWorkOrder.INSTANCE);
this.makeWorkOrderTaskInfo(resultData.getDataList());
return ResponseResult.success(resultData);
}
/**
* 为数据源主表字段上传文件。
*
* @param processDefinitionKey 流程引擎流程定义标识。
* @param processInstanceId 流程实例Id。
* @param taskId 流程任务Id。
* @param datasourceId 数据源Id。
* @param relationId 数据源关联Id。
* @param fieldName 数据表字段名。
* @param asImage 是否为图片文件。
* @param uploadFile 上传文件对象。
*/
@PostMapping("/upload")
public void upload(
@RequestParam String processDefinitionKey,
@RequestParam(required = false) String processInstanceId,
@RequestParam(required = false) String taskId,
@RequestParam Long datasourceId,
@RequestParam(required = false) Long relationId,
@RequestParam String fieldName,
@RequestParam Boolean asImage,
@RequestParam("uploadFile") MultipartFile uploadFile) throws Exception {
ResponseResult<String> verifyResult =
this.verifyUploadOrDownload(processDefinitionKey, processInstanceId, taskId, datasourceId);
if (!verifyResult.isSuccess()) {
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(verifyResult));
return;
}
ResponseResult<OnlineTable> verifyTableResult =
this.verifyAndGetOnlineTable(datasourceId, relationId, null, null);
if (!verifyTableResult.isSuccess()) {
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(verifyTableResult));
return;
}
onlineOperationHelper.doUpload(verifyTableResult.getData(), fieldName, asImage, uploadFile);
}
/**
* 下载文件接口。
* 越权访问限制说明:
* taskId为空当前用户必须为当前流程的发起人否则必须为当前任务的指派人或候选人。
* relationId为空下载数据为主表字段否则为关联的从表字段。
*
* @param processDefinitionKey 流程引擎流程定义标识。
* @param processInstanceId 流程实例Id。
* @param taskId 流程任务Id。
* @param datasourceId 数据源Id。
* @param relationId 数据源关联Id。
* @param dataId 附件所在记录的主键Id。
* @param fieldName 数据表字段名。
* @param asImage 是否为图片文件。
* @param response Http 应答对象。
*/
@GetMapping("/download")
public void download(
@RequestParam String processDefinitionKey,
@RequestParam(required = false) String processInstanceId,
@RequestParam(required = false) String taskId,
@RequestParam Long datasourceId,
@RequestParam(required = false) Long relationId,
@RequestParam(required = false) String dataId,
@RequestParam String fieldName,
@RequestParam String filename,
@RequestParam Boolean asImage,
HttpServletResponse response) throws Exception {
ResponseResult<String> verifyResult =
this.verifyUploadOrDownload(processDefinitionKey, processInstanceId, taskId, datasourceId);
if (!verifyResult.isSuccess()) {
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(verifyResult));
return;
}
ResponseResult<OnlineTable> verifyTableResult =
this.verifyAndGetOnlineTable(datasourceId, relationId, verifyResult.getData(), dataId);
if (!verifyTableResult.isSuccess()) {
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(verifyTableResult));
return;
}
onlineOperationHelper.doDownload(verifyTableResult.getData(), dataId, fieldName, filename, asImage, response);
}
/**
* 获取所有流程对象,同时获取关联的在线表单对象列表。
*
* @return 查询结果。
*/
@GetMapping("/listFlowEntryForm")
public ResponseResult<List<FlowEntryVo>> listFlowEntryForm() {
List<FlowEntry> flowEntryList = flowEntryService.getAllList();
List<FlowEntryVo> flowEntryVoList = FlowEntry.INSTANCE.fromModelList(flowEntryList);
if (CollUtil.isNotEmpty(flowEntryVoList)) {
Set<Long> pageIdSet = flowEntryVoList.stream().map(FlowEntryVo::getPageId).collect(Collectors.toSet());
List<OnlineForm> formList = onlineFormService.getOnlineFormListByPageIds(pageIdSet);
Map<Long, List<OnlineForm>> formMap =
formList.stream().collect(Collectors.groupingBy(OnlineForm::getPageId));
for (FlowEntryVo flowEntryVo : flowEntryVoList) {
List<OnlineForm> flowEntryFormList = formMap.get(flowEntryVo.getPageId());
flowEntryVo.setFormList(MyModelUtil.beanToMapList(flowEntryFormList));
}
}
return ResponseResult.success(flowEntryVoList);
}
private ResponseResult<OnlineDatasource> verifyAndGetOnlineDatasource(Long formId) {
List<OnlineFormDatasource> formDatasourceList = onlineFormService.getFormDatasourceListByFormId(formId);
if (CollUtil.isEmpty(formDatasourceList)) {
String errorMessage = "数据验证失败流程任务绑定的在线表单Id [" + formId + "] 不存在,请修改流程图!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
return onlineOperationHelper.verifyAndGetDatasource(formDatasourceList.get(0).getDatasourceId());
}
private JSONObject buildUserTaskData(
String businessKey, OnlineTable masterTable, List<OnlineDatasourceRelation> relationList) {
JSONObject jsonData = new JSONObject();
List<OnlineDatasourceRelation> oneToOneRelationList = relationList.stream()
.filter(r -> r.getRelationType().equals(RelationType.ONE_TO_ONE)).collect(Collectors.toList());
Map<String, Object> result =
onlineOperationService.getMasterData(masterTable, oneToOneRelationList, relationList, businessKey);
if (MapUtil.isEmpty(result)) {
return jsonData;
}
jsonData.put("masterAndOneToOne", result);
List<OnlineDatasourceRelation> oneToManyRelationList = relationList.stream()
.filter(r -> r.getRelationType().equals(RelationType.ONE_TO_MANY)).collect(Collectors.toList());
if (CollUtil.isEmpty(oneToManyRelationList)) {
return jsonData;
}
JSONObject oneToManyJsonData = new JSONObject();
jsonData.put("oneToMany", oneToManyJsonData);
for (OnlineDatasourceRelation relation : oneToManyRelationList) {
OnlineFilterDto filterDto = new OnlineFilterDto();
filterDto.setTableName(relation.getSlaveTable().getTableName());
OnlineColumn slaveColumn = relation.getSlaveTable().getColumnMap().get(relation.getSlaveColumnId());
filterDto.setColumnName(slaveColumn.getColumnName());
filterDto.setFilterType(FieldFilterType.EQUAL_FILTER);
Object columnValue = result.get(masterTable.getPrimaryKeyColumn().getColumnName());
filterDto.setColumnValue(columnValue);
List<Map<String, Object>> slaveResultList =
onlineOperationService.getSlaveDataList(relation, CollUtil.newLinkedList(filterDto), null);
if (CollUtil.isNotEmpty(slaveResultList)) {
oneToManyJsonData.put(relation.getVariableName(), slaveResultList);
}
}
return jsonData;
}
private ResponseResult<Void> submitNewTask(
String processInstanceId,
String taskId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
JSONObject masterData,
JSONObject slaveData,
Long datasourceId) {
ResponseResult<List<ColumnData>> columnDataListResult =
onlineOperationHelper.buildTableData(masterTable, masterData, false, null);
if (!columnDataListResult.isSuccess()) {
return ResponseResult.errorFrom(columnDataListResult);
}
// 保存在线表单提交的数据,同时启动流程和自动完成第一个用户任务。
if (slaveData == null) {
flowOnlineOperationService.saveNewAndTakeTask(
processInstanceId,
taskId,
flowTaskComment,
taskVariableData,
masterTable,
columnDataListResult.getData());
} else {
// 如果本次请求中包含从表数据,则一同插入。
ResponseResult<Map<OnlineDatasourceRelation, List<List<ColumnData>>>> slaveDataListResult =
onlineOperationHelper.buildSlaveDataList(datasourceId, slaveData);
if (!slaveDataListResult.isSuccess()) {
return ResponseResult.errorFrom(slaveDataListResult);
}
flowOnlineOperationService.saveNewAndTakeTask(
processInstanceId,
taskId,
flowTaskComment,
taskVariableData,
masterTable,
columnDataListResult.getData(),
slaveDataListResult.getData());
}
return ResponseResult.success();
}
private ResponseResult<OnlineTable> verifyAndGetOnlineTable(
Long datasourceId, Long relationId, String businessKey, String dataId) {
ResponseResult<OnlineDatasource> datasourceResult =
onlineOperationHelper.verifyAndGetDatasource(datasourceId);
if (!datasourceResult.isSuccess()) {
return ResponseResult.errorFrom(datasourceResult);
}
OnlineTable masterTable = datasourceResult.getData().getMasterTable();
OnlineTable table = masterTable;
ResponseResult<OnlineDatasourceRelation> relationResult = null;
if (relationId != null) {
relationResult = onlineOperationHelper.verifyAndGetRelation(datasourceId, relationId);
if (!relationResult.isSuccess()) {
return ResponseResult.errorFrom(relationResult);
}
table = relationResult.getData().getSlaveTable();
}
if (StrUtil.hasBlank(businessKey, dataId)) {
return ResponseResult.success(table);
}
String errorMessage;
// 如果relationId为null这里就是主表数据。
if (relationId == null) {
if (!StrUtil.equals(businessKey, dataId)) {
errorMessage = "数据验证失败参数主键Id与流程主表主键Id不匹配";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
return ResponseResult.success(table);
}
OnlineDatasourceRelation relation = relationResult.getData();
OnlineTable slaveTable = relation.getSlaveTable();
Map<String, Object> dataMap =
onlineOperationService.getMasterData(slaveTable, null, null, dataId);
if (dataMap == null) {
errorMessage = "数据验证失败从表主键Id不存在";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
OnlineColumn slaveColumn = slaveTable.getColumnMap().get(relation.getSlaveColumnId());
Object relationSlaveDataId = dataMap.get(slaveColumn.getColumnName());
if (relationSlaveDataId == null) {
errorMessage = "数据验证失败当前关联的从表字段值为NULL";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
OnlineColumn masterColumn = masterTable.getColumnMap().get(relation.getMasterColumnId());
if (masterColumn.getPrimaryKey()) {
if (!StrUtil.equals(relationSlaveDataId.toString(), businessKey)) {
errorMessage = "数据验证失败当前从表主键Id关联的主表Id当前流程的BusinessKey不一致";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
}
Map<String, Object> masterDataMap =
onlineOperationService.getMasterData(masterTable, null, null, businessKey);
if (masterDataMap == null) {
errorMessage = "数据验证失败主表主键Id不存在";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
Object relationMasterDataId = masterDataMap.get(masterColumn.getColumnName());
if (relationMasterDataId == null) {
errorMessage = "数据验证失败当前关联的主表字段值为NULL";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
if (!StrUtil.equals(relationMasterDataId.toString(), relationSlaveDataId.toString())) {
errorMessage = "数据验证失败,当前关联的主表字段值和从表字段值不一致!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
return ResponseResult.success(table);
}
private ResponseResult<String> verifyUploadOrDownload(
String processDefinitionKey, String processInstanceId, String taskId, Long datasourceId) {
if (!StrUtil.isAllBlank(processInstanceId, taskId)) {
ResponseResult<Void> verifyResult =
flowOperationHelper.verifyUploadOrDownloadPermission(processInstanceId, taskId);
if (!verifyResult.isSuccess()) {
return ResponseResult.errorFrom(ResponseResult.errorFrom(verifyResult));
}
}
String errorMessage;
FlowEntry flowEntry = flowEntryService.getFlowEntryByProcessDefinitionKey(processDefinitionKey);
if (flowEntry == null) {
errorMessage = "数据验证失败指定流程Id不存在";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
String businessKey = null;
if (processInstanceId != null) {
HistoricProcessInstance instance = flowApiService.getHistoricProcessInstance(processInstanceId);
if (!StrUtil.equals(flowEntry.getProcessDefinitionKey(), instance.getProcessDefinitionKey())) {
errorMessage = "数据验证失败,指定流程实例并不属于当前流程!";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
businessKey = instance.getBusinessKey();
}
List<OnlinePageDatasource> datasourceList =
onlinePageService.getOnlinePageDatasourceListByPageId(flowEntry.getPageId());
Optional<Long> r = datasourceList.stream()
.map(OnlinePageDatasource::getDatasourceId).filter(c -> c.equals(datasourceId)).findFirst();
if (!r.isPresent()) {
errorMessage = "数据验证失败当前数据源Id并不属于当前流程";
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
return ResponseResult.success(businessKey);
}
private void makeWorkOrderTaskInfo(List<FlowWorkOrderVo> flowWorkOrderVoList) {
if (CollUtil.isEmpty(flowWorkOrderVoList)) {
return;
}
Set<String> definitionIdSet =
flowWorkOrderVoList.stream().map(FlowWorkOrderVo::getProcessDefinitionId).collect(Collectors.toSet());
List<FlowEntryPublish> flowEntryPublishList = flowEntryService.getFlowEntryPublishList(definitionIdSet);
Map<String, FlowEntryPublish> flowEntryPublishMap =
flowEntryPublishList.stream().collect(Collectors.toMap(FlowEntryPublish::getProcessDefinitionId, c -> c));
for (FlowWorkOrderVo flowWorkOrderVo : flowWorkOrderVoList) {
FlowEntryPublish flowEntryPublish = flowEntryPublishMap.get(flowWorkOrderVo.getProcessDefinitionId());
flowWorkOrderVo.setInitTaskInfo(flowEntryPublish.getInitTaskInfo());
}
Set<String> businessKeySet =
flowWorkOrderVoList.stream().map(FlowWorkOrderVo::getBusinessKey).collect(Collectors.toSet());
Long tableId = flowWorkOrderVoList.get(0).getOnlineTableId();
OnlineTable masterTable = onlineTableService.getOnlineTableFromCache(tableId);
Set<?> convertedBusinessKeySet =
onlineOperationHelper.convertToTypeValue(masterTable.getPrimaryKeyColumn(), businessKeySet);
List<OnlineFilterDto> filterList = new LinkedList<>();
OnlineFilterDto filterDto = new OnlineFilterDto();
filterDto.setTableName(masterTable.getTableName());
filterDto.setColumnName(masterTable.getPrimaryKeyColumn().getColumnName());
filterDto.setFilterType(FieldFilterType.IN_LIST_FILTER);
filterDto.setColumnValue(convertedBusinessKeySet);
List<Map<String, Object>> dataList = onlineOperationService.getMasterDataList(
masterTable, null, null, filterList, null);
Map<Object, Map<String, Object>> dataMap = dataList.stream()
.collect(Collectors.toMap(c -> c.get(masterTable.getPrimaryKeyColumn().getColumnName()), c -> c));
for (FlowWorkOrderVo flowWorkOrderVo : flowWorkOrderVoList) {
Object dataId = onlineOperationHelper.convertToTypeValue(
masterTable.getPrimaryKeyColumn(), flowWorkOrderVo.getBusinessKey());
Map<String, Object> data = dataMap.get(dataId);
if (data != null) {
flowWorkOrderVo.setMasterData(data);
}
}
List<String> unfinishedProcessInstanceIds = flowWorkOrderVoList.stream()
.filter(c -> !c.getFlowStatus().equals(FlowTaskStatus.FINISHED))
.map(FlowWorkOrderVo::getProcessInstanceId)
.collect(Collectors.toList());
if (CollUtil.isEmpty(unfinishedProcessInstanceIds)) {
return;
}
List<Task> taskList = flowApiService.getTaskListByProcessInstanceIds(unfinishedProcessInstanceIds);
Map<String, List<Task>> taskMap =
taskList.stream().collect(Collectors.groupingBy(Task::getProcessInstanceId));
for (FlowWorkOrderVo flowWorkOrderVo : flowWorkOrderVoList) {
List<Task> instanceTaskList = taskMap.get(flowWorkOrderVo.getProcessInstanceId());
if (instanceTaskList == null) {
continue;
}
JSONArray taskArray = new JSONArray();
for (Task task : instanceTaskList) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("taskId", task.getId());
jsonObject.put("taskName", task.getName());
jsonObject.put("taskKey", task.getTaskDefinitionKey());
jsonObject.put("assignee", task.getAssignee());
taskArray.add(jsonObject);
}
flowWorkOrderVo.setRuntimeTaskInfoList(taskArray);
}
}
}

View File

@@ -0,0 +1,116 @@
package com.flow.demo.common.flow.online.service;
import com.alibaba.fastjson.JSONObject;
import com.flow.demo.common.online.model.OnlineDatasourceRelation;
import com.flow.demo.common.online.model.OnlineTable;
import com.flow.demo.common.online.object.ColumnData;
import com.flow.demo.common.flow.model.FlowTaskComment;
import org.flowable.task.api.Task;
import java.util.List;
import java.util.Map;
/**
* 流程操作服务接口。
*
* @author Jerry
* @date 2021-06-06
*/
public interface FlowOnlineOperationService {
/**
* 保存在线表单的数据同时启动流程。如果当前用户是第一个用户任务的Assignee
* 或者第一个用户任务的Assignee是流程发起人变量该方法还会自动Take第一个任务。
*
* @param processDefinitionId 流程定义Id。
* @param flowTaskComment 流程审批批注对象。
* @param taskVariableData 流程任务的变量数据。
* @param table 表对象。
* @param columnDataList 表数据。
*/
void saveNewAndStartProcess(
String processDefinitionId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable table,
List<ColumnData> columnDataList);
/**
* 保存在线表单的数据同时启动流程。如果当前用户是第一个用户任务的Assignee
* 或者第一个用户任务的Assignee是流程发起人变量该方法还会自动Take第一个任务。
*
* @param processDefinitionId 流程定义Id。
* @param flowTaskComment 流程审批批注对象。
* @param taskVariableData 流程任务的变量数据。
* @param masterTable 主表对象。
* @param masterColumnDataList 主表数据。
* @param slaveColumnDataListMap 关联从表数据Map。
*/
void saveNewAndStartProcess(
String processDefinitionId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
List<ColumnData> masterColumnDataList,
Map<OnlineDatasourceRelation, List<List<ColumnData>>> slaveColumnDataListMap);
/**
* 保存在线表单的数据同时Take用户任务。
*
* @param processInstanceId 流程实例Id。
* @param taskId 流程任务Id。
* @param flowTaskComment 流程审批批注对象。
* @param taskVariableData 流程任务的变量数据。
* @param table 表对象。
* @param columnDataList 表数据。
*/
void saveNewAndTakeTask(
String processInstanceId,
String taskId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable table,
List<ColumnData> columnDataList);
/**
* 保存在线表单的数据同时Take用户任务。
*
* @param processInstanceId 流程实例Id。
* @param taskId 流程任务Id。
* @param flowTaskComment 流程审批批注对象。
* @param taskVariableData 流程任务的变量数据。
* @param masterTable 主表对象。
* @param masterColumnDataList 主表数据。
* @param slaveColumnDataListMap 关联从表数据Map。
*/
void saveNewAndTakeTask(
String processInstanceId,
String taskId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
List<ColumnData> masterColumnDataList,
Map<OnlineDatasourceRelation, List<List<ColumnData>>> slaveColumnDataListMap);
/**
* 保存业务表数据,同时接收流程任务。
*
* @param task 流程任务。
* @param flowTaskComment 流程审批批注对象。
* @param taskVariableData 流程任务的变量数据。
* @param masterTable 主表对象。
* @param masterData 主表数据。
* @param masterDataId 主表数据主键。
* @param slaveData 从表数据。
* @param datasourceId 在线表所属数据源Id。
*/
void updateAndTakeTask(
Task task,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
JSONObject masterData,
String masterDataId,
JSONObject slaveData,
Long datasourceId);
}

View File

@@ -0,0 +1,247 @@
package com.flow.demo.common.flow.online.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.flow.demo.common.core.object.ResponseResult;
import com.flow.demo.common.online.model.OnlineColumn;
import com.flow.demo.common.online.model.OnlineDatasourceRelation;
import com.flow.demo.common.online.model.OnlineTable;
import com.flow.demo.common.online.model.constant.RelationType;
import com.flow.demo.common.online.object.ColumnData;
import com.flow.demo.common.online.service.OnlineOperationService;
import com.flow.demo.common.online.util.OnlineOperationHelper;
import com.flow.demo.common.flow.constant.FlowApprovalType;
import com.flow.demo.common.flow.constant.FlowTaskStatus;
import com.flow.demo.common.flow.exception.FlowOperationException;
import com.flow.demo.common.flow.model.FlowTaskComment;
import com.flow.demo.common.flow.service.FlowApiService;
import com.flow.demo.common.flow.service.FlowWorkOrderService;
import com.flow.demo.common.flow.online.service.FlowOnlineOperationService;
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 java.util.List;
import java.util.Map;
@Slf4j
@Service("flowOnlineOperationService")
public class FlowOnlineOperationServiceImpl implements FlowOnlineOperationService {
@Autowired
private FlowApiService flowApiService;
@Autowired
private FlowWorkOrderService flowWorkOrderService;
@Autowired
private OnlineOperationService onlineOperationService;
@Autowired
private OnlineOperationHelper onlineOperationHelper;
@Transactional(rollbackFor = Exception.class)
@Override
public void saveNewAndStartProcess(
String processDefinitionId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable table,
List<ColumnData> columnDataList) {
Object dataId = onlineOperationService.saveNew(table, columnDataList);
ProcessInstance instance =
flowApiService.startAndTakeFirst(processDefinitionId, dataId, flowTaskComment, taskVariableData);
flowWorkOrderService.saveNew(instance, dataId, table.getTableId());
}
@Transactional(rollbackFor = Exception.class)
@Override
public void saveNewAndStartProcess(
String processDefinitionId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
List<ColumnData> masterColumnDataList,
Map<OnlineDatasourceRelation, List<List<ColumnData>>> slaveColumnDataListMap) {
Object dataId = onlineOperationService.saveNewAndSlaveRelation(
masterTable, masterColumnDataList, slaveColumnDataListMap);
ProcessInstance instance =
flowApiService.startAndTakeFirst(processDefinitionId, dataId, flowTaskComment, taskVariableData);
flowWorkOrderService.saveNew(instance, dataId, masterTable.getTableId());
}
@Transactional(rollbackFor = Exception.class)
@Override
public void saveNewAndTakeTask(
String processInstanceId,
String taskId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable table,
List<ColumnData> columnDataList) {
Object dataId = onlineOperationService.saveNew(table, columnDataList);
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);
flowApiService.completeTask(task, flowTaskComment, taskVariableData);
ProcessInstance instance = flowApiService.getProcessInstance(processInstanceId);
flowWorkOrderService.saveNew(instance, dataId, table.getTableId());
}
@Transactional(rollbackFor = Exception.class)
@Override
public void saveNewAndTakeTask(
String processInstanceId,
String taskId,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
List<ColumnData> masterColumnDataList,
Map<OnlineDatasourceRelation, List<List<ColumnData>>> slaveColumnDataListMap) {
Object dataId = onlineOperationService.saveNewAndSlaveRelation(
masterTable, masterColumnDataList, slaveColumnDataListMap);
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);
flowApiService.completeTask(task, flowTaskComment, taskVariableData);
ProcessInstance instance = flowApiService.getProcessInstance(processInstanceId);
flowWorkOrderService.saveNew(instance, dataId, masterTable.getTableId());
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateAndTakeTask(
Task task,
FlowTaskComment flowTaskComment,
JSONObject taskVariableData,
OnlineTable masterTable,
JSONObject masterData,
String masterDataId,
JSONObject slaveData,
Long datasourceId) {
int flowStatus = FlowTaskStatus.APPROVING;
if (flowTaskComment.getApprovalType().equals(FlowApprovalType.REFUSE)) {
flowStatus = FlowTaskStatus.REFUSED;
}
flowWorkOrderService.updateFlowStatusByProcessInstanceId(task.getProcessInstanceId(), flowStatus);
this.handleMasterTableData(masterTable, masterData, masterDataId);
if (slaveData != null) {
for (Map.Entry<String, Object> relationEntry : slaveData.entrySet()) {
Long relationId = Long.parseLong(relationEntry.getKey());
this.handleSlaveTableData(
relationId, relationEntry.getValue(), datasourceId, masterTable, masterData, masterDataId);
}
}
flowApiService.completeTask(task, flowTaskComment, taskVariableData);
}
private void handleMasterTableData(OnlineTable masterTable, JSONObject masterData, String dataId) {
// 如果存在主表数据,就执行主表数据的更新。
if (masterData != null) {
Map<String, Object> originalMasterData =
onlineOperationService.getMasterData(masterTable, null, null, dataId);
for (Map.Entry<String, Object> entry : originalMasterData.entrySet()) {
masterData.putIfAbsent(entry.getKey(), entry.getValue());
}
ResponseResult<List<ColumnData>> columnDataListResult =
onlineOperationHelper.buildTableData(masterTable, masterData, true, null);
if (!columnDataListResult.isSuccess()) {
throw new FlowOperationException(columnDataListResult.getErrorMessage());
}
if (!onlineOperationService.update(masterTable, columnDataListResult.getData())) {
throw new FlowOperationException("主表数据不存在!");
}
}
}
private void handleSlaveTableData(
Long relationId,
Object slaveData,
Long datasourceId,
OnlineTable masterTable,
Map<String, Object> masterData,
String masterDataId) {
ResponseResult<OnlineDatasourceRelation> relationResult =
onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId, relationId);
if (!relationResult.isSuccess()) {
throw new FlowOperationException(relationResult.getErrorMessage());
}
OnlineDatasourceRelation relation = relationResult.getData();
OnlineTable slaveTable = relation.getSlaveTable();
if (relation.getRelationType().equals(RelationType.ONE_TO_ONE)) {
String keyColumnName = slaveTable.getPrimaryKeyColumn().getColumnName();
JSONObject relationData = (JSONObject) slaveData;
if (MapUtil.isEmpty(relationData)) {
return;
}
String slaveDataId = relationData.getString(keyColumnName);
if (slaveDataId == null) {
ResponseResult<List<ColumnData>> columnDataListResult =
onlineOperationHelper.buildTableData(slaveTable, relationData, false, null);
if (!columnDataListResult.isSuccess()) {
throw new FlowOperationException(columnDataListResult.getErrorMessage());
}
onlineOperationService.saveNew(slaveTable, columnDataListResult.getData());
} else {
Map<String, Object> originalSlaveData =
onlineOperationService.getMasterData(slaveTable, null, null, slaveDataId);
for (Map.Entry<String, Object> entry : originalSlaveData.entrySet()) {
relationData.putIfAbsent(entry.getKey(), entry.getValue());
}
ResponseResult<List<ColumnData>> columnDataListResult =
onlineOperationHelper.buildTableData(slaveTable, relationData, true, null);
if (!columnDataListResult.isSuccess()) {
throw new FlowOperationException(columnDataListResult.getErrorMessage());
}
if (!onlineOperationService.update(slaveTable, columnDataListResult.getData())) {
throw new FlowOperationException("关联从表 [" + slaveTable.getTableName() + "] 中的更新数据不存在");
}
}
} else if (relation.getRelationType().equals(RelationType.ONE_TO_MANY)) {
JSONArray relationDataArray = (JSONArray) slaveData;
if (CollUtil.isEmpty(relationDataArray)) {
return;
}
JSONObject firstData = relationDataArray.getJSONObject(0);
Object key = firstData.get(slaveTable.getPrimaryKeyColumn().getColumnName());
// 如果一对多关联数据中存在主键数据,则需要先批量删除。
if (key != null) {
OnlineColumn slaveColumn = relation.getSlaveTable().getColumnMap().get(relation.getSlaveColumnId());
Object relationSlaveColumnValue = firstData.get(slaveColumn.getColumnName());
onlineOperationService.forceDelete(
relation.getSlaveTable(), slaveColumn, relationSlaveColumnValue.toString());
}
if (masterData == null) {
masterData = onlineOperationService.getMasterData(
masterTable, null, null, masterDataId);
}
for (int i = 0; i < relationDataArray.size(); i++) {
JSONObject relationSlaveData = relationDataArray.getJSONObject(i);
// 自动补齐主表关联数据。
OnlineColumn masterColumn = masterTable.getColumnMap().get(relation.getMasterColumnId());
Object masterColumnValue = masterData.get(masterColumn.getColumnName());
OnlineColumn slaveColumn = slaveTable.getColumnMap().get(relation.getSlaveColumnId());
relationSlaveData.put(slaveColumn.getColumnName(), masterColumnValue);
// 拆解主表和一对多关联从表的输入参数,并构建出数据表的待插入数据列表。
ResponseResult<List<ColumnData>> columnDataListResult =
onlineOperationHelper.buildTableData(slaveTable, relationSlaveData, false, null);
if (!columnDataListResult.isSuccess()) {
throw new FlowOperationException(columnDataListResult.getErrorMessage());
}
onlineOperationService.saveNew(slaveTable, columnDataListResult.getData());
}
}
}
}

View File

@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.flow.demo.common.flow.online.config.FlowOnlineAutoConfig