关于workflow 的审批流程的业务实现<一>
版本 | 时间 | 变更内容 | 作者 | 备注 |
---|
v1.0 | 2021/11/13 | 创建 | henry_oulen@163.com | 微信号:henry_oulen | | | | | | | | | | |
一、业务背景
例如下面的例子
因此开发出一个审批业务极为重要
那么下面我们针对这个业务具体来讲解
二、业务分析
-
定义表单设计 -
定义流程设计 -
用户发起审批 -
用户进行表单审批
2.1用户表单设计
如何能够实现不同的表单能够进行自定义 那么一个字段的表结构尤其重要
"formData": [{
"type": "holidayTypes",
"field": "leaveType",
"title": "请假类型 :",
"info": "",
"hidden": false,
"display": true,
"validate": [{
"trigger": "change",
"message": "请选择请假类型",
"required": true
}],
"conditions": true
}, {
"type": "datePicker",
"field": "leaveTime",
"title": "开始时间 :",
"info": "",
"props": {
"type": "datetime",
"prefixIcon": "el-icon-date",
"placeholder": "请选择请假时间"
},
"_fc_drag_tag": "datePicker",
"hidden": false,
"display": true,
"value": null,
"validate": [{
"type": "string",
"trigger": "change",
"mode": "required",
"message": "请选择请假时间",
"required": true
}],
"emit": ["change"]
}, {
"type": "datePicker",
"field": "leaveEndTime",
"title": "结束时间 :",
"info": "",
"props": {
"type": "datetime",
"prefixIcon": "el-icon-date",
"placeholder": "请选择结束时间"
},
"_fc_drag_tag": "datePicker",
"hidden": false,
"display": true,
"value": null,
"validate": [{
"type": "string",
"trigger": "change",
"mode": "required",
"message": "请选择请假结束时间",
"required": true
}],
"emit": ["change"]
}, {
"type": "input",
"field": "leaveDuration",
"title": "请假时长 :",
"info": "",
"value": "0",
"props": {
"disabled": true,
"type": "text",
"placeholder": ""
},
"_fc_drag_tag": "input",
"hidden": false,
"display": true,
"validate": [{
"trigger": "change",
"mode": "required",
"message": "",
"required": true,
"type": "string"
}],
"conditions": true
}, {
"type": "input",
"field": "leaveReason",
"title": "请假事由 :",
"info": "",
"props": {
"type": "textarea",
"readonly": false,
"placeholder": "请输入内容"
},
"_fc_drag_tag": "input",
"hidden": false,
"display": true,
"value": "",
"validate": [{
"type": "string",
"trigger": "change",
"mode": "required",
"message": "请输入请假事由",
"required": true
}]
}]
思路分析
每一个字段其实就是一个字典
通过固定的键值对来取值,这样做的目的就是动态获取字段的名称 和对于的值
{
"type": "holidayTypes",
"field": "leaveType",
"title": "请假类型 :",
"info": "",
"hidden": false,
"display": true,
"validate": [{
"trigger": "change",
"message": "请选择请假类型",
"required": true,
}]
}
2.2用户流程定义
思路:条件分支和子节点分支
processData
里面主要的数据就是我们用来进行处理流程的数据
"processData": {
"type": "start",
"content": "所有人",
"nodeId": "3ych7azs3lsqb8bcbgg",
"properties": {
"title": "发起人",
"initiator": []
},
"childNode": {
"type": "condition",
"nodeId": "ZcKEzh",
"childNode": {
"type": "copy",
"nodeId": "uK3Fzh",
"childNode": {
"type": "approver",
"nodeId": "OKVXzh",
"childNode": {},
"prevId": "uK3Fzh",
"content": "test@8888",
"properties": {
"title": "审批人",
"assigneeType": "user",
"menbers": [{
"user_id": 3,
"user_name": "test@8888"
}],
"counterSign": true,
"residenceTime": 0
}
},
"prevId": "QkyEzh",
"content": "test@8888",
"properties": {
"title": "抄送人",
"menbers": [{
"user_id": 3,
"user_name": "test@8888"
}],
"userOptional": true
}
},
"prevId": "fwzG4i",
"conditions": [{
"content": "[请假时长 : 等于 5]",
"prevId": "ZcKEzh",
"nodeId": "WpKEzh",
"properties": {
"priority": 0,
"isDefault": false,
"initiator": null,
"conditions": [{
"conditionValue": {
"type": "equal",
"value": 5
},
"field": "leaveDuration"
}]
},
"childNode": {
"type": "approver",
"nodeId": "4BTXzh",
"childNode": {
"type": "condition",
"nodeId": "RtWXzh",
"childNode": {
"type": "approver",
"nodeId": "iGYXzh",
"childNode": {},
"prevId": "RtWXzh",
"content": "日程测试",
"properties": {
"title": "审批人",
"assigneeType": "user",
"menbers": [{
"user_id": 22,
"user_name": "日程测试"
}],
"counterSign": true,
"residenceTime": 0
}
},
"prevId": "4BTXzh",
"conditions": [{
"content": "[请假时长 : 等于 5]",
"prevId": "RtWXzh",
"nodeId": "BmWXzh",
"properties": {
"priority": 0,
"isDefault": false,
"initiator": null,
"conditions": [{
"conditionValue": {
"type": "equal",
"value": 5
},
"field": "leaveDuration"
}]
},
"childNode": {
"type": "copy",
"nodeId": "HXtXzh",
"childNode": {},
"prevId": "BmWXzh",
"content": "子账号",
"properties": {
"title": "抄送人",
"menbers": [{
"user_id": 13,
"user_name": "子账号"
}],
"userOptional": true
}
}
}, {
"content": "其他情况进入此流程",
"prevId": "RtWXzh",
"nodeId": "ZoWXzh",
"properties": {
"priority": 1,
"isDefault": true,
"initiator": null,
"conditions": []
}
}]
},
"prevId": "WpKEzh",
"content": "测试登录1",
"properties": {
"title": "审批人",
"assigneeType": "user",
"menbers": [{
"user_id": 20,
"user_name": "测试登录1"
}],
"counterSign": true,
"residenceTime": 0
}
}
}, {
"content": "[请假时长 : 大于 5]",
"prevId": "ZcKEzh",
"nodeId": "V4nOzh",
"properties": {
"priority": 1,
"isDefault": false,
"initiator": null,
"conditions": [{
"conditionValue": {
"type": "greaterThan",
"value": 5
},
"field": "leaveDuration"
}]
},
"childNode": {
"type": "approver",
"nodeId": "PEUXzh",
"childNode": {},
"prevId": "V4nOzh",
"content": "测试密码传输",
"properties": {
"title": "审批人",
"assigneeType": "user",
"menbers": [{
"user_id": 15,
"user_name": "测试密码传输"
}],
"counterSign": true,
"residenceTime": 0
}
}
}, {
"content": "[请假时长 : 小于 3]",
"prevId": "ZcKEzh",
"nodeId": "yAxZzh",
"properties": {
"priority": 2,
"isDefault": false,
"initiator": null,
"conditions": [{
"conditionValue": {
"type": "lesThan",
"value": 3
},
"field": "leaveDuration"
}]
},
"childNode": {
"type": "condition",
"nodeId": "nH4azh",
"childNode": {
"type": "approver",
"nodeId": "G57azh",
"childNode": {},
"prevId": "nH4azh",
"content": "测试登录1",
"properties": {
"title": "审批人",
"assigneeType": "user",
"menbers": [{
"user_id": 20,
"user_name": "测试登录1"
}],
"counterSign": true,
"residenceTime": 0
}
},
"prevId": "yAxZzh",
"conditions": [{
"content": "[请假时长 : 大于 0]",
"prevId": "nH4azh",
"nodeId": "sG4azh",
"properties": {
"priority": 0,
"isDefault": false,
"initiator": null,
"conditions": [{
"conditionValue": {
"type": "greaterThan",
"value": 0
},
"field": "leaveDuration"
}]
},
"childNode": {
"type": "approver",
"nodeId": "sG6azh",
"childNode": {},
"prevId": "sG4azh",
"content": "子账号",
"properties": {
"title": "审批人",
"assigneeType": "user",
"menbers": [{
"user_id": 13,
"user_name": "子账号"
}],
"counterSign": true,
"residenceTime": 0
}
}
}, {
"content": "其他情况进入此流程",
"prevId": "nH4azh",
"nodeId": "BC4azh",
"properties": {
"priority": 1,
"isDefault": true,
"initiator": null,
"conditions": []
}
}]
}
}, {
"content": "其他情况进入此流程",
"prevId": "ZcKEzh",
"nodeId": "miKEzh",
"properties": {
"priority": 3,
"isDefault": true,
"initiator": null,
"conditions": []
}
}]
}
}
2.3用户发起审批
用户发起审批
拆解
01
用户填写表单数据的时候
需要发起请求获取流程分支的数据
也就是把表单的数据发给后端
02通过字段的值 和流程分支里面的数据进行对比 选择走哪个分支
2.4进行审批
当用户发起来真正的审批流的时候,也就是用户已经进行了一次 task任务的执行和没有执行的任务的操作
01 发起审批的时候
需要处理两个事件
1:根据前面的流程来处理掉 第一个审批人的任务
2:根据流程的总节点数量和处理是不是最后的一个用户,来判断整个审批是不是已经结束
审批流程的参考资料 有能力的也可以先参考以下文档进行学习
南斗开源平台:https://gitee.com/nandouinfo/fastdp
流程后端 https://github.com/go-workflow/go-workflow
流程前端 https://github.com/go-workflow/workflow-ui
|