代码开发,流程定义相关

This commit is contained in:
lvshaohua 2023-06-15 10:24:46 +08:00
parent 33deba6d37
commit 0b45272556
14 changed files with 419 additions and 22 deletions

View File

@ -0,0 +1,56 @@
package cn.axzo.server.common.enums;
import org.springframework.util.ObjectUtils;
import java.util.Arrays;
public enum BpmProcessInstanceResultEnum {
PROCESS(1, "审核中"),
APPROVE(2, "已通过"),
REJECT(3, "已驳回"),
CANCEL(4, "已撤销"),
// ========== 流程任务独有的状态 ==========
BACK(5, "退回/驳回");
/**
* 结果
*/
private final Integer result;
/**
* 描述
*/
private final String desc;
BpmProcessInstanceResultEnum(Integer result, String desc) {
this.result = result;
this.desc = desc;
}
public Integer getResult() {
return result;
}
public String getDesc() {
return desc;
}
/**
* 判断该结果是否已经处于 End 最终结果
* <p>
* 主要用于一些结果更新的逻辑如果已经是最终结果就不再进行更新
*
* @param result 结果
* @return 是否
*/
public static boolean isEndResult(Integer result) {
return Arrays.asList(APPROVE.getResult(), REJECT.getResult(),
CANCEL.getResult(), BACK.getResult()).contains(result);
}
public static BpmProcessInstanceResultEnum valueOf(Integer result) {
return Arrays.stream(values()).filter(it -> it.getResult().equals(result)).findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,28 @@
package cn.axzo.server.common.enums;
public enum BpmProcessInstanceStatusEnum {
RUNNING(1, "进行中"),
FINISH(2, "已完成");
/**
* 状态
*/
private final Integer status;
/**
* 描述
*/
private final String desc;
BpmProcessInstanceStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
public Integer getStatus() {
return status;
}
public String getDesc() {
return desc;
}
}

View File

@ -0,0 +1,98 @@
package cn.axzo.server.dal.dataobject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import java.util.Date;
import java.util.Map;
public class BpmProcessInstanceExtDO {
/**
* 编号自增
*/
@TableId
private Long id;
/**
* 流程实例的名字
* <p>
* 冗余 ProcessInstance name 属性用于筛选
*/
private String name;
/**
* 自定义的流程实例的编号
*/
private String customProInstId;
/**
* 流程实例的编号
* <p>
* 关联 ProcessInstance id 属性
*/
private String processInstanceId;
/**
* 流程定义的编号
* <p>
* 关联 ProcessDefinition id 属性
*/
private String processDefinitionId;
/**
* 流程分类
* <p>
* 冗余 ProcessDefinition category 属性 数据字典 bpm_model_category
*/
private String category;
/**
* 流程实例的状态
* <p>
* 枚举 {@link cn.axzo.server.common.enums.BpmProcessInstanceStatusEnum}
*/
private Integer status;
/**
* 流程实例的结果
* <p>
* 枚举 {@link cn.axzo.server.common.enums.BpmProcessInstanceResultEnum}
*/
private Integer result;
/**
* 结束时间
* <p>
* 冗余 HistoricProcessInstance endTime 属性
*/
private Date endTime;
/**
* 提交的表单值
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, Object> formVariables;
/**
* 发起人所在的工作台ID(企业/项目)
* <p>
* 使用租户字段隔离
*/
private String tenantId;
/**
* 发起人所在的项目工作台中的具体单位ID
*/
private Long startCompanyId;
/**
* 发起人的身份ID
*/
private Long startIdentityId;
/**
* 发起人的姓名
*/
private String startUserName;
/**
* 拓展字段业务自定义
* */
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, Object> ext;
}

View File

@ -0,0 +1,97 @@
package cn.axzo.server.dal.dataobject;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@TableName(value = "bpm_task_ext", autoResultMap = true)
@Data
@ToString(callSuper = true)
public class BpmTaskExtDO {
/**
* 编号自增
*/
@TableId
private Long id;
/**
* 任务的审批人
* <p>
* 冗余 Task assignee 属性
*/
private Long assigneeUserId;
/**
* 任务的名字
* <p>
* 冗余 Task name 属性为了筛选
*/
private String name;
/**
* 任务的编号
* <p>
* 关联 Task id 属性
*/
private String taskId;
/**
* 任务的结果
* <p>
* 枚举 {@link BpmProcessInstanceResultEnum}
*/
private Integer result;
/**
* 审批建议
*/
private String comment;
/**
* 任务的结束时间
* <p>
* 冗余 HistoricTaskInstance endTime 属性
*/
private Date endTime;
/**
* 流程实例的编号
* <p>
* 关联 ProcessInstance id 属性
*/
private String processInstanceId;
/**
* 流程定义的编号
* <p>
* 关联 ProcessDefinition id 属性
*/
private String processDefinitionId;
/**
* 租户ID
* <p>
* 企业或项目工作台ID
*/
private String tenantId;
/**
* 审批人的安心筑用户身份id
*/
private Long identityId;
/**
* 参与单位下的具体公司ID
*/
private Long companyId;
/**
* 审批人的姓名
*/
private String userName;
/**
* 审批人的组织架构信息, 施工使用
*/
private String organizationalStructureInfo;
private Object ext;
}

View File

@ -0,0 +1,9 @@
package cn.axzo.server.dal.mapper;
import cn.axzo.server.dal.dataobject.BpmTaskExtDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BpmTaskExtMapper extends BaseMapper<BpmTaskExtDO> {
}

View File

@ -42,6 +42,7 @@ public interface BpmModelService {
* */
Boolean deployBpmModelById(String modelId);
Boolean deployBpmModelByKey(String modelKey);
/**

View File

@ -1,10 +1,14 @@
package cn.axzo.server.service;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.repository.ProcessDefinition;
public interface BpmProcessDefinitionService {
Boolean updateProcessDefinitionSuspendedState(String processDefinitionId, SuspensionState state);
void updateProcessDefinitionSuspendedState(String processDefinitionId, Integer state);
ProcessDefinition getActiveProcessDefinitionByKey(String key);
}

View File

@ -11,15 +11,33 @@ import java.util.List;
public interface BpmTaskService {
/**
* 待审核列表
* */
PageResult<BpmTaskTodoPageItemVO> getTodoTaskPage(BpmTaskTodoPageDTO taskTodoPageDTO);
/**
* 已完成的审批列表
* */
PageResult<BpmTaskDonePageItemVO> getDoneTaskPage(BpmTaskTodoPageDTO taskDonePageD);
/**
* 我发起的审批列表
* */
PageResult<BpmTaskDonePageItemVO> getOwnTaskPage(BpmTaskTodoPageDTO taskDonePageD);
/**
* 同意
* */
Boolean approveTask(BpmTaskAuditDTO taskAuditDTO);
/**
* 拒绝
* */
Boolean rejectTask(BpmTaskAuditDTO taskAuditDTO);
/**
* 撤销
* */
Boolean withdrawTask(BpmTaskAuditDTO taskAuditDTO);
}

View File

@ -10,8 +10,9 @@ import javax.validation.constraints.NotBlank;
@Data
public class BpmModelCreateDTO {
@ApiModelProperty(value = "流程标识", notes = "前端不用填写", example = "process_yudao", hidden = true)
@ApiModelProperty(value = "流程模型标识", notes = "前端不用填写", example = "process_yudao", hidden = true)
@Length(max = 255, message = "流程标识最长只支持255个字符")
@NotBlank(message = "流程模型表示不能为空")
private String key;
/**

View File

@ -12,7 +12,6 @@ import javax.validation.constraints.NotNull;
@Data
public class BpmModelUpdateDTO extends BpmModelCreateDTO{
@NotNull(message = "工作流模型ID不能为空")
private Long id;
}

View File

@ -56,16 +56,16 @@ public class BpmModelServiceImpl implements BpmModelService {
/**
* 获取模型
* */
*/
@Override
public BpmModelDetailVO getModelDetailById(String modelId) {
Model model = repositoryService.getModel(modelId);
return BpmModelConverter.convert(model);
Model model = repositoryService.getModel(modelId);
return BpmModelConverter.convert(model);
}
/**
* 获取模型
* */
*/
@Override
public BpmModelDetailVO getModelDetailByKey(String modelKey) {
Model model = repositoryService.createModelQuery().modelKey(modelKey).singleResult();
@ -74,7 +74,17 @@ public class BpmModelServiceImpl implements BpmModelService {
@Override
public Boolean updateBpmModel(BpmModelUpdateDTO updateDTO) {
return null;
Model model = repositoryService.createModelQuery().modelKey(updateDTO.getKey()).singleResult();
if (ObjectUtils.isEmpty(model)) {
throw new RuntimeException("模型不存在");
}
model.setName(updateDTO.getName());
model.setMetaInfo(JSON.toJSONString(updateDTO.getMetaInfo()));
model.setCategory(updateDTO.getCategory());
model.setKey(updateDTO.getKey());
model.setTenantId(updateDTO.getTenantId());
repositoryService.saveModel(model);
return true;
}
@Override
@ -92,20 +102,18 @@ public class BpmModelServiceImpl implements BpmModelService {
processDefinitionServiceImpl.createProcessDeinition(model, bpmnBytes);
String definitionId = this.processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
this.updateProcessDefinitionSuspended(model.getDeploymentId());
ProcessDefinition definition = this.processDefinitionService.getProcessDefinition(definitionId);
model.setDeploymentId(definition.getDeploymentId());
this.repositoryService.saveModel(model);
}
String definitionId = this.processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
this.updateProcessDefinitionSuspended(model.getDeploymentId());
ProcessDefinition definition = this.processDefinitionService.getProcessDefinition(definitionId);
model.setDeploymentId(definition.getDeploymentId());
this.repositoryService.saveModel(model);
}
}
@Override
public Boolean deployBpmModelByKey(String modelKey) {
Model model = repositoryService.createModelQuery().modelKey(modelKey).singleResult();
repositoryService.de
repositoryService.
}
@Override

View File

@ -3,11 +3,13 @@ package cn.axzo.server.service.impl;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.server.common.enums.ErrorCode;
import cn.axzo.server.service.BpmProcessDefinitionService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.Model;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
@ -15,6 +17,8 @@ import java.util.Objects;
import static cn.axzo.server.common.enums.ErrorCode.PROCESS_DEFINITION_KEY_NOT_MATCH;
import static cn.axzo.server.common.enums.ErrorCode.PROCESS_DEFINITION_NAME_NOT_MATCH;
@Service
@Slf4j
public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
private static final String BPMN_FILE_SUFFIX = ".bpmn";
@Resource
@ -26,7 +30,8 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
}
Deployment deploy = repositoryService.createDeployment()
.key(model.getKey()).name(model.getName())
.key(model.getKey())
.name(model.getName())
.category(model.getCategory())
.tenantId(String.valueOf(model.getTenantId()))
.addBytes(model.getKey() + BPMN_FILE_SUFFIX, bpmnBytes)
@ -53,7 +58,26 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
}
@Override
public Boolean updateProcessDefinitionSuspendedState(String processDefinitionId, SuspensionState state) {
this.processDefinitionService.updateProcessDefinitionState(processDefinitionId, state.getStateCode());
public void updateProcessDefinitionSuspendedState(String processDefinitionId, Integer state) {
// 激活
if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
repositoryService.activateProcessDefinitionById(processDefinitionId, false, null);
return;
}
// 挂起
if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
// suspendProcessInstances = false进行中的任务不进行挂起
// 原因只要新的流程不允许发起即可老流程继续可以执行
repositoryService.suspendProcessDefinitionById(processDefinitionId, false, null);
return;
}
log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", processDefinitionId, state);
}
@Override
public ProcessDefinition getActiveProcessDefinitionByKey(String key) {
return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active()
.singleResult();
}
}

