BOS项目第10天

10 BOS项目第10天

今天继续学习工作流activity,流程变量

10.1 请假流程存在的问题

  • 缺少请假原因和请假天数,后期可能还会有其它数据要补充
  • activiti把这些数据称为流程变量,内部提供了一张act_ru_variable 表来存这些数据


    image.png

10.2 设置流程变量的方式

  • 重新创建一个Java项目和数据库,这次用报销流程讲解


    image.png

10.2.1 第一种:启动流程实例时设置流程变量

@Test
    public void test1(){
        //2.获取部署构建器对象
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

        //3.添加流程资源
        deploymentBuilder.addClasspathResource("bxlc.bpmn");
        deploymentBuilder.addClasspathResource("bxlc.jpg");

        //4.部署
        Deployment deployment = deploymentBuilder.deploy();
        System.out.println(deployment.getId());
    }

    /**
     * 启动流程实例时设置流程变量
     */
    @Test
    public void test2(){
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("bxyy", "成都出差机票");
        varibles.put("bxje", "980");
        processEngine.getRuntimeService().startProcessInstanceByKey("bxlc", varibles);
    }

10.2.2 第二种:办理任务时设置流程变量

/**
     * 审核任务时设置流程变量
     */
    @Test
    public void test3(){
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("bxyy", "成都出差动车票");
        varibles.put("bxje", "260.00");
        processEngine.getTaskService().complete("1106", varibles);
    }

10.2.3 使用RuntimeService的set方法设置流程变量

/**
     * 使用RuntimeService的set方法设置流程变量
     */
    @Test
    public void test4(){
        String processInstanceId = "1101";
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("审核状态", "同意");
        processEngine.getRuntimeService().setVariables(processInstanceId, varibles);
    }

10.2.4 用TaskService的set方法设置

/**
     * 用TaskService的set方法设置
     */
    @Test
    public void test5(){
        String taskId = "1202";//任务id
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("审核状态", "不同意");
        processEngine.getTaskService().setVariables(taskId, varibles);
    }

10.2.5 如果设置的是自定义的类型,需要实现序列化接口

@Test
    public void test5(){
        String taskId = "1202";//任务id
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("审核状态", "不同意");
        varibles.put("user", new User("kdj", "123456"));
        processEngine.getTaskService().setVariables(taskId, varibles);
    }

10.3 读取流程变量的方式

10.3.1 方式一:使用RuntimeService的get方法获取

@Test
    public void test6() {
        //用getRuntimeService的get方法获取流程变量
        String processInstanceId = "1101";
        User user = (User) processEngine.getRuntimeService().getVariable(processInstanceId, "user");
        System.out.println(user);

        String state = (String) processEngine.getRuntimeService().getVariable(processInstanceId, "审核状态");
        System.out.println(state);
    }

10.3.2 使用TaskService的get方法获取

@Test
    public void test7() {
        //用TaskService的get方法获取流程变量
        String taskId = "1202";
        User user = (User) processEngine.getTaskService().getVariable(taskId, "user");
        System.out.println(user);

        String state = (String) processEngine.getTaskService().getVariable(taskId, "审核状态");
        System.out.println(state);
    }

10.4 动态设置任务的候选人

  • 第一步:在启动流程实现时,需要添加一个表达式里的变量值
@Test
    public void test2() {
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("bxyy", "成都出差机票");
        varibles.put("bxje", "2800");
        varibles.put("employeeName", "lisi");
        processEngine.getRuntimeService().startProcessInstanceByKey("bxlc", varibles);
    }
  • 在任务的Assignee写表达式


    image.png

10.5 组任务操作

10.5.1 候选人组任务(了解)

  • 第一步:给任务添加多个用户


    image.png
  • 第二步:重新部署流程和启动流程实现

@Test
    public void test1() {
        //2.获取部署构建器对象
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

        //3.添加流程资源
        deploymentBuilder.addClasspathResource("bxlc.bpmn");
        deploymentBuilder.addClasspathResource("bxlc.jpg");

        //4.部署
        Deployment deployment = deploymentBuilder.deploy();
        System.out.println(deployment.getId());
    }

    /**
     * 启动流程实例时设置流程变量
     */
    @Test
    public void test2() {
        HashMap<String, Object> varibles = new HashMap<>();
        varibles.put("bxyy", "成都出差机票");
        varibles.put("bxje", "2800");
        varibles.put("employeeName", "lisi");
        processEngine.getRuntimeService().startProcessInstanceByKey("bxlc", varibles);
    }
  • 第三步:办理第一个流程任务
