using AIStudio.Wpf.Flowchart.ViewModels; using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner; using Microsoft.CSharp; using System.CodeDom.Compiler; using System.Reflection; using System.Data; namespace AIStudio.Wpf.Flowchart { public static class FlowchartService { static FlowchartService() { Users = new List() { new SelectOption(){ value = "操作员1",text = "操作员1" }, new SelectOption(){ value = "操作员2",text = "操作员2" }, new SelectOption(){ value = "Admin",text = "Admin" }, }; Roles = new List() { new SelectOption(){ value = "操作员",text = "操作员" }, new SelectOption(){ value = "管理员",text = "管理员" }, }; } private static List _users; public static List Users { get { return _users; } set { _users = value; } } private static List _roles; public static List Roles { get { return _roles; } set { _roles = value; } } /// /// 流程数据 /// public static Dictionary> FlowNodes { get; set; } = new Dictionary>(); /// /// 初始化数据 /// /// /// /// public static void InitData(List oASteps, List connectors, IDiagramViewModel viewModel, bool initNew) { foreach (var edge in connectors) { if (edge.IsFullConnection == false) continue; var source = oASteps.FirstOrDefault(p => p.BottomConnector == edge.SourceConnectorInfo || p.LeftConnector == edge.SourceConnectorInfo || p.RightConnector == edge.SourceConnectorInfo); if (source != null) { if (source.Kind == NodeKinds.Decide) { source.SelectNextStep.Add(edge.SinkConnectorInfoFully.DataItem.Id.ToString(), "data.Flag" + edge.Text); } else if (source.Kind == NodeKinds.COBegin) { source.SelectNextStep.Add(edge.SinkConnectorInfoFully.DataItem.Id.ToString(), "True"); } else { source.NextStepId = edge.SinkConnectorInfoFully.DataItem.Id.ToString(); } } } foreach (var step in oASteps) { //恢复指向上一个节点 if (!string.IsNullOrEmpty(step.NextStepId)) { var nextstep = oASteps.FirstOrDefault(p => p.Id.ToString() == step.NextStepId); if (nextstep == null) throw new Exception(string.Format("流程异常,无法找到{0}的下一个流程节点{1}", step.Id, step.NextStepId)); if (nextstep.Kind == NodeKinds.Decide) { var nsteps = oASteps.Where(p => nextstep.SelectNextStep.Any(q => p.Id.ToString() == q.Key)); if (nsteps == null || nsteps.Count() == 0) throw new Exception(string.Format("流程异常,无法找到{0}的下一个流程节点{1}", step.Id, step.NextStepId)); //跳过Decide指向下面的子节点 foreach (var nstep in nsteps) { if (nstep.PreStepId == null) nstep.PreStepId = new List(); nstep.PreStepId.Add(step.Id.ToString()); } } else { if (nextstep.PreStepId == null) nextstep.PreStepId = new List(); nextstep.PreStepId.Add(step.Id.ToString()); } } } var oAStartStep = oASteps.Single(p => p.Kind == NodeKinds.Start); if (string.IsNullOrEmpty(oAStartStep.NextStepId)) { throw new Exception("开始节点没有下一个节点"); } string nextstepid = oAStartStep.NextStepId; var nodes = InitStep(oASteps, nextstepid); nodes.Insert(0, oAStartStep); FlowNodes.Add(viewModel, nodes); if (initNew) { Approve(oAStartStep, 100); } } /// /// 初始化步骤 /// /// /// /// public static List InitStep(List oASteps, string nextstepid) { List outsteps = new List(); List nextids = new List(); var step = oASteps.FirstOrDefault(p => p.Id.ToString() == nextstepid); if (step != null) { if (!string.IsNullOrEmpty(step.NextStepId)) { nextids.Add(step.NextStepId); } else if (step.SelectNextStep != null && step.SelectNextStep.Count > 0) { nextids.AddRange(step.SelectNextStep.Keys); } outsteps.Add(step); oASteps.Remove(step); } int index = outsteps.IndexOf(step); nextids.Reverse(); foreach (var next in nextids) { outsteps.InsertRange(index + 1, InitStep(oASteps, next)); } return outsteps; } /// /// 审批动作,因为是客户端模拟,假设每次都是该节点的审批人进行的操作 /// /// /// /// public static void Approve(FlowNode flowNode, int status, string remark = null) { switch (status) { case 100: if (flowNode is MiddleFlowNode middleFlowNode) { if (string.IsNullOrEmpty(flowNode.Remark)) { remark = "审批人:" + remark; } else { remark = flowNode.Remark + "\r审批人:" + remark; } if (middleFlowNode.ActType == "and")//如果是与签,那么要都审批通过 { if (middleFlowNode.UserIds != null && middleFlowNode.UserIds.Count > 1) { //实际情况不是这样的,这里只是演示,简化。 int count = remark.Split(new String[] { "审批人:" }, StringSplitOptions.RemoveEmptyEntries).Length; if (middleFlowNode.UserIds.Count != count) { SetStatus(flowNode, 1, remark); return; } } else if (middleFlowNode.RoleIds != null && middleFlowNode.RoleIds.Count > 1) { //实际情况不是这样的,这里只是演示,简化。 int count = remark.Split(new String[] { "审批人:" }, StringSplitOptions.RemoveEmptyEntries).Length; if (middleFlowNode.RoleIds.Count != count) { SetStatus(flowNode, 1, remark); return; } } } } SetStatus(flowNode, status, remark); if (!string.IsNullOrEmpty(flowNode.NextStepId)) { Next(flowNode.NextStepId, flowNode); } else if (flowNode.SelectNextStep != null && flowNode.SelectNextStep.Count > 0) { foreach (var step in flowNode.SelectNextStep) { Next(step.Key, flowNode); } } break; case 2: if (Pre(flowNode)) { SetStatus(flowNode, status, remark); } else { MessageBox.Show("该节点不支持驳回上一级"); } break; case 3: SetStatus(flowNode, status, remark); FlowNodes[flowNode.Root].ForEach(p => { if (p.Status == 100) p.Status = 0; }); Approve(FlowNodes[flowNode.Root][0], 100); MessageBox.Show("流程重新开始"); break; case 4: SetStatus(flowNode, status, remark); MessageBox.Show("流程否决"); break; } } /// /// 流向下一个节点 /// /// public static void Next(string stepid, FlowNode flowNode) { FlowNode nextNode = FlowNodes[flowNode.Root].FirstOrDefault(p => p.Id.ToString() == stepid); SetStatus(nextNode, 1); switch (nextNode.Kind) { case NodeKinds.Start: SetStatus(nextNode, 100); Next(nextNode.NextStepId, nextNode); break; case NodeKinds.End: SetStatus(nextNode, 100); MessageBox.Show("流程完成"); break; case NodeKinds.Decide: foreach (var step in nextNode.SelectNextStep) { try { //按条件选择一个分支 string expression = step.Value.Replace("data.Flag", nextNode.Text); var result = new DataTable().Compute(expression, ""); if (result.Equals(true)) { SetStatus(nextNode, 100); Next(step.Key, nextNode); return; } } catch (Exception ex) { } } //如果表达式错了,就按第一个处理 Next(nextNode.SelectNextStep.FirstOrDefault().Key, nextNode); break; case NodeKinds.COBegin: foreach (var step in nextNode.SelectNextStep)//启动各个分支 { SetStatus(nextNode, 100); Next(step.Key, nextNode); } break; case NodeKinds.COEnd: foreach (var prestep in nextNode.PreStepId) { var step = FlowNodes[flowNode.Root].FirstOrDefault(p => p.Id.ToString() == prestep); if (step.Status != 100)//如果并行分支没有都完成,那么并行结束节点也未完成 { return; } } SetStatus(nextNode, 100); Next(nextNode.NextStepId, nextNode); break; } } /// /// 流向上一个节点 /// /// /// public static bool Pre(FlowNode flowNode) { if (flowNode.PreStepId != null && flowNode.PreStepId.Count == 1) { FlowNode preNode = FlowNodes[flowNode.Root].FirstOrDefault(p => p.Id.ToString() == flowNode.PreStepId[0]); if (preNode.Kind == NodeKinds.Middle) { SetStatus(preNode, 1); return true; } } return false; } /// /// 设置颜色 /// /// /// /// public static void SetStatus(FlowNode flowNode, int status, string remark = null) { flowNode.Status = status; flowNode.Remark = remark; switch (status) { case 100: flowNode.StatusColor = Colors.Green.ToString(); break; case 0: flowNode.StatusColor = Colors.Yellow.ToString(); break; case 1: flowNode.StatusColor = Colors.Orange.ToString(); break; case 2: flowNode.StatusColor = Colors.Red.ToString(); break; case 3: flowNode.StatusColor = Colors.Red.ToString(); break; case 4: flowNode.StatusColor = Colors.Red.ToString(); break; } } public static void Dispose(IDiagramViewModel viewModel) { FlowNodes.Remove(viewModel); } } }