框架中需要整合流程设计,选择了流程设计器GooFlow作为Web端的UI组件
GooFlow下载地址:
提取码:wucr
参考示例源码如下:
顶部有保存,撤销,重做的按钮,可以绑定自定义事件。
左侧工具栏,提供基本的流程节点和按钮,也支持自定义。
导出结果,把流程设计器页面的数据已json格式显示出来
集成后效果如下图:
主要实现以下功能,点击节点,可以修改节点ID,节点名称;点击自动节点,可以给该节点增加或移除审批人;点击确认保存流程图json结果。
数据表设计:
(1)流程实例表WF_Instance,流程发起产生一条记录,记录当前节点Id和下一个节点Id,当下一节点为结束
1 /// <summary> 2 /// 流程实例表 3 /// </summary> 4 public class WF_Instance : CoreBaseEntity 5 { 6 /// <summary> 7 ///是否结束 8 /// </summary> 9 [Display(Name = "是否结束")] 10 [Description("是否结束")] 11 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 12 public TrueOrFlase IsFinished { get; set; } 13 /// <summary> 14 /// 下一个节点ID 15 /// </summary> 16 [Display(Name = "下一个节点ID")] 17 [Description("下一个节点ID")] 18 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 19 public string NextNodeID { get; set; } 20 /// <summary> 21 /// 当前节点ID 22 /// </summary> 23 [Display(Name = "当前节点ID")] 24 [Description("当前节点ID")] 25 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 26 public string CurrentNodeID { get; set; } 27 /// <summary> 28 /// F_InstanceId 29 /// </summary> 30 [Display(Name = "F_InstanceId")] 31 [Description("F_InstanceId")] 32 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 33 public string F_InstanceId { get; set; } 34 /// <summary> 35 /// CurrentNode 36 /// </summary> 37 [Display(Name = "当前节点名称")] 38 [Description("当前节点名称")] 39 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 40 public string CurrentNode { get; set; } 41 /// <summary> 42 /// F_SchemeId 43 /// </summary> 44 [Display(Name = "流程模板ID")] 45 [Description("流程模板ID")] 46 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 47 public string F_SchemeId { get; set; } 48 /// <summary> 49 /// OutCode 50 /// </summary> 51 [Display(Name = "订单编号")] 52 [Description("订单编号")] 53 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 54 public string OutCode { get; set; } 55 /// <summary> 56 /// NextNode 57 /// </summary> 58 [Display(Name = "下一个节点名称")] 59 [Description("下一个节点名称")] 60 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 61 public string NextNode { get; set; } 62 }
(2)流程节点表 WF_Instance_Node
1 public class WF_Instance_Node : CoreBaseEntity 2 { 3 /// <summary> 4 /// F_InstanceNodeID 5 /// </summary> 6 [Display(Name = "F_InstanceNodeID")] 7 [Description("F_InstanceNodeID")] 8 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 9 public string F_InstanceNodeID { get; set; } 10 /// <summary> 11 /// 上一个节点名称 12 /// </summary> 13 [Display(Name = "上一个节点名称")] 14 [Description("上一个节点名称")] 15 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 16 public string BeforeNode { get; set; } 17 /// <summary> 18 /// 当前节点名称 19 /// </summary> 20 [Display(Name = "当前节点名称")] 21 [Description("当前节点名称")] 22 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 23 public string CurrentNode { get; set; } 24 25 /// <summary> 26 /// 下个节点 27 /// </summary> 28 [Display(Name = "下个节点")] 29 [Description("下个节点")] 30 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 31 public string NextNode { get; set; } 32 /// <summary> 33 /// 上一个节点名称 34 /// </summary> 35 [Display(Name = "上一个节点名称")] 36 [Description("上一个节点名称")] 37 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 38 public string BeforeNodeId { get; set; } 39 /// <summary> 40 /// 当前节点名称 41 /// </summary> 42 [Display(Name = "当前节点名称")] 43 [Description("当前节点名称")] 44 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 45 public string CurrentNodeId { get; set; } 46 /// <summary> 47 /// 下个节点 48 /// </summary> 49 [Display(Name = "下个节点")] 50 [Description("下个节点")] 51 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 52 public string NextNodeId { get; set; } 53 /// <summary> 54 /// IsFinish 55 /// </summary> 56 [Display(Name = "IsFinish")] 57 [Description("IsFinish")] 58 public TrueOrFlase IsFinish { get; set; } 59 /// <summary> 60 /// F_InstanceId 61 /// </summary> 62 [Display(Name = "F_InstanceId")] 63 [Description("F_InstanceId")] 64 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 65 public string F_InstanceId { get; set; } 66 }
生成的Json格式:
1 { 2 "title": "newFlow_1", 3 "nodes": { 4 "demo_node_1": { 5 "name": "开始", 6 "left": 42, 7 "top": 38, 8 "type": "start round mix", 9 "width": 26, 10 "height": 26, 11 "alt": true, 12 "user": "123" 13 }, 14 "demo_node_2": { 15 "name": "结束", 16 "left": 797, 17 "top": 42, 18 "type": "end round mix", 19 "width": 26, 20 "height": 26, 21 "alt": true, 22 "user": "123" 23 }, 24 "1590218903325": { 25 "name": "步骤1", 26 "left": 303, 27 "top": 45, 28 "type": "node", 29 "userlist": [{ 30 "username": "管理员2号", 31 "userid": "1", 32 "deptname": "游戏部", 33 "deptcode": "1.4" 34 }], 35 "width": 104, 36 "height": 26, 37 "alt": true 38 } 39 }, 40 "lines": { 41 "1590218933638": { 42 "type": "sl", 43 "from": "demo_node_1", 44 "to": "1590218903325", 45 "name": "", 46 "alt": true 47 }, 48 "1590218935259": { 49 "type": "sl", 50 "from": "1590218903325", 51 "to": "demo_node_2", 52 "name": "", 53 "alt": true 54 } 55 }, 56 "areas": {}, 57 "initNum": 27, 58 "user": "管理员" 59 }
后台代码(简要):
1 //解析流程设计器的Json字符串 2 SchemeJson model = JsonConvert.DeserializeObject<SchemeJson>(schemeMol.SchemeJson); 3 var nodes = model.nodes; 4 var lines = model.lines; 5 //记录节点间的关系 6 //略
(3)流程节点审批明细表WF_Instance_NodeDetail,记录节点审批人
1 public class WF_Instance_NodeDetail : CoreBaseEntity 2 { 3 /// <summary> 4 /// F_InstanceNodeID 5 /// </summary> 6 [Display(Name = "F_InstanceNodeID")] 7 [Description("F_InstanceNodeID")] 8 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 9 public string F_InstanceNodeID { get; set; } 10 /// <summary> 11 /// Handler 12 /// </summary> 13 [Display(Name = "处理人名字")] 14 [Description("处理人名字")] 15 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 16 public string Handler { get; set; } 17 /// <summary> 18 /// F_InstanceId 19 /// </summary> 20 [Display(Name = "F_InstanceId")] 21 [Description("F_InstanceId")] 22 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 23 public string F_InstanceId { get; set; } 24 /// <summary> 25 /// HandlerID 26 /// </summary> 27 [Display(Name = "HandlerID")] 28 [Description("HandlerID")] 29 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 30 public string HandlerID { get; set; } 31 /// <summary> 32 /// HandleOpnion 33 /// </summary> 34 [Display(Name = " 处理意见")] 35 [Description(" 处理意见")] 36 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 37 public string HandleOpnion { get; set; } 38 /// <summary> 39 /// NodeName 40 /// </summary> 41 [Display(Name = "NodeName")] 42 [Description("NodeName")] 43 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 44 public string NodeName { get; set; } 45 /// <summary> 46 /// F_InstanceNodeDetailID 47 /// </summary> 48 [Display(Name = "F_InstanceNodeDetailID")] 49 [Description("F_InstanceNodeDetailID")] 50 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 51 public string F_InstanceNodeDetailID { get; set; } 52 /// <summary> 53 /// NodeID 54 /// </summary> 55 [Display(Name = "NodeID")] 56 [Description("NodeID")] 57 [StringLength(50, ErrorMessage = "{0}最多输入{1}个字符")] 58 public string NodeID { get; set; } 59 /// <summary> 60 /// HandleResult 61 /// </summary> 62 [Display(Name = "处理结果")] 63 [Description("处理结果")] 64 65 public TrueOrFlase HandleResult { get; set; } 66 }
以上,仅用于学习和总结