小工具知识网

当前位置: 首页 > 行业知识 > Vue+LogicFlow+Flowable 前端+后端实现工作流

行业知识

Vue+LogicFlow+Flowable 前端+后端实现工作流

2026-11-15 01:52:17 来源:互联网转载

一、实现效果

前���使用LogicFlow框架绘制流程图,可以导出为xml工作流标准格式数据,通过xml文件传递到后端进行Flowable流程注册,并保存到数据库中。

二、BPM传输文件格式(.xml)

如需添加承办人的话,需要在LogicFlow导出文件的基础上手动添加xmlns:flowable="http://flowable.org/bpmn"flowable插件,不然后台无法识别flowable:candidateUsers。

            Flow_a3e7d0c              Flow_a3e7d0c      Flow_3f9a386              Flow_3f9a386                                                                                                                                                                                                                                                                                            

三、前端框架(LogicFlow)

  1. LogicFlow.vue
                        保存            清空            加载            删除            获取定义流程            工作流实例    import LogicFlow from '@logicflow/core'import '@logicflow/core/dist/style/index.css'import { BpmnElement, BpmnXmlAdapter, Menu } from '@logicflow/extension'import '@logicflow/extension/lib/style/index.css'import BpmnNodePanel from "./BpmnNodePanel.vue"import { addFlow, infoFlow, deleteFlow, getDeployList, flowRun } from "../api/server"import { addFlowable, addProp, getTypeNameByTag, setValueByTag } from '../utils/xml'export default {    data() {        return {            lf: void 0,            xmlData: void 0,            definitionsId: void 0,            processId: void 0,        }    },    components: { BpmnNodePanel },    created() {},    mounted() {        this.loadFlow()    },    methods: {        loadFlow() {            LogicFlow.use(BpmnElement)            LogicFlow.use(BpmnXmlAdapter)            LogicFlow.use(Menu)            //初始化            this.lf = new LogicFlow({                container: this.$refs.container,                stopScrollGraph: true,                stopZoomGraph: true,                grid: false,                keyboard: {                    enabled: true,                },            });            // this.lf.setDefaultEdgeType('bezier')            this.lf.render();        },        // 保存        saveNode() {             // 获取xml数据            this.xmlData = this.lf.getGraphData();            // 添加flowable扩展            this.xmlData = addFlowable(this.xmlData)            // 判断是否为文档编辑            if (this.processId) {                // 修改为原流程id                this.xmlData = setValueByTag(this.xmlData, 'bpmn:definitions', 'id', this.definitionsId)                this.xmlData = setValueByTag(this.xmlData, 'bpmn:process', 'id', this.processId)            } else {                 // 添加节点用户 个人assignee  候选人candidateUsers 候选组候选人candidateGroups 动态设置${employee}                // this.xmlData = addProp(this.xmlData, 'bpmn:startEvent', 'flowable:candidateUsers', 'zhao,qian,sun')                this.xmlData = addProp(this.xmlData, 'bpmn:userTask', 'flowable:candidateUsers', 'li,zhou,wang')            }            const data = {                name: '测试流程',                xml: this.xmlData            }                        // 请求后台接口(添加工作流)            addFlow(data)                .then(res => {                    console.log(res)                })                .catch(err => {                    console.log(err)                })        },        // 清除        cleanNode() {            this.lf.clearData()        },        // 重新加载        reloadNode() {            // 查询数据            const data = {                id: 'ff292b5d-4193-11ee-8e48-502b73dc5fce',                name: '测试流程'            }            infoFlow(data)                .then(res => {                    if (res.result) {                        // 获取processId                        const definitionsNodes = getTypeNameByTag(res.result, 'bpmn:definitions')                        const processNodes = getTypeNameByTag(res.result, 'bpmn:process')                        this.definitionsId = definitionsNodes.id                        this.processId = processNodes.id                        // 渲染数据                        this.lf.render(res.result);                    }                    console.log(res)                })                .catch(err => {                    console.log(err)                })        },        // 删除数据        deleteNode() {             // 查询数据            const data = {                id: ''            }            deleteFlow(data)                .then(res => {                    console.log(res)                })                .catch(err => {                    console.log(err)                })        },         // 获取数据        getList() {             getDeployList()                .then(res => {                    console.log(res)                })                .catch(err => {                    console.log(err)                })        },        // 流程实例        flowRun() {             flowRun()                .then(res => {                    console.log(res)                })                .catch(err => {                    console.log(err)                })        },    },}.container{    width: 100%;    height: 100%;}.node-item {  position: absolute;  top: 350px;  left: 10px;  width: 50px;  padding: 10px;  background-color: white;  box-shadow: 0 0 10px 1px rgb(228, 224, 219);  border-radius: 6px;  text-align: center;  z-index: 101;}.node-item-icon {  width: 30px;  height: 30px;  margin-left: 10px;  background-size: cover;}.node-label {  font-size: 12px;  margin-top: 5px;  user-select: none;}.bpmn-save {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC)    center center no-repeat;  cursor: grab;}

2.BpmnNodePanel.vue

                      开始节点                    普通节点                            结束节点      import LogicFlow from '@logicflow/core';export default {  name: "BpmnNodePanel",  data() {    return {}  },  props: {    lf: Object,  },  mounted() {    //选区框选使用的    let lf = this.$props.lf    lf &&      lf.on("selection:selected", () => {          lf.updateEditConfig({          stopMoveGraph: false,        });      });  },  methods: {    openSelection() {      (this.$props.lf).updateEditConfig({        stopMoveGraph: true      });    },    addStartNode() {      (this.$props.lf).dnd.startDrag({        type: "bpmn:startEvent",        text: "开始节点",      });    },    addUserTask() {      (this.$props.lf).dnd.startDrag({        type: "bpmn:userTask",        text: "普通节点",       });    },    addServiceTask() {      (this.$props.lf).dnd.startDrag({        type: "bpmn:serviceTask",        text: "系统",      });    },    addGateWay() {      (this.$props.lf).dnd.startDrag({        type: "bpmn:exclusiveGateway",        text: "判断",      });    },    addEndNode() {      (this.$props.lf).dnd.startDrag({        type: "bpmn:endEvent",        text: "结束节点",      });    },  },};.node-panel {  position: absolute;  top: 100px;  left: 10px;  width: 50px;  padding: 10px;  background-color: white;  box-shadow: 0 0 10px 1px rgb(228, 224, 219);  border-radius: 6px;  text-align: center;  z-index: 101;}.node-item {  margin-bottom: 10px;}.node-item-icon {  width: 30px;  height: 30px;  margin-left: 10px;  background-size: cover;}.node-label {  font-size: 12px;  margin-top: 5px;  user-select: none;}.bpmn-selection {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=)    center center no-repeat;  cursor: grab;}.bpmn-start {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==)    center center no-repeat;  cursor: grab;}.bpmn-end {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC)    center center no-repeat;  cursor: grab;}.bpmn-user {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==)    center center no-repeat;  cursor: grab;}.bpmn-gateway {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII=)    center center no-repeat;  cursor: grab;}.bpmn-service {  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAYAAADgKtSgAAAAAXNSR0IArs4c6QAAAm9JREFUSEu1lTFo1GAUx38vZ6sOooIoVsWKk23SCp1UkIrg0EHs0M5OOolY9NJz6XXpNaeidOhQB3G1oCLUTXRxK9pe7lykk7YKhdJZuDzJXXMkaXKpBd+Y7//93sv/ve/7hP8YshO2WdKiGPQ0tMpvVTaqBSlm7f0X+EQAU4/JXcNNR5/jsRoATEcnBFqVKhSrtkz6ycySDkqOKTcvF+N/sq1yy9FXwEjDAY9JMRgDDiRYsIJQQHkGdAE11xYzrIvAw+AsP1PW511bRoO1KLysIyh+5ckhfEK5AOxNEig8rNpSSoT7H62yfkQZjGxWCl4nc7Ux2egu6r6D+xnyYBY41q7JkcrPPdXje/6wFga7tqROlOXoMtAX6OPaxkazrNekTpdCtxi0Rg7htpuXuTSXrJIOYLAYrh6DH/5ZqI7LQgNuOboADMUhRgcnl8dktV1zrbIuogzENOuuLUcDeGv8WiKh4ualP2tqrGmdQbiTDk8WbLq2HM6EO/oGuBHTfXFtGWh67t8dOU6jnAKuhoTDri1v0xKcL2l33eArcGhL8wHhFx4/3XEpRCahd1r7DWEpNKdLRidXlu7JZlICq6wvUG4Ga16O3tp9+ZY656aj6wJHQrD3Rge34o21HH0CjashiPbHv/ex9hh1atuqFCpAVet8J8cZUU7E7GtuEUbdvMwnVm45qlkNzFwPJYh4bpZ0WAxehm7BFeBsG2B0vV3ljQM1rZcR5gRmKrbM9jl6HcgrXAr97megXLHlnRVcdjFw06WEMB9pX/WB+D43YuuZS32J/ARhr1OnJTFZ8w29C9SBNfV4vetnLrNpOxT8BWh07BjujplpAAAAAElFTkSuQmCC)    center center no-repeat;  cursor: grab;}

3.xml.js

/** * 添加flowable扩展 * @param {*} xmlstr  * @returns  */export function addFlowable(xmlstr) {    const part1 = xmlstr.slice(0, 43); // 从开头到指定位置之前的部分    const part2 = xmlstr.slice(43); // 从指定位置到末尾的部分    const newString = part1 + 'xmlns:flowable="http://flowable.org/bpmn" ' + part2; // 拼接成新的字符串        return newString}/** * 添加属性信息 * @param {*} xmlstr  * @returns  */export function addProp(xmlstr, Elements, key, value) {    // 创建一个XML文档对象    const parser = new DOMParser();    const xmlDoc = parser.parseFromString(xmlstr, 'application/xml');    // 查找元素    const userTaskElement = xmlDoc.getElementsByTagName(Elements);    for (let i = 0; i  

4.server.js

import request from '../utils/request';const url = 'http://localhost:8088'/** * 添加(编辑)工作流 * @param {*} data * @returns */export function addFlow(data) {    return request({        url: url + '/flow/addFlow',        method: 'post',        data,    });}/** * 查询工作流 * @param {*} data * @returns */export function infoFlow(data) {    return request({        url: url + '/flow/infoFlow',        method: 'post',        data,    });}/** * 删除工作流 * @param {*} data * @returns */export function deleteFlow(data) {    return request({        url: url + '/flow/deleteFlow',        method: 'post',        data,    });}/** * 获取工作流定义 * @param {*} data * @returns */export function getDeployList(data) {    return request({        url: url + '/flow/getDeployList',        method: 'post',        data,    });}/** * 工作流实例 * @param {*} data * @returns */export function flowRun(data) {    return request({        url: url + '/flow/deploymentRun',        method: 'post',        data,    });}

5.request.js

import axios from 'axios';const service = axios.create({});service.defaults.timeout = 20000;// 请求拦截器service.interceptors.request.use(    (config) => {        return config;    },    (error) => {        console.log(error);        return Promise.reject(error);    });// 响应拦截器service.interceptors.response.use(    (response) => {        return response.data;    },    (error) => {        return Promise.reject(error);    });export default service;

四、后端代码(Flowable)

1.FlowController .java

@RestControllerpublic class FlowController {    @Autowired    FlowService flowService;    // 工作流部署(添加、编辑)    @CrossOrigin    @PostMapping("/flow/addFlow")    public Result addFlow(@RequestBody Map map){        return flowService.AddFlow(map.get("id"), map.get("name"), map.get("xml"), map.get("key"));    }    // 工作流返回    @CrossOrigin    @PostMapping("/flow/infoFlow")    public Result infoFlow(@RequestBody Map map) {        return flowService.InfoFlow(map.get("id"), map.get("name"));    }    // 工作流删除    @CrossOrigin    @PostMapping("/flow/deleteFlow")    public Result deleteFlow(@RequestBody Map map) {        return flowService.DeleteFlow(map.get("id"));    }    // 工作流查询    @CrossOrigin    @PostMapping("/flow/getDeployList")    public Result getDeployList() {        return flowService.GetDeployList();    }    // 流程实例    @CrossOrigin    @PostMapping("/flow/deploymentRun")    public Result deploymentRun(@RequestBody Map map) {        return flowService.DeploymentRun(map.get("userId"), map.get("key"));    }    // 流程查询    @CrossOrigin    @PostMapping("/flow/infoTask")    public Result InfoTask(@RequestBody Map map) {        return flowService.InfoTask(map.get("userId"));    }    // 流程执行    @CrossOrigin    @PostMapping("/flow/makeTask")    public Result MakeTask(@RequestBody Map map) {        return flowService.MakeTask(map.get("userId"));    }    // 流程历史    @CrossOrigin    @PostMapping("/flow/taskHistory")    public Result TaskHistory() {        return flowService.TaskHistory();    }    // 测试    @CrossOrigin    @PostMapping("/test")    public Result test(@RequestBody AskForLeaveVO test) {        return flowService.test(test);    }}

2.FlowService .java

@Servicepublic class FlowService {    @Autowired    ProcessEngine processEngine;    @Autowired    FlowTreeService flowTreeService;    /**     * 工作流部署(添加、编辑)     * @param name 名称     * @param xml xml     * @return     */    @Transactional    public Result AddFlow(String id, String name, String xml, String key){        try {            RepositoryService repositoryService = processEngine.getRepositoryService();            // 创建新流程            Deployment deployment = repositoryService.createDeployment()                    .addString(name + ".bpmn", xml)                    .deploy();            // 将工作流信息保存到流程树表            flowTreeService.AutoSave(id, deployment.getId(), key);            System.out.println("id : " + id);            System.out.println("添加id : " + deployment.getId());            System.out.println("添加key : " + key);            return Result.ok("添加成功", deployment.getId());        } catch (Exception e) {            e.printStackTrace();            return Result.error("添加失败");        }    }    /**     * 工作流返回(返回xml)     * @param id 查询id     * @param name 名称     * @return     */    @Transactional    public Result InfoFlow(String id, String name) {        try {            // 流程查询            RepositoryService repositoryService = processEngine.getRepositoryService();            InputStream resourceAsStream = repositoryService.getResourceAsStream(id, name + ".bpmn");            // Java流转String            String resultXml = new BufferedReader(new InputStreamReader(resourceAsStream,"utf-8"))                    .lines().collect(Collectors.joining(System.lineSeparator()));            return Result.ok("查询成功", resultXml);        } catch (Exception e) {            e.printStackTrace();        }        return Result.error("查询失败");    }    /**     * 工作流删除     * @param id     * @return     */    @Transactional    public  Result DeleteFlow(String id){        try {            RepositoryService repositoryService = processEngine.getRepositoryService();            // 设置为TRUE 级联删除流程定义,及时流程有实例启动,也可以删除,设置为false 非级联删除操作。            repositoryService.deleteDeployment(id);            System.out.println("删除id : " + id);            return Result.ok("删除成功", id);        } catch (Exception e) {            e.printStackTrace();            return Result.error("删除失败");        }    }    /**     * 工作流部署列表查询     * @return     */    @Transactional    public Result GetDeployList() {        try {            RepositoryService repositoryService = processEngine.getRepositoryService();            List list = repositoryService.createProcessDefinitionQuery().list();            System.out.println("list : " + list);            return Result.ok("查询成功");        } catch (Exception e) {            e.printStackTrace();            return Result.error("查询失败");        }    }    /**     * 启动流程实例     * @param userId 发起人     * @param key 流程key     * @return     */    @Transactional    public Result DeploymentRun(String userId, String key){        try {//          Map variables = new HashMap();//          variables.put("employee", userId);            RuntimeService runtimeService = processEngine.getRuntimeService();            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);            //获取流程实例的相关信息            System.out.println("流程定义的id = " + processInstance.getProcessDefinitionId());            System.out.println("流程实例的id = " + processInstance.getId());            return Result.ok("成功", "流程实例id = " + processInstance.getId());        } catch (Exception e) {            e.printStackTrace();            return Result.error("失败");        }    }    /**     * 查询流程任务     * @param userId     * @return     */    @Transactional    public Result InfoTask(String userId){        try {            TaskService taskService = processEngine.getTaskService();            // 查询多人任务            List taskList = taskService.createTaskQuery().taskCandidateUser(userId).list();            System.out.println("taskList" + taskList);            //遍历任务列表            for(Task task:taskList){                System.out.println("流程定义id = " + task.getProcessDefinitionId());                System.out.println("流程实例id = " + task.getProcessInstanceId());                System.out.println("任务id = " + task.getId());                System.out.println("任务名称 = " + task.getName());            }            return Result.ok("成功");        } catch (Exception e) {            e.printStackTrace();            return Result.error("失败");        }    }    /**     * 执行流程任务     * @param userId     * @return     */    @Transactional    public Result MakeTask(String userId){        try {            TaskService taskService = processEngine.getTaskService();            // 查询个人任务            List list = taskService.createTaskQuery().taskCandidateUser(userId).list();            System.out.println("taskList" + list);            for (Task task : list) {                taskService.complete(task.getId());                System.out.println("task.getId()" + task.getId());            }            return Result.ok("成功");        } catch (Exception e) {            e.printStackTrace();            return Result.error("失败");        }    }    /**     * 查询历史流程     * @param     * @return     */    @Transactional    public Result TaskHistory(){        try {            HistoryService historyService = processEngine.getHistoryService();            List activities = historyService.createHistoricActivityInstanceQuery()                    // .processInstanceId("12501") // 特定的实例                    .finished() // 完成的                            // .orderByHistoricActivityInstanceEndTime().asc() // 根据实例完成时间升序排列                    .list();            for (HistoricActivityInstance activity : activities) {                System.out.println("id:" + activity.getActivityId() + "  任务名:" + activity.getActivityName() + "  类型:" + activity.getActivityType() + "  持续时间:" + activity.getDurationInMillis());            }            return Result.ok("成功");        } catch (Exception e) {            e.printStackTrace();            return Result.error("失败");        }    }}

上一篇:鲸鱼花的浇水秘籍,正确呵护,让花朵茁壮成长!

下一篇:跨市怎么办理异地就医备案登记手续