代码开发

This commit is contained in:
lvshaohua 2023-06-15 14:51:55 +08:00
parent 0b45272556
commit 7f32dcd9bd
33 changed files with 424 additions and 974 deletions

View File

@ -67,6 +67,16 @@
<version>${flowable.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-basic</artifactId>
<version>${flowable.version}</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-actuator</artifactId>
<version>${flowable.version}</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-bpmn-converter</artifactId>

View File

@ -0,0 +1,23 @@
package cn.axzo.server.common;
public interface WorkflowConstants {
String SERVER_APP_ID = "server-app-id";
/**
* 引擎自己隐藏指令
*/
String FLOWABLE_SKIP_EXPRESSION_ENABLE = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
/**
* 指定单位标识
*/
String INTERNAL_EXECUTIVE_UNIT_ID = "_INTERNAL_EXECUTIVE_UNIT_ID";
String INTERNAL_START_USER_NAME = "_INTERNAL_START_USER_NAME";
String INTERNAL_END_USER_IDENTITY_ID = "_INTERNAL_END_USER_IDENTITY_ID";
String INTERNAL_END_USER_WORKSPACE_ID = "_INTERNAL_END_USER_WORKSPACE_ID";
String INTERNAL_END_USER_NAME = "_INTERNAL_END_USER_NAME";
String INTERNAL_TASK_COMMENT = "_INTERNAL_CUSTOM_TASK_COMMENT";
String PROCESS_PREFIX="Flowable";
String START_EVENT_ID="startEventNode";
String END_EVENT_ID="endEventNode";
String EXPRESSION_CLASS="exUtils.";
}

View File

@ -116,6 +116,7 @@ public enum ErrorCode implements IProjectRespCode {
MODEL_POOL_CANT_DEPLOY("1009012028", "模型已不部署,无需重复发布"),
PROCESS_DEFINITION_IS_SUSPENDED_CANT_DEPLOY("1009012029",
"模型处于挂起状态,无法发布"),
BPM_META_DATA_FORMAT_ERROR("1009012029","BpmJson数据格式有误"),
FLOWABLE_GENERAL_ERROR("1009013000", "流程引擎一般错误"),
FLOWABLE_ENGINE_OBJECT_NOT_FOUND("1009013001", "流程引擎内部错误:流程定义未找到"),
@ -127,6 +128,7 @@ public enum ErrorCode implements IProjectRespCode {
FLOWABLE_FORBIDDEN("1009013007", "当前流程引擎禁止访问"),
FLOWABLE_CLASS_LOADING_ERROR("1009013008", "流程引擎加载异常"),
USER_NOT_EXISTS("01001", "用户不存在id=%s"),
USER_PHONE_EMAIL_IS_NULL("01002", "电话和邮箱不能都为空");

View File

@ -0,0 +1,30 @@
package cn.axzo.server.common.enums;
import com.google.common.collect.Maps;
import org.flowable.bpmn.model.ExclusiveGateway;
import org.flowable.bpmn.model.ParallelGateway;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.bpmn.model.UserTask;
import java.util.Map;
public enum FlowNodeType {
//0 发起人 1审批 2抄送 3条件 4路由
NODE_STARTER("NODE_STARTER",UserTask.class, "发起人节点"),
NODE_CONDITION("NODE_CONDITION", UserTask.class, "条件节点"),
NODE_TASK("NODE_TASK", UserTask.class, "审核节点");
private String type;
private String desc;
private Class<?> typeClass;
FlowNodeType(String type, Class<?> typeClass, String desc) {
this.type = type;
this.typeClass = typeClass;
this.desc = desc;
}
public boolean isEqual(String type) {
return this.type.equals(type);
}
}

View File

@ -1,75 +0,0 @@
package cn.axzo.server.controller.web;
import cn.axzo.server.service.dto.request.user.NewUserDTO;
import cn.axzo.server.service.dto.request.user.UpdateUserDTO;
import cn.axzo.server.service.dto.request.user.UserQO;
import cn.axzo.server.service.dto.response.user.UserVO;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* @Author: liyong.tian
* @Date: 2022/9/2
* @Description:
*/
@Slf4j
@Api(tags = "web-用户信息接口")
@ApiSupport(author = "田立勇")
@RequestMapping("/api/v1")
@RestController
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@ApiOperation(value = "创建用户")
@PostMapping("/users")
public CommonResponse<UserVO> createUser(@Valid @RequestBody NewUserDTO dto) {
log.info("REST request to save user : {}", dto);
// 校验入参
dto.valid();
UserVO result = userService.create(dto);
return CommonResponse.success(result);
}
@ApiOperation(value = "修改用户")
@PutMapping("/users/{id}")
public CommonResponse<UserVO> updateUser(@ApiParam("用户ID") @PathVariable Long id,
@Valid @RequestBody UpdateUserDTO dto) {
log.info("REST request to update user : {}", dto);
// 校验入参
dto.valid();
UserVO result = userService.update(id, dto);
return CommonResponse.success(result);
}
@ApiOperation("获取用户列表")
@GetMapping("/users")
public CommonResponse<CommonPageResponse<UserVO>> getUsers(@Valid UserQO userQO) {
CommonPageResponse<UserVO> results = userService.queryByPage(userQO);
return CommonResponse.success(results);
}
@ApiOperation("获取用户详情")
@GetMapping("/users/{id}")
public CommonResponse getUser(@ApiParam("用户ID") @PathVariable Long id) {
UserVO result = userService.getOne(id);
return CommonResponse.success(result);
}
@ApiOperation("删除用户")
@DeleteMapping("/users/{id}")
public CommonResponse deleteUser(@ApiParam("用户ID") @PathVariable Long id) {
userService.delete(id);
return CommonResponse.success();
}
}

View File

@ -1,77 +0,0 @@
package cn.axzo.server.controller.web;
import cn.axzo.framework.domain.page.PageQO;
import cn.axzo.framework.domain.page.PageResp;
import cn.axzo.framework.web.http.ApiResponse;
import cn.axzo.framework.web.http.ApiPageResponse;
import cn.axzo.server.service.dto.request.user.NewUserDTO;
import cn.axzo.server.service.dto.request.user.UpdateUserDTO;
import cn.axzo.server.service.dto.request.user.UserQO1;
import cn.axzo.server.service.dto.response.user.UserVO;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* @Author: liyong.tian
* @Date: 2022/10/28
* @Description: 新项目搭建推荐方式
*/
@Slf4j
@Api(tags = "web-用户信息接口")
@ApiSupport(author = "田立勇")
@RequestMapping("/api/v2")
@RestController
@RequiredArgsConstructor
public class UserResource {
private final UserService userService;
@ApiOperation(value = "创建用户")
@PostMapping("/users")
public ApiResponse<UserVO> createUser(@Valid @RequestBody NewUserDTO dto) {
log.info("REST request to save user : {}", dto);
// 校验入参
dto.valid();
UserVO result = userService.create(dto);
return ApiResponse.ok(result);
}
@ApiOperation(value = "修改用户")
@PutMapping("/users/{id}")
public ApiResponse<UserVO> updateUser(@ApiParam("用户ID") @PathVariable Long id,
@Valid @RequestBody UpdateUserDTO dto) {
log.info("REST request to update user : {}", dto);
// 校验入参
dto.valid();
UserVO result = userService.update(id, dto);
return ApiResponse.ok(result);
}
@ApiOperation("获取用户列表")
@GetMapping("/users")
public ApiPageResponse<UserVO> getUsers(@ModelAttribute UserQO1 userQo, PageQO page) {
PageResp<UserVO> results = userService.find(userQo, page);
return ApiPageResponse.ok(results);
}
@ApiOperation("获取用户详情")
@GetMapping("/users/{id}")
public ApiResponse<UserVO> getUser(@ApiParam("用户ID") @PathVariable Long id) {
UserVO result = userService.getOne(id);
return ApiResponse.ok(result);
}
@ApiOperation("删除用户")
@DeleteMapping("/users/{id}")
public ApiResponse deleteUser(@ApiParam("用户ID") @PathVariable Long id) {
userService.delete(id);
return ApiResponse.ok();
}
}

View File

@ -1,19 +0,0 @@
package cn.axzo.server.job;
import cn.axzo.framework.domain.data.IdGenerator;
import cn.axzo.server.utils.IdWorker;
import org.springframework.stereotype.Component;
/**
* @Author:LoveMyOrange
* @Description:
* @Date:Created in 2022/10/17 13:01
*/
@Component
public class IdWorkerIdGenerator implements IdGenerator {
@Override
public String getNextId() {
return SpringContextHolder.getBean(IdWorker.class).nextId()+"";
}
}

View File

@ -0,0 +1,4 @@
package cn.axzo.server.listener;
public interface BpmProcessEventListener {
}

View File

@ -1,67 +1,29 @@
package cn.axzo.server.listener;
import cn.axzo.server.service.BpmTaskService;
import com.google.common.collect.ImmutableSet;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.task.api.Task;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.flowable.task.service.delegate.DelegateTask;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import javax.annotation.Resource;
import java.util.Set;
/**
* @author shao_hua
*/
public interface BpmTaskEventListener {
@Component
@Slf4j
public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
/**
* 用户任务已创建,未指派审核人
*/
void created(DelegateTask delegateTask);
@Resource
@Lazy // 解决循环依赖
private BpmTaskService taskService;
/**
* 用户任务已指派审核人
*/
void assigned(DelegateTask delegateTask);
/**
* 用户任务已处理完成
* <p>
* 仅审核通过一个用户任务时触发, 如果任务是拒绝了, 则直接走实例取消事件
*/
void completed(DelegateTask delegateTask);
public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
.add(FlowableEngineEventType.TASK_CREATED)
.add(FlowableEngineEventType.TASK_ASSIGNED)
.add(FlowableEngineEventType.TASK_COMPLETED)
.add(FlowableEngineEventType.ACTIVITY_CANCELLED)
.build();
public BpmTaskEventListener() {
super(TASK_EVENTS);
}
@Override
protected void taskCreated(FlowableEngineEntityEvent event) {
}
@Override
protected void taskCompleted(FlowableEngineEntityEvent event) {
}
@Override
protected void taskAssigned(FlowableEngineEntityEvent event) {
}
@Override
protected void activityCancelled(FlowableActivityCancelledEvent event) {
HistoricActivityInstance activity = null;
if (activity == null) {
log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]",
event.getExecutionId());
return;
}
if (StringUtils.isEmpty(activity.getTaskId())) {
return;
}
}
void deleted(DelegateTask delegateTask);
}

