背景
对于流程设置不友好的问题,国内钉钉另行设计与实现了一套流程建模模式,跟bpmn规范无关,有人仿照实现了下,并做了开源(https://github.com/StavinLi/Workflow-Vue3),效果图如下:
实现大致原理是基于无限嵌套的子节点,输出json数据,传给后端,今天来说说前端的集成工作。
流程建模组件封装
新增flowDesign.vue组件,用于封装流程建模的操作,调整流程模板的编辑视图,将模型属性,使用flowDesign.vue组件替代。样式如下:
源码
<template>
<div class="w-full">
<el-input disabled style="width: 152px" />
<el-button-group>
<el-button icon="grid" @click="init" style="border-left-width: 0; padding: 10px" />
<el-button icon="delete" @click="clear" style="border-left-width: 0; padding: 10px" />
</el-button-group>
<Dialog title="流程建模" v-model="visible" fullscreen>
<div>
<div class="fd-nav">
<div class="fd-nav-left">
<!-- TODO 显示流程模板名称 -->
<div class="fd-nav-title">{
{ flowTemplateName }}</div>
</div>
<div class="fd-nav-right">
<el-button type="primary" @click="save">保存</el-button>
</div>
</div>
<div class="fd-nav-content">
<section class="dingflow-design">
<div class="zoom">
<div class="zoom-out" :class="nowVal == 50 && 'disabled'" @click="zoomSize(1)"></div>
<span>{
{ nowVal }}%</span>
<div class="zoom-in" :class="nowVal == 300 && 'disabled'" @click="zoomSize(2)"></div>
</div>
<div class="box-scale" :style="`transform: scale(${nowVal / 100});`">
<nodeWrap v-model:nodeConfig="nodeConfig" v-model:flowPermission="flowPermission" />
<div class="end-node">
<div class="end-node-circle"></div>
<div class="end-node-text">流程结束</div>
</div>
</div>
</section>
</div>
<errorDialog v-model:visible="tipVisible" :list="tipList" />
<promoterDrawer />
<approverDrawer :directorMaxLevel="directorMaxLevel" />
<copyerDrawer />
<conditionDrawer />
</div>
</Dialog>
</div>
</template>
<script>
import { Dialog } from '@/components/abc/Dialog'
import errorDialog from './model/components/dialog/errorDialog.vue'
import promoterDrawer from './model/components/drawer/promoterDrawer.vue'
import approverDrawer from './model/components/drawer/approverDrawer.vue'
import copyerDrawer from './model/components/drawer/copyerDrawer.vue'
import conditionDrawer from './model/components/drawer/conditionDrawer.vue'
import nodeWrap from './model/components/nodeWrap.vue'
// import addNode from './model/components/drawer/conditionDrawer.vue'
export default {
components: {
Dialog,
errorDialog,
promoterDrawer,
approverDrawer,
copyerDrawer,
conditionDrawer,
nodeWrap
},
props: {
modelValue: {
type: String
},
flowTemplateName: {
type: String
}
},
data() {
return {
visible: false,
// 当前缩放值
nowVal: 100,
// 模型配置
nodeConfig: {},
flowPermission: [],
tipVisible: false,
directorMaxLevel: 0,
tipList: [],
// 初始化数据
defaultNodeConfig: {
nodeName: '发起人',
type: 0,
priorityLevel: '',
settype: '',
selectMode: '',
selectRange: '',
directorLevel: '',
examineMode: '',
noHanderAction: '',
examineEndDirectorLevel: '',
ccSelfSelectFlag: '',
conditionList: [],
nodeUserList: [],
childNode: {
nodeName: '审核人',
error: false,
type: 1,
settype: 2,
selectMode: 0,
selectRange: 0,
directorLevel: 1,
examineMode: 1,
noHanderAction: 2,
examineEndDirectorLevel: 0,
childNode: {
nodeName: '抄送人',
type: 2,
ccSelfSelectFlag: 1,
childNode: null,
nodeUserList: [],
error: false
},
nodeUserList: []
},
conditionNodes: []
}
}
},
mounted() {
this.init()
},
methods: {
init() {
if (this.modelValue != '{}') {
// 绑定数据不为空,则使用绑定数据初始化
this.nodeConfig = JSON.parse(this.modelValue)
} else {
// 否则,加载默认配置
this.nodeConfig = this.defaultNodeConfig
}
this.visible = true
},
save() {
this.$emit('update:modelValue', JSON.stringify(this.nodeConfig))
this.visible = false
},
// 清空配置
clear() {
this.$confirm('此操作将重置流程配置为初始状态, 是否继续?', '确认', {
type: 'warning'
})
.then(() => {
this.$emit('update:modelValue', '{}')
})
.catch(() => {
this.$message.info('已取消')
})
},
zoomSize(type) {
if (type == 1) {
if (this.nowVal == 50) {
return
}
this.nowVal -= 10
} else {
if (this.nowVal == 300) {
return
}
this.nowVal += 10
}
}
}
}
</script>
<style>
@import './model/css/workflow.css';
.error-modal-list {
width: 455px;
}
</style>
流程建模组件功能集成
之前集成和使用的vue-simple-uploader、vue-echarts等,直接安装npm包即可。
流程建模功能则不是这么简单,需要跟自己的平台或系统进行深度集成。Workflow-Vue3这个开源项目提供的不是一个简单的组件功能,而是一个独立的前端项目,封装也不多,集成更多地是参照源码进行调整,涉及到大量的改造,难度比较大,遇到的问题也比较多,下面详细展开说说。
组件迁移
在模块workflow的view目录下flowTemplate目录下,新建一个model文件夹,集中存放开源项目Workflow-Vue3的相关文件,包括components、css、stores、utils等目录。
此外,还有部分图片资源,放到了平台assets目录下
引用关系调整
文件迁移过来后,接下来,大量的工作是调整引用关系,原项目大量使用@这种根目录src指向,而在平台中,放在一个目录去管理,需要调整引用路径。
如原项目,引用如下:
import { useStore } from '@/stores/index'
import { bgColors, placeholderList } from '@/utils/const'
需要调整为:
import { useStore } from '../stores/index'
import { bgColors, placeholderList } from '../utils/const'
几乎所有的迁移过来的vue文件引用都要改一遍,并且,不仅仅是vue组件间的引用,还有css样式和图片的引用地址,也需要进行相应调整。
组件注册
独立项目调整为组件使用,需要做一些适应性调整。
原项目将两个核心组件在main.js全局注册,如下:
import nodeWrap from '@/components/nodeWrap.vue'
app.component('nodeWrap', nodeWrap);
import addNode from '@/components/addNode.vue'
app.component('addNode', addNode);
在平台中,流程建模只是工作流模块的一个功能而已,其他地方都不会用到,因此只在自行封装中的flowDesign.vue组件进行了引用。
import nodeWrap from './model/components/nodeWrap.vue'
而addNode组件,会在nodeWrap组件内部用到,因此在nodeWrap组件内部进行了引用。
开源项目workflow-vue3自身没啥集成说明和注意事项,因此大多是看着源码和报错一点点调整。比较耗时。
样式缺失问题
完成上面工作后,js不再输出错误信息,页面能加载内容,建模页面如下:
明显是css缺失导致的,原项目是加在了setting页面,我加到对应的flowDesign页面,发现仍然是变形的,在nodeWrap组件也追加了后显示正常。
@import ‘…/css/workflow.css’;
这时候,实际是产生了一个疑问,为啥原项目只需要在外围页面添加一次就行,而我需要在多个页面添加。
图标缺失问题
上面解决了css样式缺失问题,整体显示正常了,但是图标是缺失的,如下图所示:
这个地方问题排查花了很长时间,一度怀疑是iconfont使用命名与平台原来某个组件重名导致的异常,最后才发现,是css作用域问题,即需要把scoped去除,令其全局生效……这样也解决了上一章节css多次引入问题。
不过,这地方存在一个隐患,即流程建模的css样式,去除了作用域scoped限制,会影响到平台自身一些样式和功能,这块不好排查,等发现了再处理。
后端请求处理
原项目模拟量后端请求调用,包括组织机构、人员、角色、流程配置等,我做了临时性处理,将其注释,或使用静态json数据替换,待后面深度集成时再进行处理,更换为平台真正的后端数据。
运行效果
完成上述工作后,已经可以正常显示跟原项目演示效果一样的预览效果了,如下图:
这里做了一个默认示例,使用到了发起人、审核人和抄送人,作为初始的示例数据。
开发平台资料
平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:csdn专栏
开源地址:Gitee
开源协议:MIT
开源不易,欢迎收藏、点赞、评论。