fix(流程模型和部署): 修改流程模型设计方案,模型信息和流程图分开操作,表单在开始节点设置。
This commit is contained in:
@@ -16,6 +16,11 @@ import lombok.Data;
|
||||
public class WfDeployForm {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 表单主键
|
||||
*/
|
||||
private String formKey;
|
||||
|
||||
/**
|
||||
* 流程定义主键
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.ruoyi.workflow.domain.bo;
|
||||
|
||||
import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@@ -16,33 +18,31 @@ import javax.validation.constraints.NotNull;
|
||||
public class WfModelBo {
|
||||
|
||||
@ApiModelProperty(value = "模型主键")
|
||||
@NotNull(message = "模型主键不能为空", groups = { EditGroup.class })
|
||||
private String modelId;
|
||||
|
||||
@ApiModelProperty(value = "模型名称", required = true)
|
||||
@NotNull(message = "模型名称不能为空")
|
||||
@NotNull(message = "模型名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String modelName;
|
||||
|
||||
@ApiModelProperty(value = "模型Key", required = true)
|
||||
@NotNull(message = "模型Key不能为空")
|
||||
@NotNull(message = "模型Key不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String modelKey;
|
||||
|
||||
@ApiModelProperty(value = "流程分类", required = true)
|
||||
@NotBlank(message = "流程分类不能为空")
|
||||
@NotBlank(message = "流程分类不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty(value = "描述")
|
||||
private String description;
|
||||
|
||||
@ApiModelProperty(value = "表单类型", required = true)
|
||||
@NotBlank(message = "表单类型不能为空")
|
||||
private Integer formType;
|
||||
|
||||
@ApiModelProperty(value = "表单主键", required = true)
|
||||
@NotBlank(message = "表单不能为空")
|
||||
private Long formId;
|
||||
|
||||
@ApiModelProperty(value = "流程xml", required = true)
|
||||
@NotBlank(message = "流程xml不能为空")
|
||||
private String bpmnXml;
|
||||
|
||||
@ApiModelProperty(value = "是否保存为新版本", required = true)
|
||||
|
||||
@@ -9,6 +9,11 @@ import lombok.Data;
|
||||
@Data
|
||||
public class WfMetaInfoDto {
|
||||
|
||||
/**
|
||||
* 创建者(username)
|
||||
*/
|
||||
private String createUser;
|
||||
|
||||
/**
|
||||
* 流程描述
|
||||
*/
|
||||
|
||||
@@ -22,10 +22,10 @@ public interface IWfDeployFormService {
|
||||
/**
|
||||
* 保存流程实例关联表单
|
||||
* @param deployId
|
||||
* @param formId
|
||||
* @param formKey
|
||||
* @return
|
||||
*/
|
||||
int saveInternalDeployForm(String deployId, Long formId);
|
||||
int saveInternalDeployForm(String deployId, String formKey);
|
||||
|
||||
/**
|
||||
* 查询流程挂着的表单
|
||||
|
||||
@@ -13,19 +13,53 @@ import java.util.Collection;
|
||||
*/
|
||||
public interface IWfModelService {
|
||||
|
||||
/**
|
||||
* 查询流程模型列表
|
||||
*/
|
||||
TableDataInfo<WfModelVo> list(WfModelBo modelBo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询流程模型列表
|
||||
*/
|
||||
TableDataInfo<WfModelVo> historyList(WfModelBo modelBo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询流程模型详情信息
|
||||
*/
|
||||
WfModelVo getModel(String modelId);
|
||||
|
||||
/**
|
||||
* 查询流程表单详细信息
|
||||
*/
|
||||
String queryBpmnXmlById(String modelId);
|
||||
|
||||
/**
|
||||
* 新增模型信息
|
||||
*/
|
||||
void insertModel(WfModelBo modelBo);
|
||||
|
||||
/**
|
||||
* 修改模型信息
|
||||
*/
|
||||
void updateModel(WfModelBo modelBo);
|
||||
|
||||
/**
|
||||
* 保存流程模型信息
|
||||
*/
|
||||
void saveModel(WfModelBo modelBo);
|
||||
|
||||
/**
|
||||
* 设为最新流程模型
|
||||
*/
|
||||
void latestModel(String modelId);
|
||||
|
||||
/**
|
||||
* 删除流程模型
|
||||
*/
|
||||
void deleteByIds(Collection<String> ids);
|
||||
|
||||
/**
|
||||
* 部署流程模型
|
||||
*/
|
||||
void deployModel(String modelId);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,13 @@ public interface IWfProcessService {
|
||||
*/
|
||||
TableDataInfo<WfDefinitionVo> processList(PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询流程部署关联表单信息
|
||||
* @param definitionId 流程定义ID
|
||||
* @param deployId 部署ID
|
||||
*/
|
||||
String selectFormContent(String definitionId, String deployId);
|
||||
|
||||
/**
|
||||
* 启动流程实例
|
||||
* @param procDefId 流程定义ID
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.ruoyi.workflow.service.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.workflow.domain.WfDeployForm;
|
||||
import com.ruoyi.workflow.domain.WfForm;
|
||||
import com.ruoyi.workflow.domain.vo.WfFormVo;
|
||||
@@ -48,10 +50,11 @@ public class WfDeployFormServiceImpl implements IWfDeployFormService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int saveInternalDeployForm(String deployId, Long formId) {
|
||||
public int saveInternalDeployForm(String deployId, String formKey) {
|
||||
WfDeployForm deployForm = new WfDeployForm();
|
||||
deployForm.setDeployId(deployId);
|
||||
deployForm.setFormId(formId);
|
||||
deployForm.setFormKey(formKey);
|
||||
Long formId = Convert.toLong(StringUtils.substringAfter(formKey, "key_"));
|
||||
WfForm wfForm = formMapper.selectById(formId);
|
||||
if (ObjectUtil.isNotNull(wfForm)) {
|
||||
deployForm.setContent(wfForm.getContent());
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.common.utils.JsonUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.flowable.common.constant.ProcessConstants;
|
||||
@@ -21,6 +22,7 @@ import com.ruoyi.workflow.service.IWfModelService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.StartEvent;
|
||||
import org.flowable.engine.repository.Deployment;
|
||||
import org.flowable.engine.repository.Model;
|
||||
import org.flowable.engine.repository.ModelQuery;
|
||||
@@ -156,36 +158,75 @@ public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelSe
|
||||
@Override
|
||||
public String queryBpmnXmlById(String modelId) {
|
||||
byte[] bpmnBytes = repositoryService.getModelEditorSource(modelId);
|
||||
if (ObjectUtil.isNull(bpmnBytes)) {
|
||||
throw new RuntimeException("流程图不存在!");
|
||||
}
|
||||
return StrUtil.utf8Str(bpmnBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertModel(WfModelBo modelBo) {
|
||||
Model model = repositoryService.newModel();
|
||||
model.setName(modelBo.getModelName());
|
||||
model.setKey(modelBo.getModelKey());
|
||||
model.setCategory(modelBo.getCategory());
|
||||
String metaInfo = buildMetaInfo(new WfMetaInfoDto(), modelBo.getDescription());
|
||||
model.setMetaInfo(metaInfo);
|
||||
// 保存流程模型
|
||||
repositoryService.saveModel(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateModel(WfModelBo modelBo) {
|
||||
// 根据模型Key查询模型信息
|
||||
Model model = repositoryService.getModel(modelBo.getModelId());
|
||||
if (ObjectUtil.isNull(model)) {
|
||||
throw new RuntimeException("流程模型不存在!");
|
||||
}
|
||||
model.setCategory(modelBo.getCategory());
|
||||
WfMetaInfoDto metaInfoDto = JsonUtils.parseObject(model.getMetaInfo(), WfMetaInfoDto.class);
|
||||
String metaInfo = buildMetaInfo(metaInfoDto, modelBo.getDescription());
|
||||
model.setMetaInfo(metaInfo);
|
||||
// 保存流程模型
|
||||
repositoryService.saveModel(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveModel(WfModelBo modelBo) {
|
||||
// 根据模型Key查询模型信息
|
||||
Model model = repositoryService.createModelQuery().modelKey(modelBo.getModelKey()).singleResult();
|
||||
Model newModel;
|
||||
// 查询模型信息
|
||||
Model model = repositoryService.getModel(modelBo.getModelId());
|
||||
if (ObjectUtil.isNull(model)) {
|
||||
newModel = repositoryService.newModel();
|
||||
} else {
|
||||
if (modelBo.getNewVersion() != null && modelBo.getNewVersion()) {
|
||||
newModel = repositoryService.newModel();
|
||||
newModel.setVersion(model.getVersion() + 1);
|
||||
} else {
|
||||
newModel = model;
|
||||
}
|
||||
throw new RuntimeException("流程模型不存在!");
|
||||
}
|
||||
BpmnModel bpmnModel = ModelUtils.getBpmnModel(modelBo.getBpmnXml());
|
||||
if (ObjectUtil.isEmpty(bpmnModel)) {
|
||||
throw new RuntimeException("获取模型设计失败!");
|
||||
}
|
||||
String processName = bpmnModel.getMainProcess().getName();
|
||||
// 获取开始节点
|
||||
StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel);
|
||||
if (ObjectUtil.isNull(startEvent)) {
|
||||
throw new RuntimeException("开始节点不存在,请检查流程设计是否有误!");
|
||||
}
|
||||
// 获取开始节点配置的表单Key
|
||||
if (StrUtil.isBlank(startEvent.getFormKey())) {
|
||||
throw new RuntimeException("请配置流程表单");
|
||||
}
|
||||
Model newModel;
|
||||
if (Boolean.TRUE.equals(modelBo.getNewVersion())) {
|
||||
newModel = repositoryService.newModel();
|
||||
newModel.setName(processName);
|
||||
newModel.setKey(model.getKey());
|
||||
newModel.setCategory(model.getCategory());
|
||||
newModel.setMetaInfo(model.getMetaInfo());
|
||||
newModel.setVersion(model.getVersion() + 1);
|
||||
} else {
|
||||
newModel = model;
|
||||
// 设置流程名称
|
||||
newModel.setName(processName);
|
||||
}
|
||||
newModel.setName(modelBo.getModelName());
|
||||
newModel.setKey(modelBo.getModelKey());
|
||||
newModel.setCategory(modelBo.getCategory());
|
||||
newModel.setMetaInfo(buildMetaInfo(modelBo));
|
||||
// 保存流程模型
|
||||
repositoryService.saveModel(newModel);
|
||||
// 保存 BPMN XML
|
||||
saveModelBpmnXml(newModel.getId(), modelBo.getBpmnXml());
|
||||
repositoryService.addModelEditorSource(newModel.getId(), ModelUtils.getBpmnXml(bpmnModel));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,7 +255,7 @@ public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelSe
|
||||
// 保存流程模型
|
||||
repositoryService.saveModel(newModel);
|
||||
// 保存 BPMN XML
|
||||
saveModelBpmnXml(newModel.getId(), bpmnXml);
|
||||
repositoryService.addModelEditorSource(newModel.getId(), StrUtil.utf8Bytes(bpmnXml));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -237,10 +278,18 @@ public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelSe
|
||||
if (ObjectUtil.isNull(model)) {
|
||||
throw new RuntimeException("流程模型不存在!");
|
||||
}
|
||||
WfMetaInfoDto metaInfo = getMetaInfo(model.getMetaInfo());
|
||||
// 获取流程图
|
||||
String bpmnXml = queryBpmnXmlById(modelId);
|
||||
BpmnModel bpmnModel = ModelUtils.getBpmnModel(bpmnXml);
|
||||
// 获取开始节点
|
||||
StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel);
|
||||
if (ObjectUtil.isNull(startEvent)) {
|
||||
throw new RuntimeException("开始节点不存在,请检查流程设计是否有误!");
|
||||
}
|
||||
String formKey = startEvent.getFormKey();
|
||||
if (StringUtils.isEmpty(formKey)) {
|
||||
throw new RuntimeException("请配置流程表单");
|
||||
}
|
||||
String processName = model.getName() + ProcessConstants.SUFFIX;
|
||||
Deployment deployment = repositoryService.createDeployment()
|
||||
.name(model.getName())
|
||||
@@ -249,38 +298,22 @@ public class WfModelServiceImpl extends FlowServiceFactory implements IWfModelSe
|
||||
.category(model.getCategory())
|
||||
.deploy();
|
||||
// 保存部署表单
|
||||
if (FormType.PROCESS.getType().equals(metaInfo.getFormType())) {
|
||||
deployFormService.saveInternalDeployForm(deployment.getId(), metaInfo.getFormId());
|
||||
}
|
||||
deployFormService.saveInternalDeployForm(deployment.getId(), formKey);
|
||||
|
||||
}
|
||||
|
||||
private String buildMetaInfo(WfModelBo modelBo) {
|
||||
WfMetaInfoDto metaInfo = new WfMetaInfoDto();
|
||||
/**
|
||||
* 构建模型扩展信息
|
||||
* @return
|
||||
*/
|
||||
private String buildMetaInfo(WfMetaInfoDto metaInfo, String description) {
|
||||
// 只有非空,才进行设置,避免更新时的覆盖
|
||||
if (StringUtils.isNotEmpty(modelBo.getDescription())) {
|
||||
metaInfo.setDescription(modelBo.getDescription());
|
||||
if (StringUtils.isNotEmpty(description)) {
|
||||
metaInfo.setDescription(description);
|
||||
}
|
||||
if (ObjectUtil.isNotNull(modelBo.getFormType())) {
|
||||
metaInfo.setFormType(modelBo.getFormType());
|
||||
metaInfo.setFormId(modelBo.getFormId());
|
||||
if (StringUtils.isNotEmpty(metaInfo.getCreateUser())) {
|
||||
metaInfo.setCreateUser(LoginHelper.getUsername());
|
||||
}
|
||||
return JsonUtils.toJsonString(metaInfo);
|
||||
}
|
||||
|
||||
private WfMetaInfoDto getMetaInfo(String metaInfoJson) {
|
||||
WfMetaInfoDto metaInfo = JsonUtils.parseObject(metaInfoJson, WfMetaInfoDto.class);
|
||||
if (ObjectUtil.isNull(metaInfo) || ObjectUtil.hasNull(metaInfo.getFormType(), metaInfo.getFormId())) {
|
||||
throw new RuntimeException("未配置表单信息!");
|
||||
}
|
||||
return metaInfo;
|
||||
}
|
||||
|
||||
private void saveModelBpmnXml(String modelId, String bpmnXml) {
|
||||
if (StringUtils.isBlank(modelId)) {
|
||||
throw new RuntimeException("模板主键不能为空!");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(bpmnXml)) {
|
||||
repositoryService.addModelEditorSource(modelId, StrUtil.utf8Bytes(bpmnXml));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.ruoyi.workflow.service.impl;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.BetweenFormatter;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
@@ -14,14 +17,19 @@ import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.flowable.common.constant.TaskConstants;
|
||||
import com.ruoyi.flowable.factory.FlowServiceFactory;
|
||||
import com.ruoyi.flowable.utils.ModelUtils;
|
||||
import com.ruoyi.flowable.utils.TaskUtils;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
import com.ruoyi.workflow.domain.WfDeployForm;
|
||||
import com.ruoyi.workflow.domain.bo.WfProcessBo;
|
||||
import com.ruoyi.workflow.domain.vo.WfDefinitionVo;
|
||||
import com.ruoyi.workflow.domain.vo.WfTaskVo;
|
||||
import com.ruoyi.workflow.mapper.WfDeployFormMapper;
|
||||
import com.ruoyi.workflow.service.IWfProcessService;
|
||||
import com.ruoyi.workflow.service.IWfTaskService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.StartEvent;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.history.HistoricProcessInstanceQuery;
|
||||
import org.flowable.engine.repository.Deployment;
|
||||
@@ -35,6 +43,7 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -50,6 +59,7 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
|
||||
private final IWfTaskService wfTaskService;
|
||||
private final ISysUserService userService;
|
||||
private final WfDeployFormMapper deployFormMapper;
|
||||
|
||||
/**
|
||||
* 流程定义列表
|
||||
@@ -82,7 +92,6 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
vo.setProcessKey(processDefinition.getKey());
|
||||
vo.setProcessName(processDefinition.getName());
|
||||
vo.setVersion(processDefinition.getVersion());
|
||||
vo.setCategory(processDefinition.getCategory());
|
||||
vo.setDeploymentId(processDefinition.getDeploymentId());
|
||||
vo.setSuspended(processDefinition.isSuspended());
|
||||
// 流程定义时间
|
||||
@@ -95,6 +104,23 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String selectFormContent(String definitionId, String deployId) {
|
||||
InputStream inputStream = repositoryService.getProcessModel(definitionId);
|
||||
String bpmnString;
|
||||
try {
|
||||
bpmnString = IoUtil.readUtf8(inputStream);
|
||||
} catch (IORuntimeException exception) {
|
||||
throw new RuntimeException("获取流程设计失败!");
|
||||
}
|
||||
BpmnModel bpmnModel = ModelUtils.getBpmnModel(bpmnString);
|
||||
StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel);
|
||||
WfDeployForm deployForm = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>()
|
||||
.eq(WfDeployForm::getDeployId, deployId)
|
||||
.eq(WfDeployForm::getFormKey, startEvent.getFormKey()));
|
||||
return deployForm.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程定义ID启动流程实例
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user