View File

@ -1,95 +0,0 @@
package cn.axzo.server.repository.bpmModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class BpmJsonNode {
private BpmJsonNode(ShizhiJsonNode shizhiJsonNode) {
}
private BpmJsonNode() {
}
class ShizhiJsonNode {
private String id;
private String type;
private String config;
private List<ShizhiJsonNode> children;
}
private String id;
private String parentId;
private String type; // task, branch,
private String name;
private String desc;
// private Map<> properties; //ext : Object; 会签/或签
private BpmJsonNode children;
private List<BpmJsonNode> branches;
public void build(String[] args) {
BpmJsonNode node = new BpmJsonNode();
ShizhiJsonNode tempShuzhi = new ShizhiJsonNode("Asdasdgjalksdkl");
findChildren(node, tempShuzhi);
}
public List<BpmJsonNode> findCondition(BpmJsonNode node,ShizhiJsonNode shuzhiJsonNode) {
if (shuzhiJsonNode.type.equals("condition")) {
List<BpmJsonNode> branchList = new ArrayList<BpmJsonNode>();
ShizhiJsonNode lasteatShuzhi = new ShizhiJsonNode();
for (ShizhiJsonNode temp : shuzhiJsonNode.children) {
branchList.add( findChildren(new BpmJsonNode(), temp) );
lasteatShuzhi = shuzhiJsonNode;
}
node.branches = branchList;
return branchList;
}
if (shuzhiJsonNode.type.equals("task")) {
findChildren(node, shuzhiJsonNode);
}
if (shuzhiJsonNode.type.equals("endCondition")) {
return null;
}
return null;
}
public BpmJsonNode findChildren(BpmJsonNode node, ShizhiJsonNode shuzhiJsonNode) {
if (shuzhiJsonNode == null) {
return null;
}
if (shuzhiJsonNode.type.equals("task")) {
node.children = new BpmJsonNode(shuzhiJsonNode);
findChildren(node.children, shuzhiJsonNode.children.get(0));
}
if (shuzhiJsonNode.type.equals("startCondition")) {
node.branches = findCondition(node, shuzhiJsonNode);
findChildren(node, shuzhiJsonNode.children.get(0));
}
return node;
}
}

