簡單的請假流-基本操作
1:流程圖
流程圖的常用元素很簡單,開啟,結束為必要的。
一個完生的流程圖如下所示:
左邊為開始(startEvent),右邊為結束(endEvent),中間為活動(任務Task),箭頭的線 (SequenceFlow)
開發之前我們需要給eclipse安裝activiti外掛,個人建議使用eclipse,感覺idea對流程圖的外掛支援不是很好。
安裝外掛以及畫流程圖這裡不再陳述,大家可以自己百度。
由於設計開發中activiti提供的使用者相關的表很難滿足我們專案的需要,一般使用專案本身的角色資訊表。
而且在開發中審批人甚少指定為某一個人,一般為角色。
在之前的工作中使用的為分離式的流程引擎,配置角色生產與測試經常要維護兩個表,不方便,這裡提供了自己的一個實現邏輯。
簡單配置
配置流程屬性:
點選空白處—-》eclipse視窗會出現屬性的配置:配置id(流程圖的id)與name(流程圖的名稱)
配置請假申請的審批人:
點選請假審批的task,填寫id與name(當前活動的id與name),再點選Main config,再assiness框中填寫任務代理人,圖片中的表示式為獲取該流程中的變數,變數的屬性為:createLoginName
設定審批【副總】的審批人,此時使用的為角色,查詢待辦時,是根據登入人查詢出角色再次進行查詢待辦任務的。
2:流程釋出
@Test
public void deplomentActiviti() {
String folderPath = "study/activiti/diagrams/leaveBill";
HashMap<String, String> map = new HashMap<>();
map.put("name", "請假流程");// 名稱
map.put("id", "leaveBill");// id
map.put("category", "辦公流程");// 類別
activitiService.devlopActiviti(folderPath, map );
}
@Override
public boolean devlopActiviti(String folderPath, HashMap<String, String> map) {
Deployment deploy = repositoryService.createDeployment()// 建立一個部署構建器
.addClasspathResource(folderPath + File.separator + map.get("id") + ".bpmn")// 從類路徑一次只能新增一個檔案
.addClasspathResource(folderPath + File.separator + map.get("id") + ".png")// 流程圖片
.name(map.get("name")).category(map.get("category")).deploy();
LOGGER.info("流程名稱【 {}】", deploy.getName());
LOGGER.info("流程id【{}】", deploy.getId());
LOGGER.info("流程類別【{}】", deploy.getCategory());
return true;
}
日誌為:
[18:18:11:735] [INFO] - wsylp.service.impl.ActivitiServiceImpl.devlopActiviti(ActivitiServiceImpl.java:95) - 流程名稱【 請假流程】
[18:18:11:735] [INFO] - wsylp.service.impl.ActivitiServiceImpl.devlopActiviti(ActivitiServiceImpl.java:96) - 流程id【1】
[18:18:11:735] [INFO] - wsylp.service.impl.ActivitiServiceImpl.devlopActiviti(ActivitiServiceImpl.java:97) - 流程類別【辦公流程】
資料庫:
3:開啟流程並完成請假申請
由於第一個工作項審批人Assignee為“#{createLoginName}”,在進行開啟任務的時候需要設定createLoginName引數:
@Test
public void startActiviti() {
String processDefinitionKey = "leaveBill";
String orgCode = "070067801";
// 設定變數
HashMap<String, Object> map = new HashMap<>();
map.put("createLoginName", "0003");
map.put("orgCode", orgCode);
activitiService.startActivitiAndFinsh(processDefinitionKey, map);
}
@Override
public boolean startActivitiAndFinsh(String processDefinitionKey, HashMap<String, Object> map) {
// 取得流程例項
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, map);
LOGGER.info("流程(流程執行物件例項)id【{}】", processInstance.getId());// execution物件
LOGGER.info("流程例項id:【{}】", processInstance.getProcessInstanceId());// processInstance物件
LOGGER.info("流程定義id【{}】", processInstance.getProcessDefinitionId());// 預設為最新的id
LOGGER.info("流程例項id【{}】", processInstance.getSuperExecutionId());
List<Task> tasks = this.getTaskByDeploymentId(processInstance.getDeploymentId(), processDefinitionKey,
processInstance.getId(), (String) map.get("createLoginName"));
for (Task task : tasks) {
this.finshTask(task.getId());
}
return true;
}
上面程式碼中:processInstance.getId()也就是executionId的id(該流程的id)
日誌
[19:27:55:914] [INFO] - wsylp.service.impl.ActivitiServiceImpl.startActivitiAndFinsh(ActivitiServiceImpl.java:132) - 流程(流程執行物件例項)id【2501】
[19:27:55:914] [INFO] - wsylp.service.impl.ActivitiServiceImpl.startActivitiAndFinsh(ActivitiServiceImpl.java:133) - 流程例項id:【2501】
[19:27:55:914] [INFO] - wsylp.service.impl.ActivitiServiceImpl.startActivitiAndFinsh(ActivitiServiceImpl.java:134) - 流程定義id【leaveBill:1:4】
[19:27:55:914] [INFO] - wsylp.service.impl.ActivitiServiceImpl.startActivitiAndFinsh(ActivitiServiceImpl.java:135) - 流程例項id【null】
[19:29:33:040] [DEBUG] - org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33) -
4:查詢任務
查詢任務的方法有很多,這裡只是用幾個簡單的:
@Override
public boolean getTasks() {
TaskQuery taskQuery = taskService.createTaskQuery();
// 任務列表
List<Task> list = taskQuery.list();
for (Task task : list) {
LOGGER.info("任務處理人【{}】,任務id【{}】,任務名稱【{}】,任務流程定義id【{}】, 流程定義key【{}】,任務擁有者【{}】 ", task.getAssignee(),
task.getId(), task.getName(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(),
task.getOwner());
}
return true;
}
@Override
public List<Task> getTaskByDeploymentId(String deploymentId, String processDefinitionKey, String executionId,
String loginName) {
List<Task> list = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey)
.deploymentId(deploymentId).taskAssignee(loginName).executionId(executionId).list();
// 獲取當前人的
return list;
}
@Override
public boolean getTaskByLoginName(String processDefinitionKey, String loginName) {
TaskQuery taskQuery = taskService.createTaskQuery();
// 查詢登入人所在角色,在根據角色進行查詢
List<Role> roleList = userService.getRolesByLoginName(loginName);
for (Role role : roleList) {
// 任務列表
List<Task> list = taskQuery.processDefinitionKey(processDefinitionKey).taskAssignee(role.getRoleCode())
// . taskCandidateUser(assignee)
.list();// 組任務的辦理人查詢
for (Task task : list) {
LOGGER.info("任務處理人【{}】", task.getAssignee());
LOGGER.info("流程名稱【{}】", task.getName());
LOGGER.info("任務id【{}】", task.getId());
LOGGER.info("流程定義id【{}】", task.getProcessDefinitionId());
LOGGER.info("執行物件id【{}】", task.getExecutionId());
}
}
return true;
}
我們呼叫查詢所有的任務getTasks進行檢視,結果如下:
@Test
public void getTasks() {
activitiService.getTasks();
}
日誌
wsylp.service.impl.ActivitiServiceImpl.getTasks(ActivitiServiceImpl.java:166) - 任務處理人【fzjl】,任務id【2513】,任務名稱【審批[副總]】,任務流程定義id【leaveBill:1:4】, 流程定義key【fzsp】,任務擁有者【null】
此時根據登入號進行呼叫,檢視該使用者是否能查到任務
[19:47:33:515] [DEBUG] - org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:40) - --- TaskQueryImpl finished --------------------------------------------------------
[19:47:33:515] [DEBUG] - org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:41) -
[19:47:33:515] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getTaskByLoginName(ActivitiServiceImpl.java:185) - 任務處理人【fzjl】
[19:47:33:515] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getTaskByLoginName(ActivitiServiceImpl.java:186) - 流程名稱【審批[副總]】
[19:47:33:515] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getTaskByLoginName(ActivitiServiceImpl.java:187) - 任務id【2513】
[19:47:33:515] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getTaskByLoginName(ActivitiServiceImpl.java:188) - 流程定義id【leaveBill:1:4】
[19:47:33:515] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getTaskByLoginName(ActivitiServiceImpl.java:189) - 執行物件id【2501】
[19:47:33:515] [INFO] - wsylp.log.MyLog.logAfter(MyLog.java:29) - @AfterReturning:wsylp.service.ActivitiService.getTaskByLoginName end.
與上文的結果一致
資料庫資訊:
5:完成任務
@Test
public void finshTask() {
String taskId = "2513";
activitiService.finshTask(taskId);
}
@Override
public boolean finshTask(String taskId) {
taskService.complete(taskId);
LOGGER.info("完成任務【{}】", taskId);
return true;
}
日誌
[19:52:19:571] [INFO] - wsylp.service.impl.ActivitiServiceImpl.finshTask(ActivitiServiceImpl.java:148) - 完成任務【2513】
6:查詢流程定義資訊
@Test
public void getProcessDefin() {
String processDefinitionKey = "leaveBill";
activitiService.getProcessDefin(processDefinitionKey);
}
@Override
public boolean getProcessDefin(String processDefinitionKey) {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
// .processDefinitionId(processDefinitionId)//流程定義id
// BuyBill:1:10004 組成,proDefiKey(流程定義的key) + version(版本) + 自動生成的id
.processDefinitionKey(processDefinitionKey)// 流程定義的key
// .processDefinitionName(processDefinitionName)//流程定義名稱
// .processDefinitionVersion(processDefinitionVersion)//流程定義版本
// .latestVersion()//最新版本
// .orderByProcessDefinitionName().desc()//安裝版本降序排序
// .count()//統計結果
// .listPage(firstResult, maxResults)//分頁查詢
.list();
// 遍歷結果
for (ProcessDefinition processDefinition : list) {
LOGGER.info("流程定義id【{}】", processDefinition.getId());
LOGGER.info("流程定義的key【{}】", processDefinition.getKey());
LOGGER.info("流程部署id【{}】", processDefinition.getDeploymentId());
LOGGER.info("流程定義的版本【{}】", processDefinition.getVersion());
LOGGER.info("流程資源名稱【{}】", processDefinition.getResourceName());
}
return true;
}
日誌:
[19:56:53:960] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessDefin(ActivitiServiceImpl.java:221) - 流程定義id【leaveBill:1:4】
[19:56:53:960] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessDefin(ActivitiServiceImpl.java:222) - 流程定義的key【leaveBill】
[19:56:53:960] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessDefin(ActivitiServiceImpl.java:223) - 流程部署id【1】
[19:56:53:960] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessDefin(ActivitiServiceImpl.java:224) - 流程定義的版本【1】
[19:56:53:960] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessDefin(ActivitiServiceImpl.java:225) - 流程資源名稱【study/activiti/diagrams/leaveBill\leaveBill.bpmn】
7:檢視流程圖並輸出到指定目錄
@Test
public void getProcessImage() {
String deploymentId = "1";
activitiService.getProcessImage(deploymentId);
}
@Override
public boolean getProcessImage(String deploymentId) {
List<String> resourceNames = repositoryService.getDeploymentResourceNames(deploymentId);
for (String resourceName : resourceNames) {
if (resourceName.endsWith(".png")) {
LOGGER.info("流程資源名稱【{}】", resourceName);
/**
* 讀取資源
*
* @params deploymentId 部署id
* @params resourceName 資原始檔名
*/
try {
InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
// 把流寫入到檔案中
String pathName = "E:/" + resourceName;
File file = new File(pathName);
FileUtils.copyInputStreamToFile(resourceAsStream, file);
LOGGER.info("輸出完成");
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
}
return true;
}
日誌
[19:59:51:558] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessImage(ActivitiServiceImpl.java:235) - 流程資源名稱【study/activiti/diagrams/leaveBill\leaveBill.png】
8:檢視流程狀態
@Test
public void getProcessInstanceStateByProcessInstanceId() {
String processInstanceId = "2501";
activitiService.getProcessInstanceStateByProcessInstanceId(processInstanceId);
}
@Override
public void getProcessInstanceStateByProcessInstanceId(String processInstanceId) {
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
.singleResult();// 返回資料結果,要麼單行,要麼是空,其他情況報錯;
if (pi != null) {
LOGGER.info("該流程例項【{}】正在執行.....", processInstanceId);
LOGGER.info("當前活動的任務【{}】,名稱為", pi.getActivityId());
} else {
LOGGER.info("該任務已經結束。。。");
}
}
日誌
[20:05:13:657] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessInstanceStateByProcessInstanceId(ActivitiServiceImpl.java:344) - 該流程例項【2501】正在執行.....
[20:05:13:657] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getProcessInstanceStateByProcessInstanceId(ActivitiServiceImpl.java:345) - 當前活動的任務【zglsp】,名稱為
9:檢視歷史流程例項
@Test
public void getHistoryProcinst() {
activitiService.getHistoryProcinst();
}
@Override
public void getHistoryProcinst() {
List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().list();
if (list != null && list.size() > 0) {
for (HistoricProcessInstance m : list) {
LOGGER.info("歷史的流程例項【{}】", m.getId());
LOGGER.info("歷史流程定義id【{}】", m.getProcessDefinitionId());
LOGGER.info("歷史流程例項開始時間{}----結束時間:{}--->", m.getStartTime(), m.getEndTime());
}
}
}
日誌
[20:08:24:169] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryProcinst(ActivitiServiceImpl.java:357) - 歷史的流程例項【2501】
[20:08:24:169] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryProcinst(ActivitiServiceImpl.java:358) - 歷史流程定義id【leaveBill:1:4】
[20:08:24:169] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryProcinst(ActivitiServiceImpl.java:359) - 歷史流程例項開始時間2018-06-17T19:27:55.742+0800----結束時間:null--->
10:根據流程例項id查詢歷史任務
@Test
public void getHistoryTaskByProcessInstanceId() {
String processInstanceId = "2501";
activitiService.getHistoryTaskByProcessInstanceId(processInstanceId);
}
@Override
public void getHistoryTaskByProcessInstanceId(String processInstanceId) {
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId).list();
if (list != null && list.size() > 0) {
for (HistoricTaskInstance m : list) {
LOGGER.info("歷史的流程任務【{}】", m.getId());
LOGGER.info("歷史流程定義id【{}】", m.getProcessDefinitionId());
LOGGER.info("歷史任務名稱【{}】", m.getName());
LOGGER.info("歷史任務例項處理人【{}】", m.getAssignee());
}
}
}
日誌
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:372) - 歷史的流程任務【2510】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:373) - 歷史流程定義id【leaveBill:1:4】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:374) - 歷史任務名稱【請假申請】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:375) - 歷史任務例項處理人【0003】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:372) - 歷史的流程任務【2513】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:373) - 歷史流程定義id【leaveBill:1:4】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:374) - 歷史任務名稱【審批[副總]】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:375) - 歷史任務例項處理人【fzjl】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:372) - 歷史的流程任務【5002】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:373) - 歷史流程定義id【leaveBill:1:4】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:374) - 歷史任務名稱【審批[總經理]】
[20:11:51:095] [INFO] - wsylp.service.impl.ActivitiServiceImpl.getHistoryTaskByProcessInstanceId(ActivitiServiceImpl.java:375) - 歷史任務例項處理人【zjl】
11:刪除流程定義
刪除一般選擇級聯刪除,否則如果路ice好難過定義已經啟動就會報錯
@Test
public void deleteDeploment() {
String deploymentId = "1";
boolean cascade = true;
activitiService.deleteDeployment(deploymentId, cascade);
// activitiService.deleteDeployment(deploymentId);
}
@Override
public boolean deleteDeployment(String deploymentId, boolean cascade) {
repositoryService.deleteDeployment(deploymentId, cascade);
return true;
}