Pārlūkot izejas kodu

commit flowable

admin 1 gadu atpakaļ
revīzija
058e2ceb3c

+ 119 - 0
FlowableDesign/pom.xml

@@ -0,0 +1,119 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>FlowableDesign</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+<!--    <properties>-->
+<!--        <maven.compiler.source>8</maven.compiler.source>-->
+<!--        <maven.compiler.target>8</maven.compiler.target>-->
+<!--        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
+<!--        <flowable.version>6.7.0</flowable.version>-->
+<!--    </properties>-->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.6.2</version>
+        <relativePath />
+    </parent>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java.version>1.8</java.version>
+        <flowable.version>6.7.2</flowable.version>
+        <pagehelper.starter.version>1.4.2</pagehelper.starter.version>
+        <antlr4-runtime.version>4.8</antlr4-runtime.version>
+        <java.home>/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre
+        </java.home>
+        <spring.shiro.version>1.8.0</spring.shiro.version>
+    </properties>
+    <dependencies>
+        <!-- spring-boot-starter-web start -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- spring-boot-starter-web end -->
+        <!--flowable工作流依赖 start -->
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-spring-boot-starter</artifactId>
+            <version>${flowable.version}</version>
+        </dependency>
+        <!--flowable工作流依赖 end -->
+        <!-- 添加flowable-ui依赖 -->
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-spring-boot-starter-ui-modeler</artifactId>
+            <version>${flowable.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-spring-boot-starter-ui-admin</artifactId>
+            <version>${flowable.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-spring-boot-starter-ui-idm</artifactId>
+            <version>${flowable.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-spring-boot-starter-ui-task</artifactId>
+            <version>${flowable.version}</version>
+        </dependency>
+        <!-- mybatis start -->
+        <!--pagehelper分页 -->
+        <!-- <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+            <version>${pagehelper.starter.version}</version>
+        </dependency> -->
+        <!-- druid -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.10</version>
+        </dependency>
+        <!-- mysql jdbc -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <version>2.2.2.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 17 - 0
FlowableDesign/src/main/java/org/example/Config/FlowableConfig.java

@@ -0,0 +1,17 @@
+package org.example.Config;
+
+import org.flowable.spring.SpringProcessEngineConfiguration;
+import org.flowable.spring.boot.EngineConfigurationConfigurer;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
+
+
+    @Override
+    public void configure(SpringProcessEngineConfiguration engineConfiguration) {
+        engineConfiguration.setActivityFontName("宋体");
+        engineConfiguration.setLabelFontName("宋体");
+        engineConfiguration.setAnnotationFontName("宋体");
+    }
+}

+ 153 - 0
FlowableDesign/src/main/java/org/example/Controller/ExpenseController.java

@@ -0,0 +1,153 @@
+package org.example.Controller;
+
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.engine.*;
+import org.flowable.engine.runtime.Execution;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.image.ProcessDiagramGenerator;
+import org.flowable.task.api.Task;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@Controller
+@RequestMapping(value = "expense")
+public class ExpenseController {
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    private TaskService taskService;
+    @Autowired
+    private RepositoryService repositoryService;
+    @Autowired
+    private ProcessEngine processEngine;
+
+/***************此处为业务代码******************/
+
+
+    /**
+     * 添加报销
+     *
+     * @param userId    用户Id
+     * @param money     报销金额
+     * @param descption 描述
+     */
+    @RequestMapping(value = "add")
+    @ResponseBody
+    public String addExpense(String userId, Integer money, String descption) {
+        //启动流程
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("taskUser", userId); // xml中的flowable:assignee="${taskUser}"
+        map.put("money", money); // xml中的变量money
+        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Expense", map);// xml中的<process id="Expense"
+        return "提交成功.流程Id为:" + processInstance.getId();
+    }
+
+    /**
+     * 获取审批管理列表
+     */
+    @RequestMapping(value = "/list")
+    @ResponseBody
+    public Object list(String userId) {
+        List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).orderByTaskCreateTime().desc().list();
+        for (Task task : tasks) {
+            System.out.println(task.toString());
+        }
+        return tasks.toArray().toString();
+    }
+
+
+    /**
+     * 批准
+     *
+     * @param taskId 任务ID
+     */
+    @RequestMapping(value = "apply")
+    @ResponseBody
+    public String apply(String taskId) {
+        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+        if (task == null) {
+            throw new RuntimeException("流程不存在");
+        }
+        //通过审核
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("outcome", "通过");// xml中的变量outcome
+        taskService.complete(taskId, map);
+        return "processed ok!";
+    }
+
+
+    /**
+     * 拒绝
+     */
+    @ResponseBody
+    @RequestMapping(value = "reject")
+    public String reject(String taskId) {
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("outcome", "驳回");// xml中的变量outcome
+        taskService.complete(taskId, map);
+        return "reject";
+    }
+
+    /**
+     * 生成流程图
+     *
+     * @param processId 任务ID
+     */
+    @RequestMapping(value = "processDiagram")
+    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
+        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
+
+        //流程走完的不显示图
+        if (pi == null) {
+            return;
+        }
+        Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
+        //使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
+        String InstanceId = task.getProcessInstanceId();
+        List<Execution> executions = runtimeService
+                .createExecutionQuery()
+                .processInstanceId(InstanceId)
+                .list();
+
+        //得到正在执行的Activity的Id
+        List<String> activityIds = new ArrayList<>();
+        List<String> flows = new ArrayList<>();
+        for (Execution exe : executions) {
+            List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
+            activityIds.addAll(ids);
+        }
+
+        //获取流程图
+        BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
+        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
+        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
+        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
+        OutputStream out = null;
+        byte[] buf = new byte[1024];
+        int legth = 0;
+        try {
+            out = httpServletResponse.getOutputStream();
+            while ((legth = in.read(buf)) != -1) {
+                out.write(buf, 0, legth);
+            }
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+
+}

+ 13 - 0
FlowableDesign/src/main/java/org/example/Handler/BossTaskHandler.java

@@ -0,0 +1,13 @@
+package org.example.Handler;
+
+import org.flowable.engine.delegate.TaskListener;
+import org.flowable.task.service.delegate.DelegateTask;
+
+public class BossTaskHandler implements TaskListener {
+
+    @Override
+    public void notify(DelegateTask delegateTask) {
+        delegateTask.setAssignee("admin");
+    }
+
+}

+ 14 - 0
FlowableDesign/src/main/java/org/example/Handler/ManagerTaskHandler.java

@@ -0,0 +1,14 @@
+package org.example.Handler;
+
+import org.flowable.engine.delegate.TaskListener;
+import org.flowable.task.service.delegate.DelegateTask;
+
+public class ManagerTaskHandler implements TaskListener {
+
+    @Override
+    public void notify(DelegateTask delegateTask) {
+        delegateTask.setAssignee("1");
+    }
+
+}
+

+ 25 - 0
FlowableDesign/src/main/java/org/example/Main.java

@@ -0,0 +1,25 @@
+package org.example;
+
+
+//import org.flowable.ui.idm.conf.ApplicationConfiguration;
+//import org.flowable.ui.idm.servlet.AppDispatcherServletConfiguration;
+import org.flowable.ui.idm.conf.ApplicationConfiguration;
+import org.flowable.ui.idm.servlet.AppDispatcherServletConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+//@Import({
+//        ApplicationConfiguration.class,
+//        AppDispatcherServletConfiguration.class,
+//})
+//@EnableTransactionManagement
+//@ComponentScan(basePackages = {"org.flowable.ui.application"})
+@SpringBootApplication
+public class Main {
+    public static void main(String[] args){
+        SpringApplication.run(Main.class, args);
+    }
+}

+ 116 - 0
FlowableDesign/src/main/resources/ExpenseProcess.bpmn20.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+             xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
+             typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
+             targetNamespace="http://www.flowable.org/processdef">
+    <process id="Expense" name="ExpenseProcess" isExecutable="true">
+        <documentation>报销流程</documentation>
+        <startEvent id="start" name="开始"></startEvent>
+        <userTask id="fillTask" name="出差报销" flowable:assignee="${taskUser}">
+            <extensionElements>
+                <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler">
+                    <![CDATA[false]]></modeler:initiator-can-complete>
+            </extensionElements>
+        </userTask>
+        <exclusiveGateway id="judgeTask"></exclusiveGateway>
+        <userTask id="directorTak" name="经理审批">
+            <extensionElements>
+                <flowable:taskListener event="create"
+                                       class="org.example.Handler.ManagerTaskHandler"></flowable:taskListener>
+            </extensionElements>
+        </userTask>
+        <userTask id="bossTask" name="老板审批">
+            <extensionElements>
+                <flowable:taskListener event="create"
+                                       class="org.example.Handler.BossTaskHandler"></flowable:taskListener>
+            </extensionElements>
+        </userTask>
+        <endEvent id="end" name="结束"></endEvent>
+
+        <sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow>
+        <sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow>
+        <sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask">
+            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money > 500}]]></conditionExpression>
+        </sequenceFlow>
+        <sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end">
+            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
+        </sequenceFlow>
+        <sequenceFlow id="bossNotPassFlow" name="驳回" sourceRef="bossTask" targetRef="fillTask">
+            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
+        </sequenceFlow>
+        <sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak">
+            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money <= 500}]]></conditionExpression>
+        </sequenceFlow>
+        <sequenceFlow id="directorPassFlow" name="通过" sourceRef="directorTak" targetRef="end">
+            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
+        </sequenceFlow>
+        <sequenceFlow id="directorNotPassFlow" name="驳回" sourceRef="directorTak" targetRef="fillTask">
+            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
+        </sequenceFlow>
+    </process>
+
+
+    <!-- 如果使用图形化建模工具,实际的XML文件还将包含“可视化部分”,用于描述图形信息,
+    如流程定义中各个元素的坐标(所有的图形化信息包含在XML的BPMNDiagram标签中,作为definitions标签的子元素)  -->
+
+    <bpmndi:BPMNDiagram id="BPMNDiagram_Expense">
+        <bpmndi:BPMNPlane bpmnElement="Expense" id="BPMNPlane_Expense">
+            <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
+                <omgdc:Bounds height="30.0" width="30.0" x="285.0" y="135.0"></omgdc:Bounds>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape bpmnElement="fillTask" id="BPMNShape_fillTask">
+                <omgdc:Bounds height="80.0" width="100.0" x="405.0" y="110.0"></omgdc:Bounds>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask">
+                <omgdc:Bounds height="40.0" width="40.0" x="585.0" y="130.0"></omgdc:Bounds>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape bpmnElement="directorTak" id="BPMNShape_directorTak">
+                <omgdc:Bounds height="80.0" width="100.0" x="735.0" y="110.0"></omgdc:Bounds>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape bpmnElement="bossTask" id="BPMNShape_bossTask">
+                <omgdc:Bounds height="80.0" width="100.0" x="555.0" y="255.0"></omgdc:Bounds>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
+                <omgdc:Bounds height="28.0" width="28.0" x="771.0" y="281.0"></omgdc:Bounds>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+                <omgdi:waypoint x="315.0" y="150.0"></omgdi:waypoint>
+                <omgdi:waypoint x="405.0" y="150.0"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
+                <omgdi:waypoint x="505.0" y="150.16611295681062"></omgdi:waypoint>
+                <omgdi:waypoint x="585.4333333333333" y="150.43333333333334"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess">
+                <omgdi:waypoint x="624.5530726256983" y="150.44692737430168"></omgdi:waypoint>
+                <omgdi:waypoint x="735.0" y="150.1392757660167"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="directorNotPassFlow" id="BPMNEdge_directorNotPassFlow">
+                <omgdi:waypoint x="785.0" y="110.0"></omgdi:waypoint>
+                <omgdi:waypoint x="785.0" y="37.0"></omgdi:waypoint>
+                <omgdi:waypoint x="455.0" y="37.0"></omgdi:waypoint>
+                <omgdi:waypoint x="455.0" y="110.0"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="bossPassFlow" id="BPMNEdge_bossPassFlow">
+                <omgdi:waypoint x="655.0" y="295.0"></omgdi:waypoint>
+                <omgdi:waypoint x="771.0" y="295.0"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore">
+                <omgdi:waypoint x="605.4340277777778" y="169.56597222222223"></omgdi:waypoint>
+                <omgdi:waypoint x="605.1384083044983" y="255.0"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="directorPassFlow" id="BPMNEdge_directorPassFlow">
+                <omgdi:waypoint x="785.0" y="190.0"></omgdi:waypoint>
+                <omgdi:waypoint x="785.0" y="281.0"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge bpmnElement="bossNotPassFlow" id="BPMNEdge_bossNotPassFlow">
+                <omgdi:waypoint x="555.0" y="295.0"></omgdi:waypoint>
+                <omgdi:waypoint x="455.0" y="295.0"></omgdi:waypoint>
+                <omgdi:waypoint x="455.0" y="190.0"></omgdi:waypoint>
+            </bpmndi:BPMNEdge>
+        </bpmndi:BPMNPlane>
+    </bpmndi:BPMNDiagram>
+
+
+</definitions>

+ 38 - 0
FlowableDesign/src/main/resources/application.yml

@@ -0,0 +1,38 @@
+server:
+  port: 8080
+  servlet:
+    context-path: /
+
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://localhost:3306/flowable_demo?characterEncoding=UTF-8&serverTimezone=UTC
+    username: root
+    password: 5608095liyukun
+
+
+  druid:
+    initialSize: 2
+    minIdle: 10
+    maxActive: 20
+    maxWait: 60000
+    timeBetweenEvictionRunsMillis: 60000
+    minEvictableIdleTimeMillis: 300000
+    validationQuery: select 1
+    testWhileIdle: true
+    testOnBorrow: false
+    testOnReturn: false
+    poolPreparedStatements: true
+    maxPoolPreparedStatementPerConnectionSize: 20
+    filters: stat,wall,slf4j
+    stat-view-servlet:
+      allow:
+      login-username: admin
+      login-password: 123456
+    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+
+  flowable:
+    #??????JOB
+    async-executor-activate: false
+    database-schema-update: true