View File

@ -1,4 +1,4 @@
package cn.axzo.server.dal.dataobject;
package cn.axzo.server.repository.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;

View File

@ -1,4 +1,4 @@
package cn.axzo.server.dal.dataobject;
package cn.axzo.server.repository.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

View File

@ -0,0 +1 @@
package cn.axzo.server.repository.dataobject;

View File

@ -0,0 +1,25 @@
package cn.axzo.server.repository.dto;
import java.util.ArrayList;
import java.util.List;
public class BpmJsonNode {
private BpmJsonNode() {
}
private String id;
private String parentId;
/**
* {@link cn.axzo.server.common.enums.FlowNodeType}
* */
private String type; // task, branch,
private String name;
private String desc;
// private Map<> properties; //ext : Object; 会签/或签
private BpmJsonNode children;
private List<BpmJsonNode> branches;
}

View File

@ -1 +0,0 @@
package cn.axzo.server.repository.entity;

View File

@ -1,27 +0,0 @@
package cn.axzo.server.repository.entity.user;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @Author: liyong.tian
* @Date: 2022/9/5
* @Description:
*/
@Data
@TableName("b_user")
public class User extends BaseEntity<User> {
private String name;
private Integer sex;
private Integer age;
private String phone;
private String email;
private String address;
}

View File

@ -1,6 +1,6 @@
package cn.axzo.server.dal.mapper;
package cn.axzo.server.repository.mapper;
import cn.axzo.server.dal.dataobject.BpmTaskExtDO;
import cn.axzo.server.repository.entity.BpmTaskExtDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

View File

@ -35,19 +35,19 @@ public interface BpmModelService {
/**
* 修改流程信息
* */
Boolean updateBpmModel(BpmModelUpdateDTO updateDTO);
void updateBpmModel(BpmModelUpdateDTO updateDTO);
/**
* 部署模型
* */
Boolean deployBpmModelById(String modelId);
void deployBpmModelById(String modelId);
Boolean deployBpmModelByKey(String modelKey);
void deployBpmModelByKey(String modelKey);
/**
* 删除模型
* */
Boolean deleteBpmModel(String id);
void deleteBpmModel(String id);
}

View File

@ -4,9 +4,17 @@ import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.repository.ProcessDefinition;
public interface BpmProcessDefinitionService {
/**
* 挂起/激活流程
* 激活SuspensionState.ACTIVE.getStateCode()
* 挂起SuspensionState.SUSPENDED.getStateCode()
* {@link SuspensionState}
* */
void updateProcessDefinitionSuspendedState(String processDefinitionId, Integer state);
/**
* 获取活跃的流程定义
* */
ProcessDefinition getActiveProcessDefinitionByKey(String key);

View File

@ -6,6 +6,8 @@ import cn.axzo.server.service.dto.response.PageResult;
import cn.axzo.server.service.dto.response.model.BpmModelPageItemVO;
import cn.axzo.server.service.dto.response.task.BpmTaskDonePageItemVO;
import cn.axzo.server.service.dto.response.task.BpmTaskTodoPageItemVO;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import java.util.List;
@ -29,15 +31,27 @@ public interface BpmTaskService {
/**
* 同意
* */
Boolean approveTask(BpmTaskAuditDTO taskAuditDTO);
void approveTask(BpmTaskAuditDTO taskAuditDTO);
/**
* 拒绝
* */
Boolean rejectTask(BpmTaskAuditDTO taskAuditDTO);
void rejectTask(BpmTaskAuditDTO taskAuditDTO);
/**
* 撤销
* */
Boolean withdrawTask(BpmTaskAuditDTO taskAuditDTO);
void withdrawTask(BpmTaskAuditDTO taskAuditDTO);
/**
* 获取历史已审批的列表详情
*/
List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId);
/**
* 获取实例正在审核的人列表
* */
List<Task> getActiveTasksByProcessInstanceId(String processInstanceId);
}

View File

@ -1,26 +0,0 @@
package cn.axzo.server.service.converter;
import cn.axzo.server.service.dto.request.user.NewUserDTO;
import cn.axzo.server.service.dto.request.user.UpdateUserDTO;
import cn.axzo.server.service.dto.response.user.UserVO;
import cn.axzo.server.repository.entity.user.User;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
/**
* @Author: liyong.tian
* @Date: 2022/9/2
* @Description:
*/
@Mapper(
componentModel = "spring",
nullValueCheckStrategy = ALWAYS
)
public interface UserConverter extends EntityConverter<UserVO, User> {
User toEntity(NewUserDTO dto);
void updateEntity(UpdateUserDTO dto, @MappingTarget User user);
}

View File

