现有自己写的的一套审批流程逻辑,由于代码重构,需要把以前的很多业务加上审批的功能,再执行完审批与原有业务之后,生成一个任务,然后再统一处理一个任务(本来是通过数据库作业去处理的,后来说这个任务要马上去处理,只能去统一添加一个处理任务的逻辑,去手动触发作业,心里1w只草泥马在欢快的奔腾着)。现有的问题是:
项目的目录结构如下:
在开始之前,需要规范一些常量:
public enum CommonResult {
SUCCESS("200", "success","成功","成功"),
FAIL("201","fail","失败","失败");
private final String code;
private final String status;
private final String msg;
private final String data;
CommonResult(String code, String status, String msg, String data) {
this.code = code;
this.status = status;
this.msg = msg;
this.data = data;
}
public String getCode() {
return code;
}
public String getStatus() {
return status;
}
public String getMsg() {
return msg;
}
public String getData() {
return data;
}
}
public class ApproveException extends RuntimeException {
public ApproveException(String message){
super(message);
}
public ApproveException(Throwable throwable){
super(throwable);
}
}
public interface Constants {
//不执行插入任务 与 执行任务的逻辑
String FLOW_STATUS1 = "1";
//只执行审批逻辑
String FLOW_STATUS2 = "2";
//不执行业务逻辑
String FLOW_STATUS3 = "3";
//执行所有逻辑
String FLOW_STATUS4 = "4";
}
/**
* @description: 请求审批
* @create: 2020-04-24 13:40
**/
public class ApproveDTO {
//审批意见
private String suggestion;
//0 驳回 1 同意
private Integer appType;
//流程id
private Integer approveId;
//当前员工id
private String empId;
//当前员工name
private String empName;
//当前角色ID
private String roleId;
public String getSuggestion() {
return suggestion;
}
public void setSuggestion(String suggestion) {
this.suggestion = suggestion;
}
public Integer getAppType() {
return appType;
}
public void setAppType(Integer appType) {
this.appType = appType;
}
public Integer getApproveId() {
return approveId;
}
public void setApproveId(Integer approveId) {
this.approveId = approveId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
}
这里只是一个简单地审批服务类,主要有两个功能:
① execApprove()方法:用来执行审批的节点流转等逻辑。
② runApproveTask()方法:这个是后来新加的添加任务后马上执行的需求,主要调用数据库的存储过程。
public interface IApproveService {
/**
* 执行审批
* @param approveDTO 审批信息
* @return 0 失败 1 成功
*/
String execApprove(ApproveDTO approveDTO, Map<String,String> paramMap);
/**
* 执行审批存储过程
*/
void runApproveTask(Integer approveId);
}
```java
- 审批服务接口实现类
```java
public class ApproveServiceImpl implements IApproveService {
@Override
public String execApprove(ApproveDTO approveDTO, Map<String, String> paramMap) {
System.out.println(approveDTO.getEmpName()+"执行了"+(approveDTO.getAppType().equals(0)?"驳回":"通过")+"审批流程逻辑,因为:"+approveDTO.getSuggestion());
return paramMap.get("logic");
}
@Override
public void runApproveTask(Integer approveId) {
System.out.println("存储过程被执行......");
}
}
这里主要处理业务逻辑和审批逻辑之间的关系:
public interface IApproveTemplate {
String doApprove();
}
/**
* @author FluffyCatkin
* @create: 2020-06-02 14:00
**/
public abstract class CommonApproveTemplate implements IApproveTemplate {
protected IApproveService approveService;
protected ApproveDTO approveDTO;
private final Map<String,String> paramMap;
public CommonApproveTemplate(ApproveDTO approveDTO, Map<String,String> paramMap) {
this.approveDTO = approveDTO;
this.paramMap = paramMap;
this.approveService = new ApproveServiceImpl();
this.approveService = new ApproveServiceImpl();
}
@Override
public String doApprove(){
String execResult = execApprove();
String businessResult = "";
//执行自定义业务
if (Objects.equals(execResult,Constants.FLOW_STATUS1)||Objects.equals(execResult,Constants.FLOW_STATUS4)){
businessResult = business();
if (!businessResult.equals(CommonResult.SUCCESS.getStatus())){
System.out.println("审批流程执行失败,开始回滚");
}
}
//插入任务
if (Objects.equals(execResult,Constants.FLOW_STATUS3)||Objects.equals(execResult,Constants.FLOW_STATUS4)){
businessResult = taskBusiness();
if (!businessResult.equals(CommonResult.SUCCESS.getStatus())){
System.out.println("审批流程执行失败,开始回滚");
}
}
//什么也不做
if (Objects.equals(execResult,Constants.FLOW_STATUS2)){
return CommonResult.SUCCESS.getStatus();
}
return businessResult;
}
/**
* 执行审批流程节点流转逻辑
* @return 不同的执行结果
* 比如所有人审批通过或者流转到下一个审批人等等,这里不纠结具体 只用 1 2 3 4表示不同结果
*/
private String execApprove(){
return approveService.execApprove(this.approveDTO,this.paramMap);
}
/**
* 对传的审批参数进行解析校验,可以判断调用通过业务逻辑还是 拒绝的业务逻辑等等
*/
protected abstract String business();
/**
* 新增任务,不同的业务需要自定义自己的任务
*/
protected abstract String taskBusiness();
}
public interface CommonApproveService {
/**
* 跟进审批同意操作
* @param paramMap 参数
*/
String agreeApprove(Map<String, String> paramMap);
/**
* 跟进审批拒绝操作
* @param paramMap 参数
*/
String refuseApprove(Map<String, String> paramMap);
/**
* 将审批操作放到任务中跑
* @param paramMap 审批参数
*/
String insertApproveTask(Map<String, String> paramMap,Integer approveId);
/**
* 执行跟进的审批
* @param approveDTO 审批流程改变需要的参数
* @param paramMap 执行业务逻辑需要的参数
* @return 审批结果
*/
String execApprove(CommonApproveService service,ApproveDTO approveDTO, Map<String, String> paramMap);
}
/**
* @author FluffyCatkin
* @create: 2020-06-02 14:26
**/
public class ApproveConcrete<T extends CommonApproveService> extends CommonApproveTemplate {
private final T service;
private final Map<String, String> paramMap;
public ApproveConcrete(ApproveDTO approveDTO, Map<String, String> paramMap, T service) {
super(approveDTO, paramMap);
this.service = service;
this.paramMap = paramMap;
}
@Override
protected String business() {
if(super.approveDTO==null){
throw new ApproveException("审批失败,没有参数!");
}
Integer appType = super.approveDTO.getAppType();
if (appType==null){
throw new ApproveException("审批失败,未传入审批意见,请传入:1 同意 0 驳回!");
}
if (appType==0){
return service.refuseApprove(paramMap);
}
if (appType==1){
return service.agreeApprove(paramMap);
}
throw new ApproveException("审批失败,审批意见错误,请传入:1 同意 0 驳回!");
}
@Override
protected String taskBusiness() {
if(super.approveDTO==null){
throw new ApproveException("审批失败,没有参数!");
}
return service.insertApproveTask(paramMap,approveDTO.getApproveId());
}
}
4、业务逻辑服务实现
public interface IBusinessService extends CommonApproveService {
//在这里可以写业务逻辑相关方法
}
public class BusinessServiceImpl implements IBusinessService {
@Override
public String agreeApprove(Map<String, String> paramMap) {
System.out.println("执行同意业务逻辑");
return CommonResult.SUCCESS.getStatus();
}
@Override
public String refuseApprove(Map<String, String> paramMap) {
System.out.println("执行拒绝业务逻辑");
return CommonResult.SUCCESS.getStatus();
}
@Override
public String insertApproveTask(Map<String, String> paramMap, Integer approveId) {
System.out.println("执行插入任务业务逻辑");
return CommonResult.SUCCESS.getStatus();
}
@Override
public String execApprove(CommonApproveService service,ApproveDTO approveDTO, Map<String, String> paramMap) {
System.out.println("开始执行审批....");
return new ApproveUtil<> (service).execApprove(approveDTO, paramMap);
}
}
/**
* @author FluffyCatkin
* @version 1.0
* @date 2020/1/3 0003 10:04
* @description (动态代理)代理(Proxy)类:对真实主题功能的扩展
*/
public class DynamicProxy implements InvocationHandler {
//需要代理的对象
private final Object dynamicSubject;
private final IApproveService approveService = new ApproveServiceImpl();
private static final String PROXY_METHOD = "insertApproveTask";
/**
* 构造方法
* @param dynamicSubject 要代理的对象
*/
public DynamicProxy(Object dynamicSubject){
this.dynamicSubject = dynamicSubject;
}
/**
*
* @param proxy 被代理的类
* @param method 要增强的方法
* @param args 增强的方法参数
* @return 增强的方法返回值
* @throws Throwable 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(dynamicSubject, args);
if (PROXY_METHOD.equals(method.getName())){
approveService.runApproveTask(null);
}
return invoke;
}
/**
* 获取被代理的对象
* @return 被代理的对象
*/
public Object getCommonApproveService() {
return dynamicSubject;
}
/**
* 获取代理后增强的对象
* @param dynamicSubject 被代理的对象
* @return 代理后增强的对象
*/
public static CommonApproveService newInstance(Object dynamicSubject) {
InvocationHandler invocationHandler = new DynamicProxy(dynamicSubject);
return (CommonApproveService) Proxy.newProxyInstance(dynamicSubject.getClass().getClassLoader(),
dynamicSubject.getClass().getInterfaces(),invocationHandler);
}
}
public class MainTest {
//对业务的服务类进行增强,在spring中,可以通过spring配置,获取所有CommonApproveService的子类,并统一进行增强
//然后通过@Autowired注解直接拿到增强对的服务类
private final CommonApproveService businessService = DynamicProxy.newInstance(new BusinessServiceImpl());
@Test
public void testPassApprove() {
ApproveDTO approveDTO = new ApproveDTO();
approveDTO.setAppType(1);
approveDTO.setEmpName("张三");
approveDTO.setSuggestion("你长得太好看了");
//这里是业务执行需要的参数,不同的业务需要不同的参数,这里使用map封装
Map<String, String> paramMap = new HashMap<>();
//通过这里指定审批流程的流转结果,从而控制其流转到不同的业务逻辑里,实际情况是根据审批节点流转结果判断的
// paramMap.put("logic", Constants.FLOW_STATUS1);
// paramMap.put("logic", Constants.FLOW_STATUS2);
// paramMap.put("logic", Constants.FLOW_STATUS3);
paramMap.put("logic", Constants.FLOW_STATUS4);
String res = businessService.execApprove(businessService, approveDTO, paramMap);
System.out.println(res);
}
}
注意:这里简化了很多逻辑,也可以结合项目进行改造,比如:可以在spring中,可以通过spring配置,获取所有CommonApproveService的子类,并统一进行增强,然后通过@Autowired注解直接拿到增强对的服务类。