View File

@ -15,7 +15,9 @@ import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
public class BpmProcessServiceImpl {
import static cn.axzo.server.common.enums.ErrorCode.PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS;
public class BpmProcessInstanceServiceImpl {
@Autowired
private TaskService engineTaskService;

View File

@ -6,9 +6,17 @@ import cn.axzo.server.service.dto.request.task.BpmTaskTodoPageDTO;
import cn.axzo.server.service.dto.response.PageResult;
import cn.axzo.server.service.dto.response.task.BpmTaskDonePageItemVO;
import cn.axzo.server.service.dto.response.task.BpmTaskTodoPageItemVO;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class BpmTaskServiceImpl implements BpmTaskService {
@ -31,7 +39,51 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Override
public Boolean approveTask(BpmTaskAuditDTO taskAuditDTO) {
return null;
// 校验任务存在
Task task = checkTask(reqVO.getWorkspaceId(), reqVO.getIdentityId(), reqVO.getId());
// 校验流程实例存在
ProcessInstance instance = processInstanceService.getProcessInstance(
task.getProcessInstanceId(), null, true);
if (instance == null) {
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
}
bpmAddTask(task, reqVO.getAddAssignees());
// 根据流程实例ID和任务定义key查询运行中的任务并记录taskId列表
TaskQuery taskQuery = taskService.createTaskQuery()
.processInstanceId(instance.getId())
.taskTenantId(String.valueOf(reqVO.getWorkspaceId()))
.taskDefinitionKey(task.getTaskDefinitionKey());
List<Task> taskRunningListBefore = taskQuery.list();//eg123
if (taskRunningListBefore.size() > 1 && taskQuery.list().isEmpty()) {
// 满足条件1当前任务是多实例任务节点的子任务
// 满足条件2该子任务完成时将所在多实例任务节点中的其他子任务也一并删除说明此时已经满足了多实例的完成条件
// 此时需要将该任务所在多实例任务节点中的其他子任务更新任务拓展表为已完成
for (Task taskRunningBefore : taskRunningListBefore) {
if (!task.getId().equals(taskRunningBefore.getId())) {
taskExtMapper.updateByTaskId(new BpmTaskExtDO()
.setTaskId(taskRunningBefore.getId())
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
.setComment("自动完成")
.setEndTime(new Date()));
}
}
}
// 更新任务拓展表为通过
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
.setComment(reqVO.getComment()));
// 开启自动跳过功能
Map<String, Object> transientMap = new HashMap<>();
transientMap.put(WorkflowConstants.FLOWABLE_SKIP_EXPRESSION_ENABLE, true);
transientMap.put(WorkflowConstants.INTERNAL_TASK_COMMENT, reqVO.getComment());
// 完成任务审批通过
taskService.complete(task.getId(), instance.getProcessVariables(), transientMap);
return true;
}
@Override