流转工作流程
This commit is contained in:
@@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@FeignClient(value = ServerInfo.SUPERVISION,path = "/process",fallbackFactory = BpmProcessFeignClientFallbackFactory.class)
|
||||
@FeignClient(value = ServerInfo.BPM,path = "/bpm/processDefinition",fallbackFactory = BpmProcessFeignClientFallbackFactory.class)
|
||||
public interface BpmProcessFeignClient {
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.njcn.bpm.enums;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.njcn.bpm.enums;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 流程实例/任务的删除原因枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmDeleteReasonEnum {
|
||||
|
||||
// ========== 流程实例的独有原因 ==========
|
||||
|
||||
REJECT_TASK("审批不通过任务,原因:{}"), // 场景:用户审批不通过任务。修改文案时,需要注意 isRejectReason 方法
|
||||
CANCEL_PROCESS_INSTANCE_BY_START_USER("用户主动取消流程,原因:{}"), // 场景:用户主动取消流程
|
||||
CANCEL_PROCESS_INSTANCE_BY_ADMIN("管理员【{}】取消流程,原因:{}"), // 场景:管理员取消流程
|
||||
|
||||
// ========== 流程任务的独有原因 ==========
|
||||
|
||||
CANCEL_BY_SYSTEM("系统自动取消"), // 场景:非常多,比如说:1)多任务审批已经满足条件,无需审批该任务;2)流程实例被取消,无需审批该任务;等等
|
||||
;
|
||||
|
||||
private final String reason;
|
||||
|
||||
/**
|
||||
* 格式化理由
|
||||
*
|
||||
* @param args 参数
|
||||
* @return 理由
|
||||
*/
|
||||
public String format(Object... args) {
|
||||
return StrUtil.format(reason, args);
|
||||
}
|
||||
|
||||
// ========== 逻辑 ==========
|
||||
|
||||
public static boolean isRejectReason(String reason) {
|
||||
return StrUtil.startWith(reason, "审批不通过任务,原因:");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 异常处理类
|
||||
*
|
||||
* @author qijian
|
||||
* @version 1.0.0
|
||||
* @date 2022年11月11日 09:56
|
||||
@@ -15,33 +16,58 @@ public enum BpmResponseEnum {
|
||||
* 过程监督异常响应码的范围:
|
||||
* A00550 ~ A00649
|
||||
*/
|
||||
BPM_COMMON_ERROR("A00568","工作流模块异常"),
|
||||
BPM_COMMON_ERROR("A00568", "工作流模块异常"),
|
||||
|
||||
BPM_XML_ERROR("A00568","流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!"),
|
||||
BPM_XML_ERROR("A00568", "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!"),
|
||||
|
||||
BPM_MODEL_REPEAT("A00568","流程标识已存在"),
|
||||
BPM_MODEL_REPEAT("A00568", "流程标识已存在"),
|
||||
|
||||
BPM_MODEL_NOT_EXIST("A00568","流程模型不存在"),
|
||||
BPM_MODEL_NOT_EXIST("A00568", "流程模型不存在"),
|
||||
|
||||
PROCESS_DEFINITION_NOT_EXISTS("A00568","流程定义不存在"),
|
||||
PROCESS_DEFINITION_NOT_EXISTS("A00568", "流程定义不存在"),
|
||||
|
||||
TASK_NOT_EXISTS("A00568", "流程任务不存在"),
|
||||
|
||||
TASK_OPERATE_FAIL_ASSIGN_NOT_SELF("A00568", "操作失败,原因:该任务的审批人不是你"),
|
||||
|
||||
PROCESS_DEFINITION_IS_SUSPENDED("A00568", "流程定义处于挂起状态"),
|
||||
|
||||
FORM_NOT_EXISTS("A00568","动态表单不存在"),
|
||||
FORM_NOT_EXISTS("A00568", "动态表单不存在"),
|
||||
|
||||
MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG("A00568","部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置"),
|
||||
MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG("A00568", "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置"),
|
||||
|
||||
BPM_START_EVENT_NOT_EXIST("A00568","起始事件不存在"),
|
||||
BPM_START_EVENT_NOT_EXIST("A00568", "起始事件不存在"),
|
||||
|
||||
MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS("A00568","部署流程失败,原因:BPMN 流程图中,用户任务的名字不存在"),
|
||||
MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS("A00568", "部署流程失败,原因:BPMN 流程图中,用户任务的名字不存在"),
|
||||
|
||||
REPEAT_NAME_FORM("A00568","流程表单名称重复"),
|
||||
REPEAT_NAME_FORM("A00568", "流程表单名称重复"),
|
||||
|
||||
REPEAT_CATEGORY_NAME_FORM("A00568","流程类型名称重复"),
|
||||
REPEAT_CATEGORY_NAME_FORM("A00568", "流程类型名称重复"),
|
||||
|
||||
PROCESS_INSTANCE_NOT_EXISTS ("A00568", "流程实例不存在"),
|
||||
|
||||
TASK_IS_PENDING ("A00568", "当前任务处于挂起状态,不能操作"),
|
||||
|
||||
TASK_TARGET_NODE_NOT_EXISTS ("A00568", " 目标节点不存在"),
|
||||
|
||||
TASK_RETURN_FAIL_SOURCE_TARGET_ERROR ("A00568", "回退任务失败,目标节点是在并行网关上或非同一路线上,不可跳转"),
|
||||
|
||||
PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS("A00568", "流程取消失败,流程不处于运行中"),
|
||||
|
||||
TASK_DELEGATE_FAIL_USER_REPEAT("A00568", "任务委派失败,委派人和当前审批人为同一人"),
|
||||
|
||||
TASK_DELEGATE_FAIL_USER_NOT_EXISTS("A00568", "任务委派失败,被委派人不存在"),
|
||||
|
||||
TASK_TRANSFER_FAIL_USER_REPEAT("A00568", "任务转办失败,转办人和当前审批人为同一人"),
|
||||
|
||||
TASK_TRANSFER_FAIL_USER_NOT_EXISTS("A00568", "任务转办失败,转办人不存在"),
|
||||
|
||||
TASK_SIGN_CREATE_USER_NOT_EXIST("A00568", "任务加签:选择的用户不存在"),
|
||||
|
||||
TASK_SIGN_DELETE_NO_PARENT("A00568", "任务减签失败,被减签的任务必须是通过加签生成的任务"),
|
||||
|
||||
PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF("A00568", "流程取消失败,该流程不是你发起的");
|
||||
|
||||
;
|
||||
|
||||
private final String code;
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.njcn.bpm.enums;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.njcn.bpm.enums;
|
||||
|
||||
import com.njcn.bpm.utils.ObjectUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 流程任务 Task 的状态枚举
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskStatusEnum {
|
||||
|
||||
RUNNING(1, "审批中"),
|
||||
APPROVE(2, "审批通过"),
|
||||
REJECT(3, "审批不通过"),
|
||||
CANCEL(4, "已取消"),
|
||||
|
||||
RETURN(5, "已退回"),
|
||||
DELEGATE(6, "委派中"),
|
||||
|
||||
/**
|
||||
* 使用场景:
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 判断该状态是否已经处于 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.njcn.bpm.enums;
|
||||
|
||||
/**
|
||||
* Web 过滤器顺序的枚举类,保证过滤器按照符合我们的预期
|
||||
*
|
||||
* 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 enums 包下
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface WebFilterOrderEnum {
|
||||
|
||||
int CORS_FILTER = Integer.MIN_VALUE;
|
||||
|
||||
int TRACE_FILTER = CORS_FILTER + 1;
|
||||
|
||||
int REQUEST_BODY_CACHE_FILTER = Integer.MIN_VALUE + 500;
|
||||
|
||||
// OrderedRequestContextFilter 默认为 -105,用于国际化上下文等等
|
||||
|
||||
int TENANT_CONTEXT_FILTER = - 104; // 需要保证在 ApiAccessLogFilter 前面
|
||||
|
||||
int API_ACCESS_LOG_FILTER = -103; // 需要保证在 RequestBodyCacheFilter 后面
|
||||
|
||||
int XSS_FILTER = -102; // 需要保证在 RequestBodyCacheFilter 后面
|
||||
|
||||
// Spring Security Filter 默认为 -100,可见 org.springframework.boot.autoconfigure.security.SecurityProperties 配置属性类
|
||||
|
||||
int TENANT_SECURITY_FILTER = -99; // 需要保证在 Spring Security 过滤器后面
|
||||
|
||||
int FLOWABLE_FILTER = -98; // 需要保证在 Spring Security 过滤后面
|
||||
|
||||
int DEMO_FILTER = Integer.MAX_VALUE;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.njcn.bpm.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* BPM 发送流程实例被通过 Request DTO
|
||||
*/
|
||||
@Data
|
||||
public class BpmMessageSendWhenProcessInstanceApproveReqDTO {
|
||||
|
||||
/**
|
||||
* 流程实例的编号
|
||||
*/
|
||||
@NotEmpty(message = "流程实例的编号不能为空")
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 流程实例的名字
|
||||
*/
|
||||
@NotEmpty(message = "流程实例的名字不能为空")
|
||||
private String processInstanceName;
|
||||
@NotNull(message = "发起人的用户编号")
|
||||
private String startUserId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.njcn.bpm.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* BPM 发送流程实例被不通过 Request DTO
|
||||
*/
|
||||
@Data
|
||||
public class BpmMessageSendWhenProcessInstanceRejectReqDTO {
|
||||
|
||||
/**
|
||||
* 流程实例的编号
|
||||
*/
|
||||
@NotEmpty(message = "流程实例的编号不能为空")
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 流程实例的名字
|
||||
*/
|
||||
@NotEmpty(message = "流程实例的名字不能为空")
|
||||
private String processInstanceName;
|
||||
|
||||
@NotNull(message = "发起人的用户编号")
|
||||
private String startUserId;
|
||||
|
||||
/**
|
||||
* 不通过理由
|
||||
*/
|
||||
@NotEmpty(message = "不通过理由不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -24,14 +24,14 @@ public class BpmCategoryParam implements Serializable {
|
||||
* 分类名
|
||||
*/
|
||||
@ApiModelProperty("分类名")
|
||||
@NotNull(message = "分类名不能为空")
|
||||
@NotBlank(message = "分类名不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 分类标志
|
||||
*/
|
||||
@ApiModelProperty("分类标志")
|
||||
@NotNull(message = "分类标志不能为空")
|
||||
@NotBlank(message = "分类标志不能为空")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,21 +20,21 @@ public class BpmFormParam implements Serializable {
|
||||
* 表单名
|
||||
*/
|
||||
@ApiModelProperty("表单名称")
|
||||
@NotNull(message = "表单名称不能为空")
|
||||
@NotBlank(message = "表单名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@ApiModelProperty("表单状态")
|
||||
@NotNull(message = "表单状态不能为空")
|
||||
@NotBlank(message = "表单状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 表单的配置
|
||||
*/
|
||||
@ApiModelProperty("表单的配置-JSON 字符串")
|
||||
@NotNull(message = "表单的配置不能为空")
|
||||
@NotBlank(message = "表单的配置不能为空")
|
||||
private String conf;
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class BpmFormParam implements Serializable {
|
||||
*
|
||||
*/
|
||||
@ApiModelProperty("表单项的数组-JSON 字符串的数组")
|
||||
@NotNull(message = "表单项的数组不能为空")
|
||||
@NotBlank(message = "表单项的数组不能为空")
|
||||
private List<String> fields;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,11 +20,11 @@ public class BpmModelParam implements Serializable {
|
||||
|
||||
|
||||
@ApiModelProperty("流程标识")
|
||||
@NotNull(message = "流程标识不能为空")
|
||||
@NotBlank(message = "流程标识不能为空")
|
||||
private String key;
|
||||
|
||||
@ApiModelProperty("流程名称")
|
||||
@NotNull(message = "流程名称不能为空")
|
||||
@NotBlank(message = "流程名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty( "流程图标")
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.bpm.pojo.param.instance;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Schema(description = "管理后台 - 流程实例的取消 Request VO")
|
||||
@Data
|
||||
public class BpmProcessInstanceCancelParam {
|
||||
|
||||
@ApiModelProperty("流程实例的编号")
|
||||
@NotEmpty(message = "流程实例的编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("取消原因")
|
||||
@NotEmpty(message = "取消原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.njcn.bpm.pojo.param.instance;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 流程实例的创建 Request VO")
|
||||
@Data
|
||||
public class BpmProcessInstanceCreateParam {
|
||||
|
||||
@NotEmpty(message = "流程定义编号不能为空")
|
||||
@ApiModelProperty("流程定义的编号")
|
||||
private String processDefinitionId;
|
||||
|
||||
@Schema(description = "变量实例(动态表单)")
|
||||
@ApiModelProperty("变量实例(动态表单)")
|
||||
private Map<String, Object> variables;
|
||||
|
||||
@ApiModelProperty("发起人自选审批人 Map")
|
||||
private Map<String, List<Long>> startUserSelectAssignees;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.njcn.bpm.pojo.param.instance;
|
||||
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - 流程实例分页")
|
||||
@Data
|
||||
public class BpmProcessInstancePageParam extends BaseParam {
|
||||
|
||||
@ApiModelProperty("流程名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("流程定义的编号")
|
||||
private String processDefinitionId;
|
||||
|
||||
@ApiModelProperty("流程实例的状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("流程分类")
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty("发起用户编号")
|
||||
private String startUserId; // 注意,只有在【流程实例】菜单,才使用该参数
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 通过流程任务的 Request VO")
|
||||
@Data
|
||||
public class BpmTaskApproveParam {
|
||||
|
||||
@ApiModelProperty("任务编号")
|
||||
@NotBlank(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("审批意见")
|
||||
@NotBlank(message = "审批意见不能为空")
|
||||
private String reason;
|
||||
|
||||
@ApiModelProperty("抄送的用户编号数组")
|
||||
private Collection<String> copyUserIds;
|
||||
|
||||
@ApiModelProperty("变量实例(动态表单)")
|
||||
private Map<String, Object> variables;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 委派流程任务的 Request VO")
|
||||
@Data
|
||||
public class BpmTaskDelegateParam {
|
||||
|
||||
@ApiModelProperty("任务编号")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("被委派人ID")
|
||||
@NotNull(message = "被委派人 ID 不能为空")
|
||||
private String delegateUserId;
|
||||
|
||||
@ApiModelProperty("委派原因")
|
||||
@NotEmpty(message = "委派原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import com.njcn.bpm.pojo.param.PageParam;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - 流程任务的的分页 Request VO") // 待办、已办,都使用该分页
|
||||
@Data
|
||||
public class BpmTaskParam extends PageParam {
|
||||
|
||||
@Schema(description = "流程任务名", example = "芋道")
|
||||
private String name;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 待办事项分页查询实体
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class BpmTaskQueryParam extends BaseParam {
|
||||
|
||||
/**
|
||||
* 表单名称
|
||||
*/
|
||||
@ApiModelProperty("流程任务名")
|
||||
private String name;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Schema(description = "管理后台 - 不通过流程任务的 Request VO")
|
||||
@Data
|
||||
public class BpmTaskRejectParam {
|
||||
|
||||
|
||||
@ApiModelProperty("任务编号")
|
||||
@NotBlank(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
|
||||
@ApiModelProperty("审批意见")
|
||||
@NotBlank(message = "审批意见不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Schema(description = "管理后台 - 回退流程任务的 Request VO")
|
||||
@Data
|
||||
public class BpmTaskReturnParam {
|
||||
|
||||
|
||||
@ApiModelProperty("任务编号")
|
||||
@NotBlank(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
|
||||
@ApiModelProperty("回退到的任务 Key")
|
||||
@NotBlank(message = "回退到的任务 Key 不能为空")
|
||||
private String targetTaskDefinitionKey;
|
||||
|
||||
|
||||
@ApiModelProperty("回退意见")
|
||||
@NotBlank(message = "回退意见不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - 加签任务的创建(加签) Request VO")
|
||||
@Data
|
||||
public class BpmTaskSignCreateParam {
|
||||
|
||||
@ApiModelProperty("需要加签的任务编号")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("加签的用户编号")
|
||||
@NotEmpty(message = "加签用户不能为空")
|
||||
private List<String> userIds;
|
||||
|
||||
@ApiModelProperty("加签类型")
|
||||
@NotEmpty(message = "加签类型不能为空")
|
||||
private String type; // 参见 BpmTaskSignTypeEnum 枚举
|
||||
|
||||
@ApiModelProperty("加签原因")
|
||||
@NotEmpty(message = "加签原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Schema(description = "管理后台 - 加签任务的删除(减签) Request VO")
|
||||
@Data
|
||||
public class BpmTaskSignDeleteParam {
|
||||
|
||||
@ApiModelProperty("被减签的任务编号")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("减签原因")
|
||||
@NotEmpty(message = "减签原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.njcn.bpm.pojo.param.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 流程任务的转办 Request VO")
|
||||
@Data
|
||||
public class BpmTaskTransferParam {
|
||||
|
||||
@ApiModelProperty("任务编号")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("新审批人的用户编号")
|
||||
@NotNull(message = "新审批人的用户编号不能为空")
|
||||
private String assigneeUserId;
|
||||
|
||||
@ApiModelProperty("转办原因")
|
||||
@NotEmpty(message = "转办原因不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 流程定义的拓信息
|
||||
* 主要解决 Flowable {@link org.flowable.engine.repository.ProcessDefinition} 不支持拓展字段,所以新建该表
|
||||
* 主要解决 Flowable {@link} 不支持拓展字段,所以新建该表
|
||||
*
|
||||
*/
|
||||
@TableName(value = "bpm_process_definition_info", autoResultMap = true)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.njcn.bpm.pojo.po.task;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.db.bo.BaseEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BPM 流程实例抄送表
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2024-05-10
|
||||
*/
|
||||
@Data
|
||||
@TableName("bpm_process_instance_copy")
|
||||
public class ProcessInstanceCopy extends BaseEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 用户编号,被抄送人
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 发起流程的用户编号
|
||||
*/
|
||||
private String startUserId;
|
||||
|
||||
/**
|
||||
* 流程实例的id
|
||||
*/
|
||||
private String processInstanceId;
|
||||
|
||||
/**
|
||||
* 流程实例的名字
|
||||
*/
|
||||
private String processInstanceName;
|
||||
|
||||
/**
|
||||
* 流程定义的分类
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 发起抄送的任务编号
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 任务的名字
|
||||
*/
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
* 状态:0-删除 1-正常
|
||||
*/
|
||||
private Integer state;
|
||||
|
||||
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 流程定义的拓信息
|
||||
* 主要解决 Flowable {@link org.flowable.engine.repository.ProcessDefinition} 不支持拓展字段,所以新建该表
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.njcn.bpm.pojo.vo.instance;
|
||||
|
||||
import com.njcn.bpm.pojo.vo.BpmProcessDefinitionInfoVO;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
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 = "管理后台 - 流程实例的VO")
|
||||
@Data
|
||||
public class BpmProcessInstanceVO {
|
||||
|
||||
@ApiModelProperty("流程实例的编号")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("流程名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("流程分类")
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty("流程分类名称")
|
||||
private String categoryName;
|
||||
|
||||
@ApiModelProperty("流程实例的状态")
|
||||
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
|
||||
|
||||
@ApiModelProperty("发起时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@ApiModelProperty("结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@ApiModelProperty("持续时间")
|
||||
private Long durationInMillis;
|
||||
|
||||
@ApiModelProperty("提交的表单值")
|
||||
private Map<String, Object> formVariables;
|
||||
|
||||
@ApiModelProperty("业务的唯一标识")
|
||||
private String businessKey;
|
||||
|
||||
/**
|
||||
* 发起流程的用户
|
||||
*/
|
||||
private User startUser;
|
||||
|
||||
@ApiModelProperty("流程定义的编号")
|
||||
private String processDefinitionId;
|
||||
/**
|
||||
* 流程定义
|
||||
*/
|
||||
private BpmProcessDefinitionInfoVO processDefinition;
|
||||
|
||||
/**
|
||||
* 当前审批中的任务
|
||||
*/
|
||||
private List<Task> tasks; // 仅在流程实例分页才返回
|
||||
|
||||
@Schema(description = "用户信息")
|
||||
@Data
|
||||
public static class User {
|
||||
|
||||
@ApiModelProperty("用户编号")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("用户昵称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("部门编号")
|
||||
private String deptId;
|
||||
|
||||
@ApiModelProperty("部门名称")
|
||||
private String deptName;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "流程任务")
|
||||
@Data
|
||||
public static class Task {
|
||||
|
||||
@ApiModelProperty("流程任务的编号")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("任务名称")
|
||||
private String name;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.njcn.bpm.pojo.vo.task;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 流程活动的 Response VO")
|
||||
@Data
|
||||
public class BpmActivityVO {
|
||||
|
||||
@ApiModelProperty("流程活动的标识")
|
||||
private String key;
|
||||
@ApiModelProperty("流程活动的类型")
|
||||
private String type;
|
||||
|
||||
@ApiModelProperty("流程活动的开始时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@ApiModelProperty("流程活动的结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@ApiModelProperty("关联的流程任务的编号")
|
||||
private String taskId; // 关联的流程任务,只有 UserTask 等类型才有
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.njcn.bpm.pojo.vo.task;
|
||||
|
||||
import com.njcn.bpm.pojo.vo.instance.BpmProcessInstanceVO;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
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 = "管理后台-流程任务VO")
|
||||
@Data
|
||||
public class BpmTaskVO {
|
||||
|
||||
@ApiModelProperty("任务编号")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("任务名字")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty("结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "持续时间", example = "1000")
|
||||
@ApiModelProperty("持续时间")
|
||||
private Long durationInMillis;
|
||||
|
||||
@ApiModelProperty("任务状态")
|
||||
private Integer status; // 参见 BpmTaskStatusEnum 枚举
|
||||
|
||||
@ApiModelProperty("审批理由")
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 负责人的用户信息
|
||||
*/
|
||||
private BpmProcessInstanceVO.User ownerUser;
|
||||
|
||||
/**
|
||||
* 审核的用户信息
|
||||
*/
|
||||
private BpmProcessInstanceVO.User assigneeUser;
|
||||
|
||||
|
||||
@ApiModelProperty("任务定义的标识")
|
||||
private String taskDefinitionKey;
|
||||
|
||||
@ApiModelProperty("所属流程实例编号")
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 所属流程实例
|
||||
*/
|
||||
private ProcessInstance processInstance;
|
||||
|
||||
@ApiModelProperty("父任务编号")
|
||||
private String parentTaskId;
|
||||
|
||||
|
||||
@ApiModelProperty("子任务列表(由加签生成)")
|
||||
private List<BpmTaskVO> children;
|
||||
|
||||
@ApiModelProperty("表单编号")
|
||||
private String formId;
|
||||
|
||||
|
||||
@ApiModelProperty("表单名字")
|
||||
private String formName;
|
||||
|
||||
|
||||
@ApiModelProperty("表单的配置-JSON 字符串")
|
||||
private String formConf;
|
||||
|
||||
@ApiModelProperty("表单项的数组")
|
||||
private List<String> formFields;
|
||||
|
||||
@ApiModelProperty("提交的表单值")
|
||||
private Map<String, Object> formVariables;
|
||||
|
||||
@Data
|
||||
@Schema(description = "流程实例")
|
||||
public static class ProcessInstance {
|
||||
|
||||
@ApiModelProperty("流程实例编号")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("流程实例名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("提交时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty("流程定义的编号")
|
||||
private String processDefinitionId;
|
||||
|
||||
/**
|
||||
* 发起人的用户信息
|
||||
*/
|
||||
private BpmProcessInstanceVO.User startUser;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.njcn.bpm.utils;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.bpm.pojo.dto.PageResult;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -42,20 +43,20 @@ public class BeanUtils {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
//
|
||||
// public static <S, T> Page<T> toBean(Page<S> source, Class<T> targetType) {
|
||||
// return toBean(source, targetType, null);
|
||||
// }
|
||||
//
|
||||
// public static <S, T> Page<T> toBean(Page<S> source, Class<T> targetType, Consumer<T> peek) {
|
||||
// if (source == null) {
|
||||
// return null;
|
||||
// }
|
||||
// List<T> list = toBean(source.getRecords(), targetType);
|
||||
// if (peek != null) {
|
||||
// list.forEach(peek);
|
||||
// }
|
||||
// return new Page<>(list, source.getTotal());
|
||||
// }
|
||||
|
||||
public static <S, T> PageResult<T> toBean(PageResult<S> source, Class<T> targetType) {
|
||||
return toBean(source, targetType, null);
|
||||
}
|
||||
|
||||
public static <S, T> PageResult<T> toBean(PageResult<S> source, Class<T> targetType, Consumer<T> peek) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
List<T> list = toBean(source.getList(), targetType);
|
||||
if (peek != null) {
|
||||
list.forEach(peek);
|
||||
}
|
||||
return new PageResult<>(list, source.getTotal());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.njcn.bpm.utils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Key Value 的键值对
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class KeyValue<K, V> implements Serializable {
|
||||
|
||||
private K key;
|
||||
private V value;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.njcn.bpm.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Map 工具类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class MapUtils {
|
||||
|
||||
/**
|
||||
* 从哈希表表中,获得 keys 对应的所有 value 数组
|
||||
*
|
||||
* @param multimap 哈希表
|
||||
* @param keys keys
|
||||
* @return value 数组
|
||||
*/
|
||||
public static <K, V> List<V> getList(Multimap<K, V> multimap, Collection<K> keys) {
|
||||
List<V> result = new ArrayList<>();
|
||||
keys.forEach(k -> {
|
||||
Collection<V> values = multimap.get(k);
|
||||
if (CollectionUtil.isEmpty(values)) {
|
||||
return;
|
||||
}
|
||||
result.addAll(values);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从哈希表查找到 key 对应的 value,然后进一步处理
|
||||
* key 为 null 时, 不处理
|
||||
* 注意,如果查找到的 value 为 null 时,不进行处理
|
||||
*
|
||||
* @param map 哈希表
|
||||
* @param key key
|
||||
* @param consumer 进一步处理的逻辑
|
||||
*/
|
||||
public static <K, V> void findAndThen(Map<K, V> map, K key, Consumer<V> consumer) {
|
||||
if (ObjUtil.isNull(key) || CollUtil.isEmpty(map)) {
|
||||
return;
|
||||
}
|
||||
V value = map.get(key);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
consumer.accept(value);
|
||||
}
|
||||
|
||||
public static <K, V> Map<K, V> convertMap(List<KeyValue<K, V>> keyValues) {
|
||||
Map<K, V> map = Maps.newLinkedHashMapWithExpectedSize(keyValues.size());
|
||||
keyValues.forEach(keyValue -> map.put(keyValue.getKey(), keyValue.getValue()));
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.njcn.bpm.utils;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Object 工具类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class ObjectUtils {
|
||||
|
||||
/**
|
||||
* 复制对象,并忽略 Id 编号
|
||||
*
|
||||
* @param object 被复制对象
|
||||
* @param consumer 消费者,可以二次编辑被复制对象
|
||||
* @return 复制后的对象
|
||||
*/
|
||||
public static <T> T cloneIgnoreId(T object, Consumer<T> consumer) {
|
||||
T result = ObjectUtil.clone(object);
|
||||
// 忽略 id 编号
|
||||
Field field = ReflectUtil.getField(object.getClass(), "id");
|
||||
if (field != null) {
|
||||
ReflectUtil.setFieldValue(result, field, null);
|
||||
}
|
||||
// 二次编辑
|
||||
if (result != null) {
|
||||
consumer.accept(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T extends Comparable<T>> T max(T obj1, T obj2) {
|
||||
if (obj1 == null) {
|
||||
return obj2;
|
||||
}
|
||||
if (obj2 == null) {
|
||||
return obj1;
|
||||
}
|
||||
return obj1.compareTo(obj2) > 0 ? obj1 : obj2;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> T defaultIfNull(T... array) {
|
||||
for (T item : array) {
|
||||
if (item != null) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> boolean equalsAny(T obj, T... array) {
|
||||
return Arrays.asList(array).contains(obj);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user