@Test
    public void test3() {
        //李四提交申请
        processEngine.getTaskService().complete("107");
    }
  • 第四步:根据用户id查询任务
@Test
    public void test4() {
        //查找财务人员要审核任务
        TaskQuery tq = processEngine.getTaskService().createTaskQuery();

        //设置候选人名称
        tq.taskCandidateUser("kdj01");

        //打印任务id,打印名称
        for (Task task : tq.list()) {
            System.out.println(task.getId() + ":" + task.getName());
        }
    }
  • 第五步:拾取任务
@Test
    public void test4() {
        //查找财务人员要审核任务
        TaskQuery tq = processEngine.getTaskService().createTaskQuery();

        //设置候选人名称
        String user = "kdj01";
        tq.taskCandidateUser(user);

        //打印任务id,打印名称
        for (Task task : tq.list()) {
            System.out.println(task.getId() + ":" + task.getName());

            //拾取任务
            processEngine.getTaskService().claim(task.getId(), user);
        }
    }

10.5.2 候选组组任务(重点)

  • 第一步:设置一个财务分组id


    image.png
  • 第二步:重新部署流程并启动流程实例然后complete提交申请

  • 第三步:添加组


    image.png
  • 第四步:添加用户


    image.png
  • 第五步:建立用户和组的关系


    image.png
  • 第六步:根据用户id或者组查询任务

    • 注意:查询任务时,要先启动流程实现并输第一个任务
@Test
        public void testProcessInstance(){
            //启动流程实例:
            Map<String,Object> variables = new HashMap<String,Object>();
            variables.put("bxyy", "南京出差机机票");
            variables.put("bxje", "890");
            variables.put("employeeName", "小李");
            pe.getRuntimeService().startProcessInstanceByKey("bxlc", variables);
        }
        
        @Test
        public void testComplete(){
            //处理第一个任务
            pe.getTaskService().complete("2307");
        }
        @Test
        public void test5(){
            //查询组任务
            TaskQuery tq = pe.getTaskService().createTaskQuery();
            String userId = "1";
            //tq.taskCandidateUser(userId);
            tq.taskCandidateGroup("财务组");
            List<Task> tasks = tq.list();
            for(Task t:tasks){
                System.out.println(t.getId());
            }
        }
  • 第七步:拾起任务
    pe.getTaskService().claim("2402", "1");

10.6 排他网关

10.6.1 排他网关流程图

image.png

10.6.2 测试网关

  • 在开启流程实例时,必需设置流量变量qjts
public class GateWayTest {
    //1.获取流程引擎
            ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();
                    
            @Test
            public void test1(){
                
                //2.获取部署构建器对象
                DeploymentBuilder db = pe.getRepositoryService().createDeployment();
                
                //3.添加流程资源
                db.addClasspathResource("com/huaizhi/activiti/gateway/qjlc.bpmn");
                db.addClasspathResource("com/huaizhi/activiti/gateway/qjlc.png");
            
                //4.部署
                Deployment deployment = db.deploy();
                System.out.println(deployment.getId());
            }
            
            @Test
            public void test2(){
                Map<String,Object> variables = new HashMap<String,Object>();
                variables.put("qjyy", "感冒..");
                variables.put("qjts",5);
                pe.getRuntimeService().startProcessInstanceByKey("qjlc", variables);
                
            }
            @Test
            public void test3(){
                String taskId = "606";
                pe.getTaskService().complete(taskId);
                
            }
}

10.7 activiti与spring整合

10.7.1 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置数据源  -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url"  value="jdbc:mysql:///activiti_day1"/>
        <property name="username"  value="root"/>
        <property name="password"  value="root"/>
    </bean>

    <!--  配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 流程引擎配置对象 -->
    <bean id="processEngineConfiguration"
          class="org.activiti.spring.SpringProcessEngineConfiguration">
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

    <!-- 使用工厂创建流程引擎对象 -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
    </bean>
</beans>

