關(guān)于Activiti工作流使用

什么是Activiti?

Activiti5是由Alfresco軟件在2010年5月17日發(fā)布的業(yè)務流程管理(BPM)框架,它是覆蓋了業(yè)務流程管理、工作流、服務協(xié)作等領(lǐng)域的一個開源的、靈活的、易擴展的可執(zhí)行流程語言框架。Activiti基于Apache許可的開源BPM平臺,創(chuàng)始人Tom Baeyens是JBoss jBPM的項目架構(gòu)師,它特色是提供了eclipse插件,開發(fā)人員可以通過插件直接繪畫出業(yè)務流程圖。本文采用activiti5.22版本。數(shù)據(jù)庫是ORACLE11g

1.Activiti數(shù)據(jù)庫結(jié)構(gòu)

1)通過運行activiti官方提供的數(shù)據(jù)庫腳本創(chuàng)建數(shù)據(jù)庫,支持db2、h2、hsql、mssql、mysql、oracle、postgres數(shù)據(jù)庫
image.png

1、act_ge_ 通用數(shù)據(jù)表,ge是general的縮寫
2、act_hi_ 歷史數(shù)據(jù)表,hi是history的縮寫,對應HistoryService接口
3、act_id_ 身份數(shù)據(jù)表,id是identity的縮寫,對應IdentityService接口
4、act_re_ 流程存儲表,re是repository的縮寫,對應RepositoryService接口,存儲流程部署和流程定義等靜態(tài)數(shù)據(jù)
5、act_ru_ 運行時數(shù)據(jù)表,ru是runtime的縮寫,對應RuntimeService接口

2.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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 name="transactionManager" ref="transactionManager"/>
        <property name="databaseSchemaUpdate" value="true"/>
        <property name="jobExecutorActivate" value="false"/>
    </bean>

    <!-- 定義流程引擎 -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
    </bean>

    <!-- 定義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="historyService" factory-bean="processEngine"
          factory-method="getHistoryService"/>
    <bean id="managementService" factory-bean="processEngine"
          factory-method="getManagementService"/>
    <bean id="identityService" factory-bean="processEngine"
          factory-method="getIdentityService"/>
    <bean id="formService" factory-bean="processEngine"
          factory-method="getFormService"></bean>

</beans>

七大接口:

1.RepositoryService:提供一系列管理流程部署和流程定義的API。
2.RuntimeService:在流程運行時對流程實例進行管理與控制。
3.TaskService:對流程任務進行管理,例如任務提醒、任務完成和創(chuàng)建任務等。
4.IdentityService:提供對流程角色數(shù)據(jù)進行管理的API,這些角色數(shù)據(jù)包括用戶組、用戶及它們之間的關(guān)系。
5.ManagementService:提供對流程引擎進行管理和維護的服務。
6.HistoryService:對流程的歷史數(shù)據(jù)進行操作,包括查詢、刪除這些歷史數(shù)據(jù)。
7.FormService:表單服務。

3.activiti-webapp-explorer2整合

1)將模板導入項目中

explorer整合實現(xiàn)在線編輯工作流
將src目錄下diagram-viewer,editor-app,modeler.html 復制到自己項目中,如下圖,本文是復制到webapp下


image.png

image.png
2)配置全局路徑

配置前段訪問路徑,否則activiti編輯器會無法訪問

image.png
/*
 * Activiti Modeler component part of the Activiti project
 * Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
'use strict';

var ACTIVITI = ACTIVITI || {};

ACTIVITI.CONFIG = {
    'contextRoot' : '/',#配置全文訪問路徑
};
3)后臺配置

1.配置后臺,頁面訪問接口配置,activti提供了基本的頁面獲取、流程保存、流程編輯等接口,用于工作流的在線演示與編輯。


image.png

2.將stencilset.json賦值到配置文件目錄下,保證StencilsetRestResource能訪問到,這是流程設(shè)計器的菜單和功能文件,保存為json格式。


image.png

4.后臺實例代碼

1)創(chuàng)建流程
/**
     * 創(chuàng)建流程
     */
    @RequestMapping("/createActiviti")
    public void createActiviti(HttpServletRequest request,HttpServletResponse response) throws IOException{
        Model model = repositoryService.newModel();

        String name = "新建流程";
        String description = "";
        int revision = 1;
        String key = "processKey";

        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
        modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
        modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);

        model.setName(name);
        model.setKey(key);
        model.setMetaInfo(modelNode.toString());

        repositoryService.saveModel(model);
        String id = model.getId();

        //完善ModelEditorSource
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace",
                "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
//        return "redirect:/modeler.html?modelId=" + id;
        response.sendRedirect(request.getContextPath() + "/modeler.html?modelId="+id);
    }
2)更新流程
    /**
     * 更新流程
     */
    @RequestMapping("/updateActiviti")
    public void updateActiviti(String id,HttpServletRequest request,HttpServletResponse response) throws IOException{
        response.sendRedirect(request.getContextPath() + "/modeler.html?modelId="+id);
    }
