拆分 bpm 到独立的库中

This commit is contained in:
chenbowen
2025-09-29 09:36:24 +08:00
parent 0a0ecb4f80
commit fd97e608cb
292 changed files with 26715 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<?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>
<groupId>com.zt.plat</groupId>
<artifactId>zt-module-bpm</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zt-module-bpm-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
bpm 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springdoc</groupId> <!-- 接口文档:使用最新版本的 Swagger 模型 -->
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,55 @@
package com.zt.plat.module.bpm.api.definition;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.module.bpm.api.definition.dto.BpmCategoryPageReqDTO;
import com.zt.plat.module.bpm.api.definition.dto.BpmCategoryRespDTO;
import com.zt.plat.module.bpm.api.definition.dto.BpmCategorySaveReqDTO;
import com.zt.plat.module.bpm.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@FeignClient(name = ApiConstants.NAME)
@Tag(name = "RPC 服务 - BPM 流程分类")
public interface BpmCategoryApi {
String PREFIX = ApiConstants.PREFIX + "/category";
@PostMapping(PREFIX + "/create")
@Operation(summary = "创建流程分类")
CommonResult<Long> createCategory(@Valid @RequestBody BpmCategorySaveReqDTO createReqDTO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "更新流程分类")
CommonResult<Boolean> updateCategory(@Valid @RequestBody BpmCategorySaveReqDTO updateReqDTO);
@PutMapping(PREFIX + "/update-sort-batch")
@Operation(summary = "批量更新流程分类的排序")
@Parameter(name = "ids", description = "分类编号列表", required = true, example = "1,2,3")
CommonResult<Boolean> updateCategorySortBatch(@RequestParam("ids") List<Long> ids);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除流程分类")
@Parameter(name = "id", description = "编号", required = true)
CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得流程分类")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
CommonResult<BpmCategoryRespDTO> getCategory(@RequestParam("id") Long id);
@PostMapping(PREFIX + "/page")
@Operation(summary = "获得流程分类分页")
CommonResult<PageResult<BpmCategoryRespDTO>> getCategoryPage(@Valid @RequestBody BpmCategoryPageReqDTO pageReqDTO);
@GetMapping(PREFIX + "/simple-list")
@Operation(summary = "获取流程分类的精简信息列表", description = "只包含被开启的分类,主要用于前端的下拉选项")
CommonResult<List<BpmCategoryRespDTO>> getCategorySimpleList();
}

View File

@@ -0,0 +1,50 @@
package com.zt.plat.module.bpm.api.definition;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.module.bpm.api.definition.dto.BpmFormPageReqDTO;
import com.zt.plat.module.bpm.api.definition.dto.BpmFormRespDTO;
import com.zt.plat.module.bpm.api.definition.dto.BpmFormSaveReqDTO;
import com.zt.plat.module.bpm.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@FeignClient(name = ApiConstants.NAME)
@Tag(name = "RPC 服务 - 动态表单")
public interface BpmFormApi {
String PREFIX = ApiConstants.PREFIX + "/form";
@PostMapping(PREFIX + "/create")
@Operation(summary = "创建动态表单")
CommonResult<Long> createForm(@Valid @RequestBody BpmFormSaveReqDTO createReqDTO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "更新动态表单")
CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormSaveReqDTO updateReqDTO);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除动态表单")
@Parameter(name = "id", description = "编号", required = true)
CommonResult<Boolean> deleteForm(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得动态表单")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
CommonResult<BpmFormRespDTO> getForm(@RequestParam("id") Long id);
@PostMapping(PREFIX + "/page")
@Operation(summary = "获得动态表单分页")
CommonResult<PageResult<BpmFormRespDTO>> getFormPage(@Valid @RequestBody BpmFormPageReqDTO pageReqDTO);
@GetMapping(PREFIX + "/simple-list")
@Operation(summary = "获得动态表单的精简列表", description = "用于表单下拉框")
CommonResult<List<BpmFormRespDTO>> getFormSimpleList();
}

View File