10.7.2 单元测试

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class Main5 {

    @Test
    public void test1() {
        //1.创建spring工厂
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2.获取bean
        ProcessEngine pe = (ProcessEngine) ac.getBean("processEngine");

        List<ProcessDefinition> list = pe.getRepositoryService().createProcessDefinitionQuery().list();

        //有流程定义打印,代表配置成功
        for(ProcessDefinition pd : list){
            System.out.println(pd.getKey());
        }
    }
}

10.8 Bos项目集成activiti

10.8.1 第一步:在Bos数据库添加activiti所需要的表

  • 之前三个sql文件,已经导入了

10.8.2 第二步:将activiti与spring的整合转移到Bos项目中

  • 导入jar包到项目:使用spring3.2以上版本,不需要添加spring-asm.jar

  • spring中配置processengin

<!-- 流程引擎配置对象 -->
    <bean id="processEngineConfiguration"
         class="org.activiti.spring.SpringProcessEngineConfiguration">
         <property name="dataSource" ref="dataSource"/>
         <property name="transactionManager" ref="transactionManager"/>
    </bean>

    <!-- 使用工厂创建流程引擎对象 -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
    </bean>
  • 再配置activiti的各种service
<!-- 注册Service -->
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
  • 测试下是否能获取到流程定义
@Autowired
    private RepositoryService rs;
    public String login(){
        logger.info(getModel());

        System.out.println(rs); //如果有值,证明activiti的配置木有问题

10.9 流程定义管理模型

10.9.1 修改系统管理的菜单数据

  • 在admin.json 添加两行数据
  • 注意:系统管理的数据是从json中获取,不是从数据库
    { "id":"1004", "pId":"100", "name":"流程定义管理", "page":"processDefinitionAction_list.action"},
    { "id":"1005", "pId":"100", "name":"查看正在运行的流程实例", "page":"processInstanceAction_list.action"}

10.9.2 查看流程定义

  • 创建ProcessDefinitionAction,完成流程定义列表展现

10.9.3 部署流程定义

//发布一个流程
    public String deploy() throws FileNotFoundException {

        //1.获取部署的对象
        DeploymentBuilder builder = rs.createDeployment();

        //2.builder 添加压缩包的输入流
        builder.addZipInputStream(new ZipInputStream(new FileInputStream(zipFile)));

        builder.deploy();

        //部署完后回到list页面
        return "list";
    }

10.9.4 查看流程定义图

  • 第一步:修改jsp页面
<td>
    <a onclick="showPng('${id}')" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查看流程图</a>
</td>
<script>
    function showPng(id) {
        //alert(id);
        //显示流程图
        window.open("${pageContext.request.contextPath}/processDefinitionAction_viewpng.action?id=" + id);
    }
</script>
  • 第二步:Action
public String viewpng(){
        //返回一张图片给客户端
        //1.根据流程id获取图片
        InputStream imgIS = rs.getProcessDiagram(id);

        //2.把imgIS放在值栈
        ActionContext.getContext().getValueStack().set("imgIS", imgIS);
        return "viewpng";
}
  • 第三步:Struts
<action name="processDefinitionAction_*" class="com.kdj.bos.web.action.ProcessDefinitionAction" method="{1}">
    <result name="list">/WEB-INF/pages/workflow/processdefinition_list.jsp</result>

    <!--告诉客户端返回流文件-->
    <result name="viewpng" type="stream">
        <param name="contentType">image/png</param>
        <param name="inputName">imgIS</param>
    </result>
</action>

10.9.5 删除流程定义

  • 效果


    image.png
  • 第一步:添加删除的js代码

function del(id) {
    $.messager.confirm("提示","是否要删除?", function (r) {
        if (r){
            var url = "${pageContext.request.contextPath}/processDefinitionAction_del.action";
            $.post(url, {id:id}, function (data) {
                if (data == "success") {
                    $.messager.alert("提示", "删除成功", "info", function () {
                        location.href = "${pageContext.request.contextPath}/processDefinitionAction_list.action"
                    });
                } else{
                    $.messager.alert("提示", "删除失败", "error");
                }
            });
        }
    });
}
  • 第二步:Action代码
public void del() throws IOException {
    //1.先根据流程定义的id查找部署id
    ProcessDefinitionQuery query = rs.createProcessDefinitionQuery();
    query.processDefinitionId(id);
    ProcessDefinition pd = query.singleResult();

    String deploymentId = pd.getDeploymentId();
    rs.deleteDeployment(deploymentId);
    ServletActionContext.getResponse().getWriter().write("success");
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容