自制审批流框架记录
Posted Pursuer丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自制审批流框架记录相关的知识,希望对你有一定的参考价值。
一、使用步骤
下载:https://gitee.com/gs_work/process-spring-boot-starter.git
通过Maven打包
安装到本地Maven仓库:
#jar包方式安装(安装安装记得用resource下的pom文件覆盖本地仓库的)
mvn install:install-file -Dfile=jar包路径 -DgroupId=com.shallowUniverse -DartifactId=process-spring-boot-starter -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar
#在文件夹中安装
mvn clean install
导入启动器中的flowdesign.sql文件到自己的数据库
创建SpringBoot工程引入依赖
<dependency>
<groupId>com.qianyu</groupId>
<artifactId>process-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
配置文件(application.yml)配置流程引擎需要的环境
#配置流程引擎数据库对象参数、处理器扫描路径
process:
database: flowdesign
user-table: system_user
user-id: id
user-name: realName
role-table: system_role
role-id: id
role-name: rname
dept-table: dept
dept-id: id
dept-name: name
handler-packages: com.example.testflow.handler
启动类开启流程引擎自动配置(@EnableProcess)
@SpringBootApplication
@EnableProcess
@MapperScan(basePackages = {"com.example.process.mapper"})
public class TestFlowApplication {
public static void main(String[] args) {
SpringApplication.run(TestFlowApplication.class, args);
}
}
自定义拦截器(实现ProcessInterceptor接口)
@Component
public class ProcessUserInterceptor implements ProcessInterceptor {
@Resource
private ProcessUserManager processUserManager;
@Override
public void beforeExecuteProcessor(HttpServletRequest httpServletRequest) {
//这里正常情况是从request解析token或者session拿到用户信息,此处为测试
ProcessUser processUser = new ProcessUser();
processUser.setId(1L);
processUser.setRealName("gs");
processUser.setUsername("gs");
processUser.setUserRoles("1");
processUser.setDeptId(1L);
processUserManager.setSysUser(processUser);
}
@Override
public void postExecuteProcessor(Method method, Object returnValue) {
if ("findByRole".equals(method.getName())) {
System.out.println("转换之前=========>");
System.out.println(returnValue);
System.out.println("转换之后=========>");
List<Approval> approvals = (List<Approval>) returnValue;
approvals.clear();
returnValue = approvals;
}
}
}
拦截器放入流程引擎
@Configuration
public class ProcessConfig implements ProcessInterceptorConfigurer {
@Resource
private ProcessUserInterceptor processUserInterceptor;
@Override
public void configurer(ProcessEngine processEngine) {
//增加用户校验拦截器
processEngine.addInterceptor(processUserInterceptor);
}
}
自己的数据库用户表对应的实体实现SysUser接口(可以不实现直接使用ProcessUser对象封装数据)
public class SystemUser implements SysUser {
private Long id;
private String username;
private Long dept;
private String realName;
private String userRoles;
@Override
public Long getId() {
return id;
}
@Override
public Long getDept() {
return dept;
}
@Override
public String getUsername() {
return username;
}
@Override
public String getUserRoles() {
return userRoles;
}
@Override
public String getRealName() {
return realName;
}
}
在需要开启审批的方法上加上注解
@Service
public class LeavesService extends ServiceImpl<LeavesMapper, Leaves> {
@Resource
private LeavesMapper leavesMapper;
@ProcessBegin(value = "leaves")
@Override
public boolean save(@ProcessEntry(primaryKey = "leavesId", processField = "flowId",underscoreToCamelCase = true) Leaves leaves) {
return leavesMapper.insert(leaves) > 0;
}
}
编写后置处理器
//实现FlowFinishedHandler接口
//要加上component注解,因为处理器是全部放在spring容器中,后续加载也会从spring容器加载
@ProcessHandler("leaves")
@Component
public class LeavesFlowHandler implements ProcessFinishedHandler {
//审批同意后的自动回调
@Override
public void postAllowHandle(String jsonApproval, ApprovalDetails approvalDetails) {
System.out.println(JSON.parseObject(jsonApproval, Leaves.class));
}
//审批拒绝后的自动回调
@Override
public void postRefuseHandle(String jsonApproval,ApprovalDetails approvalDetails) {
System.out.println("拒绝");
}
}
在需要使用的地方引入FlowEngine对象
@Autowired
private FlowEngine flowEngine;
//此处为测试代码,实际场景由客户端发送请求controller处理
@Test
public void contextLoads() throws FormNotExistException {
Emp emp = new Emp();
emp.setEid(1);
flowEngine.login(emp);
Leaves leaves = new Leaves();
leaves.setContent("请假");
leaves.setIsvalid(1);
leavesService.save(leaves);
}
二、注解以接口介绍
@ProcessBegin
- value:要做流程的表名,和数据库对应
@ProcessEntry
- primaryKey:实体主键字段名
- underscoreToCamelCase:主键是否驼峰
- processField:实体流程字段名
@ProcessHandler
- value:做流程的表名,和@ProcessBegin填写的对应
SysUser
- Long getId();
当前用户id - Long getDept();
当前用户部门id - String getUsername();
当前用户用户名 - String getUserRoles();
当前用户角色id字符串,格式1,2,3 - String getRealName();
当前用户真实姓名
ProcessInterceptor
- void beforeExecuteProcessor(HttpServletRequest httpServletRequest);
这里主要用于解析token或者session拿到用户信息 - void postExecuteProcessor(Method method, Object returnValue);
可以对拿到的返回值进行过滤
ProcessInterceptorConfigurer
- void configurer(ProcessEngine processEngine)
可以在加载时拿到ProcessEngine对象,添加拦截器或进行改造扩展
ProcessFinishedHandler
- void postAllowHandle(String jsonForm, ApprovalDetails formAudit)
审批全部同意以后的回调方法,第一个参数为目标表数据json串,可自行转回对象 - void postRefuseHandle(String jsonForm, ApprovalDetails formAudit)
审批中途拒绝以后的回调方法,第一个参数为目标表数据json串,可自行转回对象
ProcessUserManager
- SysUser getSysUser();
拿到当前用户 - void setSysUser(SysUser sysUser);
设置当前用户
三、执行流程原理
- 应用程序启动扫描配置文件配置的处理器包路径从Spring容器中加载所有@ProcessHandler对应的类存入ProcessHandlerManager容器
- 自定义拦截器在流程引擎方法被调用前将用户信息存入ProcessUserManager
- 执行加了@ProcessBegin的方法时通过SpringAOP环绕通知解析@ProcessEntry的实体并将其封装为审批单对象存入数据库
- ProcessEngine的executeApproval()方法执行过程中发现审批流程结束从ProcessHandlerManager中通过源表名获取处理器
- 获取到处理器后调用postAllowHandle或postRefuseHandle,至此流程结束
四、注意事项
至少要编写一个自定义拦截器解析token或者session拿到用户信息并放入ProcessUserManager,否则无法正常做审批流,启动类上要加上@EnableProcess注解,否则不会加载ProcessEngine对象,配置文件的dept相关的字段可不配置,不配置的情况下不会根据部门进行节点匹配,可根据需求自行配置,用户管理器ProcessUserManager的默认作用域为审批流框架内部方法,如需增加作用域请编写切面,参考如下:
@Aspect
@Component
public class MyAspect {
@Resource
private ProcessEngine processEngine;
@Pointcut("execution(* com.example.process.service.*.*(..))")
public void pointCut() {
}
@Before("pointCut()")
public void before() throws AuthenticationException {
processEngine.autoWriedUser();
}
}
以上是关于自制审批流框架记录的主要内容,如果未能解决你的问题,请参考以下文章