using BaseOUDAL; using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using OfficeOpenXml.FormulaParsing.ExpressionGraph; using System.Linq; using System.Linq.Expressions; using YLErp.BLL.Eod; using YLErp.DBModels; using YLErp.Helpers; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Modules.TradeModule; namespace YLErp.Modules.SystemModule { /// /// 审批流程业务服务 /// public class ApprovalProcessService : YLBaseService { public ApprovalProcessService(OptUserInfo optUser) : base(optUser) { } /// /// 添加审批流程(变更或删除) /// public int AddProcess(string type, List data) { var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable(); if (type == "ClientBlackProcess") { var clientdb = DbContextFactory.GetClientDbContext(OptUser); if (clientdb.client_black.Any(x => x.State == client_black.新增审批中 || x.State == client_black.删除审批中)) { throw new ServiceException(data == null || data.Count == 0 ? "有黑名单在审批中,不能删除审批流程!" : "有黑名单在审批中,不能修改审批流程!"); } } var delList = DbContext.approvalprocess.Where(s => s.processType == type).ToArray(); DbContext.approvalprocess.RemoveRange(delList); if (data != null && data.Count > 0) { data = data.OrderBy(s => s.Index).ToList(); var list = data.Select(item => new approvalprocess { processType = item.Type, order = item.Index, roleId = item.SelectValue, ruleType = item.ApprovalRules, approvalGroupId = item.approvalGroupId, node = item.node, parentNode = item.parentNode, approvalCondition = item.approvalCondition, conditionConfig = item.conditionConfig, triggerCondition = item.triggerCondition, isOaApproval = item.isOaApproval }).ToList(); DbContext.approvalprocess.AddRange(list); } if (type == "OpenProcess") { List optTypes = new List() { "提交开户审批", "重新提交开户审批" }; var clients = GetClients(optTypes); if (data == null || data.Count == 0) { if (clients != null && clients.Count > 0) { throw new ServiceException("有用户在审批中,不能删除审批流程!"); } } else { ChangeClientProcess(data, clients, delList); } } else if (type == "TradeProcess") { if (data != null && data.Count > 0) { ChangeTradeProcess(data, delList); } else { var trade = DbContext.trade.Where(x => x.ValidState == "Valid" && (x.TradeStatus == ConsTrade.审批中 || x.TradeStatus == ConsTrade.平仓待复核 || x.TradeStatus == ConsTrade.行权待复核 || x.TradeStatus == ConsTrade.互换待复核)).ToList(); if (trade != null && trade.Count > 0) { throw new ServiceException("有交易在审批中,不能删除审批流程!"); } } } else if (type == ProcessCategoryConst.Close) // 需求②:了结/平仓/行权审批流程 { if (data != null && data.Count > 0) { ChangeTradeProcess(data, delList); } else { var trade = DbContext.trade.Where(x => x.ValidState == "Valid" && (x.TradeStatus == ConsTrade.平仓待复核 || x.TradeStatus == ConsTrade.行权待复核 || x.TradeStatus == ConsTrade.互换待复核)).ToList(); if (trade != null && trade.Count > 0) { throw new ServiceException("有交易在审批中,不能删除审批流程!"); } } } else if (type == "CreditProcess") { if (data != null && data.Count == 0) { var credit = DbContext.credit.Where(x => x.ProcessOrderId > 1).ToList(); credit.ForEach(x => x.ProcessOrderId = 1); var clientdb = DbContextFactory.GetClientDbContext(OptUser); var clientrating = clientdb.Client_Rating.Where(x => !x.IsDeleted && x.ProcessOrderId > 1).ToList(); clientrating.ForEach(x => x.ProcessOrderId = 1); clientdb.SaveChanges(); } else { var credit = DbContext.credit.Where(x => x.ProcessStatus == "审批中").ToList(); if (credit != null && credit.Count > 0) { throw new ServiceException("有授信在审批中,不能删除审批流程!"); } var clientrating = DbContextFactory.GetClientDbContext(OptUser).Client_Rating.Where(x => !x.IsDeleted && x.ProcessStatus == "审批中").ToList(); if (clientrating != null && clientrating.Count > 0) { throw new ServiceException("有资信评级在审批中,不能删除审批流程!"); } } } else if (type == "OutCashProcess") { var clientCashs = DbContext.ClientCashInCashOut.Where(x => x.State == "审批中").ToList(); if (clientCashs != null && clientCashs.Count > 0) { if (data == null || data.Count == 0) { throw new ServiceException("有资金在审批中,不能删除审批流程!"); } else { throw new ServiceException("有资金在审批中,不能修改审批流程!"); } } } else if (type == "ClientProcess") { List optTypes = new List() { "提交信息变更审批" }; var clients = GetClients(optTypes); if (data == null || data.Count == 0) { if (clients != null && clients.Count > 0) { throw new ServiceException("有用户在审批中,不能删除审批流程!"); } } else { ChangeClientProcess(data, clients, delList); } } return DbContext.SaveChanges(); } #region 交易审批流程 私有方法 /// /// 交易审批流程 /// /// 待保存数据 /// 旧数据 /// 分支节点 /// 节点 /// /// private void ChangeTradeProcess(List data, approvalprocess[] delList) { var trades = DbContext.trade.Where(x => x.ValidState == "Valid" && (x.TradeStatus == ConsTrade.审批中 || x.TradeStatus == ConsTrade.平仓待复核 || x.TradeStatus == ConsTrade.行权待复核 || x.TradeStatus == ConsTrade.互换待复核)).ToList(); var noGroupData = data.Where(x => x.approvalGroupId == 0); var branch = data.Where(x => x.approvalGroupId != 0);//修改有分支 var groupId = UserBLL.GetApprovalProcessGroup(UserInfo.UserId); var oldBranch = delList.Where(x => x.approvalGroupId != 0);//旧流程有分支 bool NotChange = false;//不允许修改 if (oldBranch.Count() == 0 && branch.Count() > 0)//旧流程无分支,新流程有分支 { NotChange = true; } if (oldBranch.Count() > 0 && branch.Count() == 0)//旧流程有分支,新流程无分支 { NotChange = true; } if (NotChange) { if (trades != null && trades.Count > 0) { throw new ServiceException("有交易在审批中,不能修改审批流程!"); } } if (branch.Count() > 0)//有分支情况 { if (groupId == 0) { throw new Exception("该申请人不符合任何条件分支"); } TradeProcessHasChange(data, delList, trades, groupId); } else //无分支情况直接修改 { UpdateTradeAudit(ProcessTradeLog.审批中, 0); } } /// /// 回到审批初始节点 /// /// /// private void UpdateTradeAudit(int processOrderId, int oldBranchNode, bool all = false) { Expression> expression = x => x.ProcessOrderId >= ProcessTradeLog.审批中; if (!all) { expression = expression.And(x => x.ProcessOrderBranch == oldBranchNode); } var trades = DbContext.trade.Where(expression).ToList(); trades.ForEach(x => { x.ProcessOrderId = processOrderId; x.CheckStatus = 0; }); } /// /// 有分支情况有修改 /// /// 新数据 /// 旧数据 /// 交易数据 /// private void TradeProcessHasChange(List data, approvalprocess[] delList, List trades, int groupId) { var processOrderId = data.Min(s => s.Index); var branchData = data.Where(x => x.approvalGroupId != 0);//修改有分支 var approvalConditionFirst = branchData.FirstOrDefault(x => x.approvalGroupId == groupId && x.approvalCondition == 1);//属于某个审批组 var approvalConditionSecend = branchData.FirstOrDefault(x => x.approvalGroupId != groupId && x.approvalCondition == 2);//不属于某个审批组 var approvalProcess = approvalConditionFirst == null ? approvalConditionSecend : approvalConditionFirst; if (approvalProcess == null) { throw new Exception("该申请人不符合任何条件分支"); } var branchNode = approvalProcess.node; var branch = branchData.First();//分支节点所在位置 var dataIds = data.Where(x => x.id != 0).Select(s => s.id).ToList(); var changeNodeIndexs = ProcessChangeIndex(data, delList); bool NotChange = false;//不允许修改 var firstBranchTrades = trades.Where(x => x.ProcessOrderBranch == 1).ToList(); var secondBranchTrades = trades.Where(x => x.ProcessOrderBranch == 2).ToList(); if (branch.Index == processOrderId)//跳过审批组流程 { processOrderId = processOrderId + 1; } //判断数据是否有变更 if (changeNodeIndexs.Count > 0) { var firstChange = changeNodeIndexs.Any(x => x.node == 1);//分支1有修改 var secondChange = changeNodeIndexs.Any(x => x.node == 2);//分支2有修改 var main = data.Any(x => x.node == 0);//新流程有主干 var mainChange = changeNodeIndexs.Any(x => x.node == 0);//有主节点修改-包括新增&删除 if (main || mainChange) { if (firstChange || secondChange)// 分支不可修改 { if (trades.Count > 0)//有交易审批,不允许修改 { NotChange = true; } } else { if (mainChange && trades.Count > 0) //主节点修改回到初始 { UpdateTradeAudit(processOrderId, 0, true); } } } else { if (firstChange && secondChange)//分支1,2有修改 { if (trades.Count > 0)//有交易审批,不允许修改 { NotChange = true; } } else if (firstChange && !secondChange)//只修改了分支1 { if (firstBranchTrades.Count > 0) { NotChange = true; } } else if (!firstChange && secondChange)//只修改了分支2 { if (secondBranchTrades.Count > 0) { NotChange = true; } } } if (NotChange) { throw new ServiceException("有交易在审批中,不能修改审批流程!"); } } } /// /// 获取数据修改节点集合 /// /// 新数据 /// 旧数据 /// private List ProcessChangeIndex(List data, approvalprocess[] oldList) { List indexList = new List(); foreach (var item in oldList)//筛选删除的节点 { ApprovalProcessNode upNode = new ApprovalProcessNode(); var addNode = data.FirstOrDefault(x => x.id == item.id); if (addNode == null) { upNode.node = item.node ?? 0; upNode.Index = item.order; indexList.Add(upNode); } } foreach (ApprovalProcessAddRequest item in data)//筛选新增及修改节点 { ApprovalProcessNode upNode = new ApprovalProcessNode(); if (item.id == 0) { upNode.node = item.node; upNode.Index = item.Index; indexList.Add(upNode); } var oldData = oldList.FirstOrDefault(x => x.id == item.id); if (oldData != null) { if (item.approvalGroupId != oldData.approvalGroupId || item.approvalCondition != oldData.approvalCondition || item.ApprovalRules != oldData.ruleType || item.SelectValue != oldData.roleId) { upNode.node = item.node; upNode.Index = item.Index; indexList.Add(upNode); } } } return indexList; } #endregion #region 客户开户&客户信息 /// /// 开户审批流程 /// /// 待保存数据 /// 旧数据 /// 分支节点 /// 节点 /// /// private void ChangeClientProcess(List data, List clients, approvalprocess[] delList) { var noGroupData = data.Where(x => x.approvalGroupId == 0); var branch = data.Where(x => x.approvalGroupId != 0);//修改有分支 var groupId = UserBLL.GetApprovalProcessGroup(UserInfo.UserId); var oldBranch = delList.Where(x => x.approvalGroupId != 0);//旧流程有分支 bool NotChange = false;//不允许修改 if (oldBranch.Count() == 0 && branch.Count() > 0)//旧流程无分支,新流程有分支 { NotChange = true; } if (oldBranch.Count() > 0 && branch.Count() == 0)//旧流程有分支,新流程无分支 { NotChange = true; } if (NotChange) { if (clients != null && clients.Count > 0) { throw new ServiceException("有用户在审批中,不能更改审批流程!"); } } if (branch.Count() > 0)//有分支情况 { if (groupId == 0) { throw new Exception("该申请人不符合任何条件分支"); } ClientProcessHasChange(data, delList, clients, groupId); } else //无分支情况直接修改 { UpdateClientAudit(ProcessTradeLog.审批中, 0, clients); } } /// /// 回到审批初始节点 /// /// /// private void UpdateClientAudit(int processOrderId, int oldBranchNode, List clients, bool all = false) { var clientdb = DbContextFactory.GetClientDbContext(OptUser); if (!all) { clients = clients.Where(x => x.ProcessOrderBranch == oldBranchNode).ToList(); } var cids = clients.Select(x => x.id).ToList(); var range = clientdb.client_file_audit.Where(x => cids.Contains(x.ClientId)).ToList(); clientdb.client_file_audit.RemoveRange(range); for (int i = 0; i < clients.Count; i++) { Client c = clientdb.client.Find(clients[i].id); c.ApprovalOrderId = processOrderId; } clientdb.SaveChanges(); } private List GetClients(List optTypes) { var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable().Where(x => x.ApprovalOrderId >= ProcessTradeLog.审批中).ToList(); var clientdb = DbContextFactory.GetClientDbContext(OptUser); var clientQuerys = from c in clientQuery join audit in clientdb.ClientAuditLog.Where(x => optTypes.Contains(x.OptType)) on c.ApprovalLogId equals audit.id select c; var clients = clientQuerys.ToList(); return clients; } #endregion /// /// 有分支情况有修改 /// /// 新数据 /// 旧数据 /// 交易数据 /// private void ClientProcessHasChange(List data, approvalprocess[] delList, List clients, int groupId) { var processOrderId = data.Min(s => s.Index); var branchData = data.Where(x => x.approvalGroupId != 0);//修改有分支 var approvalConditionFirst = branchData.FirstOrDefault(x => x.approvalGroupId == groupId && x.approvalCondition == 1);//属于某个审批组 var approvalConditionSecend = branchData.FirstOrDefault(x => x.approvalGroupId != groupId && x.approvalCondition == 2);//不属于某个审批组 var approvalProcess = approvalConditionFirst == null ? approvalConditionSecend : approvalConditionFirst; if (approvalProcess == null) { throw new Exception("该申请人不符合任何条件分支"); } var branchNode = approvalProcess.node; var branch = branchData.First();//分支节点所在位置 var dataIds = data.Where(x => x.id != 0).Select(s => s.id).ToList(); var changeNodeIndexs = ProcessChangeIndex(data, delList); bool NotChange = false;//不允许修改 var firstBranchClients = clients.Where(x => x.ProcessOrderBranch == 1).ToList(); var secondBranchClients = clients.Where(x => x.ProcessOrderBranch == 2).ToList(); if (branch.Index == processOrderId)//跳过审批组流程 { processOrderId = processOrderId + 1; } //判断数据是否有变更 if (changeNodeIndexs.Count > 0) { var firstChange = changeNodeIndexs.Any(x => x.node == 1);//分支1有修改 var secondChange = changeNodeIndexs.Any(x => x.node == 2);//分支2有修改 var main = data.Any(x => x.node == 0);//新流程有主干 var mainChange = changeNodeIndexs.Any(x => x.node == 0);//有主节点修改-包括新增&删除 if (main || mainChange) { if (firstChange|| secondChange)// 分支不可修改 { if (clients.Count > 0)//有交易审批,不允许修改 { NotChange = true; } } else { if (mainChange&& clients.Count > 0) //主节点修改回到初始 { UpdateClientAudit(processOrderId, 0, clients, true); } } } else { if (firstChange && secondChange)//分支1,2有修改 { if (clients.Count > 0)//有交易审批,不允许修改 { NotChange = true; } } else if (firstChange && !secondChange)//只修改了分支1 { if (firstBranchClients.Count > 0) { NotChange = true; } } else if (!firstChange && secondChange)//只修改了分支2 { if (secondBranchClients.Count > 0) { NotChange = true; } } } if (NotChange) { throw new ServiceException("有用户在审批中,不能修改审批流程!"); } } } /// /// 投资规模审核 /// public bool CheckTradeScale(trade trade) { var orderId = trade.ProcessOrderId; var um = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(trade.UnderlyingId); if (um == null) { return true; } //2021/06/23 规模审批使用deltaCash var UsedScale = 0.0; // 如果是审批组 var tradeProcess = TradeProcess(); var orderIdCount = tradeProcess.Where(x => x.order == trade.ProcessOrderId);//判断是否有分支 int orderNode = orderIdCount.Count() > 1 ? trade.ProcessOrderBranch : 0; if (orderIdCount.Count() == 1) { orderNode = orderIdCount.First().node ?? 0; } var roleId = tradeProcess.OrderBy(o => o.order).FirstOrDefault(o => o.order == orderId && o.node == orderNode && o.processType == "TradeProcess").roleId; var approvalGrade = DbContext.approvalGrade.FirstOrDefault(o => o.RoleId == roleId && o.AssetId == trade.AssetId && o.Rule == RuleEnum.投资规模); List trades; var underlyingPrice = DataCacheProvider.GetUnderlyingDataSource(); trades = (from t in DbContext.trade join u in DbContext.underlying_manager on t.UnderlyingId equals u.id where t.AssetId == trade.AssetId && t.TradeType != "结构化交易" && ConsTrade.PositionTradeStatusList.Contains(t.TradeStatus) && !ConsTrade.TradeTypesForHedge.Contains(t.TradeType) && t.ValidState != "InValid" select t).ToList(); trades.Add(trade); BLL.tradeBLL.SetFieldsByTradeType(trade); if (trades != null && trades.Count > 0) { var riskList = RealtimePnlCalc.RealTimeRiskCalc(SystemValueDate, trades, underlyingPrice, new List { "持仓" }, false, QdpModule.QdpPricingRequest.BASIC_PRICING); UsedScale += riskList.Sum(o => (o.DeltaCash ?? 0)); } if (approvalGrade != null) { return UsedScale <= (approvalGrade.DeltaCashScale ?? 0); } return false; } public bool CheckTradeScale(int enid) { var trade = DbContext.trade.FirstOrDefault(o => o.id == enid); if (trade != null) { return CheckTradeScale(trade); } else { throw new ServiceException("未找到交易"); } } /// /// 仅审批投资规模的步骤 /// /// /// -2:该步骤存在字段审核没审核或者没有规模审核 -1:规模审核未过 0:审核直接通过 1:规模审核通过,之后的流程中存在字段审核 public int CheckTradeApprovalStep(trade trade, int userId, bool hadCheckParam = false) { var roles = UserBLL.GetRolesByUserId(userId).Select(o => o.Id); var groupId = UserBLL.GetApprovalProcessGroup(userId); // 需求②:按交易状态推断开仓/了结流程。 var tradeProcess = TradeProcessByCategory(trade); bool approvalBranch = tradeProcess.Any(x => x.approvalGroupId != 0);//审批流程有分支情况 trade.ProcessOrderBranch = 0; if (trade.ProcessOrderId <= 0) { if (approvalBranch)//审批流程有分支情况 { //该审批组属于流程的审批组或该审批组不属于流程审批组 var tradeProessBranchQuery = tradeProcess.FirstOrDefault(x => (x.approvalGroupId == groupId && x.approvalCondition == 1) || (x.approvalGroupId != groupId && x.approvalCondition == 2)); if (tradeProessBranchQuery == null)//都没有情况 { return -3; } trade.ProcessOrderId = ProcessTradeLog.审批中; if (trade.ProcessOrderId >= tradeProessBranchQuery.order) { trade.ProcessOrderId = tradeProessBranchQuery.order + 1;//跳过审批组那一级 } trade.ProcessOrderBranch = tradeProessBranchQuery.node ?? 1;//审批组分子 if (!tradeProcess.Any(x => x.order >= trade.ProcessOrderId && (x.node == trade.ProcessOrderBranch || x.node == 0)))//分支无需审批,直接通过 { trade.ProcessOrderId = ProcessTradeLog.审批通过; trade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew); trade.ProcessOptDate = DateTime.Now; trade.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); return 0; } } else { trade.ProcessOrderId = ProcessTradeLog.审批中; } } // 需求①:开仓交易首次进入审批时,应用触发条件——跳过起始就不满足触发条件的节点。 // 若所有节点均不满足 → 直接审批通过,无需审核。 if (tradeProcess.Count > 0) { ApplyTriggerOnStart(tradeProcess, trade, userId); if (trade.ProcessOrderId == ProcessTradeLog.审批通过) { return 0; } } // 如果是审批组 var orderIdCount = tradeProcess.Where(x => x.order == trade.ProcessOrderId);//判断是否有分支 int processOrderNode = orderIdCount.Count() > 1 ? trade.ProcessOrderBranch : 0; if (orderIdCount.Count() == 1) { processOrderNode = orderIdCount.First().node ?? 0; } var NowProcess = tradeProcess.FirstOrDefault(o => o.order == trade.ProcessOrderId && o.node == processOrderNode && roles.Contains(o.roleId)); trade.TradeStatus = ConsTrade.审批中; trade.ProcessStatus = ProcessTradeStatus.审批中.ToString(); trade.ProcessOptDate = DateTime.Now; if (NowProcess != null && NowProcess.ruleType != null && (NowProcess.ruleType == "1" || (NowProcess.ruleType.Contains("1") && hadCheckParam))) { if (CheckTradeScale(trade)) { var process = tradeProcess.FirstOrDefault(o => o.ruleType != null && o.ruleType.Contains("0") && o.order > NowProcess.order && o.node == processOrderNode); if (process != null) { trade.ProcessOrderId = process.order; return 1; } else { trade.ProcessOrderId = ProcessTradeLog.审批通过; trade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew); trade.ProcessOptDate = DateTime.Now; trade.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); return 0; } } else { var lastScaleProcessOrder = tradeProcess.Where(o => o.ruleType.Contains("1")).Select(o => o.order).Max(); if (trade.ProcessOrderId >= lastScaleProcessOrder) { throw new ServiceException($"该交易'{trade.TradeNumber}'规模审批流程最后一步的审批角色对审批簿记的投资规模依然不足!"); } trade.ProcessOrderId = trade.ProcessOrderId + 1; } return -1; } return -2; } /// /// 需求①:开仓交易首次进入审批流程时,从起始节点应用触发条件。 /// 跳过起始就不满足触发条件的节点;若所有节点均不满足 → 直接审批通过。 /// private void ApplyTriggerOnStart(List tradeProcess, trade trade, int userId) { // 取当前起点节点(主干 node=0) var start = tradeProcess.FirstOrDefault(x => x.order == trade.ProcessOrderId && x.node == 0); if (start == null) { start = tradeProcess.FirstOrDefault(x => x.order >= trade.ProcessOrderId && x.node == 0); } if (start == null) return; // 构建求值上下文(开仓场景无 trade_cash,CurrentNotional 不设) var ctx = new ConditionContext { UserId = userId, Trade = trade, ProcessCategory = ProcessCategoryConst.Resolve(trade), InitGroupId = UserBLL.GetApprovalProcessGroup(userId) }; var target = ConditionEvaluator.FindFirstTriggeredNode(tradeProcess, start, ctx); if (target == null) { // 所有节点都不满足触发条件 → 直接审批通过 trade.ProcessOrderId = ProcessTradeLog.审批通过; trade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew); trade.ProcessOptDate = DateTime.Now; trade.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); return; } if (target.order != trade.ProcessOrderId) { trade.ProcessOrderId = target.order; } } /// /// 获取所有交易审批节点 /// /// public List TradeProcess() { var tradeOrders = DbContext.approvalprocess.Where(t => t.processType == "TradeProcess").OrderBy(o => o.order).ToList(); return tradeOrders; } /// /// 按交易推断流程类别(开仓/了结)获取审批节点(需求②)。 /// 了结类优先取 CloseProcess;未配置则回退 TradeProcess。 /// public List TradeProcessByCategory(trade td) { var category = ProcessCategoryConst.Resolve(td); var orders = DbContext.approvalprocess.Where(t => t.processType == category).OrderBy(o => o.order).ToList(); if (category == ProcessCategoryConst.Close && orders.Count == 0) { return TradeProcess(); } return orders; } } /// /// 添加审批流程请求 /// public class ApprovalProcessAddRequest { public int id { get; set; } public string Type { get; set; } public int Index { get; set; } public int SelectValue { get; set; } public string ApprovalRules { get; set; } public int approvalGroupId { get; set; } public int node { get; set; } public int parentNode { get; set; } public int approvalCondition { get; set; } /// 分支网关条件(JSON),需求①③共用。为空则回退旧 approvalGroupId/approvalCondition 二元判断。 public string conditionConfig { get; set; } /// 节点触发条件(JSON),需求①:满足才进入该审批节点,不满足则跳过。 public string triggerCondition { get; set; } public bool isOaApproval { get; set; } } /// /// 审批流程修改节点 /// public class ApprovalProcessNode { public int Index { get; set; } public int node { get; set; } } }