IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot 集成Activiti 实现Model(模型)管理 -> 正文阅读

[Java知识库]SpringBoot 集成Activiti 实现Model(模型)管理

Activiti 之Model 模型管理需求:

实现Model 检索、新增、编辑、删除、导出和部署功能。

Activiti 之Model 模型管理页面操作:

Model 首页:

Model 检索:

Model 新增:

?Model 编辑:

简单设计转正流程,记得点击保存按钮。

?Model 导出:

?

Model 删除:?

5001 流程模型已经被删除。

?Model 部署:?

功能说明:依据流程模型定义发起一次流程实例,由于该功能涉及用户和用户组设置、表单设计。这里仅仅实现在控制台后端输出流程实例Id。

选择模型定义,点击部署:

请教流程实例Id输出:

SpringBoot 之Activiti Model 模型管理后台

SpringBoot程序入口排除Activiti自带SpringSecurity 安全框架校验

package com.zzg;

import org.activiti.spring.boot.SecurityAutoConfiguration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(exclude={SecurityAutoConfiguration.class})
@MapperScan("com.zzg.mapper")
public class OAApplication {
    public static void main(String[] args) {
        SpringApplication.run(OAApplication.class, args);
    }
}

SpringBoot 引入前端开发框架LayUI

在layUI 开源网站中,下载LayUI。下载地址:Layui - 经典开源模块化前端 UI 框架

在本项目的resource/static文件夹中,引入layui 框架。

SpringBoot 配置SpringMVC 资源路径映射

package com.zzg.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class SpringMVCConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");super.addResourceHandlers(registry);
    }
}

SpringBoot 添加流程模型控制器(ModelController

package com.zzg.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.zzg.common.vo.PageList;
import com.zzg.common.vo.Resp;
import com.zzg.common.vo.enums.CodeMsgEnum;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ModelQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RequestMapping("/model")
@RestController
public class ModelController {
    private static Logger logger= LoggerFactory.getLogger(ActivitiController.class);

    /**
     * 流程存储服务
     */
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 模型默认首页
     * @return
     */
    @GetMapping("/index")
    public ModelAndView index() {
        return new ModelAndView("redirect:/model.html");
    }

    /**
     * 模型分页查询
     * @param request
     * @return
     */
    @GetMapping("/page")
    public PageList getModels(HttpServletRequest request){
        String pageParame = request.getParameter("page");
        String sizeParame = request.getParameter("size");
        String modelName = request.getParameter("name");
        Integer page = StringUtils.isNotEmpty(pageParame) ? Integer.valueOf(pageParame) : 1;
        Integer size = StringUtils.isNotEmpty(sizeParame) ? Integer.valueOf(sizeParame) : 10;

        // 获取模型查询实例
        ModelQuery modelQuery = repositoryService.createModelQuery();
        // 根据模型名称模糊查询
        Integer total;
        List<Model> models;

        if (StringUtils.isNotEmpty(modelName)) {
            // 获取模型总数
            total = (int) modelQuery.modelNameLike("%" + modelName + "%").count();
            // 获取列表数据
            models = modelQuery
                    .modelNameLike("%" + modelName + "%")
                    .orderByLastUpdateTime()
                    .desc()
                    .listPage((page - 1) * size, size);
        } else {
            // 获取模型总数
            total = (int) modelQuery.count();
            // 获取列表数据
            models = modelQuery
                    .orderByLastUpdateTime()
                    .desc()
                    .listPage((page - 1) * size, size);
        }
        //封装到pageList对象中
        PageList pageList = new PageList(page,total, size);
        pageList.setList(models);

        return pageList;
    }

    /**
     * 模型删除
     * @param request
     */
    @GetMapping("/delete")
    public Resp<String> delete(HttpServletRequest request){
        String processId = request.getParameter("processId");
        System.out.println("processId is:" + processId);
//        if(StringUtils.isNotEmpty(processId)){
//            return Resp.ERROR(CodeMsgEnum.ERROR);
//        }
        Model model = repositoryService.getModel(processId);
        if(model!=null){
            System.out.println("指定模型存在");
            repositoryService.deleteModel(processId);
        }
        return Resp.OK_WITHOUT_DATA();
    }

    /**
     * 新增模型
     * @param map
     * @return
     * @throws UnsupportedEncodingException
     */
    @PostMapping(value = "/insert", produces = "application/json;charset=utf-8")
    public Resp<String> insert(@RequestBody Map map) throws UnsupportedEncodingException {
        System.out.println("model 参数接受:" + map);
        //初始化一个空模型
        Model model = repositoryService.newModel();

        //设置一些默认信息,可以用参数接收
        int revision = 1;
        String key = String.valueOf(map.get("processKey"));
        String name =String.valueOf(map.get("processName"));;
        String description = String.valueOf(map.get("processDesc"));

        //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);


        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();

        repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
        // return new ModelAndView("redirect:/modeler.html?modelId=" + id);
        return Resp.OK(id);

    }

    /**
     * 根据Model部署流程
     */
    @PostMapping(value = "deploy/{modelId}")
    public Resp<String> deploy(@PathVariable("modelId") String modelId) {
        try {
            // 获取模型
            Model model = repositoryService.getModel(modelId);
            ObjectNode objectNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(model.getId()));
            BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(objectNode);

            String processName = model.getName()+".bpmn20.xml";
            byte[] bytes = new BpmnXMLConverter().convertToXML(bpmnModel);
            // 部署流程
            Deployment deployment = repositoryService
                    .createDeployment().name(model.getName())
                    .addString(processName, new String(bytes,"UTF-8"))
                    .deploy();
            System.out.println("流程部署id----"+deployment.getId());
            return Resp.OK(deployment.getId());
        } catch (Exception e) {
            logger.error("根据模型部署流程失败:modelId={}", modelId, e);
            return Resp.ERROR(CodeMsgEnum.ERROR);
        }
    }

    /**
     * 导出指定模型xml 文件
     * @param modelId
     * @param response
     */
    @GetMapping(value = "export/{modelId}")
    public void export(@PathVariable String modelId, HttpServletResponse response) {
        try {
            Model modelData = repositoryService.getModel(modelId);
            BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
            JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
            BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
            byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel);

            ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes);
            OutputStream outputStream = response.getOutputStream();
            IOUtils.copy(in, outputStream);
            String filename = bpmnModel.getMainProcess().getId() + ".bpmn.xml";
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            logger.error("导出model的xml文件失败:{}", e.getMessage(), e);
        }
    }


}