@@ -0,0 +1,29 @@
package com.zt.plat.module.bpm.api.definition;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.bpm.api.definition.dto.BpmUserGroupRespDTO;
import com.zt.plat.module.bpm.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@FeignClient(name = ApiConstants.NAME)
@Tag(name = "RPC 服务 - 用户组")
public interface BpmUserGroupApi {
String PREFIX = ApiConstants.PREFIX + "/user-group";
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得用户组")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
CommonResult<BpmUserGroupRespDTO> getUserGroup(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/simple-list")
@Operation(summary = "获取用户组精简信息列表", description = "只包含被开启的用户组,主要用于前端的下拉选项")
CommonResult<List<BpmUserGroupRespDTO>> getUserGroupSimpleList();
}

View File

@@ -0,0 +1,32 @@
package com.zt.plat.module.bpm.api.definition.dto;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.common.pojo.PageParam;
import com.zt.plat.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.zt.plat.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "RPC 服务 - BPM 流程分类分页 Request DTO")
@Data
public class BpmCategoryPageReqDTO extends PageParam {
@Schema(description = "分类名", example = "王五")
private String name;
@Schema(description = "分类标志", example = "OA")
private String code;
@Schema(description = "分类状态", example = "1")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.bpm.api.definition.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "RPC 服务 - BPM 流程分类 Response DTO")
@Data
public class BpmCategoryRespDTO {
@Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
private Long id;
@Schema(description = "分类名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
private String name;
@Schema(description = "分类标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "OA")
private String code;
@Schema(description = "分类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
private String description;
@Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer sort;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,37 @@
package com.zt.plat.module.bpm.api.definition.dto;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "RPC 服务 - BPM 流程分类新增/修改 Request DTO")
@Data
public class BpmCategorySaveReqDTO {
@Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
private Long id;
@Schema(description = "分类名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@NotEmpty(message = "分类名不能为空")
private String name;
@Schema(description = "分类描述", example = "你猜")
private String description;
@Schema(description = "分类标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "OA")
@NotEmpty(message = "分类标志不能为空")
private String code;
@Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "分类状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "分类排序不能为空")
private Integer sort;
}

View File

@@ -0,0 +1,18 @@
package com.zt.plat.module.bpm.api.definition.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "动态表单分页 Request DTO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmFormPageReqDTO extends PageParam {
@Schema(description = "表单名称", example = "芋道")
private String name;
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.bpm.api.definition.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "RPC 服务 - 动态表单 Response DTO")
@Data
public class BpmFormRespDTO {
@Schema(description = "表单编号", example = "1024")
private Long id;
@Schema(description = "表单名", example = "芋艿")
private String name;
@Schema(description = "表单状态", example = "1")
private Integer status;
@Schema(description = "表单的配置")
private String conf;
@Schema(description = "表单项的数组")
private String fields;
@Schema(description = "备注", example = "我是备注")
private String remark;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,32 @@
package com.zt.plat.module.bpm.api.definition.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Schema(description = "RPC 服务 - 动态表单新增/修改 Request DTO")
@Data
public class BpmFormSaveReqDTO {
@Schema(description = "表单编号", example = "1024")
private Long id;
@Schema(description = "表单名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@NotEmpty(message = "表单名不能为空")
private String name;
@Schema(description = "表单状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "表单的配置", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "表单的配置不能为空")
private String conf;
@Schema(description = "表单项的数组", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "表单项的数组不能为空")
private String fields;
@Schema(description = "备注", example = "我是备注")
private String remark;
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.api.definition.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Set;
@Schema(description = "RPC 服务 - 用户组 Response DTO")
@Data
public class BpmUserGroupRespDTO {
@Schema(description = "编号", example = "1024")
private Long id;
@Schema(description = "组名", example = "芋艿")
private String name;
@Schema(description = "描述", example = "芋艿")
private String description;
@Schema(description = "成员用户编号数组", example = "1,2,3")
private Set<Long> memberUserIds;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,41 @@
package com.zt.plat.module.bpm.api.event;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.context.ApplicationEvent;
/**
* 流程实例的状态(结果)发生变化的 Event
*
* @author ZT
*/
@SuppressWarnings("ALL")
@Data
public class BpmProcessInstanceStatusEvent extends ApplicationEvent {
/**
* 流程实例的编号
*/
@NotNull(message = "流程实例的编号不能为空")
private String id;
/**
* 流程实例的 key
*/
@NotNull(message = "流程实例的 key 不能为空")
private String processDefinitionKey;
/**
* 流程实例的结果
*/
@NotNull(message = "流程实例的状态不能为空")
private Integer status;
/**
* 流程实例对应的业务标识
* 例如说,请假
*/
private String businessKey;
public BpmProcessInstanceStatusEvent(Object source) {
super(source);
}
}

View File

@@ -0,0 +1,34 @@
package com.zt.plat.module.bpm.api.event;
import org.springframework.context.ApplicationListener;
import java.util.List;
/**
* {@link BpmProcessInstanceStatusEvent} 的监听器
*
* @author ZT
*/
public abstract class BpmProcessInstanceStatusEventListener
implements ApplicationListener<BpmProcessInstanceStatusEvent> {
@Override
public final void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
if (getProcessDefinitionKey().contains(event.getProcessDefinitionKey())){
onEvent(event);
}
}
/**
* @return 返回监听的流程定义 Key
*/
protected abstract List<String> getProcessDefinitionKey();
/**
* 处理事件
*
* @param event 事件
*/
protected abstract void onEvent(BpmProcessInstanceStatusEvent event);
}

View File

@@ -0,0 +1,4 @@
/**
* bpm API 包,定义暴露给其它模块的 API
*/
package com.zt.plat.module.bpm.api;

View File

@@ -0,0 +1,67 @@
package com.zt.plat.module.bpm.api.task;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.bpm.api.task.dto.*;
import com.zt.plat.module.bpm.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 流程实例")
public interface BpmProcessInstanceApi {
String PREFIX = ApiConstants.PREFIX + "/process-instance";
@PostMapping(PREFIX + "/create")
@Operation(summary = "创建流程实例(提供给内部),返回实例编号")
@Parameter(name = "userId", description = "用户编号", required = true, example = "1")
CommonResult<String> createProcessInstance(@RequestParam("userId") Long userId,
@Valid @RequestBody BpmProcessInstanceCreateReqDTO reqDTO);
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得指定流程实例", description = "在【流程详细】界面中,进行调用")
@Parameter(name = "id", description = "流程实例的编号", required = true)
CommonResult<BpmProcessInstanceRespDTO> getProcessInstance(@RequestParam("id") String id);
@DeleteMapping(PREFIX + "/cancel-by-start-user")
@Operation(summary = "用户取消流程实例", description = "取消发起的流程")
CommonResult<Boolean> cancelProcessInstanceByStartUser(
@RequestParam("userId") Long userId,
@Valid @RequestBody BpmProcessInstanceCancelReqDTO cancelReqDTO);
@DeleteMapping(PREFIX + "/cancel-by-admin")
@Operation(summary = "管理员取消流程实例", description = "管理员撤回流程")
CommonResult<Boolean> cancelProcessInstanceByAdmin(
@RequestParam("userId") Long userId,
@Valid @RequestBody BpmProcessInstanceCancelReqDTO cancelReqDTO);
@PostMapping(PREFIX + "/get-approval-detail")
@Operation(summary = "获得审批详情")
CommonResult<BpmApprovalDetailRespDTO> getApprovalDetail(@RequestParam("userId") Long userId,
@Valid BpmApprovalDetailReqDTO reqDTO);
@PostMapping(PREFIX + "/get-next-approval-nodes")
@Operation(summary = "获取下一个执行的流程节点")
CommonResult<List<BpmApprovalDetailRespDTO.ActivityNode>> getNextApprovalNodes(@RequestParam("userId") Long userId,
@Valid BpmApprovalDetailReqDTO reqDTO);
@PostMapping(PREFIX + "/get-bpmn-model-view")
@Operation(summary = "获取流程实例的 BPMN 模型视图", description = "在【流程详细】界面中,进行调用")
@Parameter(name = "id", description = "流程实例的编号", required = true)
CommonResult<BpmProcessInstanceBpmnModelViewRespDTO> getProcessInstanceBpmnModelView(@RequestParam(value = "id") String id);
@PutMapping(PREFIX + "/approveTask")
@Operation(summary = "通过任务")
CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqDTO reqVO);
@PutMapping(PREFIX + "/rejectTask")
@Operation(summary = "不通过任务")
CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqDTO reqVO);
}

View File

@@ -0,0 +1,53 @@
package com.zt.plat.module.bpm.api.task;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.bpm.api.task.dto.BpmTaskPageReqDTO;
import com.zt.plat.module.bpm.api.task.dto.BpmTaskRespDTO;
import com.zt.plat.module.bpm.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = ApiConstants.NAME)
@Tag(name = "RPC 服务 - 流程任务实例")
public interface BpmTaskApi {
String PREFIX = ApiConstants.PREFIX + "/task";
@PostMapping(PREFIX + "/todo-page")
@Operation(summary = "获取 Todo 待办任务分页")
CommonResult<List<BpmTaskRespDTO>> getTaskTodoPage(@Valid @RequestBody BpmTaskPageReqDTO pageReqDTO);
@PostMapping(PREFIX + "/done-page")
@Operation(summary = "获取 Done 已办任务分页")
CommonResult<List<BpmTaskRespDTO>> getTaskDonePage(@Valid @RequestBody BpmTaskPageReqDTO pageReqDTO);
@PostMapping(PREFIX + "/manager-page")
@Operation(summary = "获取全部任务的分页", description = "用于【流程任务】菜单")
CommonResult<List<BpmTaskRespDTO>> getTaskManagerPage(@Valid @RequestBody BpmTaskPageReqDTO pageReqDTO);
@GetMapping(PREFIX + "/list-by-process-instance-id")
@Operation(summary = "获得指定流程实例的任务列表", description = "包括完成的、未完成的")
@Parameter(name = "processInstanceId", description = "流程实例的编号", required = true)
CommonResult<List<BpmTaskRespDTO>> getTaskListByProcessInstanceId(
@RequestParam("processInstanceId") String processInstanceId);
@GetMapping(PREFIX + "/list-by-return")
@Operation(summary = "获取所有可退回的节点", description = "用于【流程详情】的【退回】按钮")
@Parameter(name = "id", description = "当前任务ID", required = true)
CommonResult<List<BpmTaskRespDTO>> getTaskListByReturn(@RequestParam("id") String id);
@GetMapping(PREFIX + "/list-by-parent-task-id")
@Operation(summary = "获得指定父级任务的子任务列表") // 目前用于,减签的时候,获得子任务列表
@Parameter(name = "parentTaskId", description = "父级任务编号", required = true)
CommonResult<List<BpmTaskRespDTO>> getTaskListByParentTaskId(@RequestParam("parentTaskId") String parentTaskId);
}

View File

@@ -0,0 +1,40 @@
package com.zt.plat.module.bpm.api.task.dto;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import lombok.Data;
import java.util.Map;
@Schema(description = "RPC 服务 - 审批详情 Request DTO")
@Data
public class BpmApprovalDetailReqDTO {
@Schema(description = "流程定义的编号", example = "1024")
private String processDefinitionId; // 使用场景:发起流程时,传流程定义 ID
@Schema(description = "流程变量")
private Map<String, Object> processVariables; // 使用场景:同 processDefinitionId用于流程预测
@Schema(description = "流程变量")
private String processVariablesStr; // 解决 GET 无法传递对象的问题,最终转换成 processVariables 变量
@Schema(description = "流程实例的编号", example = "1024")
private String processInstanceId; // 使用场景:流程已发起时候传流程实例 ID
// TODO @芋艿:如果未来 BPMN 增加流程图,它没有发起人节点,会有问题。
@Schema(description = "流程活动编号", example = "StartUserNode")
private String activityId; // 用于获取表单权限。1发起流程时传"发起人节点" activityId 可获取发起人的表单权限2从抄送列表界面进来时传抄送的 activityId 可获取抄送人的表单权限;
@Schema(description = "流程任务编号", example = "95f2f08b-621b-11ef-bf39-00ff4722db8b")
private String taskId; // 用于获取表单权限。1从待审批/已审批界面进来时,传递 taskId 任务编号,可获取任务节点的变得权限
@AssertTrue(message = "流程定义的编号和流程实例的编号不能同时为空")
@JsonIgnore
public boolean isValidProcessParam() {
return StrUtil.isNotEmpty(processDefinitionId) || StrUtil.isNotEmpty(processInstanceId);
}
}

View File

@@ -0,0 +1,110 @@
package com.zt.plat.module.bpm.api.task.dto;
import com.zt.plat.module.bpm.api.task.dto.BpmTaskRespDTO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Schema(description = "RPC 服务 - 审批详情 Response DTO")
@Data
public class BpmApprovalDetailRespDTO {
@Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
@Schema(description = "活动节点列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<ActivityNode> activityNodes;
@Schema(description = "表单字段权限")
private Map<String, String> formFieldsPermission;
@Schema(description = "待办任务")
private BpmTaskRespDTO todoTask;
/**
* 所属流程定义信息
*/
private BpmProcessDefinitionRespDTO processDefinition;
/**
* 所属流程实例信息
*/
private BpmProcessInstanceRespDTO processInstance;
@Schema(description = "活动节点信息")
@Data
public static class ActivityNode {
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartUserNode")
private String id;
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "发起人")
private String name;
@Schema(description = "节点类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer nodeType; // 参见 BpmSimpleModelNodeType 枚举
@Schema(description = "节点状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer status; // 参见 BpmTaskStatusEnum 枚举
@Schema(description = "节点的开始时间")
private LocalDateTime startTime;
@Schema(description = "节点的结束时间")
private LocalDateTime endTime;
@Schema(description = "审批节点的任务信息")
private List<ActivityNodeTask> tasks;
@Schema(description = "候选人策略", example = "35")
private Integer candidateStrategy; // 参见 BpmTaskCandidateStrategyEnum 枚举。主要用于发起时,审批节点、抄送节点自选
@Schema(description = "候选人用户 ID 列表", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1818")
@JsonIgnore // 不返回,只是方便后续读取,赋值给 candidateUsers
private List<Long> candidateUserIds;
@Schema(description = "候选人用户列表")
private List<UserSimpleDTO> candidateUsers; // 只包含未生成 ApprovalTaskInfo 的用户列表
@Schema(description = "流程编号", example = "8761d8e0-0922-11f0-bd37-00ff1db677bf")
private String processInstanceId; // 当且仅当该节点是子流程节点时才会有值CallActivity 的 processInstanceId 字段)
}
@Schema(description = "活动节点的任务信息")
@Data
public static class ActivityNodeTask {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String id;
@Schema(description = "任务所属人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1818")
@JsonIgnore // 不返回,只是方便后续读取,赋值给 ownerUser
private Long owner;
@Schema(description = "任务所属人", example = "1024")
private UserSimpleDTO ownerUser;
@Schema(description = "任务分配人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2048")
@JsonIgnore // 不返回,只是方便后续读取,赋值给 assigneeUser
private Long assignee;
@Schema(description = "任务分配人", example = "2048")
private UserSimpleDTO assigneeUser;
@Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmTaskStatusEnum 枚举
@Schema(description = "审批意见", example = "同意")
private String reason;
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
private String signPicUrl;
}
}

View File

@@ -0,0 +1,55 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "RPC 服务 - 流程定义 Response DTO")
@Data
public class BpmProcessDefinitionRespDTO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String id;
@Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "process_order")
private String key;
@Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假流程")
private String name;
@Schema(description = "流程描述", example = "请假流程描述")
private String description;
@Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "oa")
private String category;
@Schema(description = "表单类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer formType;
@Schema(description = "表单编号", example = "1024")
private Long formId;
@Schema(description = "表单的配置", requiredMode = Schema.RequiredMode.REQUIRED)
private String formConf;
@Schema(description = "表单项的数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> formFields;
@Schema(description = "表单项的 JSON 数组字符串", requiredMode = Schema.RequiredMode.REQUIRED)
private String formFieldsStr;
@Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
private String bpmnXml;
@Schema(description = "版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer version;
@Schema(description = "是否挂起", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Integer suspensionState;
@Schema(description = "部署时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime deploymentTime;
}

View File

@@ -0,0 +1,41 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
import java.util.Set;
@Schema(description = "RPC 服务 - 流程示例的 BPMN 视图 Response DTO")
@Data
public class BpmProcessInstanceBpmnModelViewRespDTO {
// ========== 基本信息 ==========
@Schema(description = "流程实例信息", requiredMode = Schema.RequiredMode.REQUIRED)
private BpmProcessInstanceRespDTO processInstance;
@Schema(description = "任务列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<BpmTaskRespDTO> tasks;
@Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
private String bpmnXml;
@Schema(description = "SIMPLE 模型")
private BpmSimpleModelNodeDTO simpleModel;
// ========== 进度信息 ==========
@Schema(description = "进行中的活动节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
private Set<String> unfinishedTaskActivityIds; // 只包括 UserTask
@Schema(description = "已经完成的活动节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
private Set<String> finishedTaskActivityIds; // 包括 UserTask、Gateway 等,不包括 SequenceFlow
@Schema(description = "已经完成的连线节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
private Set<String> finishedSequenceFlowActivityIds; // 只包括 SequenceFlow
@Schema(description = "已经拒绝的活动节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
private Set<String> rejectedTaskActivityIds; // 只包括 UserTask
}

View File

@@ -0,0 +1,19 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Schema(description = "RPC 服务 - 流程实例的取消 Request DTO")
@Data
public class BpmProcessInstanceCancelReqDTO {
@Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotEmpty(message = "流程实例的编号不能为空")
private String id;
@Schema(description = "取消原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "不请假了!")
@NotEmpty(message = "取消原因不能为空")
private String reason;
}

View File

@@ -0,0 +1,36 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;
@Schema(description = "RPC 服务 - 流程实例的创建 Request DTO")
@Data
public class BpmProcessInstanceCreateReqDTO {
@Schema(description = "流程定义的标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "leave")
@NotEmpty(message = "流程定义的标识不能为空")
private String processDefinitionKey;
@Schema(description = "变量实例", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, Object> variables;
@Schema(description = "业务的唯一标识", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "业务的唯一标识不能为空")
private String businessKey; // 例如说,请假申请的编号。通过它,可以查询到对应的实例
/**
* 发起人自选审批人 Map
*
* keytaskKey 任务编码
* value审批人的数组
* 例如:{ taskKey1 :[1, 2] },则表示 taskKey1 这个任务,提前设定了,由 userId 为 1,2 的用户进行审批
*/
@Schema(description = "发起人自选审批人 Map")
private Map<String, List<Long>> startUserSelectAssignees;
}

View File

@@ -0,0 +1,51 @@
package com.zt.plat.module.bpm.api.task.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.zt.plat.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "RPC 服务 - 流程实例分页 Request DTO")
@Data
public class BpmProcessInstancePageReqDTO extends PageParam {
@Schema(description = "流程实例的编号", example = "1024")
private String id;
@Schema(description = "流程实例的名字", example = "芋艿")
private String name;
@Schema(description = "流程定义的编号", example = "2048")
private String processDefinitionId;
@Schema(description = "流程定义的标识", example = "2048")
private String processDefinitionKey; // 精准匹配
@Schema(description = "流程分类", example = "1")
private String category;
@Schema(description = "流程实例的状态", example = "1")
private Integer status;
@Schema(description = "流程实例的结果", example = "1")
private Integer result;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] endTime;
@Schema(description = "发起用户编号", example = "1024")
private Long startUserId; // 注意,只有在【流程实例】菜单,才使用该参数
@Schema(description = "动态表单字段查询 JSON Str", example = "{}")
private String formFieldsParams; // SpringMVC 在 get 请求下,无法方便的定义 Map 类型的参数,所以通过 String 接收后,逻辑里面转换
}

View File

@@ -0,0 +1,92 @@
package com.zt.plat.module.bpm.api.task.dto;
import com.zt.plat.framework.common.core.KeyValue;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Schema(description = "RPC 服务 - 流程实例 Response DTO")
@Data
public class BpmProcessInstanceRespDTO {
@Schema(description = "流程实例的编号", example = "1024")
private String id;
@Schema(description = "流程实例的名字", example = "芋艿")
private String name;
@Schema(description = "流程摘要")
private List<KeyValue<String, String>> summary; // 只有流程表单,才有摘要!
@Schema(description = "流程定义的编号", example = "2048")
private String processDefinitionId;
@Schema(description = "流程分类", example = "1")
private String category;
@Schema(description = "流程分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假")
private String categoryName;
@Schema(description = "流程实例的状态", example = "1")
private Integer status;
@Schema(description = "流程实例的结果", example = "1")
private Integer result;
@Schema(description = "发起时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime startTime;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "持续时间", example = "1000")
private Long durationInMillis;
@Schema(description = "提交的表单值", example = "{\"name\": \"芋艿\"}")
private Map<String, Object> formVariables;
@Schema(description = "业务的唯一标识", example = "1")
private String businessKey;
/**
* 发起流程的用户
*/
private UserSimpleDTO startUser;
/**
* 流程定义
*/
private BpmProcessDefinitionRespDTO processDefinition;
/**
* 当前审批中的任务
*/
private List<Task> tasks; // 仅在流程实例分页才返回
@Schema(description = "流程任务")
@Data
public static class Task {
@Schema(description = "流程任务的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String id;
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
@Schema(description = "任务分配人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2048")
@JsonIgnore // 不返回,只是方便后续读取,赋值给 assigneeUser
private Long assignee;
@Schema(description = "任务分配人", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2048")
private UserSimpleDTO assigneeUser;
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Schema(description = "RPC 服务 - 简单模型节点 DTO")
@Data
public class BpmSimpleModelNodeDTO {
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartNode")
private String id;
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "开始节点")
private String name;
@Schema(description = "节点类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer type;
@Schema(description = "节点属性")
private Map<String, Object> attributes;
@Schema(description = "子节点列表")
private List<BpmSimpleModelNodeDTO> childNode;
@Schema(description = "条件节点列表")
private List<BpmSimpleModelNodeDTO> conditionNodes;
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Schema(description = "RPC 服务 - 通过流程任务的 Request DTO")
@Data
public class BpmTaskApproveReqDTO {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotEmpty(message = "任务编号不能为空")
private String id;
@Schema(description = "审批意见", example = "不错不错!")
private String reason;
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
private String signPicUrl;
@Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, Object> variables;
@Schema(description = "下一个节点审批人", example = "{nodeId:[1, 2]}")
private Map<String, List<Long>> nextAssignees; // 为什么是 Map而不是 List 呢?因为下一个节点可能是多个,例如说并行网关的情况
// 新增任务变量实例,业务表单
@Schema(description = "任务变量实例,业务表单", example = "{'formField1': 'value1', 'formField2': 'value2'}")
private Map<String, String> taskVariables;
}

View File

@@ -0,0 +1,29 @@
package com.zt.plat.module.bpm.api.task.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.zt.plat.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "RPC 服务 - 流程任务分页 Request DTO")
@Data
public class BpmTaskPageReqDTO extends PageParam {
@Schema(description = "流程任务名", example = "芋艿")
private String name;
@Schema(description = "流程定义的编号", example = "2048")
private String processDefinitionId;
@Schema(description = "流程分类", example = "1")
private String category;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,18 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Schema(description = "RPC 服务 - 不通过流程任务的 Request DTO")
@Data
public class BpmTaskRejectReqDTO {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotEmpty(message = "任务编号不能为空")
private String id;
@Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
private String reason;
}

View File

@@ -0,0 +1,133 @@
package com.zt.plat.module.bpm.api.task.dto;
import com.zt.plat.framework.common.core.KeyValue;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Schema(description = "RPC 服务 - 流程任务 Response DTO")
@Data
public class BpmTaskRespDTO {
@Schema(description = "任务编号", example = "1024")
private String id;
@Schema(description = "任务名字", example = "芋艿")
private String name;
@Schema(description = "接收人的用户编号", example = "1")
private Long assigneeUserId;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "持续时间", example = "1000")
private Long durationInMillis;
@Schema(description = "流程实例的编号", example = "1024")
private String processInstanceId;
@Schema(description = "流程定义的编号", example = "2048")
private String processDefinitionId;
@Schema(description = "任务状态", example = "1")
private Integer status;
@Schema(description = "审批建议", example = "不错不错!")
private String reason;
@Schema(description = "任务定义的标识", example = "Activity_one")
private String taskDefinitionKey;
@Schema(description = "表单编号", example = "1024")
private Long formId;
@Schema(description = "表单路径", example = "/form/leave")
private String formPath;
@Schema(description = "表单名字", example = "请假表单")
private String formName;
@Schema(description = "表单的配置", example = "[]")
private String formConf;
@Schema(description = "表单项的数组", example = "[]")
private List<String> formFields;
@Schema(description = "提交的表单值", example = "{\"name\": \"芋艿\"}")
private Map<String, Object> formVariables;
@Schema(description = "任务负责人编号", example = "2048")
private Long owner;
@Schema(description = "负责人的用户信息")
private UserSimpleDTO ownerUser;
@Schema(description = "任务分配人编号", example = "2048")
private Long assignee;
@Schema(description = "审核的用户信息")
private UserSimpleDTO assigneeUser;
@Schema(description = "父任务编号", example = "1024")
private String parentTaskId;
@Schema(description = "子任务列表(由加签生成)")
private List<BpmTaskRespDTO> children;
@Schema(description = "所属流程实例")
private ProcessInstanceDTO processInstance;
@Schema(description = "操作按钮设置值")
private Map<Integer, OperationButtonSettingDTO> buttonsSetting;
@Schema(description = "是否需要签名", example = "false")
private Boolean signEnable;
@Schema(description = "是否填写审批意见", example = "false")
private Boolean reasonRequire;
@Schema(description = "节点类型", example = "10")
private Integer nodeType;
@Data
@Schema(description = "流程实例信息")
public static class ProcessInstanceDTO {
@Schema(description = "流程实例编号", example = "1024")
private String id;
@Schema(description = "流程实例名称", example = "芋道")
private String name;
@Schema(description = "提交时间")
private LocalDateTime createTime;
@Schema(description = "流程定义的编号", example = "2048")
private String processDefinitionId;
@Schema(description = "流程摘要", example = "[]")
private List<KeyValue<String, String>> summary;
@Schema(description = "发起人的用户信息")
private UserSimpleDTO startUser;
}
@Data
@Schema(description = "操作按钮设置")
public static class OperationButtonSettingDTO {
@Schema(description = "显示名称", example = "审批")
private String displayName;
@Schema(description = "是否启用", example = "true")
private Boolean enable;
}
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.module.bpm.api.task.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "RPC 服务 - 用户精简信息 DTO")
@Data
public class UserSimpleDTO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
private String nickname;
@Schema(description = "用户头像", example = "https://www.iocoder.cn/1.png")
private String avatar;
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long deptId;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
private String deptName;
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.bpm.enums;
import com.zt.plat.framework.common.enums.RpcConstants;
/**
* API 相关的枚举
*
* @author ZT
*/
public class ApiConstants {
/**
* 服务名
*
* 注意,需要保证和 spring.application.name 保持一致
*/
public static final String NAME = "bpm-server";
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/bpm";
public static final String VERSION = "1.0.0";
}

View File

@@ -0,0 +1,10 @@
package com.zt.plat.module.bpm.enums;
/**
* BPM 字典类型的枚举类
*
* @author ZT
*/
public interface DictTypeConstants {
}

View File

@@ -0,0 +1,87 @@
package com.zt.plat.module.bpm.enums;
import com.zt.plat.framework.common.exception.ErrorCode;
/**
* Bpm 错误码枚举类
* <p>
* bpm 系统,使用 1-009-000-000 段
*/
public interface ErrorCodeConstants {
// ========== 通用流程处理 模块 1-009-000-000 ==========
// ========== OA 流程模块 1-009-001-000 ==========
ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1_009_001_001, "请假申请不存在");
// ========== 流程模型 1-009-002-000 ==========
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程");
ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1_009_002_001, "流程模型不存在");
ErrorCode MODEL_KEY_VALID = new ErrorCode(1_009_002_002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1_009_002_003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
ErrorCode MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG = new ErrorCode(1_009_002_004, "部署流程失败," +
"原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置");
ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败原因BPMN 流程图中,没有开始事件");
ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败原因BPMN 流程图中,用户任务({})的名字不存在");
ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程({})的管理员");
ErrorCode MODEL_DEPLOY_FAIL_FIRST_USER_TASK_CANDIDATE_STRATEGY_ERROR = new ErrorCode(1_009_002_008, "部署流程失败,原因:首个任务({})的审批人不能是【审批人自选】");
// ========== 流程定义 1-009-003-000 ==========
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1_009_003_001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_009_003_002, "流程定义不存在");
ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1_009_003_003, "流程定义处于挂起状态");
// ========== 流程实例 1-009-004-000 ==========
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1_009_004_000, "流程实例不存在");
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1_009_004_001, "流程取消失败,流程不处于运行中");
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1_009_004_002, "流程取消失败,该流程不是你发起的");
ErrorCode PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG = new ErrorCode(1_009_004_003, "任务({})的候选人未配置");
ErrorCode PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_EXISTS = new ErrorCode(1_009_004_004, "任务({})的候选人({})不存在");
ErrorCode PROCESS_INSTANCE_START_USER_CAN_START = new ErrorCode(1_009_004_005, "发起流程失败,你没有权限发起该流程");
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_005, "流程取消失败,该流程不允许取消");
ErrorCode PROCESS_INSTANCE_HTTP_TRIGGER_CALL_ERROR = new ErrorCode(1_009_004_006, "流程 Http 触发器请求调用失败");
ErrorCode PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG = new ErrorCode(1_009_004_007, "下一个任务({})的审批人未配置");
ErrorCode PROCESS_INSTANCE_CANCEL_CHILD_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_008, "子流程取消失败,子流程不允许取消");
// ========== 流程任务 1-009-005-000 ==========
ErrorCode TASK_OPERATE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "操作失败,原因:该任务的审批人不是你");
ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在");
ErrorCode TASK_IS_PENDING = new ErrorCode(1_009_005_003, "当前任务处于挂起状态,不能操作");
ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_004, " 目标节点不存在");
ErrorCode TASK_RETURN_FAIL_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_006, "退回任务失败,目标节点是在并行网关上或非同一路线上,不可跳转");
ErrorCode TASK_DELEGATE_FAIL_USER_REPEAT = new ErrorCode(1_009_005_007, "任务委派失败,委派人和当前审批人为同一人");
ErrorCode TASK_DELEGATE_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_008, "任务委派失败,被委派人不存在");
ErrorCode TASK_SIGN_CREATE_USER_NOT_EXIST = new ErrorCode(1_009_005_009, "任务加签:选择的用户不存在");
ErrorCode TASK_SIGN_CREATE_TYPE_ERROR = new ErrorCode(1_009_005_010, "任务加签:当前任务已经{},不能{}");
ErrorCode TASK_SIGN_CREATE_USER_REPEAT = new ErrorCode(1_009_005_011, "任务加签失败,加签人与现有审批人[{}]重复");
ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在");
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
ErrorCode TASK_SIGNATURE_NOT_EXISTS = new ErrorCode(1_009_005_015, "签名不能为空!");
ErrorCode TASK_REASON_REQUIRE = new ErrorCode(1_009_005_016, "审批意见不能为空!");
// ========== 动态表单模块 1-009-010-000 ==========
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1_009_010_000, "动态表单不存在");
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1_009_010_001, "表单项({}) 和 ({}) 使用了相同的字段名({})");
// ========== 用户组模块 1-009-011-000 ==========
ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1_009_011_000, "用户分组不存在");
ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1_009_011_001, "名字为【{}】的用户分组已被禁用");
// ========== 用户组模块 1-009-012-000 ==========
ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1_009_012_000, "流程分类不存在");
ErrorCode CATEGORY_NAME_DUPLICATE = new ErrorCode(1_009_012_001, "流程分类名字【{}】重复");
ErrorCode CATEGORY_CODE_DUPLICATE = new ErrorCode(1_009_012_002, "流程分类编码【{}】重复");
// ========== BPM 流程监听器 1-009-013-000 ==========
ErrorCode PROCESS_LISTENER_NOT_EXISTS = new ErrorCode(1_009_013_000, "流程监听器不存在");
ErrorCode PROCESS_LISTENER_CLASS_NOT_FOUND = new ErrorCode(1_009_013_001, "流程监听器类({})不存在");
ErrorCode PROCESS_LISTENER_CLASS_IMPLEMENTS_ERROR = new ErrorCode(1_009_013_002, "流程监听器类({})没有实现接口({})");
ErrorCode PROCESS_LISTENER_EXPRESSION_INVALID = new ErrorCode(1_009_013_003, "流程监听器表达式({})不合法");
// ========== BPM 流程表达式 1-009-014-000 ==========
ErrorCode PROCESS_EXPRESSION_NOT_EXISTS = new ErrorCode(1_009_014_000, "流程表达式不存在");
}

View File

@@ -0,0 +1,32 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 自动去重的类型的枚举
*
* @author Lesan
*/
@Getter
@AllArgsConstructor
public enum BpmAutoApproveTypeEnum implements ArrayValuable<Integer> {
NONE(0, "不自动通过"),
APPROVE_ALL(1, "仅审批一次,后续重复的审批节点均自动通过"),
APPROVE_SEQUENT(2, "仅针对连续审批的节点自动通过");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmAutoApproveTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* BPM 边界事件 (boundary event) 自定义类型枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmBoundaryEventTypeEnum {
USER_TASK_TIMEOUT(1, "用户任务超时"),
DELAY_TIMER_TIMEOUT(2, "延迟器超时"),
CHILD_PROCESS_TIMEOUT(3, "子流程超时");
private final Integer type;
private final String name;
public static BpmBoundaryEventTypeEnum typeOf(Integer type) {
return ArrayUtil.firstMatch(eventType -> eventType.getType().equals(type), values());
}
}

View File

@@ -0,0 +1,37 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 子流程多实例来源类型枚举
*
* @author Lesan
*/
@Getter
@AllArgsConstructor
public enum BpmChildProcessMultiInstanceSourceTypeEnum implements ArrayValuable<Integer> {
FIXED_QUANTITY(1, "固定数量"),
NUMBER_FORM(2, "数字表单"),
MULTIPLE_FORM(3, "多选表单");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmChildProcessMultiInstanceSourceTypeEnum::getType).toArray(Integer[]::new);
public static BpmChildProcessMultiInstanceSourceTypeEnum typeOf(Integer type) {
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,36 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 当子流程发起人为空时类型枚举
*
* @author Lesan
*/
@Getter
@AllArgsConstructor
public enum BpmChildProcessStartUserEmptyTypeEnum implements ArrayValuable<Integer> {
MAIN_PROCESS_START_USER(1, "同主流程发起人"),
CHILD_PROCESS_ADMIN(2, "子流程管理员"),
MAIN_PROCESS_ADMIN(3, "主流程管理员");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmChildProcessStartUserEmptyTypeEnum::getType).toArray(Integer[]::new);
public static BpmChildProcessStartUserEmptyTypeEnum typeOf(Integer type) {
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,35 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 子流程发起人类型枚举
*
* @author Lesan
*/
@Getter
@AllArgsConstructor
public enum BpmChildProcessStartUserTypeEnum implements ArrayValuable<Integer> {
MAIN_PROCESS_START_USER(1, "同主流程发起人"),
FROM_FORM(2, "表单");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmChildProcessStartUserTypeEnum::getType).toArray(Integer[]::new);
public static BpmChildProcessStartUserTypeEnum typeOf(Integer type) {
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 延迟器类型枚举
*
* @author Lesan
*/
@Getter
@AllArgsConstructor
public enum BpmDelayTimerTypeEnum implements ArrayValuable<Integer> {
FIXED_TIME_DURATION(1, "固定时长"),
FIXED_DATE_TIME(2, "固定日期");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmDelayTimerTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* BPM 表单权限的枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmFieldPermissionEnum {
READ(1, "只读"),
WRITE(2, "可编辑"),
NONE(3, "隐藏");
/**
* 权限
*/
private final Integer permission;
/**
* 名字
*/
private final String name;
public static BpmFieldPermissionEnum valueOf(Integer permission) {
return ArrayUtil.firstMatch(item -> item.getPermission().equals(permission), values());
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM HTTP 请求参数设置类型。用于 Simple 设计器任务监听器和触发器配置。
*
* @author Lesan
*/
@Getter
@AllArgsConstructor
public enum BpmHttpRequestParamTypeEnum implements ArrayValuable<Integer> {
FIXED_VALUE(1, "固定值"),
FROM_FORM(2, "表单");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmHttpRequestParamTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,32 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 模型的表单类型的枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmModelFormTypeEnum implements ArrayValuable<Integer> {
NORMAL(10, "流程表单"), // 对应 BpmFormDO
CUSTOM(20, "业务表单") // 业务自己定义的表单,自己进行数据的存储
;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmModelFormTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 模型的类型的枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmModelTypeEnum implements ArrayValuable<Integer> {
BPMN(10, "BPMN 设计器"), // https://bpmn.io/toolkit/bpmn-js/
SIMPLE(20, "SIMPLE 设计器"); // 参考钉钉、飞书工作流的设计器
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmModelTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,21 @@
package com.zt.plat.module.bpm.enums.definition;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* BPM 流程监听器的类型
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmProcessListenerTypeEnum {
EXECUTION("execution", "执行监听器"),
TASK("task", "任务执行器");
private final String type;
private final String name;
}

View File

@@ -0,0 +1,22 @@
package com.zt.plat.module.bpm.enums.definition;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* BPM 流程监听器的值类型
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmProcessListenerValueTypeEnum {
CLASS("class", "Java 类"),
DELEGATE_EXPRESSION("delegateExpression", "代理表达式"),
EXPRESSION("expression", "表达式");
private final String type;
private final String name;
}

View File

@@ -0,0 +1,36 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 仿钉钉的流程器设计器条件节点的条件类型
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmSimpleModeConditionTypeEnum implements ArrayValuable<Integer> {
EXPRESSION(1, "条件表达式"),
RULE(2, "条件规则");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmSimpleModeConditionTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
private final String name;
public static BpmSimpleModeConditionTypeEnum valueOf(Integer type) {
return ArrayUtil.firstMatch(nodeType -> nodeType.getType().equals(type), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,70 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 仿钉钉的流程器设计器的模型节点类型
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmSimpleModelNodeTypeEnum implements ArrayValuable<Integer> {
// 0 ~ 1 开始和结束
START_NODE(0, "开始", "startEvent"),
END_NODE(1, "结束", "endEvent"),
// 10 ~ 49 各种节点
START_USER_NODE(10, "发起人", "userTask"), // 发起人节点。前端的开始节点Id 固定
APPROVE_NODE(11, "审批人", "userTask"),
COPY_NODE(12, "抄送人", "serviceTask"),
TRANSACTOR_NODE(13, "办理人", "userTask"),
DELAY_TIMER_NODE(14, "延迟器", "receiveTask"),
TRIGGER_NODE(15, "触发器", "serviceTask"),
CHILD_PROCESS(20, "子流程", "callActivity"),
// 50 ~ 条件分支
CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式
CONDITION_BRANCH_NODE(51, "条件分支", "exclusiveGateway"),
PARALLEL_BRANCH_NODE(52, "并行分支", "parallelGateway"),
INCLUSIVE_BRANCH_NODE(53, "包容分支", "inclusiveGateway"),
ROUTER_BRANCH_NODE(54, "路由分支", "exclusiveGateway")
;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmSimpleModelNodeTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
private final String name;
private final String bpmnType;
/**
* 判断是否为分支节点
*
* @param type 节点类型
*/
public static boolean isBranchNode(Integer type) {
return Objects.equals(CONDITION_BRANCH_NODE.getType(), type)
|| Objects.equals(PARALLEL_BRANCH_NODE.getType(), type)
|| Objects.equals(INCLUSIVE_BRANCH_NODE.getType(), type)
|| Objects.equals(ROUTER_BRANCH_NODE.getType(), type);
}
public static BpmSimpleModelNodeTypeEnum valueOf(Integer type) {
return ArrayUtil.firstMatch(nodeType -> nodeType.getType().equals(type), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,46 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM Simple 触发器类型枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmTriggerTypeEnum implements ArrayValuable<Integer> {
HTTP_REQUEST(1, "发起 HTTP 请求"), // BPM => 业务,流程继续执行,无需等待业务
HTTP_CALLBACK(2, "接收 HTTP 回调"), // BPM => 业务 => BPM流程卡主等待业务回调
FORM_UPDATE(10, "更新流程表单数据"),
FORM_DELETE(11, "删除流程表单数据"),
;
/**
* 触发器执行动作类型
*/
private final Integer type;
/**
* 触发器执行动作描述
*/
private final String desc;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmTriggerTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
public static BpmTriggerTypeEnum typeOf(Integer type) {
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
}
}

View File

@@ -0,0 +1,47 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 多人审批方式的枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmUserTaskApproveMethodEnum implements ArrayValuable<Integer> {
RANDOM(1, "随机挑选一人审批", null),
RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances/nrOfInstances >= %s}"), // 会签(按通过比例)
ANY(3, "多人或签(一人通过或拒绝)", "${ nrOfCompletedInstances > 0 }"), // 或签(通过只需一人,拒绝只需一人)
SEQUENTIAL(4, "依次审批", "${ nrOfCompletedInstances >= nrOfInstances }"); // 依次审批
/**
* 审批方式
*/
private final Integer method;
/**
* 名字
*/
private final String name;
/**
* 完成表达式
*/
private final String completionCondition;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmUserTaskApproveMethodEnum::getMethod).toArray(Integer[]::new);
public static BpmUserTaskApproveMethodEnum valueOf(Integer method) {
return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 用户任务的审批类型枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmUserTaskApproveTypeEnum implements ArrayValuable<Integer> {
USER(1), // 人工审批
AUTO_APPROVE(2), // 自动通过
AUTO_REJECT(3); // 自动拒绝
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmUserTaskApproveTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* BPM 用户任务的审批人为空时,处理类型枚举
*
* @author ZT
*/
@RequiredArgsConstructor
@Getter
public enum BpmUserTaskAssignEmptyHandlerTypeEnum implements ArrayValuable<Integer> {
APPROVE(1), // 自动通过
REJECT(2), // 自动拒绝
ASSIGN_USER(3), // 指定人员审批
ASSIGN_ADMIN(4), // 转交给流程管理员
;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmUserTaskAssignEmptyHandlerTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* BPM 用户任务的审批人与发起人相同时,处理类型枚举
*
* @author ZT
*/
@RequiredArgsConstructor
@Getter
public enum BpmUserTaskAssignStartUserHandlerTypeEnum implements ArrayValuable<Integer> {
START_USER_AUDIT(1), // 由发起人对自己审批
SKIP(2), // 自动跳过【参考飞书】1如果当前节点还有其他审批人则交由其他审批人进行审批2如果当前节点没有其他审批人则该节点自动通过
TRANSFER_DEPT_LEADER(3); // 转交给部门负责人审批【参考飞书】:若部门负责人为空,则自动通过
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmUserTaskAssignStartUserHandlerTypeEnum::getType).toArray(Integer[]::new);
private final Integer type;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,35 @@
package com.zt.plat.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* BPM 用户任务拒绝处理类型枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmUserTaskRejectHandlerTypeEnum implements ArrayValuable<Integer> {
FINISH_PROCESS_INSTANCE(1, "终止流程"),
RETURN_USER_TASK(2, "驳回到指定任务节点");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmUserTaskRejectHandlerTypeEnum::getType).toArray(Integer[]::new);
public static BpmUserTaskRejectHandlerTypeEnum typeOf(Integer type) {
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,32 @@
package com.zt.plat.module.bpm.enums.definition;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 用户任务超时处理类型枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmUserTaskTimeoutHandlerTypeEnum implements ArrayValuable<Integer> {
REMINDER(1,"自动提醒"),
APPROVE(2, "自动同意"),
REJECT(3, "自动拒绝");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmUserTaskTimeoutHandlerTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.bpm.enums.message;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Bpm 消息的枚举
*
* @author ZT
*/
@AllArgsConstructor
@Getter
public enum BpmMessageEnum {
PROCESS_INSTANCE_APPROVE("bpm_process_instance_approve"), // 流程任务被审批通过时,发送给申请人
PROCESS_INSTANCE_REJECT("bpm_process_instance_reject"), // 流程任务被审批不通过时,发送给申请人
TASK_ASSIGNED("bpm_task_assigned"), // 任务被分配时,发送给审批人
TASK_TIMEOUT("bpm_task_timeout"); // 任务审批超时时,发送给审批人
/**
* 短信模板的标识
*
* 关联 SmsTemplateDO 的 code 属性
*/
private final String smsTemplateCode;
}

View File

@@ -0,0 +1,46 @@
package com.zt.plat.module.bpm.enums.task;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 流程任务的 Comment 评论类型枚举
*
* @author kehaiyou
*/
@Getter
@AllArgsConstructor
public enum BpmCommentTypeEnum {
APPROVE("1", "审批通过", "审批通过,原因是:{}"),
REJECT("2", "不通过", "审批不通过:原因是:{}"),
CANCEL("3", "已取消", "系统自动取消,原因是:{}"),
RETURN("4", "退回", "任务被退回,原因是:{}"),
DELEGATE_START("5", "委派发起", "[{}]将任务委派给[{}],委派理由为:{}"),
DELEGATE_END("6", "委派完成", "[{}]完成委派任务,任务重新回到[{}]手中,审批建议为:{}"),
TRANSFER("7", "转派", "[{}]将任务转派给[{}],转派理由为:{}"),
ADD_SIGN("8", "加签", "[{}]{}给了[{}],理由为:{}"),
SUB_SIGN("9", "减签", "[{}]操作了【减签】,审批人[{}]的任务被取消"),
;
/**
* 操作类型
*
* 由于 BPM Comment 类型为 String所以这里就不使用 Integer
*/
private final String type;
/**
* 操作名字
*/
private final String name;
/**
* 操作描述
*/
private final String comment;
public String formatComment(Object... params) {
return StrUtil.format(comment, params);
}
}

View File

@@ -0,0 +1,80 @@
package com.zt.plat.module.bpm.enums.task;
import com.zt.plat.framework.common.core.ArrayValuable;
import com.zt.plat.framework.common.util.object.ObjectUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
/**
* 流程实例 ProcessInstance 的状态
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmProcessInstanceStatusEnum implements ArrayValuable<Integer> {
NOT_START(-1, "未开始"),
RUNNING(1, "审批中"),
APPROVE(2, "审批通过"),
REJECT(3, "审批不通过"),
CANCEL(4, "已取消");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BpmProcessInstanceStatusEnum::getStatus).toArray(Integer[]::new);
/**
* 状态
*/
private final Integer status;
/**
* 描述
*/
private final String desc;
@Override
public Integer[] array() {
return ARRAYS;
}
public static boolean isRejectStatus(Integer status) {
return REJECT.getStatus().equals(status);
}
public static boolean isProcessEndStatus(Integer status) {
return ObjectUtils.equalsAny(status,
APPROVE.getStatus(), REJECT.getStatus(), CANCEL.getStatus());
}
/**
* 通过流程的状态返回对应的枚举
* @param status 流程状态
* @return
*/
public static BpmProcessInstanceStatusEnum getEnumByStatus(Integer status){
for (BpmProcessInstanceStatusEnum e : BpmProcessInstanceStatusEnum.values()) {
if (e.getStatus().equals(status)) {
return e;
}
}
return NOT_START;
}
/**
* 通过枚举描述返回对应的枚举
* @param desc 描述
* @return
*/
public static BpmProcessInstanceStatusEnum getEnumByDesc(String desc){
if (StringUtils.isEmpty(desc)) return NOT_START;
for (BpmProcessInstanceStatusEnum e : BpmProcessInstanceStatusEnum.values()) {
if (desc.equals(e.getDesc())) {
return e;
}
}
return NOT_START;
}
}

View File

@@ -0,0 +1,52 @@
package com.zt.plat.module.bpm.enums.task;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 流程实例/任务的的处理原因枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum BpmReasonEnum {
// ========== 流程实例的独有原因 ==========
REJECT_TASK("审批不通过任务,原因:{}"), // 场景:用户审批不通过任务。修改文案时,需要注意 isRejectReason 方法
CANCEL_PROCESS_INSTANCE_BY_START_USER("用户主动取消流程,原因:{}"), // 场景:用户主动取消流程
CANCEL_PROCESS_INSTANCE_BY_ADMIN("管理员【{}】取消流程,原因:{}"), // 场景:管理员取消流程
CANCEL_CHILD_PROCESS_INSTANCE_BY_MAIN_PROCESS("子流程自动取消,原因:主流程已取消"),
// ========== 流程任务的独有原因 ==========
CANCEL_BY_SYSTEM("系统自动取消"), // 场景非常多比如说1多任务审批已经满足条件无需审批该任务2流程实例被取消无需审批该任务等等
TIMEOUT_APPROVE("审批超时,系统自动通过"),
TIMEOUT_REJECT("审批超时,系统自动不通过"),
ASSIGN_START_USER_APPROVE("审批人与提交人为同一人时,自动通过"),
ASSIGN_START_USER_APPROVE_WHEN_SKIP("审批人与提交人为同一人时,自动通过"),
ASSIGN_START_USER_APPROVE_WHEN_SKIP_START_USER_NODE("发起人节点首次自动通过"), // 目前仅“子流程”使用
ASSIGN_START_USER_APPROVE_WHEN_DEPT_LEADER_NOT_FOUND("审批人与提交人为同一人时,找不到部门负责人,自动通过"),
ASSIGN_START_USER_TRANSFER_DEPT_LEADER("审批人与提交人为同一人时,转交给部门负责人审批"),
ASSIGN_EMPTY_APPROVE("审批人为空,自动通过"),
ASSIGN_EMPTY_REJECT("审批人为空,自动不通过"),
APPROVE_TYPE_AUTO_APPROVE("非人工审核,自动通过"),
APPROVE_TYPE_AUTO_REJECT("非人工审核,自动不通过"),
CANCEL_BY_PROCESS_CLEAN("进程清理自动取消"),
;
private final String reason;
/**
* 格式化理由
*
* @param args 参数
* @return 理由
*/
public String format(Object... args) {
return StrUtil.format(reason, args);
}
}

View File

@@ -0,0 +1,47 @@
package com.zt.plat.module.bpm.enums.task;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 流程任务的加签类型枚举
*
* @author kehaiyou
*/
@Getter
@AllArgsConstructor
public enum BpmTaskSignTypeEnum {
/**
* 向前加签,需要前置任务审批完成,才回到原审批人
*/
BEFORE("before", "向前加签"),
/**
* 向后加签,需要后置任务全部审批完,才会通过原审批人节点
*/
AFTER("after", "向后加签");
/**
* 类型
*/
private final String type;
/**
* 名字
*/
private final String name;
public static String nameOfType(String type) {
for (BpmTaskSignTypeEnum value : values()) {
if (value.type.equals(type)) {
return value.name;
}
}
return null;
}
public static BpmTaskSignTypeEnum of(String type) {
return ArrayUtil.firstMatch(value -> value.getType().equals(type), values());
}
}

View File

@@ -0,0 +1,100 @@
package com.zt.plat.module.bpm.enums.task;
import cn.hutool.core.util.ObjUtil;
import com.zt.plat.framework.common.util.object.ObjectUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
/**
* 流程任务 Task 的状态枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmTaskStatusEnum {
NOT_START(-1, "未开始"),
RUNNING(1, "审批中"),
APPROVE(2, "审批通过"),
REJECT(3, "审批不通过"),
CANCEL(4, "已取消"),
RETURN(5, "已退回"),
/**
* 使用场景:
* 1. 任务被向后【加签】时,它在审批通过后,会变成 APPROVING 这个状态,然后等到【加签】出来的任务都被审批后,才会变成 APPROVE 审批通过
*/
APPROVING(7, "审批通过中"),
/**
* 使用场景:
* 1. 任务被向前【加签】时,它会变成 WAIT 状态,需要等待【加签】出来的任务被审批后,它才能继续变为 RUNNING 继续审批
* 2. 任务被向后【加签】时,【加签】出来的任务处于 WAIT 状态,它们需要等待该任务被审批后,它们才能继续变为 RUNNING 继续审批
*/
WAIT(0, "待审批");
/**
* 状态
* <p>
* 如果新增时,注意 {@link #isEndStatus(Integer)} 是否需要变更
*/
private final Integer status;
/**
* 名字
*/
private final String name;
public static boolean isRejectStatus(Integer status) {
return REJECT.getStatus().equals(status);
}
/**
* 判断该状态是否已经处于 End 最终状态
* <p>
* 主要用于一些状态更新的逻辑,如果已经是最终状态,就不再进行更新
*
* @param status 状态
* @return 是否
*/
public static boolean isEndStatus(Integer status) {
return ObjectUtils.equalsAny(status,
APPROVE.getStatus(), REJECT.getStatus(), CANCEL.getStatus(),
RETURN.getStatus(), APPROVING.getStatus());
}
public static boolean isCancelStatus(Integer status) {
return ObjUtil.equal(status, CANCEL.getStatus());
}
/**
* 通过流程的状态返回对应的枚举
* @param status 流程状态
* @return
*/
public static BpmTaskStatusEnum getEnumByStatus(Integer status){
for (BpmTaskStatusEnum e : BpmTaskStatusEnum.values()) {
if (e.getStatus().equals(status)) {
return e;
}
}
return NOT_START;
}
/**
* 通过枚举描述返回对应的枚举
* @param name 描述
* @return
*/
public static BpmTaskStatusEnum getEnumByName(String name){
if (StringUtils.isEmpty(name)) return NOT_START;
for (BpmTaskStatusEnum e : BpmTaskStatusEnum.values()) {
if (name.equals(e.getName())) {
return e;
}
}
return NOT_START;
}
}