3)發(fā)布流程
      /**
     * 發(fā)布
     */
    @PostMapping("/publish")
    @ResponseBody
    public Object publish(@RequestParam(value="id")String id){
        Result result=new Result();
        try {
            Model modelData=repositoryService.getModel(id);
            byte[] bytes=repositoryService.getModelEditorSource(modelData.getId());
            if(bytes==null){
                result.setMsg("模型不得為空");
                result.setSuccess(false);
                return result;
            }
            JsonNode modelNode=null;
            modelNode=new ObjectMapper().readTree(bytes);
            BpmnModel model=new BpmnJsonConverter().convertToBpmnModel(modelNode);
            if(model.getProcesses().size()==0){
                result.setMsg("數(shù)據(jù)不符合要求");
                result.setSuccess(false);
                return result;
            }
            byte[] bpmnByates = new BpmnXMLConverter().convertToXML(model);
            //發(fā)布流程
            String processName=modelData.getName()+".bpmn20.xml";
            String convertToXML=new String(bpmnByates);
            System.out.println(convertToXML);
            Deployment deployment=repositoryService.createDeployment()
                    .name(modelData.getName())
                    .addString(processName, new String(bpmnByates, "UTF-8"))
                    .deploy();
            modelData.setDeploymentId(deployment.getId());
            repositoryService.saveModel(modelData);
            result.setMsg("發(fā)布成功");
            result.setSuccess(true);
        } catch (Exception e) {
            result.setMsg("發(fā)布失敗");
            result.setSuccess(false);
        }
        return result;
    }
3)流程查詢
    /**
     * 流程查詢
     */
    @PostMapping("/deployDatagrid")
    @ResponseBody
    public Object deployDatagrid(String s_name, HttpServletResponse response,Integer page, Integer rows, String sort, String order){
        PageInfo pageInfo = new PageInfo(page, rows, sort, order);
        if(StringUtils.isBlank(s_name)){
            s_name="";
        }
        int p1=page-1;
        int r1=9-p1;
        List<Deployment> deploymentList=repositoryService.createDeploymentQuery()
                .deploymentNameLike("%" + s_name + "%").orderByDeploymenTime().desc()
                .listPage(p1, r1);
        long total=repositoryService.createDeploymentQuery().deploymentNameLike("%"+s_name+"%").count();
        List<com.pasic.model.po.DeploymentEntity> deploymentList2=new ArrayList<com.pasic.model.po.DeploymentEntity>();
        for (Deployment deployment : deploymentList) {
            com.pasic.model.po.DeploymentEntity depm=new com.pasic.model.po.DeploymentEntity(deployment.getId(),deployment.getName(),deployment.getCategory(),deployment.getTenantId(),deployment.getDeploymentTime());
            deploymentList2.add(depm);
        }

        System.out.println(deploymentList2);
        pageInfo.setRows(deploymentList2);
        pageInfo.setTotal((int)total);
        if(total/rows==0){
            pageInfo.setPagesize(0);
        }else{
            pageInfo.setPagesize(page++);
        }
        
        pageInfo.setNowpage(page);
        pageInfo.setSize(rows);
        pageInfo.setSuccess(true);
        pageInfo.setMessage("列表獲取成功");
        return pageInfo;
    }
4)刪除流程
    /**
     * 刪除流程
     */
    @PostMapping("/deleteDeploy")
    @ResponseBody
    public Object deleteDeploy(@RequestParam(value="id")String id){
        Result result=new Result();
        try {
            //加true強制刪除
            repositoryService.deleteDeployment(id,true);
            result.setSuccess(true);
            result.setMsg("刪除成功");
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMsg("刪除失敗");
        }
        return result;
    }
5)查看流程圖片

1.后臺

    /**
     * 查看流程圖 圖片
     */
    @GetMapping("/showProcessPng")
    public String showProcessPng(@RequestParam(value="deployId")String deployId,org.springframework.ui.Model model){
        
//      model.addAttribute("diagramResourceName", processDefinition.getDiagramResourceName());
        model.addAttribute("deployId", deployId);
        return "activiti/deploy/showProcessPng";
    }
    
    @RequestMapping("/showView")
    public String showView(String deploymentId, HttpServletResponse response)
            throws Exception {
        ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery()
                   .deploymentId(deploymentId)
                   .singleResult();
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
        OutputStream outputStream = response.getOutputStream();
        for (int b = -1; (b = inputStream.read()) != -1; ) {
            outputStream.write(b);
        }
        outputStream.close();
        inputStream.close();
        return null;
    }

2.前臺

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/commons/global.jsp" %>
<script>
</script>
<div class="bootui-layout" data-options="fit:true,border:false">
    <div data-options="region:'center',fit:true,border:false">
        <img style="position:absolute;top:0px;left:0px" src="${path }/act/showView?deploymentId=${deployId}">
    </div>
</div>
6)將用戶同步到activiti認證表中
    /**
     * 同步用戶到activiti中
     */
    @PostMapping("/syncdata")
    @ResponseBody
    public Object syncdata(){
        Result result=new Result();
        try {
            Wrapper<SysUser> wrapper=new EntityWrapper<SysUser>();
            List<SysUser> userList=userService.selectList(wrapper);
            User au = null;
            for (SysUser user : userList) {
                au=new UserEntity();
                au.setId(user.getId());
                au.setFirstName(user.getName());
                au.setEmail("");
                identityService.deleteUser(au.getId());
                identityService.saveUser(au);
            }
            Wrapper<SysRole> wrapper2=new EntityWrapper<SysRole>();
            List<SysRole> sysRoleList=roleService.selectList(wrapper2);
            Group group=null;
            for (SysRole role : sysRoleList) {
                group=new GroupEntity();
                group.setId(role.getId());
                group.setName(role.getName());
                identityService.deleteGroup(group.getId());
                identityService.saveGroup(group);
            }
            Wrapper<SysUserRole> wrapper3=new EntityWrapper<SysUserRole>();
            List<SysUserRole> roleUserList=userRoleService.selectList(wrapper3);
            for (SysUserRole userRole : roleUserList) {
                identityService.deleteMembership(userRole.getUserId(), userRole.getRoleId());
                identityService.createMembership(userRole.getUserId(), userRole.getRoleId());
            }
            result.setMsg("同步成功");
            result.setSuccess(true);
        } catch (Exception e) {
            result.setMsg("同步失敗");
            result.setSuccess(false);
        }
        return result;
    }

*****整合完成后效果

image.png

image.png

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容