日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

SpringBoot - 工作流Activiti开发

發(fā)布時(shí)間:2025/3/15 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot - 工作流Activiti开发 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.工作流

1.1 開發(fā)前奏

介紹

當(dāng)前系統(tǒng)activit開發(fā)以springboot+mybatis開發(fā)為準(zhǔn),

1.1.1 IDEA安裝actiBPM

通過(guò)File -> Settings -> Plugins 找到actiBPM插件進(jìn)行安裝

1.1.2 核心API介紹

ProcessEngineConfiguration:流程引擎配置。 ProcessEngine:流程引擎 核心七大接口 RepositoryService:提供一系列管理流程部署和流程定義的API。 RuntimeService:在流程運(yùn)行時(shí)對(duì)流程實(shí)例進(jìn)行管理與控制。 TaskService:對(duì)流程任務(wù)進(jìn)行管理,例如任務(wù)提醒、任務(wù)完成和創(chuàng)建任務(wù)等。 IdentityService:提供對(duì)流程角色數(shù)據(jù)進(jìn)行管理的API,這些角色數(shù)據(jù)包括用戶組、用戶及它們之間的關(guān)系。 ManagementService:提供對(duì)流程引擎進(jìn)行管理和維護(hù)的服務(wù),提供對(duì)activiti數(shù)據(jù)庫(kù)的直接訪問(wèn)【一般不用】 HistoryService:對(duì)流程的歷史數(shù)據(jù)進(jìn)行操作,包括查詢、刪除這些歷史數(shù)據(jù)。FormService:表單服務(wù)

1.1.3 添加依賴 pom.xml

<dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter-basic</artifactId><version>6.0.0</version> </dependency>

1.1.4 yml配置

spring:activiti:check-process-definitions: true #自動(dòng)檢查、部署流程定義文件database-schema-update: true #自動(dòng)更新數(shù)據(jù)庫(kù)結(jié)構(gòu)history-level: full #保存歷史數(shù)據(jù)級(jí)別設(shè)置為full最高級(jí)別,便于歷史數(shù)據(jù)的追溯# process-definition-location-prefix: classpath:/processes/ #流程定義文件存放目錄#process-definition-location-suffixes: #流程文件格式# - **.bpmn20.xml# - **.bpmn

springboot環(huán)境下不再以activiti.cfg.xml文件的形式配置,activiti使用starter配置后屬于spring下,所以在yml里配置。

  • check-process-definitions【檢查Activiti數(shù)據(jù)表是否存在及版本號(hào)是否匹配】默認(rèn)為true,自動(dòng)創(chuàng)建好表之后設(shè)為false。設(shè)為false會(huì)取消自動(dòng)部署功能。
  • database-schema-update【在流程引擎啟動(dòng)和關(guān)閉時(shí)處理數(shù)據(jù)庫(kù)模式】如下四個(gè)值:

    • false (默認(rèn)值):在創(chuàng)建流程引擎時(shí)檢查庫(kù)模式的版本,如果版本不匹配則拋出異常。
    • true:在創(chuàng)建流程引擎時(shí),執(zhí)行檢查并在必要時(shí)對(duì)數(shù)據(jù)庫(kù)中所有的表進(jìn)行更新,如果表不存在,則自動(dòng)創(chuàng)建。 、
    • create-drop:在創(chuàng)建流程引擎時(shí),會(huì)創(chuàng)建數(shù)據(jù)庫(kù)的表,并在關(guān)閉流程引擎時(shí)刪除數(shù)據(jù)庫(kù)的表。
    • drop-create:Activiti啟動(dòng)時(shí),執(zhí)行數(shù)據(jù)庫(kù)表的刪除操作,在Activiti關(guān)閉時(shí),會(huì)執(zhí)行數(shù)據(jù)庫(kù)表的創(chuàng)建操作。
  • history-level 【歷史數(shù)據(jù)保存級(jí)別】

    • none:不保存任何的歷史數(shù)據(jù),因此,在流程執(zhí)行過(guò)程中,這是最高效的。
    • activity:級(jí)別高于none,保存流程實(shí)例與流程行為,其他數(shù)據(jù)不保存。
    • audit:除activity級(jí)別會(huì)保存的數(shù)據(jù)外,還會(huì)保存全部的流程任務(wù)及其屬性。audit為history的默認(rèn)值。
    • full:保存歷史數(shù)據(jù)的最高級(jí)別,除了會(huì)保存audit級(jí)別的數(shù)據(jù)外,還會(huì)保存其他全部流程相關(guān)的細(xì)節(jié)數(shù)據(jù),包括一些流程參數(shù)等。

1.1.5 添加processes目錄

SpringBoot集成activiti默認(rèn)會(huì)從classpath下的processes目錄下讀取流程定義文件,所以需要在src/main/resources目錄下添加processes目錄,并在目錄中創(chuàng)建流程文件.

如果沒(méi)有processes目錄,則需要修改配置spring.activiti.process-definition-location-prefix,指定流程文件存放目錄。