@ -102,17 +102,6 @@ public class PageParam implements Serializable {
}
}
@Override
public int hashCode() {
int PRIME = true;
int result = 1;
Object $pageNo = this.getPageNo();
int result = result * 59 + ($pageNo == null ? 43 : $pageNo.hashCode());
Object $pageSize = this.getPageSize();
result = result * 59 + ($pageSize == null ? 43 : $pageSize.hashCode());
return result;
}
@Override
public String toString() {
return "PageParam(pageNo=" + this.getPageNo() + ", pageSize=" + this.getPageSize() + ")";

View File

@ -1,6 +1,6 @@
package cn.axzo.server.service.dto.request.model;
import cn.axzo.server.repository.bpmModel.BpmJsonNode;
import cn.axzo.server.repository.dto.BpmJsonNode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

View File

@ -1,44 +0,0 @@
package cn.axzo.server.service.dto.request.user;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @Author: liyong.tian
* @Date: 2022/9/2
* @Description:
*/
@Data
public class NewUserDTO {
@ApiModelProperty(value = "名称", position = 1)
@NotBlank(message = "名称不能为空")
private String name;
@ApiModelProperty(value = "性别", position = 2)
@NotNull
private Integer sex;
@ApiModelProperty(value = "年龄", position = 3)
private Integer age;
@ApiModelProperty(value = "电话", position = 4)
private String phone;
@ApiModelProperty(value = "邮箱", position = 5)
private String email;
@ApiModelProperty(value = "地址", position = 6)
private String address;
public void valid() {
// 电话和邮箱不能都为空
if (StringUtils.isEmpty(phone) && StringUtils.isEmpty(email)) {
throw new RuntimeException("电话和邮箱不能都为空");
}
}
}

View File

@ -1,45 +0,0 @@
package cn.axzo.server.service.dto.request.user;
import cn.axzo.framework.domain.web.ApiException;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @Author: liyong.tian
* @Date: 2022/9/5
* @Description:
*/
@Data
public class UpdateUserDTO {
@ApiModelProperty(value = "名称", position = 1)
@NotBlank(message = "名称不能为空")
private String name;
@ApiModelProperty(value = "性别", position = 2)
@NotNull
private Integer sex;
@ApiModelProperty(value = "年龄", position = 3)
private Integer age;
@ApiModelProperty(value = "电话", position = 4)
private String phone;
@ApiModelProperty(value = "邮箱", position = 5)
private String email;
@ApiModelProperty(value = "地址", position = 6)
private String address;
public void valid() {
// 电话和邮箱不能都为空
if (StringUtils.isEmpty(phone) && StringUtils.isEmpty(email)) {
throw new ApiException(USER_PHONE_EMAIL_IS_NULL);
}
}
}

View File

@ -1,26 +0,0 @@
package cn.axzo.server.service.dto.request.user;
import cn.axzo.framework.domain.page.PageQO;
import io.swagger.annotations.ApiParam;
import lombok.Data;
/**
* @Author: liyong.tian
* @Date: 2022/9/5
* @Description:
*/
@Data
public class UserQO extends PageQO {
@ApiParam("主键")
private Long id;
@ApiParam("姓名")
private String name;
@ApiParam("手机")
private String phone;
@ApiParam("邮箱")
private String email;
}

View File

@ -1,26 +0,0 @@
package cn.axzo.server.service.dto.request.user;
import cn.axzo.framework.domain.page.PageQO;
import io.swagger.annotations.ApiParam;
import lombok.Data;
/**
* @Author: liyong.tian
* @Date: 2022/9/5
* @Description:
*/
@Data
public class UserQO1 {
@ApiParam("主键")
private Long id;
@ApiParam("姓名")
private String name;
@ApiParam("手机")
private String phone;
@ApiParam("邮箱")
private String email;
}

View File

@ -90,20 +90,4 @@ public class PageResult<T> implements Serializable {
return true;
}
}
@Override
public int hashCode() {
int PRIME = true;
int result = 1;
Object $total = this.getTotal();
int result = result * 59 + ($total == null ? 43 : $total.hashCode());
Object $list = this.getList();
result = result * 59 + ($list == null ? 43 : $list.hashCode());
return result;
}
public String toString() {
return "PageResult(list=" + this.getList() + ", total=" + this.getTotal() + ")";
}
}

View File

@ -1,6 +1,6 @@
package cn.axzo.server.service.dto.response.model;
import cn.axzo.server.repository.bpmModel.BpmJsonNode;
import cn.axzo.server.repository.dto.BpmJsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

View File

