說明:
activiti -> activity
一、idea集成activity插件
1,File -> Settings -> Plugins -> 搜索actiBPM並安裝:

安裝好后,需要重啟;
2,創建一個流程
項目工程 -> src/main/resources -> 右鍵鼠標:



記得ctrl + s保存;

繼續補全這個流程:

查看流程定義的xml:


3,如果xml亂碼了


或者:

二、pom引入依賴jar包
<!-- activiti 工作流需要依賴的jar -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti-engine.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti-spring.version}</version>
<exclusions>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
如果maven你想使用另外一個settings.xml,可以把maven重新復制一遍,修改復制后的maven的settings.xml,
然后idea工作空間指定新的settings.xml;環境變量不需要重配,不影響拉取依賴jar包;
三、創建工作流配置文件



四、一些准備工作
1,准備一些代碼和頁面


五、初始化流程引擎
1,初始化前
我的數據庫只有一張表:

2,初始化
啟動項目,加載activiti.cfg.xml,注入@Controller:

// 會默認按照Resources目錄下的activiti.cfg.xml創建流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
初始化的過程中會自動創建工作流涉及的23張表;
初始化工作流引擎,也可以放在啟動后;

3,初始化后(即啟動后)

只有這個表有數據:

六、發布部署流程



查看數據庫表變化:



其他表都為空;
七、啟動流程



查看數據庫表變化:





八、user辦理任務
1,但是我忘記指定代理人了,修改工作流配置后,需要重新發布工作流,所以我又把上面的流程重新走了一遍:


重新走了一遍之后:
啟動流程后變化:

有些表的這個字段會更新:比如

2,代理人辦理任務





查看數據庫表變化:




九、查看流程圖


十、代理人繼續辦理業務





流程走到這兒,再看下數據庫表格變化:







讓“丹丹姐”完成她名下的待辦任務:

至此,這個流程結束了:







十一、遇到的問題
1,項目啟動的時候,通過@ImportResource加載xml,同時加載transaction.xml和activiti.cfg.xml:



transaction.xml依賴druidDataSource就沒報錯,但是activiti.cfg.xml的那個bean依賴druidDataSource就報錯了,說這個bean不存在;
可以試試,在@ImportResource的時候再加一個注解,指定在某個類之后;
2,項目啟動后,工作流並沒有自動創建那23張表格,並且報錯了,說表不存在,是因為代碼走到了
isEngineTablePresent() = true
,需要在配置文件里面如下配置:

;加了如上配置,啟動成功並且自動創建了23張表后,需要注釋掉這個配置,不然下次啟動時會報錯;
3,工作流可以重復發布,沒注意過這些重復的工作流的processKey是不是一樣的,啟動流程的時候需要processKey;
4,相關代碼,也是從網上抄的,稍微修改了下,什么異常處理、日志、代碼規范都沒有做,僅供參考,
當然工作流還要很多api:
package com.springbootbuild.contoller.activiti;
import com.springbootbuild.entity.activity.WorkFlowTask;
import org.activiti.engine.*;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.misc.BASE64Encoder;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 工作流測試<br>
* 示例從網上copy的
*
* @Date 2020/12/11
*/
@Controller
@RequestMapping("/activity")
public class ActivityController {
// 會默認按照Resources目錄下的activiti.cfg.xml創建流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* 發布流程<br>
* 可以重復發布
*
* @param bpmnName 流程定義文件名稱
*/
@ResponseBody
@RequestMapping(value = "/deployProcess", method = RequestMethod.POST)
public Map<String, Object> deployProcess(@RequestParam("bpmnName") String bpmnName) {
Map<String, Object> responseMap = new HashMap<String, Object>();
RepositoryService repositoryService = processEngine.getRepositoryService();
DeploymentBuilder builder = repositoryService.createDeployment();
builder.addClasspathResource(bpmnName);
builder.deploy();
responseMap.put("msg", "發布流程成功");
return responseMap;
}
/**
* 啟動流程
*
* @param processKey 流程key
*/
@ResponseBody
@RequestMapping(value = "/startProcessByKey", method = RequestMethod.POST)
public Map<String, Object> startProcessByKey(@RequestParam("processKey") String processKey) {
Map<String, Object> responseMap = new HashMap<String, Object>();
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.startProcessInstanceByKey(processKey);
responseMap.put("msg", "啟動流程成功");
return responseMap;
}
/**
* 查看任務
*
* @param assigneeName 代理人
*/
@ResponseBody
@RequestMapping(value = "/queryTask", method = RequestMethod.POST)
public Map<String, Object> queryTask(@RequestParam("assigneeName") String assigneeName) {
Map<String, Object> responseMap = new HashMap<String, Object>();
// 根據assignee(代理人)查詢任務
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskAssignee(assigneeName).list();
if (CollectionUtils.isEmpty(tasks)) {
return responseMap;
}
List<WorkFlowTask> wfTaskList = new ArrayList<>();
for (Task task : tasks) {
wfTaskList.add(new WorkFlowTask(task.getId(), task.getName(), task.getAssignee(), task.getCreateTime()));
}
responseMap.put("msg", "成功! ");
responseMap.put("taskList", wfTaskList);
return responseMap;
}
/**
* 辦理任務
*
* @param taskId 任務id
*/
@ResponseBody
@RequestMapping(value = "/handleTask", method = RequestMethod.POST)
public Map<String, Object> handleTask(@RequestParam("taskId") String taskId) {
Map<String, Object> responseMap = new HashMap<String, Object>();
// 根據上一步生成的taskId執行任務
TaskService taskService = processEngine.getTaskService();
taskService.complete(taskId);
responseMap.put("msg", "辦理任務成功");
return responseMap;
}
/**
* 查看流程圖
*
* @param processKey 流程key
*/
@ResponseBody
@RequestMapping(value = "/getProcessView", method = RequestMethod.POST)
public Map<String, Object> getProcessView(@RequestParam("processKey") String processKey) throws IOException {
Map<String, Object> responseMap = new HashMap<String, Object>();
// 根據流程key查詢流程定義,發布了幾次流程,這個list就有幾個,不要重復發布流程
List<ProcessDefinition> processList = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.processDefinitionKey(processKey)
.orderByProcessDefinitionVersion().desc()
.list();
List<String> list = processEngine.getRepositoryService().getDeploymentResourceNames(processList.get(0).getDeploymentId());
String resourceName = "";
if (list != null && list.size() > 0) {
for (String name : list) {
if (name.indexOf(".png") >= 0) {
resourceName = name;
}
}
}
//獲取圖片的輸入流
InputStream in = processEngine.getRepositoryService().getResourceAsStream(processList.get(0).getDeploymentId(), resourceName);
byte[] data = new byte[in.available()];
in.read(data);
BASE64Encoder encoder = new BASE64Encoder();
String viewCode = "data:image/png;base64, " + encoder.encode(data);
responseMap.put("viewCode", viewCode);
responseMap.put("msg", "查詢成功");
return responseMap;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"></property>
<property name="jdbcUsername" value=""></property>
<property name="jdbcPassword" value=""></property>
<!-- 不知道為什么,druidDataSource可以在transaction.xml使用,在這兒就不行 -->
<!--<property name="dataSource" ref="druidDataSource"></property>-->
<!-- isEngineTablePresent() = true,不會創建初始化表格,需要加下面這個屬性
表格創建好后,記得把下面一行注釋了-->
<!--<property name="databaseSchema" value="ACTIVITI"></property>-->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>
