Activiti(二)簡單請假流程實現
阿新 • • 發佈:2018-12-16
在SpringBoot2整合Activiti6的環境中,實現簡單的請假流程。編寫請假業務流程。流程業務為:
1,員工請假,先建立請假流程
2,員工填寫請假申請,也可以不填寫,直接結束流程
3,提交給直接主管審批,如果直接主管拒絕,則重新填寫,如果直接主管同意,再到部門主管審批,
4,部門主管審批部門主管同意,則請假流程結束,請假成功,如果部門主管不同意,返回員工重新提交申請。
建立流程檔案
流程定義程式碼如下
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/testm1539766523202" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1539766523202" name="" targetNamespace="http://www.activiti.org/testm1539766523202" typeLanguage="http://www.w3.org/2001/XMLSchema"> <process id="leave1" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" name="start"/> <userTask activiti:assignee="${leave.userId}" activiti:exclusive="true" id="_3" name="submit"/> <exclusiveGateway gatewayDirection="Unspecified" id="_4" name="result"/> <userTask activiti:assignee="${leave.approver1}" activiti:exclusive="true" id="_5" name="approve1"/> <exclusiveGateway gatewayDirection="Unspecified" id="_6" name="result"/> <userTask activiti:assignee="${leave.approver2}" activiti:exclusive="true" id="_7" name="approve2"/> <exclusiveGateway gatewayDirection="Unspecified" id="_8" name="result"/> <endEvent id="_9" name="end"/> <sequenceFlow id="_10" sourceRef="_2" targetRef="_3"/> <sequenceFlow id="_11" sourceRef="_3" targetRef="_4"/> <sequenceFlow id="_12" name="y" sourceRef="_4" targetRef="_5"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_13" name="n" sourceRef="_4" targetRef="_9"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_14" sourceRef="_5" targetRef="_6"/> <sequenceFlow id="_15" name="n" sourceRef="_6" targetRef="_7"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_16" sourceRef="_7" targetRef="_8"/> <sequenceFlow id="_17" name="y" sourceRef="_6" targetRef="_3"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_18" name="n" sourceRef="_8" targetRef="_3"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree2==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_19" name="y" sourceRef="_8" targetRef="_9"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree2==true}]]></conditionExpression> </sequenceFlow> </process> </definitions>
請注意流程圖中userTask的assignee屬性表示任務的所有者,userTask需要指定任務的所有者變數,如:
sequenceFlow中的condition描述流程的走向,當滿足條件是,流程自動走該sequenceFlow
編寫使用者介面
@RestController @RequestMapping("/level/v1") public class LeaveController { public static final Logger log = LoggerFactory.getLogger(LeaveController.class); @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private ProcessEngine processEngine; /** * 啟動流程 * @param userId * @return */ @RequestMapping(value = "/start", method = RequestMethod.GET) public Map<String, Object> start(@RequestParam String userId){ Map<String, Object> vars = new HashMap<>(); Leave leave = new Leave(); leave.setUserId(userId); vars.put("leave",leave); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave1",vars); Map<String, Object> resultMap = new HashMap<>(); return resultMap; } /** * 填寫請假單 * @param leave * @return */ @RequestMapping(value="/apply", method = RequestMethod.POST) public Map<String, Object> apply(@RequestBody Leave leave){ Task task = taskService.createTaskQuery().taskId(leave.getTaskId()).singleResult(); Map<String, Object> vars = new HashMap<>(); Leave origin = (Leave) taskService.getVariable(leave.getTaskId(), "leave"); origin.setDesc(leave.getDesc()); origin.setStartDate(leave.getStartDate()); origin.setEndDate(leave.getEndDate()); origin.setTotalDay(leave.getTotalDay()); origin.setApprover1(leave.getApprover1()); origin.setApprover2(leave.getApprover2()); origin.setSubmit(leave.getSubmit()); vars.put("leave", origin); taskService.complete(leave.getTaskId(), vars); Map<String, Object> resultMap = ResultMapHelper.getSuccessMap(); return resultMap; } /** * 查詢使用者流程 * @param userId * @return */ @RequestMapping(value = "/find", method = RequestMethod.GET) public Map<String, Object> find(@RequestParam("userId")String userId){ List<Task> taskList = taskService.createTaskQuery().taskAssignee(userId).list(); List<Leave> resultList = new ArrayList<>(); if(!CollectionUtils.isEmpty(taskList)){ for(Task task : taskList){ Leave leave = (Leave) taskService.getVariable(task.getId(),"leave"); leave.setTaskId(task.getId()); leave.setTaskName(task.getName()); resultList.add(leave); } } Map<String, Object> resultMap = ResultMapHelper.getSuccessMap(); resultMap.put("datas", resultList); return resultMap; } /** * 直接主管審批 * @param leave * @return */ @RequestMapping(value = "/approve1", method = RequestMethod.POST) public Map<String, Object> approve1(@RequestBody Leave leave){ Task task = taskService.createTaskQuery().taskId(leave.getTaskId()).singleResult(); Map<String, Object> vars = new HashMap<>(); Leave origin = (Leave) taskService.getVariable(leave.getTaskId(), "leave"); origin.setApproveDesc1(leave.getApproveDesc1()); origin.setAgree1(leave.getAgree1()); vars.put("leave", origin); taskService.complete(leave.getTaskId(),vars); Map<String, Object> resultMap = ResultMapHelper.getSuccessMap(); return resultMap; } /** * 部門主管審批 * @param leave * @return */ @RequestMapping(value = "/approve2", method = RequestMethod.POST) public Map<String, Object> approve2(@RequestBody Leave leave){ Task task = taskService.createTaskQuery().taskId(leave.getTaskId()).singleResult(); Map<String, Object> vars = new HashMap<>(); Leave origin = (Leave) taskService.getVariable(leave.getTaskId(), "leave"); origin.setApproveDesc2(leave.getApproveDesc2()); origin.setAgree2(leave.getAgree2()); vars.put("leave", origin); taskService.complete(leave.getTaskId(),vars); Map<String, Object> resultMap = ResultMapHelper.getSuccessMap(); return resultMap; } /** * 檢視歷史記錄 * @param userId * @return */ @RequestMapping(value="/findClosed", method = RequestMethod.GET) public Map<String, Object> findClosed(String userId){ HistoryService historyService = processEngine.getHistoryService(); List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("leave1").variableValueEquals("leave.userId",userId).list(); List<Leave> leaves = new ArrayList<>(); for(HistoricProcessInstance pi : list){ leaves.add((Leave) pi.getProcessVariables().get("leave")); } Map<String, Object> resultMap = ResultMapHelper.getSuccessMap(); resultMap.put("datas", leaves); return resultMap; } }
請假相關Java Model
public class Leave implements Serializable { private static final long serialVersionUID = 2248469053125414262L; private String userId; private Boolean submit; private Date startDate; private Date endDate; private float totalDay; private String desc; private String taskId; private String taskName; private String approver1; private Boolean agree1; private String approveDesc1; private String approver2; private Boolean agree2; private String approveDesc2; }
測試
1,啟動流程
訪問GET請求http://192.168.104.24:8092/level/v1/start?userId=3000,使用者3000啟動請求流程
curl -X GET --header 'Accept: application/json' 'http://192.168.104.24:8092/level/v1/start?userId=3000'
2,檢視使用者的3000的任務
訪問GET請求http://192.168.104.24:8092/level/v1/find?userId=3000
curl -X GET --header 'Accept: application/json' 'http://192.168.104.24:8092/level/v1/find?userId=3000'
返回:
{
"msg": "ok",
"code": "0",
"datas": [
{
"userId": "3000",
"submit": null,
"startDate": null,
"endDate": null,
"totalDay": 0,
"desc": null,
"taskId": "15021",
"taskName": "submit",
"approver1": null,
"agree1": null,
"approveDesc1": null,
"approver2": null,
"agree2": null,
"approveDesc2": null
}
]
}
表示使用者3000已經有請假單待提交
3,使用者提交請假單
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"desc": "沒有理由", \
"endDate": "2018-10-24 18:00:00", \
"startDate": "2018-10-21 09:00:00", \
"submit": true, \
"taskId": "15021", \
"totalDay": 3, \
"approver1": "3001", \
"approver2": "3002" \
4,檢視直接主管任務提交請假理由,直接主管3001,部門主管3002,開始時間,結束時間,提交狀態(提交,或者關閉),任務ID,請假天數,請假事由等。
curl -X GET --header 'Accept: application/json' 'http://192.168.104.24:8092/level/v1/find?userId=3001'
返回直接主管審批任務資訊
{
"msg": "ok",
"code": "0",
"datas": [
{
"userId": "3000",
"submit": true,
"startDate": "2018-10-21 09:00:00",
"endDate": "2018-10-24 18:00:00",
"totalDay": 3,
"desc": "沒有理由",
"taskId": "15025",
"taskName": "approve1",
"approver1": "3001",
"agree1": null,
"approveDesc1": null,
"approver2": "3002",
"agree2": null,
"approveDesc2": null
}
]
}
5,直接主管審批
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"agree1": true, \
"approveDesc1": "同意", \
"taskId": "15025" \
\
}' 'http://192.168.104.24:8092/level/v1/approve1'
提交審批結果agree1,審批意見,任務id
6,檢視部門主管任務提交審批結果agree1,審批意見,任務id
curl -X GET --header 'Accept: application/json' 'http://192.168.104.24:8092/level/v1/find?userId=3002'
返回部門主管審批任務資訊
{
"msg": "ok",
"code": "0",
"datas": [
{
"userId": "3000",
"submit": true,
"startDate": "2018-10-21 09:00:00",
"endDate": "2018-10-24 18:00:00",
"totalDay": 3,
"desc": "沒有理由",
"taskId": "15029",
"taskName": "approve2",
"approver1": "3001",
"agree1": true,
"approveDesc1": "同意",
"approver2": "3002",
"agree2": null,
"approveDesc2": null
}
]
}
7,部門主管審批
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"agree2": true, \
"approveDesc2": "string", \
"taskId": "15029" \
}' 'http://192.168.104.24:8092/level/v1/approve2'
執行成功後請假流程執行成功。
8,檢視歷史任務
curl -X GET --header 'Accept: application/json' 'http://192.168.104.24:8092/level/v1/findClosed?userId=3000'
返回任務的歷史記錄資訊
{
"msg": "ok",
"code": "0",
"datas": [
{
"userId": "3000",
"submit": true,
"startDate": "2018-10-21 09:00:00",
"endDate": "2018-10-24 18:00:00",
"totalDay": 3,
"desc": "沒有理由",
"taskId": null,
"taskName": null,
"approver1": "3001",
"agree1": true,
"approveDesc1": "同意",
"approver2": "3002",
"agree2": true,
"approveDesc2": "string"
}
]
}
篇幅有限,就不一一羅列其他測試用例了。
(完)