Acticiti7工作流引擎
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.imooc</groupId> <artifactId>activitiweb</artifactId> <version>0.0.1-SNAPSHOT</version> <name>activitiweb</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>7.1.0.M4</version> </dependency> <dependency> <groupId>org.activiti.dependencies</groupId> <artifactId>activiti-dependencies</artifactId> <version>7.1.0.M4</version> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> <configuration> <skipTests>true</skipTests> </configuration> </plugin> </plugins> </build> </project>
ymal
server: port: 8080 servlet: context-path: / session: timeout: 9000 spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&nullCatalogMeansCurrent=true driver-class-name: com.mysql.cj.jdbc.Driver #日志的相关配置 logging: level: root: info #日志的相关配置 spring.activiti.history-level: full spring.activiti.db-history-used: true # spring-activiti # 自动部署验证设置:true-开启(默认)、false-关闭 spring.activiti.check-process-definitions: false
user.sql
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- 创建用户表 -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL COMMENT '姓名', `address` varchar(64) DEFAULT NULL COMMENT '联系地址', `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号', `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码', `roles` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '角色', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- 填充用户表 -- ---------------------------- INSERT INTO `user` VALUES ('1', 'admincn', 'beijing', 'admin', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_ADMIN'); INSERT INTO `user` VALUES ('2', 'bajiecn', 'shanghang', 'bajie', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_USER,GROUP_activitiTeam,g_bajiewukong'); INSERT INTO `user` VALUES ('3', 'wukongcn', 'beijing', 'wukong', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_USER,GROUP_activitiTeam'); INSERT INTO `user` VALUES ('4', 'salaboycn', 'beijing', 'salaboy', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_USER,GROUP_activitiTeam'); -- ---------------------------- -- 修复Activiti7的M4版本缺失字段Bug -- ---------------------------- alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255) DEFAULT NULL; alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255) DEFAULT NULL; -- ---------------------------- -- 动态表单数据存储 -- ---------------------------- DROP TABLE IF EXISTS `formdata`; CREATE TABLE `formdata` ( `PROC_DEF_ID_` varchar(64) DEFAULT NULL, `PROC_INST_ID_` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `FORM_KEY_` varchar(255) DEFAULT NULL, `Control_ID_` varchar(100) DEFAULT NULL, `Control_VALUE_` varchar(2000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
---------------------------------------------------------------------------------- Activiti7工作流引擎 activiti bpmn visualizer最终这个插件可用(idea插件)。 Activiti7经典类 流程部署deployment 流程定义processDefinition 流程实例processInstance 任务处理Task 历史任务historicTaskInstance 流程部署deploymen:指定流程key,指定流程名称,任务指定执行人,上传bpmn,增删改查,查询列表和查询xml。 //通过bpmn部署流程 @Test public void initDeploymentBPMN(){ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { Resource[] resources = resolver.getResources("classpath*:**/process/Part1_Deployment.bpmn"); for (Resource resource : resources) { Deployment deployment=repositoryService.createDeployment() .addInputStream(resource.getFilename(), resource.getInputStream()) .name("流程部署测试bpmn") .deploy(); System.out.println(deployment.getName()); } } catch (IOException e) { e.printStackTrace(); } } //act_re_deployment表增加了记录 //act_ge_bytearray表增加了记录 //通过png部署流程 @Test public void initDeploymentPNG(){ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { Resource[] resources = resolver.getResources("classpath*:**/process/Part1_Deployment.png"); for (Resource resource : resources) { Deployment deployment=repositoryService.createDeployment() .addInputStream(resource.getFilename(), resource.getInputStream()) .name("流程部署测试png") .deploy(); System.out.println(deployment.getName()); } } catch (IOException e) { e.printStackTrace(); } } //act_re_deployment表增加了记录 //act_ge_bytearray表增加了记录 //通过ZIP部署流程 @Test public void initDeploymentZIP() { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { Resource[] resources = resolver.getResources("classpath*:**/process/Part1_DeploymentV2.zip"); for (Resource resource : resources) { ZipInputStream zip=new ZipInputStream(resource.getInputStream()); Deployment deployment=repositoryService.createDeployment() .addZipInputStream(zip) .name("流程部署测试zip") .deploy(); System.out.println(deployment.getName()); } } catch (IOException e) { e.printStackTrace(); } } //act_re_deployment表增加了记录 //act_ge_bytearray表增加了记录 //查询流程部署 @Test public void getDeployments() { List<Deployment> list = repositoryService.createDeploymentQuery().list(); for(Deployment dep : list){ System.out.println("Id:"+dep.getId()); System.out.println("Name:"+dep.getName()); System.out.println("DeploymentTime:"+dep.getDeploymentTime()); System.out.println("Key:"+dep.getKey()); } } ----------------------------------------------------------------------------------------------------------- 流程定义processDefinition Deployment:添加资源文件,获取部署信息,部署时间 ProcessDefinition: 获取版本号,key,资源名称,部署ID等。 act_re_procdef表 //查询流程定义 @Test public void getDefinitions(){ List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery() .list(); for(ProcessDefinition pd : list){ System.out.println("------流程定义--------"); System.out.println("Name:"+pd.getName()); System.out.println("Key:"+pd.getKey()); System.out.println("ResourceName:"+pd.getResourceName()); System.out.println("DeploymentId:"+pd.getDeploymentId()); System.out.println("Version:"+pd.getVersion()); } } //删除流程定义 @Test public void delDefinition(){ String pdID="1a8bcf80-e132-11f0-9d85-0a0027000006"; repositoryService.deleteDeployment(pdID,true); System.out.println("删除流程定义成功"); } ----------------------------------------------------------------------------------------------------------- 流程实例processInstance //初始化流程实例 @Test public void initProcessInstance(){ //1、获取页面表单填报的内容,请假时间,请假事由,String fromData //2、fromData 写入业务表,返回业务表主键ID==businessKey //3、把业务数据与Activiti7流程数据关联 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Part1_Deployment","bKey001"); System.out.println("流程实例ID:"+processInstance.getProcessDefinitionId()); } //act_ru_execution表 //act_ru_identitylink表 //获取流程实例列表 @Test public void getProcessInstances(){ List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().list(); for(ProcessInstance pi : list){ System.out.println("--------流程实例------"); System.out.println("ProcessInstanceId:"+pi.getProcessInstanceId()); System.out.println("ProcessDefinitionId:"+pi.getProcessDefinitionId()); System.out.println("isEnded:"+pi.isEnded()); System.out.println("isSuspended:"+pi.isSuspended()); System.out.println("Name:"+pi.getName()); } } //挂起与激活流程实例 @Test public void activitieProcessInstance(){ // runtimeService.suspendProcessInstanceById("5dc1d19a-e158-11f0-8ad9-0a0027000006"); // System.out.println("挂起流程实例"); runtimeService.activateProcessInstanceById("5dc1d19a-e158-11f0-8ad9-0a0027000006"); System.out.println("激活流程实例"); } //删除流程实例 @Test public void delProcessInstance(){ runtimeService.deleteProcessInstance("5dc1d19a-e158-11f0-8ad9-0a0027000006","测试"); System.out.println("删除流程实例"); } ----------------------------------------------------------------------------------------------------------- 任务处理Task 用户任务:Assignee:执行人、代理人。 用户任务:Candidate Users: 候选人。 用户任务:Candidate Groups: 候选组。 用户任务:Due Date: 任务到期时间。 新建 Part4_Task.bpmn 运行 initDeploymentBPMN 运行 getDefinitions 运行 initProcessInstance //任务查询 @Test public void getTasks(){ List<Task> list = taskService.createTaskQuery().list(); for(Task tk : list){ System.out.println("Id:"+tk.getId()); System.out.println("Name:"+tk.getName()); System.out.println("Assignee:"+tk.getAssignee()); } } //查询我的代办任务 @Test public void getTasksByAssignee(){ List<Task> list = taskService.createTaskQuery() .taskAssignee("bajie") .list(); for(Task tk : list){ System.out.println("Id:"+tk.getId()); System.out.println("Name:"+tk.getName()); System.out.println("Assignee:"+tk.getAssignee()); } } //act_ru_task表 新建 Part4_Task_claim.bpmn 运行 initDeploymentBPMN 运行 getDefinitions 运行 initProcessInstance //拾取任务 @Test public void claimTask(){ Task task = taskService.createTaskQuery().taskId("210a762b-e167-11f0-b62e-0a0027000006").singleResult(); taskService.claim("210a762b-e167-11f0-b62e-0a0027000006","bajie"); System.out.println("拾取任务"); } ----------------------------------------------------------------------------------------------------------- 查询历史记录 历史综合信息:HistoricTaskInstance 历史变量:HistoricVariableInstance //act_hi_actinst表 //act_hi_identitylink表 //act_hi_procinst表 //act_hi_taskinst表 //根据用户名查询历史记录 @Test public void HistoricTaskInstanceByUser(){ List<HistoricTaskInstance> list = historyService .createHistoricTaskInstanceQuery() .orderByHistoricTaskInstanceEndTime().asc() .taskAssignee("bajie") .list(); for(HistoricTaskInstance hi : list){ System.out.println("Id:"+ hi.getId()); System.out.println("ProcessInstanceId:"+ hi.getProcessInstanceId()); System.out.println("Name:"+ hi.getName()); } } //根据流程实例ID查询历史 @Test public void HistoricTaskInstanceByPiID(){ List<HistoricTaskInstance> list = historyService .createHistoricTaskInstanceQuery() .orderByHistoricTaskInstanceEndTime().asc() .processInstanceId("33c69ef1-e160-11f0-b1e2-0a0027000006") .list(); for(HistoricTaskInstance hi : list){ System.out.println("Id:"+ hi.getId()); System.out.println("ProcessInstanceId:"+ hi.getProcessInstanceId()); System.out.println("Name:"+ hi.getName()); } } ----------------------------------------------------------------------------------------------------------- UEL表达式 EL为表达式语言(Expression Language) UEL统一表达式语言(Unified Expression Language) 表达式描述 表达式以 "${"开始",以"}"结束,例如${day > 100} 支持逻辑运算${userName == "bajie" and pwd== "123"} 支持变量与实体类赋值 对应activiti数据表 act_ru_variable运行时参数表 act_hi_varinst历史参数表 UEL表达式的保留字 and,eq,gt, instanceof,div,or, le,false,empty, not,Lt,ge, UEL表达式的运算符 +加 -减 *乘 /或div 除 %或 mod 求余 新建 Part6_UEL_V1.bpmn 运行 initDeploymentBPMN 运行 getDefinitions //运行 initProcessInstance //启动流程实例带参数,执行执行人 @Test public void initProcessInstanceWithArgs() { //流程变量//${ZhiXingRen} Map<String, Object> variables = new HashMap<String, Object>(); variables.put("ZhiXingRen", "wukong"); ProcessInstance processInstance = runtimeService .startProcessInstanceByKey("myProcess_UEL_V1" , "bKey004" , variables); System.out.println("流程实例ID:" + processInstance.getProcessDefinitionId()); } 运行getTasksByAssignee 新建 Part6_UEL_V2.bpmn 运行 initDeploymentBPMN 运行 getDefinitions 运行 initProcessInstance //完成任务带参数 @Test public void completeTaskWithArgs() { Map<String, Object> variables = new HashMap<String, Object>(); variables.put("ZhiXingRen", "wukong"); taskService.complete("210a762b-e167-11f0-b62e-0a0027000006",null); System.out.println("完成任务"); } //完成任务带参数,指定流程变量 @Test public void completeTaskWithArgs2() { Map<String, Object> variables = new HashMap<String, Object>(); variables.put("pay", "101"); taskService.complete("6e7e1179-e17e-11f0-ae29-0a0027000006",variables); System.out.println("完成任务"); } 新建 Part6_UEL_V3.bpmn 运行 initDeploymentBPMN //运行 getDefinitions //启动流程实例带参数,使用实体类 @Test public void initProcessInstanceWithClassArgs() { UEL_POJO uelPojo = new UEL_POJO(); uelPojo.setZhixingren("bajie"); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("uelpojo", uelPojo); ProcessInstance processInstance = runtimeService .startProcessInstanceByKey("myProcess_UEL_V3" , "bKey005" , variables); System.out.println("流程实例ID:" + processInstance.getProcessDefinitionId()); } //任务完成环节带参数,指定多个候选人 @Test public void initProcessInstanceWithCandiDateArgs() { Map<String, Object> variables = new HashMap<String, Object>(); variables.put("houxuanren", "wukong,tangseng"); taskService.complete("e0f16f7c-e18e-11f0-bcbb-0a0027000006",variables); System.out.println("完成任务"); } ------------------------------------------------------------------------------------------------- BPMN2.0网关 并行网关 排他网关 包容网关 事件网关 新建 Part7_Parallel.bpmn 运行 initDeploymentBPMN 运行 initProcessInstance 运行 completeTask 新建 Part7_Exclusive.bpmn 运行 initDeploymentBPMN // Map<String, Object> variables = new HashMap<String, Object>(); // variables.put("day", "1"); // taskService.complete("c9506c43-e24f-11f0-9c08-0a0027000006",variables); // System.out.println("完成任务"); //沙僧 3c8dc419-e250-11f0-89f9-0a0027000006 //悟空 3c8dc417-e250-11f0-89f9-0a0027000006 taskService.complete("3c8dc419-e250-11f0-89f9-0a0027000006"); taskService.complete("3c8dc417-e250-11f0-89f9-0a0027000006"); System.out.println("完成任务"); ------------------------------------------------------------------------------------------------- ProcessRuntime TaskRuntime 从github.com下载activiti https://github.com/Activiti/Activiti 打开项目,复制子项目activiti-examples/activiti-api-basic-full-example-bean/下的 DemoApplicationConfiguration.java和SecurityUtil.java到Activiti7SpringbootApplication同级目录 //获取流程实例 @Test public void getProcessInstance(){ securityUtil.logInAs("bajie"); Page<ProcessInstance> processInstancePage = processRuntime .processInstances(Pageable.of(0,100)); System.out.println("流程实例数量:" + processInstancePage.getTotalItems()); List<ProcessInstance> list = processInstancePage.getContent(); for(ProcessInstance pi : list){ System.out.println("===================>"); System.out.println("id:" + pi.getId()); System.out.println("name:" + pi.getName()); System.out.println("StartDate:" + pi.getStartDate()); System.out.println("Status:" + pi.getStatus()); System.out.println("ProcessDefinitionId:" + pi.getProcessDefinitionId()); System.out.println("ProcessDefinitionKey:" + pi.getProcessDefinitionKey()); } } 新建 Part8_ProcessRunTime.bpmn 运行 initDeploymentBPMN 运行 startProcessInstance //启动流程实例 @Test public void startProcessInstance(){ securityUtil.logInAs("bajie"); ProcessInstance processInstance = processRuntime.start( ProcessPayloadBuilder.start() .withProcessDefinitionKey("myProcess_ProcessRunTime") .withName("第一个流程实例名称") // .withVariable() .withBusinessKey("buskey001") .build() ); System.out.println("流程实例ID:"+processInstance.getProcessDefinitionId()); } //挂起流程实例 @Test public void suspendProcessInstance(){ securityUtil.logInAs("bajie"); ProcessInstance processInstance = processRuntime.suspend( ProcessPayloadBuilder.suspend() .withProcessInstanceId("170c3c11-e54f-11f0-a51e-0a0027000006") .build() ); System.out.println("挂起流程实例" + processInstance.getId()); } TaskRuntime //获取当前登录用户任务 @Test public void getTasks(){ securityUtil.logInAs("bajie"); Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 100)); System.out.println("任务数量:" + tasks.getTotalItems()); List<Task> list = tasks.getContent(); for(Task task: list){ System.out.println("++++++++++++++++"); System.out.println("Id: " + task.getId()); System.out.println("name: " + task.getName()); System.out.println("status: " + task.getStatus()); System.out.println("createDate: " + task.getCreatedDate()); System.out.println("assignee: " + task.getAssignee()); } } //完成任务 @Test public void completeTask(){ securityUtil.logInAs("bajie"); Task task = taskRuntime.task("eddbd9a9-e229-11f0-9645-0a0027000006"); if(task.getAssignee() == null){ taskRuntime.claim(TaskPayloadBuilder.claim() .withTaskId(task.getId()) .build()); } taskRuntime.complete(TaskPayloadBuilder .complete() .withTaskId(task.getId()) .build()); System.out.println("任务执行完成"); } ------------------------------------------------------------------------------------------------- SpringSecurity 认证 鉴权/授权 导入 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> @Component public class UserInfoBean implements UserDetails { private Long id; private String name; private String address; private String username; private String password; private String roles; public String getAddress(){ return address; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return Arrays.stream(roles.split(",")) .map(s -> new SimpleGrantedAuthority(s)) .collect(Collectors.toList()); } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } } @Mapper @Component public interface UserInfoBeanMapper { @Select("select * from user where username=#{username}") UserInfoBean selectByUsername(@Param("username") String username); } @Component public class MyUserDetailsService implements UserDetailsService { @Resource UserInfoBeanMapper userInfoBeanMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { /* String passWorld = passwordEncoder().encode("111"); // String passWorld = new BCryptPasswordEncoder().encode("111"); return new User(username ,passWorld , AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ACTIVITI_USER")); */ UserInfoBean userInfoBean = userInfoBeanMapper.selectByUsername(username); if(userInfoBean == null){ throw new UsernameNotFoundException("数据库中无此用户"); } return userInfoBean; } @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } } @Component("loginSuccessHandler") public class LoginSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException { AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication); } @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.getWriter().write("登录成功LoginSuccessHandler," + authentication.getName()); } } @Configuration public class ActivitiSecurityConfig extends WebSecurityConfigurerAdapter { @Resource private LoginSuccessHandler loginSuccessHandler; @Resource private LoginFailureHandler loginFailureHandler; @Override protected void configure(HttpSecurity http)throws Exception{ http.formLogin() .loginPage("/login") .loginProcessingUrl("/login") .successHandler(loginSuccessHandler) .failureHandler(loginFailureHandler) .and() .authorizeRequests() .anyRequest().permitAll() .and() .logout().permitAll() .and() .csrf().disable() .headers().frameOptions().disable(); } } @Component("loginFailureHandler") public class LoginFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.getWriter().write("登录失败: " + e.getMessage()); } } @Controller public class ActivitiSecurityController { @RequestMapping("/login") @ResponseStatus(code = HttpStatus.UNAUTHORIZED) public String requireAuthentication(HttpServletRequest request, HttpServletResponse response){ return new String("需要登录,请使用login.html或者发起POST登录请求"); } } ------------------------------------------------------------------------------------------------- bpmnjs整合 下载bpmnjs地址如下 https://github.com/bpmn-io/bpmn-js-examples resources下再建resources目录 复制properties-panel到resources/resources目录下 在cmd窗口中cd到resources\resources\bpmnjs目录下,运行 npm install 再运行npm run dev https://git.imooc.com/coding-454/activiti7_workflow 复制customControls文件夹 复制customTranslate文件夹 复制properties-panel文件夹 复制activiti.json 复制newDiagram.bpmn 到resources\resources\bpmnjs\resources下 打开resources\resources\bpmnjs\app\index.js 注释以下内容 import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'; import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json'; 注释以下内容 var bpmnModeler = new BpmnModeler({ container: canvas, propertiesPanel:{ parent: '#js-properties-panel' }, additionalModules:[ propertiesPanelModule, propertiesProviderModule ], moddleExtensions:{ camunda: camundaModdleDescriptor } }); 添加以下内容 import propertiesProviderModule from '../resources/properties-panel/provider/activiti'; import activitiModdleDescriptor from '../resources/activiti.json'; import customTranslate from '../resources/customTranslate/customTranslate'; import customControlsModule from '../resources/customControls'; 添加组件 var customTranslateModule = { translate: ['value',customTranslate] }; var bpmnModeler = new BpmnModeler({ container: canvas, propertiesPanel:{ parent: '#js-properties-panel' }, additionalModules: [ propertiesPanelModule, propertiesProviderModule, customControlsModule, customTranslateModule ], moddleExtensions:{ activiti:activitiModdleDescriptor } }); 增加bpmn可执行选项默认勾选,打开resources/newDiagram.bpmn 属性修改isExecutable="true" <bpmn2:process id="Process_1" isExecutable="true"> --------------------------------------------------------------------------- 流程定义-------- //添加流程定义通过上传bpmn @PostMapping("/uploadStreamAndDeployment") public AjaxResponse uploadStreamAndDeployment(@RequestParam("processFile") MultipartFile multipartFile ,@RequestParam("deploymentName") String deploymentName){ try { String fileName = multipartFile.getOriginalFilename(); //文件扩展名 String extension = FilenameUtils.getExtension(fileName); InputStream fileInputStream = multipartFile.getInputStream(); Deployment deployment = null; if(extension.equals("zip")){ ZipInputStream zip = new ZipInputStream(fileInputStream); deployment = repositoryService.createDeployment()//初始化部署 .addZipInputStream(zip) .name(deploymentName) .deploy(); }else{ deployment = repositoryService.createDeployment() .addInputStream(fileName,fileInputStream) .name(deploymentName) .deploy(); } System.out.println("添加流程定义通过上传bpmn"); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), deployment.getId() +";" + fileName ); }catch (Exception e){ return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "流程部署失败",e.getMessage()); } } //添加流程定义通过在线提交bpmn的xml @PostMapping("/addDeploymentByString") public AjaxResponse addDeploymentByString(@RequestParam("stringBPMN") String stringBPMN ,@RequestParam("deploymentName") String deploymentName){ System.out.println("111111111111111111"); try { Deployment deployment = repositoryService.createDeployment() .addString("CreateWithBPMNJS.bpmn", stringBPMN) .name(deploymentName) .deploy(); System.out.println("添加流程定义通过在线提交bpmn的xml"); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), deployment.getId() ); }catch (Exception e){ return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "string流程部署失败",e.getMessage()); } } //获取流程定义列表 @GetMapping("/getDefinitions") public AjaxResponse getDefinitions(){ try { List<HashMap<String,Object>> listMap = new ArrayList<HashMap<String,Object>>(); List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery() .list(); for (ProcessDefinition pd : list) { HashMap<String,Object> hashMap = new HashMap<>(); hashMap.put("Name" , pd.getName()); hashMap.put("Key" , pd.getKey()); hashMap.put("ResourceName" , pd.getResourceName()); hashMap.put("DeploymentId" , pd.getDeploymentId()); hashMap.put("Version" , pd.getVersion()); System.out.println("------流程定义--------"); System.out.println("Name:" + pd.getName()); System.out.println("Key:" + pd.getKey()); System.out.println("ResourceName:" + pd.getResourceName()); System.out.println("DeploymentId:" + pd.getDeploymentId()); System.out.println("Version:" + pd.getVersion()); listMap.add(hashMap); } return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap); }catch (Exception e){ return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取流程定义失败",e.getMessage()); } } //获取流程定义XML @GetMapping("/getDefinitionXML") public void getDefinitionXML(HttpServletResponse response, @RequestParam("deploymentID") String deploymentID , @RequestParam("resourceName") String resourceName){ try { InputStream inputStream = repositoryService.getResourceAsStream(deploymentID,resourceName); int count = inputStream.available(); byte[] bytes = new byte[count]; response.setContentType("text/xml"); OutputStream outputStream = response.getOutputStream(); while (inputStream.read(bytes) != -1){ outputStream.write(bytes); } inputStream.close(); }catch (Exception e){ e.getMessage(); } } //获取流程部署列表 @GetMapping("/getDeployments") public AjaxResponse getDeployments(){ try { List<HashMap<String,Object>> listMap = new ArrayList<HashMap<String,Object>>(); List<Deployment> list = repositoryService.createDeploymentQuery() .list(); for (Deployment dep : list) { HashMap<String,Object> hashMap = new HashMap<>(); hashMap.put("Id" , dep.getId()); hashMap.put("Name" , dep.getName()); hashMap.put("DeploymentTime" , dep.getDeploymentTime()); System.out.println("------流程定义--------"); System.out.println("Id:" + dep.getId()); System.out.println("Name:" + dep.getName()); System.out.println("DeploymentTime:" + dep.getDeploymentTime()); listMap.add(hashMap); } return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap); }catch (Exception e){ return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取流程部署列表失败",e.getMessage()); } } //删除流程定义 @GetMapping("/delDefinition") public AjaxResponse delDefinition(@RequestParam("pdID") String pdID){ try { repositoryService.deleteDeployment(pdID,true); System.out.println("添加流程定义通过在线提交bpmn的xml"); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), null ); }catch (Exception e){ return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "删除流程定义失败",e.getMessage()); } } ----------------------------------------------------------------------------------------------------------- 流程实例processInstance //获取流程实例列表 @GetMapping("/getInstances") public AjaxResponse getInstances(@AuthenticationPrincipal UserInfoBean userInfoBean){ try { if(GlobalConfig.Test){ securityUtil.logInAs("bajie"); } //else { // securityUtil.logInAs(userInfoBean.getUsername());//这句不需要 // } Page<ProcessInstance> processInstancePage = processRuntime.processInstances(Pageable.of(0,100)); System.out.println("流程实例数量:" + processInstancePage.getTotalItems()); List<ProcessInstance> list = processInstancePage.getContent(); list.sort((y,x)->x.getStartDate().toString().compareTo(y.getStartDate().toString())); List<HashMap<String,Object>> listMap = new ArrayList<HashMap<String,Object>>(); for(ProcessInstance pi: list){ HashMap<String,Object> hashMap = new HashMap<>(); hashMap.put("id",pi.getId()); hashMap.put("name",pi.getName()); hashMap.put("status",pi.getStatus()); hashMap.put("processDefinitionId",pi.getProcessDefinitionId()); hashMap.put("processDefinitionKey",pi.getProcessDefinitionKey()); hashMap.put("startDate",pi.getStartDate()); hashMap.put("processDefinitionVersion",pi.getProcessDefinitionVersion()); //因为processRuntime.processDefinition("流程部署ID")查询的结果没有部署流程与部署ID,所以用repositoryService查询 ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() .processDefinitionId(pi.getProcessDefinitionId()) .singleResult(); hashMap.put("resourceName", pd.getResourceName()); hashMap.put("deploymentId", pd.getDeploymentId()); listMap.add(hashMap); } return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap); }catch (Exception e){ return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取流程实例列表失败",e.getMessage()); } } //启动流程实例 @GetMapping(value = "/startProcess") public AjaxResponse startProcess(@RequestParam("processDefinitionKey") String processDefinitionKey, @RequestParam("instanceName") String instanceName // ,@RequestParam("instanceVariable") String instanceVariable ) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } // else{ // securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName()); // } ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder .start() .withProcessDefinitionKey(processDefinitionKey) .withName(instanceName) //.withVariable("content", instanceVariable) //.withVariable("参数2", "参数2的值") .withBusinessKey("自定义BusinessKey") .build()); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName()+";"+processInstance.getId()); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "启动流程实例失败", e.toString()); } } //挂起流程实例 @GetMapping(value = "/suspendInstance") public AjaxResponse suspendInstance(@RequestParam("instanceID") String instanceID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } ProcessInstance processInstance = processRuntime.suspend(ProcessPayloadBuilder .suspend() .withProcessInstanceId(instanceID) .build() ); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName()); } catch(Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "挂起流程实例失败", e.toString()); } } //激活、重启流程实例 @GetMapping(value = "/resumeInstance") public AjaxResponse resumeInstance(@RequestParam("instanceID") String instanceID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } ProcessInstance processInstance = processRuntime.resume(ProcessPayloadBuilder .resume() .withProcessInstanceId(instanceID) .build() ); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName()); } catch(Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "激活流程实例失败", e.toString()); } } //删除流程实例 @GetMapping(value = "/deleteInstance") public AjaxResponse deleteInstance(@RequestParam("instanceID") String instanceID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } ProcessInstance processInstance = processRuntime.delete(ProcessPayloadBuilder .delete() .withProcessInstanceId(instanceID) .build() ); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName()); } catch(Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "删除流程实例失败", e.toString()); } } //查询流程参数 @GetMapping(value = "/getVariables") public AjaxResponse getVariables(@RequestParam("instanceID") String instanceID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } List<VariableInstance> variableInstance = processRuntime.variables(ProcessPayloadBuilder .variables() .withProcessInstanceId(instanceID) .build()); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), variableInstance); } catch(Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取流程参数失败", e.toString()); } } ----------------------------------------------------------------------------------------------------------- 任务处理Task //获取我的待办任务 @GetMapping(value = "/getTasks") public AjaxResponse getTasks() { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 100)); List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>(); for (Task tk : tasks.getContent()) { HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put("id", tk.getId()); hashMap.put("name", tk.getName()); hashMap.put("status", tk.getStatus()); hashMap.put("createdDate", tk.getCreatedDate()); if (tk.getAssignee() == null) {//执行人,null时前台显示未拾取 hashMap.put("assignee", "待拾取任务"); } else { hashMap.put("assignee", tk.getAssignee());// } ProcessInstance processInstance = processRuntime.processInstance(tk.getProcessInstanceId()); hashMap.put("instanceName", processInstance.getName()); listMap.add(hashMap); } return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取我的待办任务失败", e.toString()); } } //完成待办任务 @GetMapping(value = "/completeTask") public AjaxResponse completeTask(@RequestParam("taskID") String taskID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } Task task = taskRuntime.task(taskID); if (task.getAssignee() == null) { taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build()); } taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()) //.withVariable("num", "2")//执行环节设置变量 .build()); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), null); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "完成失败", e.toString()); } } ----------------------------------------------------------------------------------------------------------- 查询历史记录 //用户历史任务 @GetMapping(value = "/getInstancesByUserName") public AjaxResponse InstancesByUser() {//@AuthenticationPrincipal UserInfoBean userInfoBean try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } // else{ // securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName()); // } List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery() .orderByHistoricTaskInstanceEndTime().asc() .taskAssignee(SecurityContextHolder.getContext().getAuthentication().getName())//userInfoBean.getUsername()//"bajie" .list(); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), historicTaskInstances); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取用户历史任务失败", e.toString()); } } //根据流程实例ID查询任务 @GetMapping(value = "/getInstancesByPiID") public AjaxResponse getInstancesByPiID(@RequestParam("piID") String piID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } // else{ // securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName()); // } //--------------------------------------------另一种写法------------------------- List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery() .orderByHistoricTaskInstanceEndTime().asc() .processInstanceId(piID) .list(); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), historicTaskInstances); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取历史任务失败", e.toString()); } } ----------------------------------------------------------------------------------------------------------- 任务 //获取我的待办任务 @GetMapping(value = "/getTasks") public AjaxResponse getTasks() { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } // else{ // securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName()); // } Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 100)); List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>(); for (Task tk : tasks.getContent()) { HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put("id", tk.getId()); hashMap.put("name", tk.getName()); hashMap.put("status", tk.getStatus()); hashMap.put("createdDate", tk.getCreatedDate()); if (tk.getAssignee() == null) {//执行人,null时前台显示未拾取 hashMap.put("assignee", "待拾取任务"); } else { hashMap.put("assignee", tk.getAssignee());// } ProcessInstance processInstance = processRuntime.processInstance(tk.getProcessInstanceId()); hashMap.put("instanceName", processInstance.getName()); listMap.add(hashMap); } return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "获取我的待办任务失败", e.toString()); } } //完成待办任务 @GetMapping(value = "/completeTask") public AjaxResponse completeTask(@RequestParam("taskID") String taskID) { try { if (GlobalConfig.Test) { securityUtil.logInAs("bajie"); } // else{ // securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName()); // } Task task = taskRuntime.task(taskID); if (task.getAssignee() == null) { taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build()); } taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()) //.withVariable("num", "2")//执行环节设置变量 .build()); return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), null); } catch (Exception e) { return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(), "完成失败", e.toString()); } }
<meta charset="utf-8" />
posted on 2025-12-24 20:42 yebinghuai-qq-com 阅读(11) 评论(0) 收藏 举报
浙公网安备 33010602011771号