• day58_BOS项目_10


    • 今天内容安排:
      • 1、流程变量(设置、获取)
      • 2、组任务操作(候选人、候选组)
      • 3、排他网关的使用
      • 4、spring 整合 activiti框架
      • 5、将activiti框架应用到bos项目中
      • 6、在bos项目中实现流程定义管理(部署、查询、查看png、删除)

    1、流程变量(设置、获取)

    之前的请假流程,是没有实际意义的,我们要使得我们流程变得有意义(有实际意义),需要在流程向下推进的过程中带着数据推进才有意义。如下图所示:

    1.1、设置流程变量的方式

    准备工作:重新新建一个数据库,名为activiti_day02,使用框架提供的sql文件建表,今天我们执行Windows批处理文件建表,再使用插件设计一个报销流程图。之后我们部署流程定义。
    批处理文件内容如下:
    ActivitiAcutoCreateTable.bat

    @echo off
    title Activiti5-CreateTableProcess
    color b
    @echo activiti_day02数据库导入中...

    mysql -uroot -proot activiti_day02 < activiti.mysql.create.engine.sql
    mysql -uroot -proot activiti_day02 < activiti.mysql.create.history.sql
    mysql -uroot -proot activiti_day02 < activiti.mysql.create.identity.sql

    @rem pause

    if "%OS%"=="Windows_NT" ENDLOCAL

    一共有4种设置流程变量方式,实际开发中都会用到。

    • 方式一:启动流程实例时设置流程变量
        /**
         * 方式一:启动流程实例时设置流程变量
         */

        @Test
        public void test2() {
            String processDefinitionKey = "baoxiaoliucheng"// 流程定义id
            Map<StringObject> variables = new HashMap<>(); // 注意:第二个参数是一个HashMap
            // 设置流程变量
            variables.put("key1""value1");
            variables.put("key2"100);
            ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey, variables);
            System.out.println(processInstance.getId());
        }
    • 方式二:办理任务时设置流程变量
        /**
         * 方式二:办理任务时设置流程变量
         */

        @Test
        public void test3() {
            String taskId = "106";
            Map<StringObject> variables = new HashMap<>(); // 注意:第二个参数是也一个HashMap
            // 设置流程变量
            variables.put("reason""差旅费用");
            variables.put("money"500);
            processEngine.getTaskService().complete(taskId, variables);
        }

    就我们当前的报销场景来说,方式二:办理任务时设置流程变量更合理,因为我们在办报销任务的时候,浏览器端会给用户提供一个用户页面,在页面上有一个表单,在表单上可以填写报销原因、报销金额等信息。填写完表单后,一点击提交按钮,这个任务就办理了。所以方式二:办理任务时设置流程变量更合理。在服务器端会将表单提交过来的数据保存至数据库中。


    • 方式三:使用RuntimeService的set方法时设置流程变量
        /**
         * 方式三:使用RuntimeService的set方法时设置流程变量
         */

        @Test
        public void test4() {
            String executionId = "101"// 流程实例id
            Map<StringObject> variables = new HashMap<>(); // 注意:第二个参数是也一个HashMap集合
            // 设置流程变量
            variables.put("审批意见""报销原因不够详细");
            variables.put("user"new User(1025"北京市朝阳区")); // 设置的是自定义的类型
            processEngine.getRuntimeService().setVariables(executionId, variables);
            // processEngine.getRuntimeService().setVariable(executionId, variableName, value); // 一个一个的设置
        }

    注意:如果设置的是自定义的类型,如User,需要该类实现序列化接口。

    • 方式四:使用TaskService的set方法时设置流程变量
        /**
         * 方式四:使用TaskService的set方法时设置流程变量
         */

        @Test
        public void test5() 
    {
            String taskId = "204"// 任务id
            String variableName = "审批意见"// 注意:在同一个流程实例里面,流程变量的key是不能重复的,若出现重复,会覆盖
            String value = "不批,需要详细写清楚报销原因";
            processEngine.getTaskService().setVariable(taskId, variableName, value);
        }

    1.2、获取流程变量的方式

    • 方式一:使用RuntimeService的get方法时获取流程变量
        /**
         * 方式一:使用RuntimeService的get方法获取流程变量
         */

        @Test
        public void test6() {
            String executionId = "101"// 流程实例id
            Map<StringObject> variables = processEngine.getRuntimeService().getVariables(executionId);
            System.out.println(variables); // Map集合的toString()方法比较友好,还可以看

            // 如果我们自己遍历Map:通过键找值
            Set<String> keySet = variables.keySet(); // 先获得键集合
            for (String key : keySet) {
                Object value = variables.get(key); // 通过键找值
                System.out.println(key + " = " + value); 
                // 注意:为了使得自定义的类型User打印出来的结果好看些,我们需要在User类中重写User的toString()方法,但是需要重新进行序列化,不然反序列化的时候会报错
            }
        }
    • 方式二:使用TaskService的get方法时获取流程变量
        /**
         * 方式二:使用TaskService的get方法时获取流程变量
         */

        @Test
        public void test7() 
    {
            String taskId = "204"// 任务id
            Object value = processEngine.getTaskService().getVariable(taskId , "user");
            System.out.println(value);
        }
    • 方式三:使用框架提供的表达式获取流程变量
      示例演示的是:当创建任务的时候(即启动流程实例时),${variableName}表示activiti框架会拿着variableName(流程变量的name,即键key)到流程变量表中去找对应的name。其他的同理。
      相应的代码截图:

      相应的流程图截图:

      相应的数据库表截图:

    2、组任务操作(候选人、候选组)

    2.1、候选人的组任务(了解)


    示例代码如下:
    package com.itheima.activiti.grouptask;

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    import org.activiti.engine.ProcessEngine;
    import org.activiti.engine.ProcessEngines;
    import org.activiti.engine.repository.DeploymentBuilder;
    import org.activiti.engine.runtime.ProcessInstance;
    import org.activiti.engine.task.Task;
    import org.activiti.engine.task.TaskQuery;
    import org.junit.Test;

    /**
     * 组任务测试(候选人)
     * @author Bruce
     *
     */

    public class GroupTaskTest {
        // 获取默认流程引擎(全局变量)
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        /**
         * 部署流程定义
         */

        @Test
        public void test1() 
    {
            DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
            deploymentBuilder.addClasspathResource("com/itheima/activiti/grouptask/baoxiaoliucheng.bpmn");
            deploymentBuilder.addClasspathResource("com/itheima/activiti/variable/baoxiaoliucheng.png");
            deploymentBuilder.deploy();
        }

        /**
         * 启动流程实例时设置流程变量
         */

        @Test
        public void test2() 
    {
            String processDefinitionKey = "baoxiaoliucheng"// 流程定义id
            Map<String, Object> variables = new HashMap<>(); // 注意:第二个参数是一个HashMap集合
            // 设置流程变量
            variables.put("loginUser""熊五");
            ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey, variables);
            System.out.println(processInstance.getId());
        }

        /**
         * 办理任务
         */

        @Test
        public void test3() 
    {
            String taskId = "1002"// 任务id
            processEngine.getTaskService().complete(taskId);
        }

        /**
         * 查询组任务
         *      如果财务二拾取了组任务,财务三就查询不到组任务了。
         */

        @Test
        public void test4() 
    {
            TaskQuery query = processEngine.getTaskService().createTaskQuery();
            String candidateUser = "财务三";
            query.taskCandidateUser(candidateUser); // 使用候选人过滤
            List<Task> list = query.list();
            for (Task task : list) {
                System.out.println(task.getId());
            }
        }

        /**
         * 拾取组任务,即将组任务变为个人任务
         *      不能两个人拾取同一组任务,若拾取,框架会抛异常
         */

        @Test
        public void test5() 
    {
            String taskId = "902";
            processEngine.getTaskService().claim(taskId , "财务二");
        }
    }

    候选人的组任务相对于个人任务来说,先进了一些,但是还不够灵活,虽然写了3个具体的人,但是一旦3个人中有人离职了,那么这个流程就不能正常运行了。于是,有个更加灵活的候选组的组任务。

    2.2、候选组的组任务(重点)


    示例代码如下:
    package com.itheima.activiti.grouptask;

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    import org.activiti.engine.ProcessEngine;
    import org.activiti.engine.ProcessEngines;
    import org.activiti.engine.identity.Group;
    import org.activiti.engine.identity.User;
    import org.activiti.engine.impl.persistence.entity.GroupEntity;
    import org.activiti.engine.impl.persistence.entity.UserEntity;
    import org.activiti.engine.repository.Deployment;
    import org.activiti.engine.repository.DeploymentBuilder;
    import org.activiti.engine.runtime.ProcessInstance;
    import org.activiti.engine.task.Task;
    import org.activiti.engine.task.TaskQuery;
    import org.junit.Test;

    /**
     * 组任务测试(候选组)
     * @author Bruce
     *
     */

    public class GroupTaskTest2 {
        // 获取默认流程引擎(全局变量)
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        /**
         * 部署流程定义
         */

        @Test
        public void test1() 
    {
            DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
            deploymentBuilder.addClasspathResource("com/itheima/activiti/grouptask/baoxiaoliucheng2.bpmn");
            deploymentBuilder.addClasspathResource("com/itheima/activiti/grouptask/baoxiaoliucheng2.png");
            deploymentBuilder.deploy();
        }

        /**
         * 创建组
         */

        @Test
        public void test2() 
    {
            Group group = new GroupEntity(); // 注意:后期框架act_id_group表与BOS项目的auth_role同步
            group.setId("财务组"); // 与流程图的一致
            group.setName("管理财务");
            processEngine.getIdentityService().saveGroup(group);
        }

        /**
         * 创建用户
         */

        @Test
        public void test3() 
    {
            User user = new UserEntity(); // 注意:后期框架act_id_user表与BOS项目的t_user同步
            user.setId("2");
            processEngine.getIdentityService().saveUser(user);
        }

        /**
         * 建立用户和组的关系
         */

        @Test
        public void test4() 
    {
            processEngine.getIdentityService().createMembership("2""财务组");
        }

        /**
         * 启动流程实例时设置流程变量
         */

        @Test
        public void test5() 
    {
            String processDefinitionKey = "baoxiaoliucheng"// 流程定义key
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("loginUser""晓艺");
            ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey, variables);
            System.out.println(pi.getId());
        }

        /**
         * 办理任务
         */

        @Test
        public void test6() 
    {
            String taskId = "1605";
            processEngine.getTaskService().complete(taskId);
        }

        /**
         * 查询组任务
         */

        @Test
        public void test7() 
    {
            TaskQuery query = processEngine.getTaskService().createTaskQuery();
            String candidateUser = "2";
            query.taskCandidateUser(candidateUser); // 使用候选人过滤,更实用直接,因为User是从session中取过来
            // query.taskCandidateGroup("财务组");  // 使用候选组过滤,Group是从角色中取过来,稍微麻烦些
            List<Task> list = query.list();
            for (Task task : list) {
                System.out.println(task.getId());
            }
        }

        /**
         * 拾取组任务,将组任务变为个人任务
         */

        @Test
        public void test8() 
    {
            String taskId = "1702";
            processEngine.getTaskService().claim(taskId , "1");
        }

        /**
         * 删除 所有部署流程定义数据(带级联删除)
         */

        @Test
        public void test9() 
    {
            List<Deployment> list = processEngine.getRepositoryService().createDeploymentQuery().list();
            for (Deployment deployment : list) {
                processEngine.getRepositoryService().deleteDeployment(deployment.getId(), true); 
            }
        }
    }

    3、排他网关的使用(常用)


    示例代码如下:
    package com.itheima.activiti.gateway;

    import java.util.HashMap;
    import java.util.Map;

    import org.activiti.engine.ProcessEngine;
    import org.activiti.engine.ProcessEngines;
    import org.activiti.engine.repository.DeploymentBuilder;
    import org.activiti.engine.runtime.ProcessInstance;
    import org.junit.Test;

    /**
     * 排他网关的测试
     * @author Bruce
     *
     */

    public class GatewayTest {
        // 获取默认流程引擎(全局变量)
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        /**
         * 部署流程定义
         */

        @Test
        public void test1() {
            DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
            deploymentBuilder.addClasspathResource("com/itheima/activiti/gateway/qingjialiucheng.bpmn");
            deploymentBuilder.addClasspathResource("com/itheima/activiti/gateway/qingjialiucheng.png");
            deploymentBuilder.deploy();
        }

        /**
         * 方式一:启动流程实例时设置流程变量
         */

        @Test
        public void test2() {
            String processDefinitionKey = "qingjialiucheng"// 流程定义id
            Map<String, Object> variables = new HashMap<>(); // 注意:第二个参数是一个HashMap集合
            // 设置流程变量
            variables.put("qjts"2);
            ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey, variables);
            System.out.println(processInstance.getId());
        }

        /**
         * 方式二:办理任务时设置流程变量
         */

        @Test
        public void test3() {
            String taskId = "2005"// 任务id
            Map<String, Object> variables = new HashMap<>(); // 注意:第二个参数是也一个HashMap集合
            // 设置流程变量
            variables.put("qjts"5);
            processEngine.getTaskService().complete(taskId, variables);
        }
    }

    4、spring 整合 activiti框架

    步骤一:读取(加载)spring配置文件,使用spring提供的流程引擎配置对象
    步骤二:提供数据源和事务管理器
    步骤三:使用spring提供的流程引擎工厂bean创建流程引擎对象
    示例代码如下:
    applicationContext.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" 
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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-2.5.xsd
                            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
    >

        <!-- 配置流程引擎配置对象 -->
        <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
            <!-- 注入数据源 -->
            <property name="dataSource" ref="dataSource"></property>
            <!-- 注入事务管理器对象 -->
            <property name="transactionManager" ref="transactionManager"></property>
            <!-- 开启自动建表 -->
            <property name="databaseSchemaUpdate" value="true"/>
        </bean>

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

        <!-- 注册一个数据源:暂时使用Spring框架提供的 (实际用的是c3p0)-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/activiti_day02"/>
            <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>
    </beans>

    步骤四:读取spring配置文件,创建spring工厂,从工厂中获得默认流程引擎对象

    package com.itheima.activiti.spring;

    import java.util.List;

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

    public class SpringActivitiTest {

        public static void main(String[] args) {
            // 读取(加载)spring配置文件,创建spring工厂
            ApplicationContext ctx = new ClassPathXmlApplicationContext("com\itheima\activiti\spring\applicationContext.xml");
            // 从工厂中获得默认流程引擎对象
            ProcessEngine processEngine = (ProcessEngine) ctx.getBean("processEngine");
            List<ProcessDefinition> list = processEngine.getRepositoryService().createProcessDefinitionQuery().list();
            for (ProcessDefinition processDefinition : list) {
                System.out.println(processDefinition);
            }
        }
    }

    5、将activiti框架应用到bos项目中

    5.1、查询流程定义

    第一步:添加jar包,修改Spring配置文件,测试整合是否成功,在UserAction中通过注解注入ProcessEngine,在登录的时候打印输出该对象,能打印出来,说明整合成功,否则失败。
    第二步:修改admin.json,加入工作流相关的菜单


    浏览器显示效果如下:

    第三步:在spring配置文件中配置activiti框架使用的Service

    第四步:提供ProcessDefinitionAction,使用注解注入RepositoryService,提供list()方法
    package com.itheima.bos.web.action;

    import java.util.List;

    import org.activiti.engine.ProcessEngine;
    import org.activiti.engine.RepositoryService;
    import org.activiti.engine.repository.ProcessDefinition;
    import org.activiti.engine.repository.ProcessDefinitionQuery;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;

    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;

    /**
     * 流程定义管理
     * @author Bruce
     *
     */

    @Controller
    @Scope("prototype")
    public class ProcessDefinitionAction extends ActionSupport // 我们不用去继承BaseAction<T>,因为我们没有合适的模型对象来对应

        // 注入流程引擎
        // @Autowired
        // private ProcessEngine processEngine; 

        // 注入Service
        @Autowired
        private RepositoryService repositoryService;
        /**
         * 查询最新版本的流程定义列表数据
         * @return
         */

        public String list() {
            // 创建流程定义查询对象
            // ProcessDefinitionQuery query = processEngine.getRepositoryService().createNativeProcessDefinitionQuery();
            // 我们发现,在Action中注入流程引擎后,每次使用都是通过流程引擎getXxxService,那么我们直接注入Service该多好啊!!!
            ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
            query.latestVersion(); // 查询最新版本的流程定义
            query.orderByProcessDefinitionName().desc(); // 根据流程定义名称降序
            List<ProcessDefinition> list = query.list(); // 执行查询,获得流程定义列表数据
            // 将流程定义列表数据压入值栈
            ActionContext.getContext().getValueStack().set("list", list); 
            return "list";
        }
    }

    第五步:配置struts.xml

        <!-- 流程定义管理:配置processDefinitionAction-->
        <action name="processDefinitionAction_*" class="processDefinitionAction" method="{1}">
            <result name="list">/WEB-INF/pages/workflow/processdefinition_list.jsp</result>
        </action>

    第六步:提供processdefinition_list.jsp页面,展示流程定义列表数据


    注意:上述流程列表页面使用的是jQuery easyUI 数据网格控件 datagrid,我们这里使用的是datagrid显示数据的方式一:将HTML代码渲染成datagrid样式,为什么呢?
    答:因为我们看到的代码<s:iterator>...</s:iterator>不是最终效果,因为jsp其实是一个类,是一个servlet,这句代码<s:iterator>...</s:iterator>实际上是运行在服务端的,在服务端计算出Html代码,计算完毕后,生成静态代码发回给浏览器进行显示。所以说,我们浏览器接收到的是静态的Html代码。
    浏览器显示效果:

    5.2、部署流程定义(即发布新流程)

    FreeMarke(模板引擎)简介:

    • 我们通常看到的购物网站,比如淘宝,我们看见的每一个页面的格式都差不多,怎么做的呢?
    • 答:使用模板技术。静态的模板 + 动态的数据 = html页面。所以我们在淘宝上看到的页面就是静态的,淘宝后台有商品发布系统。
    • 比如:一个商品上架会向数据库中插入一条数据,并在web服务器里面生成一个静态页面。
      • 参考链接:https://freemarker.apache.org/
    • 比如:我们使用的struts标签,其实也是模板,我们只需要给它动态的数据,它就可以形成静态的网页(html代码),浏览器一解析,就显示出来了。
      • 模板文件的后缀名为:xxx.ftl。

    第一步:提供部署流程定义页面
    文件位置:/bos19/WebContent/WEB-INF/pages/workflow/processdefinition_deploy.jsp

    <s:form action="processDefinitionAction_deploy" theme="simple" 
            method="post" enctype="multipart/form-data" id="uploadForm">

        <table class="table-edit" width="100%" >
            <tr class="title"><td colspan="2">发布新流程</td></tr>
            <tr>
                <td width="200">浏览流程定义的zip压缩文件</td>
                <td>
                    <input type="file" name="zipFile" />
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <a id="btn" href="javascript:$('#uploadForm').submit();" 
                       class="easyui-linkbutton" data-options="iconCls:'icon-save'">
    发布新流程</a>  
                </td>
            </tr>
        </table>
    </s:form>

    第二步:在ProcessDefinitionAction中提供deploy()方法,提供zipFile的属性和相应的set方法接收上传的文件

        // 提供zipFile的属性和相应的set方法接收上传的文件
        private File zipFile;
        public void setZipFile(File zipFile) {
            this.zipFile = zipFile;
        }

        /**
         * 部署流程定义(即发布新流程)
         * @return
         * @throws FileNotFoundException
         */

        public String deploy() throws FileNotFoundException {
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
            deploymentBuilder.addZipInputStream(new ZipInputStream(new FileInputStream(zipFile)));
            deploymentBuilder.deploy();
            return "toList";
        }

    第三步:配置struts.xml

        <!-- 流程定义管理:配置processDefinitionAction-->
        <action name="processDefinitionAction_*" class="processDefinitionAction" method="{1}">
            <result name="list">/WEB-INF/pages/workflow/processdefinition_list.jsp</result>
            <result name="toList" type="redirectAction"> <!-- 请求重定向 -->
                processDefinitionAction_list
            </result>
        </action>

    5.3、查看png图片

    第一步:修改jsp页面中弹出窗口的效果


    第二步:在Action中提供showpng()方法,提供id属性和对应的set方法,用于接收页面提交过来的参数:流程定义id
        /**
         * 展示png图片
         */

        public String showpng() {
            // 获取png图片对应的输入流(根据流程定义id获取)
            InputStream pngStream = repositoryService.getProcessDiagram(id);
            // 使用Struts框架提供的文件下载功能(文件下载结果集):通过输出流把服务端的资源写到客户端
            // 先把输入流压入值栈
            ActionContext.getContext().getValueStack().set("pngStream", pngStream);
            return "showpng";
        }

    第三步:配置struts.xml,配置struts文件下载结果集

        <!-- 流程定义管理:配置processDefinitionAction-->
        <action name="processDefinitionAction_*" class="processDefinitionAction" method="{1}">
            <result name="list">/WEB-INF/pages/workflow/processdefinition_list.jsp</result>
            <result name="toList" type="redirectAction"> <!-- 请求重定向 -->
                processDefinitionAction_list
            </result>
            <result name="showpng" type="stream">
                <param name="contentType">image/png</param>
                <param name="inputName">pngStream</param><!-- 输入流压栈时起的名字 -->
                <!-- 
                <param name="contentDisposition">attachment;filename="abc.png"</param>
                <param name="bufferSize">1024</param>
                 -->

            </result>
        </action>

    5.4、删除流程定义

    第一步:在jsp页面中提供删除按钮,指定onclick事件


    定义删除方法

    第二步:在Action中提供delete()方法
        /**
         * 删除流程定义(即删除流程部署定义)
         */

        public String delete() {
            String deltag = "0"// 设置删除标志
            // 根据流程定义id获取部署id
            ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery(); // 创建流程定义查询对象
            query.processDefinitionId(id); // 根据流程定义id过滤
            ProcessDefinition processDefinition = query.singleResult(); // 得到流程定义对象
            String deploymentId = processDefinition.getDeploymentId(); // 根据流程定义id获取部署id
            try {
                repositoryService.deleteDeployment(deploymentId);
            } catch (Exception e) {
                // 说明当前删除的流程定义正在使用
                deltag = "1";
                // 把删除标志位存进值栈,便于页面取出来判断
                ActionContext.getContext().getValueStack().set("deltag", deltag);

                // 重新查询最新版本的流程定义列表数据
                ProcessDefinitionQuery query2 = repositoryService.createProcessDefinitionQuery();
                query2.latestVersion(); // 查询最新版本的流程定义
                query2.orderByProcessDefinitionName().desc(); // 根据流程定义名称降序
                List<ProcessDefinition> list = query2.list(); // 执行查询,获得列表数据
                // 将列表数据压入值栈
                ActionContext.getContext().getValueStack().set("list"list); 
                return "list";
            }
            return "toList"// 正常删除,页面发生变化,需要请求重定向
        }

    第三步:在jsp页面中根据deltag标志位判断删除是否成功
    注意:下面的代码只能放到页面的最后面,不然会出现提示信息无法显示的问题,可能与js的加载顺序有关,之前我们写的代码放到了onload()里面,所以没有出现问题。

    <script type="text/javascript">
        // 获取服务器响应回来的删除标志位
        var deltag = '${deltag}';
        // alert(deltag);
        if (deltag == '1') {
            // 存在关联数据,不能删除
            $.messager.alert("提示信息","当前流程定义正在使用,不能删除!","warning");
        }
    </script>
  • 相关阅读:
    python 发送邮件
    java 获取两个时间之前所有的日期
    java 子线程定时去更改主线程的变量
    post 两种方式 application/x-www-form-urlencoded和multipart/form-data
    aws 社交媒体技术大会 部分总结
    java操作Mongodb数据库
    实体类注解 @entity
    spring security 部分注解讲解
    @Column
    阿里云搭建服务器
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9802903.html
Copyright © 2020-2023  润新知