SpringBoot 添加流程模型管理页面

在项目中的resource/static文件夹中添加流程模型管理页面(model.html)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>**系统 - Layui</title>
    <link rel="stylesheet" href="layui/css/layui.css">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
    <div class="layui-header">
        <div class="layui-logo">** 系统</div>
        <ul class="layui-nav layui-layout-right">
            <li class="layui-nav-item"><a href="javascript:;"> 超级管理员 </a>
                <dl class="layui-nav-child">
                    <dd>
                        <a href="">基本资料</a>
                    </dd>
                    <dd>
                        <a href="">安全设置</a>
                    </dd>
                </dl></li>
            <li class="layui-nav-item"><a href="">退了</a></li>
        </ul>
    </div>

    <div class="layui-side layui-bg-black">
        <div class="layui-side-scroll">
            <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
            <ul class="layui-nav layui-nav-tree" lay-filter="test">
                <li class="layui-nav-item layui-nav-itemed"><a class=""
                                                               href="javascript:;">流程管理</a>
                    <dl class="layui-nav-child">
                        <dd>
                            <a href="javascript:;">流程定义</a>
                        </dd>
                        <dd>
                            <a href="javascript:;">表单定义</a>
                        </dd>

                    </dl></li>
                <li class="layui-nav-item"><a href="javascript:;">用户管理</a>
                    <dl class="layui-nav-child">
                        <dd>
                            <a href="javascript:;">查询用户</a>
                        </dd>
                        <dd>
                            <a href="javascript:;">新增用户</a>
                        </dd>
                    </dl></li>
                <li class="layui-nav-item"><a href="javascript:;">借阅信息</a>
                    <dl class="layui-nav-child">
                        <dd>
                            <a href="javascript:;">所有记录</a>
                        </dd>
                        <dd>
                            <a href="javascript:;">个人记录</a>
                        </dd>
                    </dl></li>
                <li class="layui-nav-item"><a href="">帮助</a></li>
            </ul>
        </div>
    </div>

    <div class="layui-body">
        <!-- 内容主体区域 -->
        <div style="padding: 15px;">

            <div class="demoTable">
                流程名称:
                <div class="layui-inline">
                    <input class="layui-input" name="id" id="demoReload" autocomplete="off">
                </div>
                <button class="layui-btn" data-type="reload">搜索</button>
                <button class="layui-btn" data-type="add">新增</button>

            </div>


            <table id="tb-book" lay-filter="tb-book"></table>

            <script type="text/html" id="barDemo">
                <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
                <a class="layui-btn layui-btn-xs" lay-event="deploy">部署</a>
                <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
                <a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="export">导出</a>
            </script>

            <!--    编辑弹出层-->
            <script type="text/html" id="edit_form">
                <div class="layui-col-md10" style="margin-left: 35px;margin-top: 20px">
                    <form class="layui-form layui-form-pane" lay-filter="edit_form" action="">
                        <div class="layui-form-item">
                            <label class="layui-form-label">流程Key</label>
                            <div class="layui-input-block">
                                <input type="text" name="processKey" required  lay-verify="required" placeholder="请输入流程Key"
                                       autocomplete="off" class="layui-input">
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">流程名称</label>
                            <div class="layui-input-block">
                                <input type="text" name="processName" required  lay-verify="required" placeholder="请输入流程Key"
                                       autocomplete="off" class="layui-input">
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">流程描述</label>
                            <div class="layui-input-block">
                                <input type="text" name="processDesc" required  lay-verify="required" placeholder="请输入流程Key"
                                       autocomplete="off" class="layui-input">
                            </div>
                        </div>
                        <div class="layui-form-item" style="margin-top: 20px">
                            <div class="layui-input-block">
                                <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
                                <button type="reset" class="layui-btn layui-btn-primary">重置</button>
                            </div>
                        </div>

                    </form>

                </div>
            </script>

        </div>
    </div>

    <div class="layui-footer">
        <!-- 底部固定区域 -->
        ? layui.com - **系统
    </div>


