记录一下golang使用工作流easy_workflow的情况
首先这里感谢一下作者,先贴地址:
easy-workflow 是一个基于 Golang
的工作流引擎,它能够帮助开发者轻松地在应用程序中实现复杂的业务流程自动化。该库提供了丰富的特性,如事件驱动、角色分配、条件分支以及网关节点,使得工作流的定义和执行变得直观且灵活。
工作流定义 工作流定义采用 JSON 格式,描述了工作流的各个阶段及其逻辑。例如,一个员工请假的工作流可能包含以下节点:
请假:员工发起请假申请。 请假天数判断:根据请假天数决定是否需要主管审批。 主管审批:主管根据请假天数判断是否批准。
并行网关:同时进行人事审批和副总审批。 人事审批:人事部门审批。 副总审批:副总审批。 老板审批:最终审批者。
END:流程结束节点。
项目使用gin框架做的,但是也能非常方便整合到其他框架,直接调用方法就可
先来说说流程定义
{
"ProcessName": "员工请假",
"Source": "办公系统",
"RevokeEvents": ["MyEvent_Revoke"],
"Nodes": [{
"NodeID": "Start",
"NodeName": "请假",
"NodeType": 0,
"PrevNodeIDs": null,
"UserIDs": ["$starter"],
"Roles": null,
"GWConfig": {
"Conditions": null,
"InevitableNodes": null,
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": null,
"NodeEndEvents": ["MyEvent_End"],
"TaskFinishEvents": null
}, {
"NodeID": "GW-Day",
"NodeName": "请假天数判断",
"NodeType": 2,
"PrevNodeIDs": ["Start"],
"UserIDs": null,
"Roles": null,
"GWConfig": {
"Conditions": [{
"Expression": "$days>=3",
"NodeID": "Manager"
}, {
"Expression": "$days<3",
"NodeID": "END"
}],
"InevitableNodes": [],
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": null,
"NodeEndEvents": null,
"TaskFinishEvents": null
}, {
"NodeID": "Manager",
"NodeName": "主管审批",
"NodeType": 1,
"PrevNodeIDs": ["GW-Day"],
"UserIDs": null,
"Roles": ["主管"],
"GWConfig": {
"Conditions": null,
"InevitableNodes": null,
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": ["MyEvent_ResolveRoles", "MyEvent_Notify"],
"NodeEndEvents": ["MyEvent_End"],
"TaskFinishEvents": null
}, {
"NodeID": "GW-Parallel",
"NodeName": "并行网关",
"NodeType": 2,
"PrevNodeIDs": ["Manager"],
"UserIDs": null,
"Roles": null,
"GWConfig": {
"Conditions": null,
"InevitableNodes": ["HR", "DeputyBoss"],
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": null,
"NodeEndEvents": null,
"TaskFinishEvents": null
}, {
"NodeID": "HR",
"NodeName": "人事审批",
"NodeType": 1,
"PrevNodeIDs": ["GW-Parallel"],
"UserIDs": null,
"Roles": ["人事经理"],
"GWConfig": {
"Conditions": null,
"InevitableNodes": null,
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": ["MyEvent_ResolveRoles", "MyEvent_Notify"],
"NodeEndEvents": ["MyEvent_End"],
"TaskFinishEvents": null
}, {
"NodeID": "DeputyBoss",
"NodeName": "副总审批",
"NodeType": 1,
"PrevNodeIDs": ["GW-Parallel"],
"UserIDs": null,
"Roles": ["副总"],
"GWConfig": {
"Conditions": null,
"InevitableNodes": null,
"WaitForAllPrevNode": 0
},
"IsCosigned": 1,
"NodeStartEvents": ["MyEvent_ResolveRoles", "MyEvent_Notify"],
"NodeEndEvents": ["MyEvent_End"],
"TaskFinishEvents": ["MyEvent_TaskForceNodePass"]
}, {
"NodeID": "GW-Parallel2",
"NodeName": "并行网关",
"NodeType": 2,
"PrevNodeIDs": ["HR", "DeputyBoss"],
"UserIDs": null,
"Roles": null,
"GWConfig": {
"Conditions": null,
"InevitableNodes": ["Boss"],
"WaitForAllPrevNode": 1
},
"IsCosigned": 0,
"NodeStartEvents": null,
"NodeEndEvents": null,
"TaskFinishEvents": null
}, {
"NodeID": "Boss",
"NodeName": "老板审批",
"NodeType": 1,
"PrevNodeIDs": ["GW-Parallel2"],
"UserIDs": null,
"Roles": ["老板"],
"GWConfig": {
"Conditions": null,
"InevitableNodes": null,
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": ["MyEvent_ResolveRoles", "MyEvent_Notify"],
"NodeEndEvents": ["MyEvent_End"],
"TaskFinishEvents": null
}, {
"NodeID": "END",
"NodeName": "END",
"NodeType": 3,
"PrevNodeIDs": ["GW-Day", "Boss"],
"UserIDs": null,
"Roles": null,
"GWConfig": {
"Conditions": null,
"InevitableNodes": null,
"WaitForAllPrevNode": 0
},
"IsCosigned": 0,
"NodeStartEvents": ["MyEvent_Notify"],
"NodeEndEvents": null,
"TaskFinishEvents": null
}]
}
easy_work.StartWorkFlow(DBConnConfig, false, &easy_workflow.MyEvent{})
启动工作流需要调用 easy_work.StartWorkFlow
方法,传入数据库连接配置、是否开启调试模式以及自定义事件结构体实例。自定义事件结构体可以包含各种业务事件,如角色解析、通知发送等。
easy_workflow.MyEvent{} :其实就是你自定义的方法,可以定义到上面流程中的Events
包括各种自定义事件,角色用户解析绑定,结束通知等,作者相当于完全把整个工作流给独立出来,方便外面业务对接 因为我这是多分公司的情况,所以在解析角色的时候直接去根据角色和发起人id查数据库
for _, role := range CurrentNode.Roles {
//根据角色和分公司查找主管(没有分公司的员工直接提交给管理员)
CurrentNode.UserIDs = getUserIdsBy(tx, role, int64(userModel.BranchID))
}
- 网关GW-Parallel:因为之前没接触过工作流系统,请教作者后才明白,这个东西其实就是条件判断流程后的走向
任务通过/拒绝
TaskPass(TaskID int, Comment string, VariableJson string, DirectlyToWhoRejectedMe bool) error
就是这里我之前踩了一个大坑:员工请假-》主管审核驳回后-〉再次生成员工请假数据时,数据处理人竟然是主管
后来发现 VariableJson不是必传的,提交这个会导致覆盖数据,导致了这个问题
- *其他的问题应该不是太大 。。。。待后续发现补充 *
总结
easy-workflow 提供了一种强大而灵活的方式来管理业务流程。通过定义清晰的工作流模型和利用其提供的事件机制,可以实现复杂业务逻辑的自动化处理。在实际应用中,需要注意细节处理,如角色解析和任务状态管理,以确保流程的正确性和效率。