@ -73,7 +73,7 @@ public class BpmModelServiceImpl implements BpmModelService {
}
@Override
public Boolean updateBpmModel(BpmModelUpdateDTO updateDTO) {
public void updateBpmModel(BpmModelUpdateDTO updateDTO) {
Model model = repositoryService.createModelQuery().modelKey(updateDTO.getKey()).singleResult();
if (ObjectUtils.isEmpty(model)) {
throw new RuntimeException("模型不存在");
@ -84,11 +84,10 @@ public class BpmModelServiceImpl implements BpmModelService {
model.setKey(updateDTO.getKey());
model.setTenantId(updateDTO.getTenantId());
repositoryService.saveModel(model);
return true;
}
@Override
public Boolean deployBpmModelById(String modelId) {
public void deployBpmModelById(String modelId) {
Model model = this.repositoryService.getModel(modelId);
if (org.springframework.util.ObjectUtils.isEmpty(model)) {
throw new ServiceException(ErrorCode.MODEL_NOT_EXISTS);
@ -101,23 +100,22 @@ 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) {
public void deployBpmModelByKey(String modelKey) {
Model model = repositoryService.createModelQuery().modelKey(modelKey).singleResult();
repositoryService.
}
@Override
public Boolean deleteBpmModel(String id) {
return null;
public void deleteBpmModel(String id) {
}
}

View File

@ -19,173 +19,173 @@ import static cn.axzo.server.common.enums.ErrorCode.PROCESS_INSTANCE_CANCEL_FAIL
public class BpmProcessInstanceServiceImpl {
@Autowired
private TaskService engineTaskService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ManagementService managementService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private BpmProcessInstanceExtMapper processInstanceExtMapper;
@Autowired
@Lazy // 解决循环依赖
private BpmTaskService taskService;
@Autowired
private BpmProcessDefinitionService processDefinitionService;
@Autowired
private HistoryService historyService;
@Resource
private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
@Autowired
private CustomIdGeneratorService customIdGeneratorService;
@Override
public ProcessInstance getProcessInstance(String id, String tenantId) {
ProcessInstanceQuery instanceQuery = runtimeService.createProcessInstanceQuery()
.processInstanceId(id);
if (StrUtil.isNotBlank(tenantId)) {
instanceQuery.processInstanceTenantId(tenantId);
}
return instanceQuery.singleResult();
}
@Override
public ProcessInstance getProcessInstance(String id, String tenantId, boolean hasVariable) {
ProcessInstanceQuery instanceQuery = runtimeService.createProcessInstanceQuery();
instanceQuery.processInstanceId(id);
if (hasVariable) {
instanceQuery.includeProcessVariables();
}
if (StrUtil.isNotBlank(tenantId)) {
instanceQuery.processInstanceTenantId(tenantId);
}
return instanceQuery.singleResult();
}
@Override
public List<ProcessInstance> getProcessInstances(Set<String> ids) {
return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
}
@Override
public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(
BpmProcessInstanceMyPageReqVO pageReqVO) {
// 通过 BpmProcessInstanceExtDO 先查询到对应的分页
PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(null,
pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return new PageResult<>(pageResult.getTotal());
}
// 获得流程 Task Map
List<String> processInstanceIds = convertList(pageResult.getList(),
BpmProcessInstanceExtDO::getProcessInstanceId);
Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(
processInstanceIds);
// 转换返回
return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createProcessInstance(@Valid BpmProcessInstanceCreateReqVO reqVO) {
// 获得流程定义
ProcessDefinition definition = processDefinitionService.getProcessDefinition2(
reqVO.getProcessDefinitionId());
// 发起流程
reqVO.getVariables().put(INTERNAL_EXECUTIVE_UNIT_ID, reqVO.getExecutiveUnitId());
return createProcessInstanceForAxzo(reqVO.getWorkspaceId(), reqVO.getCompanyId(),
reqVO.getIdentityId(), reqVO.getStartUserName(), reqVO.getCustomProcessInstanceName(),
definition, reqVO.getVariables(), null);
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createProcessInstance(@Valid BpmProcessInstanceCreateReqDTO reqDTO) {
ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(
reqDTO.getProcessDefinitionKey());
return createProcessInstanceForAxzo(reqDTO.getWorkspaceId(), reqDTO.getCompanyId(),
reqDTO.getIdentityId(), reqDTO.getUserName(), reqDTO.getCustomProcessInstanceName(),
definition, reqDTO.getVariables(), reqDTO.getBusinessKey());
}
@Override
public String createProcessInstance(Long userId,
@Valid BpmProcessInstanceCreateReqDTO createReqDTO) {
// 获得流程定义
ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(
createReqDTO.getProcessDefinitionKey());
// 发起流程
return createProcessInstance0(userId, definition, createReqDTO.getVariables(),
createReqDTO.getBusinessKey());
}
@Override
public BpmProcessInstanceRespVO getProcessInstanceVO(String id, String tenantId) {
// 获得流程实例
HistoricProcessInstance processInstance = getHistoricProcessInstance(id, tenantId);
if (processInstance == null) {
return null;
}
BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(
id, tenantId);
Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);
// 获得流程定义
ProcessDefinition processDefinition = processDefinitionService
.getProcessDefinition(processInstance.getProcessDefinitionId());
Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());
BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(
processInstance.getProcessDefinitionId());
Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);
String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(
processInstance.getProcessDefinitionId());
// 拼接数据
BpmProcessInstanceRespVO bpmProcessInstanceRespVO = BpmProcessInstanceConvert.INSTANCE.convert2(
processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, null,
null);
// 设置发起人姓名
String startUserName = processInstanceExtMapper.selectOne(
new QueryWrapper<BpmProcessInstanceExtDO>().lambda()
.eq(BpmProcessInstanceExtDO::getProcessInstanceId, processInstance.getId()))
.getStartUserName();
BpmProcessInstanceRespVO.User startUser = bpmProcessInstanceRespVO.getStartUser();
startUser.setStartUserName(startUserName);
bpmProcessInstanceRespVO.setStartUser(startUser);
// 拼接结果
return bpmProcessInstanceRespVO;
}
@Override
public void cancelProcessInstance(@Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
// 校验流程实例存在
ProcessInstance instance = getProcessInstance(cancelReqVO.getId(),
String.valueOf(cancelReqVO.getWorkspaceId()));
if (instance == null) {
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
}
// 只能取消自己的
Long workspaceId = cancelReqVO.getWorkspaceId();
Long identityId = cancelReqVO.getIdentityId();
if (!Objects.equals(instance.getStartUserId(),
workspaceId + "_" + identityId)) {
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
}
Map<String, Object> variables = new HashMap<>();
variables.put(INTERNAL_END_USER_WORKSPACE_ID, cancelReqVO.getWorkspaceId());
variables.put(INTERNAL_END_USER_NAME, cancelReqVO.getName());
variables.put(INTERNAL_END_USER_IDENTITY_ID, cancelReqVO.getIdentityId());
runtimeService.setVariables(instance.getProcessInstanceId(), variables);
// 通过删除流程实例实现流程实例的取消,
// 删除流程实例正则执行任务ACT_RU_TASK. 任务会被删除通过历史表查询
deleteProcessInstance(cancelReqVO.getId(),
BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
}
// @Autowired
// private TaskService engineTaskService;
// @Autowired
// private RepositoryService repositoryService;
// @Autowired
// private ManagementService managementService;
//
// @Autowired
// private RuntimeService runtimeService;
// @Autowired
// private BpmProcessInstanceExtMapper processInstanceExtMapper;
// @Autowired
// @Lazy // 解决循环依赖
// private BpmTaskService taskService;
// @Autowired
// private BpmProcessDefinitionService processDefinitionService;
// @Autowired
// private HistoryService historyService;
// @Resource
// private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
// @Autowired
// private CustomIdGeneratorService customIdGeneratorService;
//
// @Override
// public ProcessInstance getProcessInstance(String id, String tenantId) {
// ProcessInstanceQuery instanceQuery = runtimeService.createProcessInstanceQuery()
// .processInstanceId(id);
// if (StrUtil.isNotBlank(tenantId)) {
// instanceQuery.processInstanceTenantId(tenantId);
// }
// return instanceQuery.singleResult();
// }
//
// @Override
// public ProcessInstance getProcessInstance(String id, String tenantId, boolean hasVariable) {
// ProcessInstanceQuery instanceQuery = runtimeService.createProcessInstanceQuery();
// instanceQuery.processInstanceId(id);
// if (hasVariable) {
// instanceQuery.includeProcessVariables();
// }
// if (StrUtil.isNotBlank(tenantId)) {
// instanceQuery.processInstanceTenantId(tenantId);
// }
// return instanceQuery.singleResult();
// }
//
// @Override
// public List<ProcessInstance> getProcessInstances(Set<String> ids) {
// return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
// }
//
// @Override
// public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(
// BpmProcessInstanceMyPageReqVO pageReqVO) {
// // 通过 BpmProcessInstanceExtDO 先查询到对应的分页
// PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(null,
// pageReqVO);
// if (CollUtil.isEmpty(pageResult.getList())) {
// return new PageResult<>(pageResult.getTotal());
// }
//
// // 获得流程 Task Map
// List<String> processInstanceIds = convertList(pageResult.getList(),
// BpmProcessInstanceExtDO::getProcessInstanceId);
// Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(
// processInstanceIds);
// // 转换返回
// return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);
// }
//
// @Override
// @Transactional(rollbackFor = Exception.class)
// public String createProcessInstance(@Valid BpmProcessInstanceCreateReqVO reqVO) {
// // 获得流程定义
// ProcessDefinition definition = processDefinitionService.getProcessDefinition2(
// reqVO.getProcessDefinitionId());
// // 发起流程
// reqVO.getVariables().put(INTERNAL_EXECUTIVE_UNIT_ID, reqVO.getExecutiveUnitId());
// return createProcessInstanceForAxzo(reqVO.getWorkspaceId(), reqVO.getCompanyId(),
// reqVO.getIdentityId(), reqVO.getStartUserName(), reqVO.getCustomProcessInstanceName(),
// definition, reqVO.getVariables(), null);
// }
//
// @Override
// @Transactional(rollbackFor = Exception.class)
// public String createProcessInstance(@Valid BpmProcessInstanceCreateReqDTO reqDTO) {
// ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(
// reqDTO.getProcessDefinitionKey());
// return createProcessInstanceForAxzo(reqDTO.getWorkspaceId(), reqDTO.getCompanyId(),
// reqDTO.getIdentityId(), reqDTO.getUserName(), reqDTO.getCustomProcessInstanceName(),
// definition, reqDTO.getVariables(), reqDTO.getBusinessKey());
// }
//
// @Override
// public String createProcessInstance(Long userId,
// @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {
// // 获得流程定义
// ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(
// createReqDTO.getProcessDefinitionKey());
// // 发起流程
// return createProcessInstance0(userId, definition, createReqDTO.getVariables(),
// createReqDTO.getBusinessKey());
// }
//
//
// @Override
// public BpmProcessInstanceRespVO getProcessInstanceVO(String id, String tenantId) {
// // 获得流程实例
// HistoricProcessInstance processInstance = getHistoricProcessInstance(id, tenantId);
// if (processInstance == null) {
// return null;
// }
// BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(
// id, tenantId);
// Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);
//
// // 获得流程定义
// ProcessDefinition processDefinition = processDefinitionService
// .getProcessDefinition(processInstance.getProcessDefinitionId());
// Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());
// BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(
// processInstance.getProcessDefinitionId());
// Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);
// String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(
// processInstance.getProcessDefinitionId());
//
// // 拼接数据
// BpmProcessInstanceRespVO bpmProcessInstanceRespVO = BpmProcessInstanceConvert.INSTANCE.convert2(
// processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, null,
// null);
// // 设置发起人姓名
// String startUserName = processInstanceExtMapper.selectOne(
// new QueryWrapper<BpmProcessInstanceExtDO>().lambda()
// .eq(BpmProcessInstanceExtDO::getProcessInstanceId, processInstance.getId()))
// .getStartUserName();
// BpmProcessInstanceRespVO.User startUser = bpmProcessInstanceRespVO.getStartUser();
// startUser.setStartUserName(startUserName);
// bpmProcessInstanceRespVO.setStartUser(startUser);
//
// // 拼接结果
// return bpmProcessInstanceRespVO;
// }
//
// @Override
// public void cancelProcessInstance(@Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
// // 校验流程实例存在
// ProcessInstance instance = getProcessInstance(cancelReqVO.getId(),
// String.valueOf(cancelReqVO.getWorkspaceId()));
// if (instance == null) {
// throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
// }
// // 只能取消自己的
// Long workspaceId = cancelReqVO.getWorkspaceId();
// Long identityId = cancelReqVO.getIdentityId();
// if (!Objects.equals(instance.getStartUserId(),
// workspaceId + "_" + identityId)) {
// throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
// }
// Map<String, Object> variables = new HashMap<>();
// variables.put(INTERNAL_END_USER_WORKSPACE_ID, cancelReqVO.getWorkspaceId());
// variables.put(INTERNAL_END_USER_NAME, cancelReqVO.getName());
// variables.put(INTERNAL_END_USER_IDENTITY_ID, cancelReqVO.getIdentityId());
// runtimeService.setVariables(instance.getProcessInstanceId(), variables);
//
// // 通过删除流程实例实现流程实例的取消,
// // 删除流程实例正则执行任务ACT_RU_TASK. 任务会被删除通过历史表查询
// deleteProcessInstance(cancelReqVO.getId(),
// BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
// }
}

View File

@ -9,6 +9,7 @@ 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.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@ -38,61 +39,72 @@ public class BpmTaskServiceImpl implements BpmTaskService {
}
@Override
public Boolean approveTask(BpmTaskAuditDTO taskAuditDTO) {
public void approveTask(BpmTaskAuditDTO taskAuditDTO) {
// 校验任务存在
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);
}
// 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;
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
public Boolean rejectTask(BpmTaskAuditDTO taskAuditDTO) {
public void rejectTask(BpmTaskAuditDTO taskAuditDTO) {
}
@Override
public void withdrawTask(BpmTaskAuditDTO taskAuditDTO) {
}
@Override
public List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId) {
return null;
}
@Override
public Boolean withdrawTask(BpmTaskAuditDTO taskAuditDTO) {
public List<Task> getActiveTasksByProcessInstanceId(String processInstanceId) {
return null;
}
}

View File

@ -1,54 +1,62 @@
package cn.axzo.server.service.utils;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.server.common.WorkflowConstants;
import cn.axzo.server.common.enums.FlowNodeType;
import cn.axzo.server.repository.dto.BpmJsonNode;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.repository.Model;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;
import static cn.axzo.server.common.enums.ErrorCode.BPM_META_DATA_FORMAT_ERROR;
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;
public class BpmTransformUtil {
public String transformBpmnJsonToXml(DDBpmModelSaveReqVO updateReqVO) {
public String transformBpmnJsonToXml(BpmJsonNode bpmnJson, Model model) {
JSONObject bpmnJson = (JSONObject) updateReqVO.getBpmnJson();
// JSONObject bpmnJson = (JSONObject) updateReqVO.getBpmnJson();
BpmnModel bpmnModel =new BpmnModel();
Process process=new Process();
bpmnModel.addProcess(process);
List<SequenceFlow> sequenceFlows = Lists.newArrayList();
process.setId(updateReqVO.getKey());
StartEvent startEvent = DDBpmnModelUtils.createStartEvent();
process.setId(model.getKey());
StartEvent startEvent = createStartEvent();
process.addFlowElement(startEvent);
process.setName(updateReqVO.getName());
ExtensionAttribute extensionAttribute=new ExtensionAttribute();
extensionAttribute.setName("TestName");
extensionAttribute.setNamespace("http://flowable.org/bpmn");
extensionAttribute.setValue(bpmnJson.toJSONString());
// process.addAttribute(extensionAttribute);
JSONObject processNodes = bpmnJson.getJSONObject("nodeConfig");
process.setName(model.getName());
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(bpmnJson);
// ExtensionAttribute extensionAttribute=new ExtensionAttribute();
// extensionAttribute.setName("TestName");
// extensionAttribute.setNamespace("http://flowable.org/bpmn");
// extensionAttribute.setValue(bpmnJson.toJSONString());
//// process.addAttribute(extensionAttribute);
// JSONObject processNodes = bpmnJson.getJSONObject("nodeConfig");
String lastNode = null;
try {
lastNode = create(startEvent.getId(), processNodes,bpmnModel,process,sequenceFlows);
lastNode = create(startEvent.getId(), jsonObject, bpmnModel,process,sequenceFlows);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(1245, "协议解析出错");
throw new ServiceException(BPM_META_DATA_FORMAT_ERROR);
}
EndEvent endEvent = createEndEvent();
process.addFlowElement(endEvent);
process.addFlowElement(connect(lastNode, endEvent.getId(),sequenceFlows));
new BpmnAutoLayout(bpmnModel).execute();
String xmlResult = new String(new BpmnXMLConverter().convertToXML(bpmnModel));
System.err.println(xmlResult);
@ -85,15 +93,9 @@ public class BpmTransformUtil {
// return R.ok("保存成功");
// }
private static String create(String fromId, com.alibaba.fastjson.JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
private static String create(String fromId, JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
String nodeType = flowNode.getString("type");
if (DDFlowNodeType.NODE_PARALLEL.name().equals(nodeType)) {
return createParallelGatewayBuilder(fromId, flowNode,model,process,sequenceFlows);
}
else if (DDFlowNodeType.NODE_ROUTER.name().equals(nodeType)) {
return createExclusiveGatewayBuilder(fromId, flowNode,model,process,sequenceFlows);
}
else if (DDFlowNodeType.NODE_STARTER.name().equals(nodeType)) {
if (FlowNodeType.NODE_STARTER.name().equals(nodeType)) {
// flowNode.put("incoming", Collections.singletonList(fromId));
String id = fromId;
@ -106,20 +108,7 @@ public class BpmTransformUtil {
return id;
}
}
else if (DDFlowNodeType.NODE_COPY.name().equals(nodeType)) {
flowNode.put("incoming", Collections.singletonList(fromId));
String id = createServiceTask(flowNode,process,sequenceFlows);
// 如果当前任务还有后续任务则遍历创建后续任务
com.alibaba.fastjson.JSONObject nextNode = flowNode.getJSONObject("childNode");
if (Objects.nonNull(nextNode)) {
FlowElement flowElement = model.getFlowElement(id);
return create(id, nextNode,model,process,sequenceFlows);
} else {
return id;
}
}
else if (DDFlowNodeType.NODE_TASK.name().equals(nodeType)) {
else if (FlowNodeType.NODE_TASK.name().equals(nodeType)) {
flowNode.put("incoming", Collections.singletonList(fromId));
String id = createTask(flowNode,process,sequenceFlows);
@ -137,153 +126,6 @@ public class BpmTransformUtil {
}
}
private static String createExclusiveGatewayBuilder(String formId, com.alibaba.fastjson.JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
String name = flowNode.getString("nodeName");
String exclusiveGatewayId = id("exclusiveGateway");
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
exclusiveGateway.setId(exclusiveGatewayId);
exclusiveGateway.setName(name);
process.addFlowElement(exclusiveGateway);
process.addFlowElement(connect(formId, exclusiveGatewayId,sequenceFlows));
if (Objects.isNull(flowNode.getJSONArray("conditionNodes")) && Objects.isNull(flowNode.getJSONObject("childNode"))) {
return exclusiveGatewayId;
}
List<com.alibaba.fastjson.JSONObject> flowNodes = Optional.ofNullable(flowNode.getJSONArray("conditionNodes")).map(e -> e.toJavaList(com.alibaba.fastjson.JSONObject.class)).orElse(Collections.emptyList());
List<String> incoming = Lists.newArrayListWithCapacity(flowNodes.size());
List<com.alibaba.fastjson.JSONObject> conditions = Lists.newCopyOnWriteArrayList();
for (com.alibaba.fastjson.JSONObject element : flowNodes) {
com.alibaba.fastjson.JSONObject childNode = element.getJSONObject("childNode");
String nodeName = element.getString("nodeName");
String expression = element.getString("conditionExpression");
if (Objects.isNull(childNode)) {
incoming.add(exclusiveGatewayId);
com.alibaba.fastjson.JSONObject condition = new com.alibaba.fastjson.JSONObject();
condition.fluentPut("nodeName", nodeName)
.fluentPut("expression", expression);
conditions.add(condition);
continue;
}
// 只生成一个任务同时设置当前任务的条件
childNode.put("incoming", Collections.singletonList(exclusiveGatewayId));
String identifier = create(exclusiveGatewayId, childNode,model,process,sequenceFlows);
List<SequenceFlow> flows = sequenceFlows.stream().filter(flow -> StringUtils.equals(exclusiveGatewayId, flow.getSourceRef()))
.collect(Collectors.toList());
flows.stream().forEach(
e -> {
if (StringUtils.isBlank(e.getName()) && StringUtils.isNotBlank(nodeName)) {
e.setName(nodeName);
}
// 设置条件表达式
if (Objects.isNull(e.getConditionExpression()) && StringUtils.isNotBlank(expression)) {
e.setConditionExpression(expression);
}
}
);
if (Objects.nonNull(identifier)) {
incoming.add(identifier);
}
}
com.alibaba.fastjson.JSONObject childNode = flowNode.getJSONObject("childNode");
if (Objects.nonNull(childNode)) {
if (incoming == null || incoming.isEmpty()) {
return create(exclusiveGatewayId, childNode,model,process,sequenceFlows);
}
else {
// 所有 service task 连接 end exclusive gateway
childNode.put("incoming", incoming);
FlowElement flowElement = model.getFlowElement(incoming.get(0));
// 1.0 先进行边连接, 暂存 nextNode
com.alibaba.fastjson.JSONObject nextNode = childNode.getJSONObject("childNode");
String endExId=id("exclusiveGateway")+"end";
process.addFlowElement(DDBpmnModelUtils.createExclusiveGateWayEnd(endExId));
childNode.put("childNode", null);
String identifier =endExId;/*create(flowElement.getId(), childNode,model,process,sequenceFlows);*/
for (int i = 0; i < incoming.size(); i++) {
process.addFlowElement(connect(incoming.get(i), endExId,sequenceFlows));
}
// 针对 gateway 空任务分支 添加条件表达式
if (!conditions.isEmpty()) {
FlowElement flowElement1 = model.getFlowElement(identifier);
// 获取从 gateway 到目标节点 未设置条件表达式的节点
List<SequenceFlow> flows = sequenceFlows.stream().filter(flow -> StringUtils.equals(flowElement1.getId(), flow.getTargetRef()))
.filter(flow -> StringUtils.equals(flow.getSourceRef(), exclusiveGatewayId))
.collect(Collectors.toList());
flows.stream().forEach(sequenceFlow -> {
if (!conditions.isEmpty()) {
com.alibaba.fastjson.JSONObject condition = conditions.get(0);
String nodeName = condition.getString("nodeName");
String expression = condition.getString("expression");
if (StringUtils.isBlank(sequenceFlow.getName()) && StringUtils.isNotBlank(nodeName)) {
sequenceFlow.setName(nodeName);
}
// 设置条件表达式
if (Objects.isNull(sequenceFlow.getConditionExpression()) && StringUtils.isNotBlank(expression)) {
sequenceFlow.setConditionExpression(expression);
}
conditions.remove(0);
}
});
}
// 1.1 边连接完成后在进行 nextNode 创建
if (Objects.nonNull(childNode)) {
return create(endExId, childNode,model,process,sequenceFlows);
} else {
return endExId;
}
}
}
else{
// 所有 service task 连接 end exclusive gateway
// 1.0 先进行边连接, 暂存 nextNode
String endExId=id("exclusiveGateway")+"end";
process.addFlowElement(DDBpmnModelUtils.createExclusiveGateWayEnd(endExId));
String identifier =endExId;/*create(flowElement.getId(), childNode,model,process,sequenceFlows);*/
for (int i = 0; i < incoming.size(); i++) {
process.addFlowElement(connect(incoming.get(i), endExId,sequenceFlows));
}
// 针对 gateway 空任务分支 添加条件表达式
if (!conditions.isEmpty()) {
FlowElement flowElement1 = model.getFlowElement(identifier);
// 获取从 gateway 到目标节点 未设置条件表达式的节点
List<SequenceFlow> flows = sequenceFlows.stream().filter(flow -> StringUtils.equals(flowElement1.getId(), flow.getTargetRef()))
.filter(flow -> StringUtils.equals(flow.getSourceRef(), exclusiveGatewayId))
.collect(Collectors.toList());
flows.stream().forEach(sequenceFlow -> {
if (!conditions.isEmpty()) {
com.alibaba.fastjson.JSONObject condition = conditions.get(0);
String nodeName = condition.getString("nodeName");
String expression = condition.getString("expression");
if (StringUtils.isBlank(sequenceFlow.getName()) && StringUtils.isNotBlank(nodeName)) {
sequenceFlow.setName(nodeName);
}
// 设置条件表达式
if (Objects.isNull(sequenceFlow.getConditionExpression()) && StringUtils.isNotBlank(expression)) {
sequenceFlow.setConditionExpression(expression);
}
conditions.remove(0);
}
});
}
return endExId;
}
// return exclusiveGatewayId;
}
private static String createParallelGatewayBuilder(String formId, com.alibaba.fastjson.JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
String name = flowNode.getString("nodeName");
@ -370,7 +212,7 @@ public class BpmTransformUtil {
userTask.setName(flowNode.getString("nodeName"));
userTask.setId(id);
process.addFlowElement(userTask);
if(DDFlowNodeType.NODE_STARTER.name().equals(flowNode.getString("type"))){
if(FlowNodeType.NODE_STARTER.name().equals(flowNode.getString("type"))){
id = WorkflowConstants.START_EVENT_ID;
}
else{
@ -464,4 +306,11 @@ public class BpmTransformUtil {
endEvent.setId(id("end"));
return endEvent;
}
// public static StartEvent createStartEvent() {
// StartEvent startEvent = new StartEvent();
// startEvent.setId(WorkflowConstants.START_EVENT_ID);
// startEvent.setInitiator("applyUserId");
// return startEvent;
// }
}