</div>
<script src="layui/layui.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>


<script>
	layui.use(['element','table', 'form'], function(){
  	  	element = layui.element;
  	  	table = layui.table;
  	  	form = layui.form;

  	  	//第一个实例
  table.render({
    elem: '#tb-book'
    ,height: 312
    ,url: 'http://localhost:8080/model/page'
    ,where: {page: '1', size: '10'}
    ,page: true //开启分页
    ,cols: [[ //表头
      {field: 'id', title: 'ID', sort: true, fixed: 'left'}
      ,{field: 'name', title: '流程名称', }
      ,{field: 'key', title: '流程Key', }
      ,{field: 'category', title: '流程分类', }
      ,{field: 'createTime', title: '创建时间', }
      ,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:260}
    ]]
    ,parseData: function (res) { //将原始数据解析成 table 组件所规定的数据
        console.log(res)
                return {
                    "code": 0, //解析接口状态
                    "count": res.totalData, //解析数据长度
                    "data": res.list //解析数据列表
                };
     }
  });

     // 表格数据重载
    var $ = layui.$, active = {
    reload: function(){
      var demoReload = $('#demoReload');
      console.log('----'+ demoReload.val())
      //执行重载
      table.reload('tb-book', {
        page: {
          curr: 1 //重新从第 1 页开始
        }
        ,where: {
            name: demoReload.val()
        }
      });
    },
    add: function(){
         layer.open({
                type: 1,
                title: '新增流程',
                area: ['420px', '330px'],
                content: $('#edit_form').html()
            });

             form.on('submit(formDemo)',function(messge){
                 console.log(messge);
                 var str={
                                "processDesc":messge.field.processDesc,
                                "processKey":messge.field.processKey,
                                "processName":messge.field.processName
                          };
                    $.ajax({
                            url:"http://localhost:8080/model/insert",
                            type:"POST",
                            contentType: "application/json; charset=utf-8",
                            dataType: "json",
                            data: JSON.stringify(str),
                            success:function (msg) {
                                console.log("成功消息:" + msg);
                                if (msg.code === 200) {
                                    layer.msg("新增成功", {icon: 6});
                                  	layer.closeAll();
                                    // 跳转至流程设计界面
                                     window.location.href ="http://localhost:8080/modeler.html?modelId=" + msg.data
                                } else {
                                    layer.msg("新增失败", {icon: 5});
                                }
                            }
                        })
                        return false;//阻止表单跳转,网页url不显示提交的参数。
                    })

    }
  };

  $('.demoTable .layui-btn').on('click', function(){
    var type = $(this).data('type');
    active[type] ? active[type].call(this) : '';
  });


  //监听工具条
  table.on('tool(tb-book)', function(obj){
    console.log(obj);
    var data = obj.data;
    if(obj.event === 'deploy') {

                    $.ajax({
                            url:"http://localhost:8080/model/deploy/" + data.id,
                            type:"POST",
                            success:function (msg) {
                                console.log(msg);
                                // var returnCode = msg.returnValue//取得返回数据(Sting类型的字符串)的信息进行取值判断
                                if (msg.code === 200) {
                                    //layer.closeAll('loading');
                                    //layer.load(2);
                                    layer.msg("模型部署成功:" + msg.data, {icon: 6});
                                  	layer.closeAll();
                                    // 加载层 - 风格
                                } else {
                                    layer.msg("模型部署失败", {icon: 5});
                                }
                            }
                        })


    } else if(obj.event === 'del'){
      layer.confirm('真的删除行么', function(index){
        obj.del();
        layer.close(index);
        console.log('id is:', data.id)
         $.ajax({
                            url:"http://localhost:8080/model/delete?processId="+data.id,
                            success:function (msg) {
                                console.log(msg);
                                // var returnCode = msg.returnValue//取得返回数据(Sting类型的字符串)的信息进行取值判断
                                if (msg) {
                                    //layer.closeAll('loading');
                                    //layer.load(2);
                                    layer.msg("修改成功", {icon: 6});
                                  	layer.closeAll();
                                    // 加载层 - 风格
                                } else {
                                    layer.msg("新增失败", {icon: 5});
                                }
                            }
                        })

      });
    } else if(obj.event === 'edit'){
      console.log("点击编辑")
      window.location.href ="http://localhost:8080/modeler.html?modelId=" + data.id

    } else if(obj.event ==='export'){
      console.log("点击导出")
      window.location.href ="http://localhost:8080/model/export/" + data.id
    }


  });

	});
</script>
</body>
</html>

?GitHub地址:https://github.com/zhouzhiwengang/SpringBoot-Project.git

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:20:26  更:2022-05-12 16:20:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:14:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码