1.1.6 其他相關(guān)配置

  • 現(xiàn)在系統(tǒng)的啟動(dòng)類排除org.activiti.spring.boot.SecurityAutoConfiguration即可

    @SpringBootApplication(exclude = SecurityAutoConfiguration.class,scanBasePackages="com.poly")
    public class AvtivityApplication {

    public static void main(String[] args) {SpringApplication.run(AvtivityApplication.class, args); }

    }

  • 官方文檔給出的啟動(dòng)類配置

    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    public class MyApplication {

    public static void main(String[] args) {SpringApplication.run(MyApplication.class, args); }

    }

1.1.7 配置bpmn

  • 通過(guò)插件配置
  • 官方文檔測(cè)試bpmn文件 命名為one-task-process.bpmn20.xml 放入processes目錄

    <?xml version="1.0" encoding="UTF-8"?> <definitionsxmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:activiti="http://activiti.org/bpmn"targetNamespace="Examples"><process id="oneTaskProcess" name="The One Task Process"><startEvent id="theStart" /><sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" /><userTask id="theTask" name="my task" /><sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" /><endEvent id="theEnd" /></process></definitions>

1.1.8 配置數(shù)據(jù)源

注意mysql連接池版本

# com.mysql.cj.jdbc.Driver spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/activiti_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCusername: rootpassword: 12345678

1.2 表介紹

在1.1.2~1.1.8完成后 啟動(dòng)項(xiàng)目會(huì)生成如下表

  • act_ge_ 通用數(shù)據(jù)表,ge是general的縮寫
  • act_hi_ 歷史數(shù)據(jù)表,hi是history的縮寫,對(duì)應(yīng)HistoryService接口
  • act_id_ 身份數(shù)據(jù)表,id是identity的縮寫,對(duì)應(yīng)IdentityService接口
  • act_re_ 流程存儲(chǔ)表,re是repository的縮寫,對(duì)應(yīng)RepositoryService接口,存儲(chǔ)流程部署和流程定義等靜態(tài)數(shù)據(jù)
  • act_ru_ 運(yùn)行時(shí)數(shù)據(jù)表,ru是runtime的縮寫,對(duì)應(yīng)RuntimeService接口和TaskService接口,存儲(chǔ)流程實(shí)例和用戶任務(wù)等動(dòng)態(tài)數(shù)據(jù)

    資源庫(kù)流程規(guī)則表1)?act_re_deployment?部署信息表2)?act_re_model ?流程設(shè)計(jì)模型部署表3)?act_re_procdef ?流程定義數(shù)據(jù)表運(yùn)行時(shí)數(shù)據(jù)庫(kù)表1)?act_ru_execution運(yùn)行時(shí)流程執(zhí)行實(shí)例表2)?act_ru_identitylink運(yùn)行時(shí)流程人員表,主要存儲(chǔ)任務(wù)節(jié)點(diǎn)與參與者的相關(guān)信息3)?act_ru_task運(yùn)行時(shí)任務(wù)節(jié)點(diǎn)表4)?act_ru_variable運(yùn)行時(shí)流程變量數(shù)據(jù)表歷史數(shù)據(jù)庫(kù)表1)?act_hi_actinst?歷史節(jié)點(diǎn)表2)?act_hi_attachment歷史附件表3)?act_hi_comment歷史意見(jiàn)表4)?act_hi_identitylink歷史流程人員表5)?act_hi_detail歷史詳情表,提供歷史變量的查詢6)?act_hi_procinst歷史流程實(shí)例表7)?act_hi_taskinst歷史任務(wù)實(shí)例表8)?act_hi_varinst歷史變量表組織機(jī)構(gòu)表1)?act_id_group用戶組信息表2)?act_id_info用戶擴(kuò)展信息表3)?act_id_membership用戶與用戶組對(duì)應(yīng)信息表4)?act_id_user用戶信息表
  • 1.3 開發(fā)實(shí)例

    1.3.1 項(xiàng)目開發(fā)案例

  • 通過(guò)actiBPM設(shè)置流程
    在processes下建立bpmn流程,之后更改為bpmn20.xml格式(注:具體xml內(nèi)容請(qǐng)看項(xiàng)目中processes文件)
  • 1.3.2 個(gè)人實(shí)例

    思路

  • 員工請(qǐng)假,先創(chuàng)建請(qǐng)假流程
  • 員工填寫請(qǐng)假申請(qǐng),也可以不填寫,直接結(jié)束流程
  • 提交給直接主管審批,如果直接主管拒絕,則重新填寫,如果直接主管同意,再到部門主管審批,
  • 部門主管審批部門主管同意,則請(qǐng)假流程結(jié)束,請(qǐng)假成功,如果部門主管不同意,返回員工重新提交申請(qǐng)。
    • 創(chuàng)建流程文件

    代碼

    <?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>
    • 編寫接口

      @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;/*** 啟動(dòng)流程* @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; }/*** 填寫請(qǐng)假單* @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; }

      }

    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; }

    總結(jié)

    以上是生活随笔為你收集整理的SpringBoot - 工作流Activiti开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。