using BaseOUDAL; using YLErp.BLL; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.Helpers; namespace YLErp.Modules.TradeModule { /// /// 交易服务基类 /// public class TradeServiceBase : YLBaseService { int? _tradeProcessCount; public TradeServiceBase(YLBaseService baseService) : base(baseService) { } public TradeServiceBase(OptUserInfo userInfo) : base(userInfo) { } public TradeServiceBase(OptUserInfo userInfo, YLContext dbContext) : base(userInfo, dbContext) { } /// /// 是否有交易审批(复核)任务 /// protected bool HasTradeProcess() { return TradeProcessCount() > 0; } /// /// 交易审批(复核)任务数量 /// public int TradeProcessCount() { if (_tradeProcessCount == null) { _tradeProcessCount = DbContext.approvalprocess.Count(t => t.processType == "TradeProcess"); } return _tradeProcessCount.Value; } /// /// 获取所有交易审批节点(开仓流程 TradeProcess)。 /// 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 = ResolveProcessCategory(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 int TradeProcessCountByCategory(trade td) { return TradeProcessByCategory(td).Count; } /// /// 初始化交易 审批点 /// /// public void InitTradeProcessOrder(trade td,int userId) { td.ProcessOrderId = ProcessTradeLog.审批中; td.ProcessStatus = ProcessTradeStatus.审批中.ToString(); var tradeProcess = TradeProcessByCategory(td); var groupId = UserBLL.GetApprovalProcessGroup(userId); bool approvalBranch = tradeProcess.Any(x => x.approvalGroupId != 0);//审批流程有分支情况 if (td.ProcessOrderId == 1) { if (approvalBranch)//审批流程有分支情况 { //该审批组属于流程的审批组或该审批组不属于流程审批组 var tradeProessBranchQuery = tradeProcess.FirstOrDefault(x => (x.approvalGroupId == groupId && x.approvalCondition == 1) || (x.approvalGroupId != groupId && x.approvalCondition == 2)); if (tradeProessBranchQuery == null)//都没有情况 { throw new ServiceException("当前存在分支交易审批流程,检测到申请人不满足任意一个分支进入条件,无法提交审批,请更换申请人或调整审批组"); } td.ProcessOrderBranch = tradeProessBranchQuery.node ?? 1;//审批组分子 } else { td.ProcessOrderBranch = 0; } } var branch = tradeProcess.Where(x=>x.node==td.ProcessOrderBranch).OrderBy(o=>o.order); var branchFirst= branch.FirstOrDefault(); if (branchFirst!=null&& branchFirst.order==1&& td.ProcessOrderBranch!=0) { td.ProcessOrderId = 2; } // 需求①:进入审批流程时即应用触发条件——从起始节点开始,跳过所有不满足触发条件的节点。 // 若所有节点均不满足 → 直接审批通过(无需任何人审核)。 ApplyTriggerFromStart(tradeProcess, td, userId); } /// /// 从当前 ProcessOrderId 起点开始,按触发条件跳过无需审批的节点(需求①)。 /// 场景:交易提交进入审批流程时,若节点1、2配置的触发条件均不满足,则直接跳到节点3; /// 若全部节点都不满足,则直接审批通过。 /// private void ApplyTriggerFromStart(List tradeProcess, trade td, int userId) { if (tradeProcess == null || tradeProcess.Count == 0) return; // 取当前起点节点(主干 node=0) var current = tradeProcess.FirstOrDefault(x => x.order == td.ProcessOrderId && x.node == 0); // 若起点不在主干(如分支调整后 ProcessOrderId=2),取该 order 的主干节点 if (current == null) { current = tradeProcess.FirstOrDefault(x => x.order >= td.ProcessOrderId && x.node == 0); } if (current == null) return; var ctx = BuildTriggerContext(td, userId); var target = ConditionEvaluator.FindFirstTriggeredNode(tradeProcess, current, ctx); if (target == null) { // 所有节点都不满足触发条件 → 直接审批通过,无需审核 td.ProcessOrderId = ProcessTradeLog.审批通过; td.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); td.ProcessOptDate = DateTime.Now; return; } // target 即为第一个满足触发条件、需实际审批的节点 if (target.order != td.ProcessOrderId) { td.ProcessOrderId = target.order; } } /// /// 节点触发条件(需求①):在已确定下一审批节点 nextOrder 后,若该节点配置了 triggerCondition, /// 则只有「满足触发条件」才进入该节点审批;不满足则跳过该节点,继续向后寻找,直到找到可进入的节点或抵达流程末尾。 /// 语义:triggerCondition 为空 → 无条件进入审批;非空 → 满足才进入,不满足则跳过。 /// 非侵入式:原有分支推进逻辑不变,仅在其结果之上叠加触发判断循环。 /// /// 当前流程的全部节点(已按 order 排序) /// 原逻辑计算出的下一节点(可能为 null) /// 条件求值业务上下文(已含 trade、本次交易名义本金等) /// 最终应推进到的节点;若应结束流程则返回 null protected static approvalprocess AdvanceThroughTriggerNodes( List tradeProcess, approvalprocess nextOrder, ConditionContext ctx) { // 不满足触发条件的节点需跳过:循环向后找第一个可进入的节点。 while (nextOrder != null && !string.IsNullOrWhiteSpace(nextOrder.triggerCondition)) { if (ConditionEvaluator.Evaluate(nextOrder.triggerCondition, ctx)) { break; // 满足触发条件 → 进入该节点审批,停止跳过。 } // 不满足触发条件 → 跳过该节点,向后取下一个主干节点(node=0),继续判断。 nextOrder = tradeProcess.FirstOrDefault(x => x.order > nextOrder.order && x.node == 0); } return nextOrder; } /// /// 构建触发条件求值上下文:从 trade 及其关联的 trade_cash 取本次交易名义本金(了结场景)。 /// 本次交易名义本金 = 本次了结操作的 trade_cash.UnwindStockEqvNotional 绝对值。 /// protected ConditionContext BuildTriggerContext(trade td, int userId) { var ctx = new ConditionContext { UserId = userId, Trade = td, ProcessCategory = ResolveProcessCategory(td), InitGroupId = UserBLL.GetApprovalProcessGroup(userId) }; // 了结场景:取本次影响的名义本金(trade_cash.UnwindStockEqvNotional 绝对值) if (td != null && ctx.ProcessCategory == ProcessCategoryConst.Close) { var tc = DbContext.trade_cash .Where(t => t.TradeId == td.id && t.ValidState == ConsGlobal.InValid && !t.IsDeleted) .OrderByDescending(t => t.id) .FirstOrDefault(); if (tc != null && tc.UnwindStockEqvNotional.HasValue) { ctx.CurrentNotional = Math.Abs(tc.UnwindStockEqvNotional.Value); } } return ctx; } /// /// 按交易状态推断流程类别:开仓(TradeProcess) / 了结(CloseProcess)。需求②。 /// 委托给 ProcessCategoryConst.Resolve,供全局复用。 /// protected static string ResolveProcessCategory(trade td) { return ProcessCategoryConst.Resolve(td); } /// /// 添加交易操作日志 /// protected void AddTradeOperationHistoryAndSetParentTradeInfo(bool saveChanges, OtcTradeBase trade, string optType, string comments = null) { DbContext.TradeAuditLog.Add(new TradeAuditLog { TradeId = trade.id, AuditFlag = TradeAuditFlag.operation, OptType = optType, Changes = comments ?? string.Empty, DataType = "00", OptId = UserId, OptName = UserName, OptDate = OptDate }); if (trade.IsGroup == 0) { SetParentTrade(trade); } if (saveChanges) { DbContext.SaveChanges(); } } /// /// 保存交易操作日志(调用SaveChanges) /// protected void SaveTradeOperationHistory(OtcTradeBase trade, string optType, string Comments = null) { AddTradeOperationHistoryAndSetParentTradeInfo(true, trade, optType, Comments); } /// /// 添加交易元数据 /// public void AddTradeMeta(bool saveChanges, int tradeId, string metaKey, string metaValue) { DbContext.TradeMeta.Add(new TradeMeta { TradeId = tradeId, MetaKey = metaKey, MetaValue = metaValue, CreateTime = DateTime.Now }); if (saveChanges) { DbContext.SaveChanges(); } } /// /// 添加或更新交易元数据 /// protected void AddOrUpdateTradeMeta(bool saveChanges, int tradeId, string metaKey, string metaValue) { new TradeMetaService(this).AddTradeMeta(tradeId, metaKey, metaValue, saveChanges); } /// /// 设置交易元数据 /// protected void SaveTradeMeta(int tradeId, string metaKey, string metaValue) { new TradeMetaService(this).AddTradeMeta(tradeId, metaKey, metaValue, true); } /// /// 移除指定交易的相关数据 /// /// /// 交易Id /// 删除数据开始日期 /// 指定要删除的TradeCash记录 public void RemoveEodTradeAndFutureInfo(bool saveChanges, int tradeId, DateTime removeStartDate, IEnumerable tradeCashIds = null, bool deleteOtherCashs = false, IEnumerable tradeCashPreIds = null, bool isDelTradeCashIncludeStartDay = false, bool backToBegin = false) { var tradeIds = new List { tradeId }; var trade = DbContext.trade.Find(tradeId); if (removeStartDate.Year < 2000) { removeStartDate = new DateTime(2000, 1, 1); } if (trade.ParentTradeId > 0 && trade.IsGroup == 0) { var pTrideId = trade.ParentTradeId; //DbContext.SetDebugLog(); var subIds = DbContext.eod_trade .Where(O => O.ValueDate >= removeStartDate && O.ParentTradeId == pTrideId) .Select(O => O.TradeId) .ToArray() .GroupBy(O => O) .Select(O => O.Key) .ToArray(); //查询eodTrade表中相同父交易id仅有一条记录,且包含当前Id,表示不存在兄弟交易,应同步删除主交易 if (subIds.Length <= 1 && subIds.Contains(tradeId)) { tradeIds.Add(trade.ParentTradeId); } } var delEodArr = DbContext.eod_trade.Where(O => tradeIds.Contains(O.TradeId) && O.ValueDate >= removeStartDate); DbContext.eod_trade.RemoveRange(delEodArr); var delBodArr = DbContext.bod_Trade.Where(O => tradeIds.Contains(O.TradeId) && O.ValueDate > removeStartDate); DbContext.bod_Trade.RemoveRange(delBodArr); if (deleteOtherCashs) { //其他收入其他收入/支出在删除资金记录时跟着删除 var delTcOthers = DbContext.trade_cash.Where(x => x.TradeId == tradeId && !x.IsDeleted && x.Action == ClientCashInCashOut.人工操作_其他); delTcOthers.ToList().ForEach(O => { O.ValidState = "InValid"; O.OptDate = DateTime.Now; O.IsDeleted = true; }); var delCashInCashOutOthers = DbContext.ClientCashInCashOut.Where(x => x.TradeId == tradeId && x.Action == ClientCashInCashOut.人工操作_其他); DbContext.ClientCashInCashOut.RemoveRange(delCashInCashOutOthers); } var delTCArr = new List(); var delTCPreArr = new List(); if (tradeCashIds != null && tradeCashIds.Any() || tradeCashPreIds != null && tradeCashPreIds.Any()) { if (tradeCashIds != null && tradeCashIds.Any()) { delTCArr = DbContext.trade_cash.Where(O => tradeCashIds.Contains(O.id) && !O.IsDeleted).ToList(); } if (tradeCashPreIds != null && tradeCashPreIds.Any()) { delTCPreArr = DbContext.trade_cash_pre.Where(O => tradeCashPreIds.Contains(O.id)).ToList(); } } else { if(isDelTradeCashIncludeStartDay) { delTCArr = DbContext.trade_cash.Where(O => O.TradeId == tradeId && (O.ValueDate >= removeStartDate && (O.HappenedDate == null || O.HappenedDate >= removeStartDate)) && O.ValidState != ConsGlobal.InValid && !O.IsDeleted).ToList(); if (removeStartDate.Year > 2000) { delTCArr = delTCArr.Where(O => O.Action != "系统操作-期权费" || O.Action == "系统操作-期权费" && O.ValueDate != trade.TradeDate && O.ValueDate != trade.PremiumPayDate).ToList(); } delTCPreArr = DbContext.trade_cash_pre.Where(x => x.TradeId == tradeId && x.HappenedDate >= removeStartDate).ToList(); } else { delTCArr = DbContext.trade_cash.Where(O => O.TradeId == tradeId && (O.ValueDate > removeStartDate && (O.HappenedDate == null || O.HappenedDate > removeStartDate)) && O.ValidState != ConsGlobal.InValid && !O.IsDeleted).ToList(); if (removeStartDate.Year > 2000) { delTCArr = delTCArr.Where(O => O.Action != "系统操作-期权费" || O.Action == "系统操作-期权费" && O.ValueDate != trade.TradeDate && O.ValueDate != trade.PremiumPayDate).ToList(); } delTCPreArr = DbContext.trade_cash_pre.Where(x => x.TradeId == tradeId && x.HappenedDate > removeStartDate).ToList(); } } if (trade.IsGroup == 1) { var delTCArrIds = delTCArr.Select(x => x.id).ToArray(); //如果回退到开仓日,则删除所有的group action var groupActions = DbContext.trade_cash_group_action.Where(x => x.ParentTradeId == tradeId && (delTCArrIds.Contains(x.ParentTradeCashId) || backToBegin)); if (groupActions.Any()) { DbContext.trade_cash_group_action.RemoveRange(groupActions); } } var mindate = removeStartDate; if (delTCArr.Any()) { delTCArr.ToList().ForEach(O => { O.ValidState = "InValid"; O.Status = TradeCashStatusEnum.已执行; O.OptDate = DateTime.Now; O.IsDeleted = true; }); mindate = delTCArr.Min(O => (DateTime?)O.ValueDate).GetValueOrDefault(); //如果权利金支付日在回退日期以后,则需要将权利金记录还原; if (trade.PremiumPayDate != null && trade.TradeDate != trade.PremiumPayDate && trade.PremiumPayDate >= mindate) { DbContext.trade_cash .Where(O => O.TradeId == tradeId && O.Action == ClientCashInCashOut.系统操作_期权费 && O.ValidState != "InValid" && !O.IsDeleted) .ToList().ForEach(O => { if (O.Status != TradeCashStatusEnum.冻结) { O.Comments = ""; O.OptId = UserId; O.OptDate = DateTime.Now; O.OptName = UserName; O.Status = TradeCashStatusEnum.冻结; } }); } } var codeList = DbContext.trade_contract_r.Where(O => O.TradeId == tradeId && O.Type == "交易确认书").Select(O => O.ContractCode).ToList(); foreach (var code in codeList) { var infoTag = "_" + code.Replace("_", "-") + "_" + "了结_"; var notes = from note in DbContext.sac_report_notes where note.IsValid && note.InfoTag.Contains(infoTag) && note.ReportDate >= mindate select note; foreach (var item in notes) { item.changeStatus = true; } } //DbContext.trade_cash.RemoveRange(delTCArr); var tcIds = delTCArr.Select(O => O.id).ToArray(); var predicate_detail = PredicateBuilder.Create(x => tcIds.Contains(x.TradeCashId)); //如果权利金支付日在回退日期以后,则需要将权利金记录一起删除; if (trade.PremiumPayDate != null && trade.TradeDate != trade.PremiumPayDate && trade.PremiumPayDate >= mindate) { predicate_detail = predicate_detail.Or(O => O.TradeId == tradeId && O.Action == ClientCashInCashOut.系统操作_期权费); } var tradeCashDetials = DbContext.trade_cash_detail.Where(predicate_detail); if (tradeCashDetials.Any()) { DbContext.trade_cash_detail.RemoveRange(tradeCashDetials); } if (PS.Config.SalesCommissionCalculation == "公式1") { //删除销售提成数据 var commissionInfos = DbContext.SalesCommissionDetail.Where(l => l.TradeID == tradeId && tcIds.Contains(l.TradeCashID)).ToList(); var useZero = DbContext.SalesCommissionDetail.Where(l => l.TradeID == tradeId && l.TradeCashID == 0).Any();//有tradeCashId为0的记录,则直接将有TradeCashId不为0的记录置为无效; commissionInfos.ForEach(l => { l.IsValid = false; l.TradeCashID = (!useZero && l.TradeCashID == tcIds.First()) ? 0 : -1; }); } var trade_cash_swaps = DbContext.trade_cash_swap.Where(x => tcIds.Contains(x.TradeCashId)); if (trade_cash_swaps.Any()) { if (PS.Config.IsGuoJun) { var flowid = trade_cash_swaps.Select(x => x.FlowId).ToList(); var swapflowmore = DbContext.trade_swap_flow_more.Where(x => flowid.Contains(x.id)).ToList(); swapflowmore.ForEach(x => { x.IsDelete = true; }); } DbContext.trade_cash_swap.RemoveRange(trade_cash_swaps); } if (delTCPreArr.Any()) { var tcPreIds = delTCPreArr.Select(O => O.id).ToArray(); var tradeCashDetialsPre = DbContext.trade_cash_detail.Where(x => tcPreIds.Contains(x.TradeCashPreId)); if (tradeCashDetials.Any()) { DbContext.trade_cash_detail.RemoveRange(tradeCashDetials); } var trade_cash_swapsPre = DbContext.trade_cash_swap.Where(x => tcPreIds.Contains(x.TradeCashPreId)); if (trade_cash_swaps.Any()) { DbContext.trade_cash_swap.RemoveRange(trade_cash_swaps); } DbContext.trade_cash_pre.RemoveRange(delTCPreArr); } var predicate_cashIncashOut = PredicateBuilder.Create(x => tcIds.Contains(x.TradeCashId)); //如果权利金支付日在回退日期以后,则需要将权利金记录一起删除; if (trade.PremiumPayDate != null && trade.TradeDate != trade.PremiumPayDate && trade.PremiumPayDate >= mindate) { predicate_cashIncashOut = predicate_cashIncashOut.Or(O => O.TradeId == tradeId && O.Action == ClientCashInCashOut.系统操作_期权费); } var delCashInCashOutArr = DbContext.ClientCashInCashOut.Where(predicate_cashIncashOut); DbContext.ClientCashInCashOut.RemoveRange(delCashInCashOutArr); var delContractArr = DbContext.trade_contract_r.Where(O => tcIds.Contains(O.TradeCashId ?? 0) && O.IsValid).ToList(); //DbContext.trade_contract_r.RemoveRange(delContractArr); delContractArr.ForEach(O => O.IsValid = false); if (trade.TradeType == "远期") { var forwardMargin = DbContext.eod_forward_margin .Where(x => x.TradeId == trade.id && x.ValueDate > removeStartDate); DbContext.eod_forward_margin.RemoveRange(forwardMargin); } var tradeChanges = DbContext.trade_changes.Where(O => O.RecordId == trade.id && (O.OptDate > removeStartDate || (O.ChangeType == ConsInfoChangeType.Dividend && O.OptDate >= removeStartDate))); DbContext.trade_changes.RemoveRange(tradeChanges); if (saveChanges) { DbContext.SaveChanges(); } } /// /// 移除指定交易的相关数据 /// /// 交易Id /// 删除数据开始日期 /// 指定要删除的TradeCash记录 protected void RemoveGroupEodTradeAndFutureInfo(IEnumerable tradeIds, DateTime removeStartDate, IEnumerable tradeCashIds = null) { if (removeStartDate.Year < 2000) { removeStartDate = new DateTime(2000, 1, 1); } var delEodArr = DbContext.eod_trade.Where(O => tradeIds.Contains(O.TradeId) && O.ValueDate >= removeStartDate); DbContext.eod_trade.RemoveRange(delEodArr); var delBodArr = DbContext.bod_Trade.Where(O => tradeIds.Contains(O.TradeId) && O.ValueDate > removeStartDate); DbContext.bod_Trade.RemoveRange(delBodArr); var tradeCashDetials = DbContext.trade_cash_detail.Where(x => tradeCashIds.Contains(x.TradeCashId)); if (tradeCashDetials.Any()) { DbContext.trade_cash_detail.RemoveRange(tradeCashDetials); } var trade_cash_swaps = DbContext.trade_cash_swap.Where(x => tradeCashIds.Contains(x.TradeCashId)); if (trade_cash_swaps.Any()) { DbContext.trade_cash_swap.RemoveRange(trade_cash_swaps); } var delCashInCashOutArr = DbContext.ClientCashInCashOut.Where(O => tradeCashIds.Contains(O.TradeCashId)); DbContext.ClientCashInCashOut.RemoveRange(delCashInCashOutArr); var delContractArr = DbContext.trade_contract_r.Where(O => tradeCashIds.Contains(O.TradeCashId ?? 0) && O.IsValid).ToList(); delContractArr.ForEach(O => O.IsValid = false); var tradeChanges = DbContext.trade_changes.Where(O => tradeIds.Contains(O.RecordId) && (O.OptDate > removeStartDate || (O.ChangeType == ConsInfoChangeType.Dividend && O.OptDate >= removeStartDate))); DbContext.trade_changes.RemoveRange(tradeChanges); DbContext.SaveChanges(); } /// /// 设置子交易数据到父交易, /// 这个方法在AddTradeOperationHistory和SaveTradeOperationHistory中调用, /// 除非必要才公开此方法以便调用 /// protected void SetParentTrade(OtcTradeBase subTrade, trade parent = null) { if (subTrade is null) { throw new ArgumentNullException(nameof(subTrade)); } if (parent is null) { if (subTrade.ParentTradeId == 0) { return; } parent = DbContext.trade.Find(subTrade.ParentTradeId); if (parent == null) { throw new ServiceException("结构化交易父交易不存在"); } } //分组交易单独逻辑处理 if (subTrade.IsGroup == 2 && subTrade.TradeStatus == "审批中") { parent.OptId = subTrade.OptId; parent.OptName = subTrade.OptName; parent.OptDate = subTrade.OptDate; parent.ProcessStatus = subTrade.ProcessStatus; parent.ProcessOptDate = subTrade.OptDate; parent.ProcessOrderId = subTrade.ProcessOrderId; } else { parent.OptId = subTrade.OptId; parent.OptName = subTrade.OptName; parent.OptDate = subTrade.OptDate; parent.UnderlyingCode = subTrade.UnderlyingCode; parent.UnderlyingId = subTrade.UnderlyingId; parent.TradePrice = subTrade.TradePrice; parent.TradeSinglePrice = subTrade.TradeSinglePrice; parent.UnWindNotional = subTrade.UnWindNotional; parent.Notional = subTrade.Notional; parent.TradeAmount = subTrade.TradeAmount; parent.StockEqvNotional = subTrade.StockEqvNotional; parent.StockEqvNotionalReal = subTrade.StockEqvNotionalReal; parent.OriginalNotional = subTrade.OriginalNotional; parent.OriginalStockEqvNotional = subTrade.OriginalStockEqvNotional; parent.HasPartialUnWind = subTrade.HasPartialUnWind; parent.UnWindDate = subTrade.UnWindDate; parent.ExerciseDate = subTrade.ExerciseDate; parent.ValidState = subTrade.ValidState; parent.DividendDate = subTrade.DividendDate; parent.ProcessStatus = subTrade.ProcessStatus; parent.ProcessOptDate = subTrade.OptDate; parent.ProcessOrderId = subTrade.ProcessOrderId; parent.ClientId = subTrade.ClientId; parent.ClientName = subTrade.ClientName; } if (parent.id > 0 && ConsTrade.TradeCompleteStatus.Contains(subTrade.TradeStatus)) { parent.TradeStatus = DbContext.trade .Where(n => n.ParentTradeId == parent.id && n.ValidState != "InValid" && !ConsTrade.TradeCompleteStatus.Contains(n.TradeStatus)) .Select(n => n.TradeStatus).FirstOrDefault() ?? subTrade.TradeStatus; } else { parent.TradeStatus = subTrade.TradeStatus; } if (parent.ExerciseDate < subTrade.ExerciseDate) { parent.ExerciseDate = subTrade.ExerciseDate; } } /// /// 计息方式 /// /// public string GetRateCalcMode(string rateCalcMode) { Dictionary ret = new Dictionary(); //11:算头算尾;10:算头不算尾;01:不算头算尾;00:不算头不算尾 ret.Add("算头算尾","11"); ret.Add("算头不算尾", "10"); ret.Add("不算头算尾", "01"); ret.Add("不算头不算尾", "00"); string rateCalcModeValue = "11"; ret.TryGetValue(rateCalcMode,out rateCalcModeValue); return rateCalcModeValue; } } /// /// 交易流程类别常量(需求②):对应 approvalprocess.processType 的取值。 /// public static class ProcessCategoryConst { /// 开仓审批流程 public const string Open = "TradeProcess"; /// 了结/平仓/行权审批流程 public const string Close = "CloseProcess"; /// /// 按交易状态推断流程类别:处于平仓/行权/互换待复核的交易视为「了结」类操作。 /// public static string Resolve(trade td) { if (td == null) return Open; if (td.TradeStatus == ConsTrade.平仓待复核 || td.TradeStatus == ConsTrade.行权待复核 || td.TradeStatus == ConsTrade.互换待复核) { return Close; } return Open; } } }