using System.Xml.Linq; namespace YLErp.Modules.AppModule { partial class AppInitializer { /// /// 系统升级 /// public void UpgradSystem(Version appVersion) { Task.Run(UpgradeDictionaries); var versionConfig = configService.GetData("System", "Version"); if (versionConfig == null) { versionConfig = new AppConfig { PGroup = "System", PName = "Version", PValue = "0", PType = "decimal", Remark = "系统版本", CreateTime = DateTime.Now }; configService.AddData(versionConfig); } //解析appconfig表中的程序版本 //Version.TryParse(versionConfig.PValue, out var version); //升级程序配置 UpgradeAppConfig(configService); UpgradeAppConfigV2(configService); versionConfig.PValue = appVersion.ToString(); configService.SaveChanges(); } /// /// 升级配置 /// private static void UpgradeAppConfig(InnerAppConfigService configService) { configService.AddDataIfNotExists("System", "Guid", Guid.NewGuid().ToString("N"), "string", "系统GUID"); configService.AddDataIfNotExists("System", "AdminPwd", Guid.NewGuid().ToString("N") + Guid.NewGuid().ToString("N"), "string", "系统管理密码"); //----------------------------------------------- // 1.9 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Client.CanSelectCreditVariety", "false", "bool", "默认True需要设置限制的交易品种, 如果为false,新增授信页不限制交易品种,不用显示“是否限制交易品种”选项"); configService.AddDataIfNotExists("ProjectConfig", "Client.BankOnlyDropDown", "true", "bool", "银行账户只能在下拉中选择,不可以手动输入"); configService.AddDataIfNotExists("ProjectConfig", "Client.IsCreditLimit", "false", "bool", "授信控制"); configService.AddDataIfNotExists("ProjectConfig", "Erp.AutoGenerateContracts", "true", "bool", "自动生成确认书"); configService.AddDataIfNotExists("ProjectConfig", "Erp.Company", "国泰君安", "CompanyEnum", ""); configService.AddDataIfNotExists("ProjectConfig", "Erp.CompanyAbbreviation", "GTJA", "string", "公司名称缩写"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CompanyName", "国泰君安风险管理有限公司", "string", "公司名称"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CompanyEnName", "ContryGoodBroFine", "string", "公司英文名称"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ComponentVersion", "MarketMaker", "ComponentVersion", "部署组件版本"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CompanyFullName", "国泰君安风险管理有限公司", "string", "机构完整名称"); configService.AddDataIfNotExists("ProjectConfig", "Erp.EodSendMaturityEmail", "true", "bool", "结算完成是,是否发送近期到期交易报告"); configService.AddDataIfNotExists("ProjectConfig", "Erp.IsExportEntryexit", "true", "bool", "是否导出出金单"); configService.AddDataIfNotExists("ProjectConfig", "Erp.IsPVRounded", "false", "bool", "持仓市值是否进行四舍五入处理"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ShowAccruedTotalPnL", "false", "bool", "是否展示已清仓包含累积盈亏的对冲信息"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ShowOtherClientCash", "false", "bool", "资金记录页面是否显示和客户的其他资金往来记录"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseHedgingRule", "true", "bool", "是否在风险对冲页面采用自动对冲策略"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseOldGenerateBook", "true", "bool", ""); configService.AddDataIfNotExists("ProjectConfig", "Erp.VolMode", "TradeVol", "VolModeEnum", "波动率模式,TradeVol(支持平仓开仓波动率) 和 VolSurface"); configService.AddDataIfNotExists("ProjectConfig", "Erp.RealTimeServiceNotifyRoles", "系统管理员,风控,交易员", "string", "RealTime相关信息通知的角色"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ShowRealTimeServiceNotify", "true", "bool", "是否显示RealTime相关信息通知"); configService.AddDataIfNotExists("ProjectConfig", "Erp.SupportEntryExitSimpleVersion", "false", "bool", "是否支持简洁版的出入金导入"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseSingleLogin", "false", "bool", "是否用户登录会相互排斥登录状态"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseOldEodPnLExplainer", "false", "bool", "在收盘时使用老的EodPnLExplainer方法"); configService.AddDataIfNotExists("ProjectConfig", "Erp.AtmQuotePreviousBizDayAdjust", "true", "bool", "平值期权报价,当到期日是非交易日时,是否向前移;如果false,则向后移"); configService.AddDataIfNotExists("ProjectConfig", "Trade.AmendableAfterConfirm", "True", "bool", "是否成交确认后可以修改默认false"); configService.AddDataIfNotExists("ProjectConfig", "Trade.GenerateAmendDoc", "false", "bool", "如果为true,在保存修改信息时,生成一个交易变更确认书文档并下载"); configService.AddDataIfNotExists("ProjectConfig", "Trade.SingleExecutionTemplate", "False", "bool", "美式提前行权是否和到期行权用相同的结算单模板),默认值为True"); configService.AddDataIfNotExists("ProjectConfig", "Trade.ExecuteAfterGeneratedConfirmDoc", "false", "bool", "平仓行权时是否检查确认书是否生成"); //----------------------------------------------- // 2.0 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.SkewMapVolConstruction", "false", "bool", "是否采用SkewMap的方法构造波动率,目前只有光大光子为true"); configService.AddDataIfNotExists("ProjectConfig", "Erp.PrecisionOfMinuteInQuote", "false", "bool", "在报价中,TTM是否精确到分钟级别"); configService.AddDataIfNotExists("ProjectConfig", "Erp.VolSurfaceKeyDateShift", "None", "VolSurfaceKeyDateShiftEnum", "波动率曲面上的日期节点的shift规则"); configService.AddDataIfNotExists("ProjectConfig", "Erp.VolSurfaceTermExcludeEndDate", "false", "bool", "波动率曲面的期限,是否不包含截止日期"); configService.AddDataIfNotExists("ProjectConfig", "Erp.NonInterBankMarginNetting", "true", "bool", "非同业之前计算预付金时是否有轧差"); configService.AddDataIfNotExists("ProjectConfig", "Erp.TapConsoleWebServer", "", "string", "TapConsoleWebServer"); configService.AddDataIfNotExists("ProjectConfig", "Erp.VolMoreAccurate", "false", "bool", "是否使用更加精确的波动率"); configService.AddDataIfNotExists("ProjectConfig", "Erp.HasClientSide", "false", "bool", "是否包含客户端"); configService.AddDataIfNotExists("ProjectConfig", "Erp.HasClientSign", "false", "bool", "客户端是否可以注册"); configService.AddDataIfNotExists("ProjectConfig", "Erp.TwoSideMargin", "false", "bool", "双向预付金"); configService.AddDataIfNotExists("ProjectConfig", "Erp.NeedShowSpv", "false", "bool", "是否展示计算维持预付金的Spv"); configService.AddDataIfNotExists("ProjectConfig", "Erp.PositionDetialShowMargin", "false", "bool", "结算报告是否显示持仓预付金"); //----------------------------------------------- // 2.1 //----------------------------------------------- var config = configService.GetData("ProjectConfig", "Erp.SendMailConfig"); if (config == null) { config = new AppConfig { PGroup = "ProjectConfig", PName = "Erp.SendMailConfig", PType = "text", PValue = string.Empty, Remark = "邮件发送配置(格式:&server=192.168.1.1&port=25&userName=test@test.com&password=123456&enableSsl=false|true)", CreateTime = DateTime.Now }; configService.AddData(config); } //----------------------------------------------- // 3.4 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.ClientFileAudit", "false", "bool", "客户上传文件审核是否启用"); var str = @" [{ ""Group"": ""资质核实"", ""Titles"": [""营业执照副本复印件"", ""法定代表人身份证复印件"", ""签约代理人身份证复印件(若有)""] }, { ""Group"": ""开户资料完成情况"", ""Titles"": [""投资者基本信息表(机构)"", ""回访""] }, { ""Group"": ""专业客户资料审核情况"", ""Titles"": [""协会的复函或经营金融业务许可证""] }, { ""Group"": ""客户资格审查"", ""Titles"": [""资料是否齐全"", ""资料是否合格"", ""能否参与交易""] }] "; configService.AddDataIfNotExists("ProjectConfig", "Erp.ClientFileAuditItems", str, "string", "客户上传文件审核记录"); //----------------------------------------------- // 3.6 //----------------------------------------------- str = configService.GetValue("ProjectConfig", "Erp.Company") ?? "公司"; configService.AddDataIfNotExists("ProjectConfig", "Erp.CompanyShortName", str, "string", "公司简称"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CompanyID", str, "string", "公司ID(由镒链分配)"); //----------------------------------------------- // 3.7 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.CheckPassword", "false", "bool", "是否检查密码符合监管要求"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UnderlyingBlockConfig", "&block1=&block2=&block3=&block4=&block5=", "string", "板块性质别名配置"); //----------------------------------------------- // 3.9 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.UpperTradeNumber", "true", "bool", "交易编号必须大写"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CanSetTradePremium", "false", "bool", "能否设置和导出成交溢价和了结溢价"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ExchangeOptionSettleByPrice", "false", "bool", "场内期权是否使用行情价收盘"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseStockEqvNotionalMax", "false", "bool", "多标的组合交易时使用单标的最大名义本金"); //----------------------------------------------- // 3.10 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.QdpParallelDegree", "4", "int", "Qdp计算的并行度,小于等于1时代表不并行;该数字不要超过机器的CPU核数"); //configService.AddDataIfNotExists("ProjectConfig", "Erp.CalculatePnlExplain", "false", "bool", "是否计算盈亏分解指标"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ExternalPricingServiceUrl", "", "string", "外部定价计算服务的Url地址"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ConfirmBookStampStatus", "false", "bool", "确认书用印记录"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CalcAutocallGreeksInRisk", "false", "bool", "是否在实时风险中计算凤凰和雪球的所有greeks"); configService.AddDataIfNotExists("ProjectConfig", "Erp.CanEditTradeNumber", "true", "bool", "交易编号是否允许修改"); //----------------------------------------------- // 3.11 //----------------------------------------------- configService.AddDataIfNotExists("PrivateConfig", "快速收盘", "false", "bool", "是否收盘时只结算PV"); configService.AddDataIfNotExists("ProjectConfig", "Erp.IsStockMargin", "false", "bool", "是否是权益类预付金算法"); configService.AddDataIfNotExists("ProjectConfig", "Erp.SecuritiesEnvironment", "false", "bool", "券商环境"); var data = configService.RemoveData("ProjectConfig", "OnlySettlementBoolPage"); configService.AddDataIfNotExists("ProjectConfig", "SettlementPageV2", data?.PValue ?? "false", "bool", "使用结算确认书页面"); data = configService.RemoveData("ProjectConfig", "RemotePath"); configService.AddDataIfNotExists("ProjectConfig", "SAC_RemotePath", data?.PValue ?? "", "string", "远程地址,如果是共享目录,应填ip,例:192.168.1.200;如果是ftp,应填ftp:\\\\192.168.1.200:21"); configService.AddDataIfNotExists("ProjectConfig", "SAC_RemotePath_Outbox", data?.PValue ?? "", "string", "发件箱远程登录地址,不填则使用SAC_RemotePath,如果是共享目录,应填ip,例:192.168.1.200;如果是ftp,应填ftp:\\\\192.168.1.200:21"); data = configService.RemoveData("ProjectConfig", "RemoteUser"); configService.AddDataIfNotExists("ProjectConfig", "SAC_RemoteUser", data?.PValue ?? "", "string", "登录远程地址的用户名,例:administrator"); data = configService.RemoveData("ProjectConfig", "RemotePassword"); configService.AddDataIfNotExists("ProjectConfig", "SAC_RemotePassword", data?.PValue ?? "", "string", "登录远程地址的密码,例:11"); configService.AddDataIfNotExists("ProjectConfig", "SAC_EnableSsl", data?.PValue ?? "false", "bool", "FDEP收发目录如果采用Ftp时,这里要选择FTP是否启用SSL,不确定就选false"); data = configService.RemoveData("ProjectConfig", "FDEPInboxPath"); configService.AddDataIfNotExists("ProjectConfig", "SAC_FDEPInboxPath", data?.PValue ?? "", "string", "FDEP收件箱目录,支持本地目录,内网共享目录和Ftp目录,共享路径例:\\\\192.168.1.200\\share-test\\ ;Ftp目录应填不包含根目录的相对目录例\\share-test\\ 注意:共享路径和ftp模式下,不要忘记最后的\\"); data = configService.RemoveData("ProjectConfig", "FDEPOutboxPath"); configService.AddDataIfNotExists("ProjectConfig", "SAC_FDEPOutboxPath", data?.PValue ?? "", "string", "FDEP发件箱目录,支持本地目录,内网共享目录和Ftp目录,共享路径例:\\\\192.168.1.200\\share-test\\ ;Ftp目录应填不包含根目录的相对目录例\\share-test\\ 注意:共享路径和ftp模式下,不要忘记最后的\\"); data = configService.RemoveData("ProjectConfig", "SACReportDataSource"); configService.AddDataIfNotExists("ProjectConfig", "SAC_ReportDataSource", data?.PValue ?? "3", "int", "证券业报送数据源;2=Excel模板;"); configService.AddDataIfNotExists("ProjectConfig", "SAC_FtpUsePassive", data?.PValue ?? "false", "bool", "FDEP收发目录如果采用Ftp时,这里要选择是否为被动模式,不确定就选false"); data = configService.RemoveData("ProjectConfig", "StrictAuthorize"); configService.AddDataIfNotExists("ProjectConfig", "Erp.StrictAuthorize", data?.PValue ?? "false", "bool", "严格的权限验证"); configService.AddDataIfNotExists("ProjectConfig", "Erp.DisablePasswordLogin", "false", "bool", "禁用账号密码登录,仅允许SSO"); configService.AddDataIfNotExists("ProjectConfig", "Erp.RiskAccPnl_SumExpiredExchangeTrades", data?.PValue ?? "false", "bool", "风险对冲累积总盈亏是否统计已过期的场内交易"); //----------------------------------------------- // 3.12 //----------------------------------------------- var pvalue = "出入金入金=100201012601&出入金出金=224106&借方成交入金=3101030301020101&借方成交出金=224106&贷方成交入金=3101030301020201&贷方成交出金=224106&借方期权费入金=6111060303010101&借方期权费出金=3101030301020201&贷方期权费入金=6111060303010102&贷方期权费出金=3101030301020101&借方终止费入金=224106&借方终止费出金=6111060303010102&贷方终止费入金=224106&贷方终止费出金=6111060303010101"; if (configService.GetValue("ProjectConfig", "Company") == "瑞达") { pvalue = "出入金入金=21010101&出入金出金=224101&借方成交入金=21010101&借方成交出金=224101&贷方成交入金=21010101&贷方成交出金=224101&借方期权费入金=6111&借方期权费出金=21010101&贷方期权费入金=6111&贷方期权费出金=21010101&借方终止费入金=224101&借方终止费出金=6111&贷方终止费入金=224101&贷方终止费出金=6111"; } configService.AddDataIfNotExists("ProjectConfig", "Erp.YongYouKeMuCode", pvalue, "string", "用友科目编码"); configService.AddDataIfNotExists("ProjectConfig", "Erp.TradeOpenVolOff", string.Empty, "string", "成交首日结算波动率扣除比例"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ReportMaxMonth", "12", "int", "证券业报送定期报告最大可报告月"); //----------------------------------------------- // 3.13 //----------------------------------------------- data = configService.RemoveData("ProjectConfig", "Erp.InterfaceApproval"); bool.TryParse(data?.PValue, out var temp); configService.AddDataIfNotExists("ProjectConfig", "Erp.InterfaceApprovalMode", temp ? "1" : "0", "int", "接口审批:0:不开启接口审批;1:仅使用接口审批;2:使用接口审批和系统审批(目前仅控制客户开户管理页面是否显示审批按钮)"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseSettleDataAcquisition", "false", "bool", "收盘时是否执行数据采集相关逻辑"); configService.AddDataIfNotExists("ProjectConfig", "Erp.EodVarPvPercent", "0.99", "double", "EodVar中百分比的默认值,小数点后两位小数,大于零且小于一"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UploadFileAccepts", "", "string", "文件上传允许的文件类型(多个类型用'|'分隔),样例:.xlsx|.docx"); configService.AddDataIfNotExists("ProjectConfig", "Erp.TradePricingCfg", "", "string", "交易定价要素配置(querystring格式)"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseClientStockEqvNotional", "false", "bool", "是否启用客户名义本金规模"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseClientStockEqvNotional", "false", "bool", "是否启用客户名义本金规模"); configService.AddDataIfNotExists("ProjectConfig", "Erp.SmoothingDaycountMode", "TradingDay", "SmoothingDaycountMode", "平滑过渡日历处理模式"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UnderlyingCacheCfg", "", "string", "标的资产信息缓存配置"); configService.AddDataIfNotExists("ProjectConfig", "Erp.RealtimeRisk_SkipTradeTypes", "", "string", "实时风险-跳过特定交易类型的计算"); configService.AddDataIfNotExists("ProjectConfig", "Erp.NeedIsolateSACInfo", data?.PValue ?? "false", "bool", "是否需要隔离报备信息"); configService.AddDataIfNotExists("ProjectConfig", "Erp.DisableAnonymousAccessFiles", "false", "bool", "是否禁止匿名访问文件(比如App_Docs文件夹中的文件)"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ForwardTradePriceModel", "STANDARD", "ForwardTradePriceModel", "远期交易价格模式,支持标准模式和挂钩标的模式;标的模式:标的1现价-标的2现价的差为期初价格;挂钩标的模式:挂钩标的现价+基差的和为期初价格;"); configService.AddDataIfNotExists("ProjectConfig", "Erp.UseDisplayNotional", "false", "bool", "用于控制页面展示和导出只有数量时,默认返回份额还是数量,true:份额;false:数量;默认为false,方顿为true"); configService.AddDataIfNotExists("ProjectConfig", "Erp.IsForwardTradeToBuy", "false", "bool", "产业客户累计转远期多空反向固定为多头"); configService.AddDataIfNotExists("ProjectConfig", "SAC_SubSystemOutboxPath", "", "string", "子系统发件箱目录,只支持本地系统"); configService.AddDataIfNotExists("ProjectConfig", "SAC_SubSystemInboxPath", "", "string", "子系统收件箱目录,只支持本地系统"); configService.AddDataIfNotExists("ProjectConfig", "KingstarViewConnectionString", "", "string", "金仕达视图连接字符串"); configService.AddDataIfNotExists("ProjectConfig", "KingstarViewTableSchema", "", "string", "金仕达视图Schema"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_RemotePath", "", "string", "金仕达视图附件FTP远程地址,应填ftp:\\\\192.168.1.200:21"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_RemoteUser", "", "string", "金仕达视图附件FTP远程地址的用户名,例:administrator"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_RemotePassword", "", "string", "金仕达视图附件FTP登录远程地址的密码,例:11"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_EnableSsl", "false", "bool", "金仕达视图附件FTP是否启用SSL,不确定就选false"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_FtpUsePassive", "false", "bool", "金仕达视图附件FTP连接方式是否为被动模式,不确定就选false"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_LocalViewAttDir", "", "string", "金仕达视图附件本地存放目录"); configService.AddDataIfNotExists("ProjectConfig", "KingstarView_RemoteFileRootPath", "", "string", "金仕达视图附件FTP远程文件服务器存放根路径"); configService.AddDataIfNotExists("ProjectConfig", "Erp.IsCalcRealtimeWarning", "false", "bool", "是否实时预警配置"); configService.AddDataIfNotExists("ProjectConfig", "Erp.TradeMarketReportCfg", "", "string", "结算报告配置(querystring格式)"); //----------------------------------------------- // 5.3 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.IsAutoSealAndUploadFiles", "false", "bool", "是否使用电子章系统对确认书进行用印并上传用印文件"); configService.AddDataIfNotExists("ProjectConfig", "Erp.SealApi", "", "string", "电子章用印接口地址"); configService.AddDataIfNotExists("ProjectConfig", "Erp.SealKeyWord", "", "string", "电子章用印关键字"); //----------------------------------------------- // 5.4.1 //----------------------------------------------- configService.AddDataIfNotExists("ProjectConfig", "Erp.IsAutoSealAfterGeneratedBook", "false", "bool", "确认书生成时是否自动用印(IsAutoSealAndUploadFiles勾选时生效)"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ReportFileBeginNumber", "0", "int", "报送文件开始编号"); configService.AddDataIfNotExists("ProjectConfig", "Erp.SwapFloatingIncomeReceiveOnlyMode", "false", "bool", "收益互换浮动收益端默认为我方收取,并隐藏收支方向"); RemoveUnUsed(configService); } private static void RemoveUnUsed(InnerAppConfigService configService) { configService.RemoveData("ProjectConfig", "Trade.SwapMarginTemplateConfig"); if (AppManager.Version.Major < 3) { configService.RemoveData("ProjectConfig", "Erp.TradeConfirmBookEmailTPL"); configService.RemoveData("ProjectConfig", "Erp.SettleConfirmBookEmailTPL"); configService.RemoveData("ProjectConfig", "Trade.UseTradeProject"); configService.RemoveData("ProjectConfig", "Erp.AutoCalcRisk"); configService.RemoveData("ProjectConfig", "Erp.UseRealTimeRiskCalcV2"); configService.RemoveData("ProjectConfig", "Erp.Enabl eHedgeVol"); configService.RemoveData("ProjectConfig", "Erp.UseSignalR"); } if (AppManager.Version.Major == 3) { configService.RemoveData("ProjectConfig", "Plugin.BaseDirectory"); configService.RemoveData("ProjectConfig", "Erp.SmallLogo"); configService.RemoveData("ProjectConfig", "Erp.LargeLogo"); configService.RemoveData("ProjectConfig", "Erp.ShowStructTrade"); configService.RemoveData("ProjectConfig", "Erp.CanOnlyUnWindAll"); configService.RemoveData("ProjectConfig", "Erp.IsVolMultiImport"); configService.RemoveData("ProjectConfig", "Erp.ShowBusinessLog"); configService.RemoveData("ProjectConfig", "Erp.ShowCapitalTab"); configService.RemoveData("ProjectConfig", "Erp.ShowManager"); configService.RemoveData("ProjectConfig", "Trade.ShowRecordBtnIn_PriceCalc"); configService.RemoveData("ProjectConfig", "Erp.EnableHedgeVol"); configService.RemoveData("ProjectConfig", "Erp.IsHedgingTogether"); configService.RemoveData("ProjectConfig", "Erp.HedgeTradeFromSystem"); configService.RemoveData("ProjectConfig", "Erp.IntradayRiskUseTradeVol"); configService.RemoveData("ProjectConfig", "Erp.UseVarietyVolEod"); configService.RemoveData("ProjectConfig", "Trade.EditStockEqvNotional"); var targetPath = OtcAppContext.MapPath("~/App_Docs/Images/title.png"); if (!File.Exists(targetPath)) { Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); var filePath = OtcAppContext.MapPath("~/Images/title.png"); if (File.Exists(filePath)) { File.Copy(filePath, targetPath); } } configService.RemoveData("ProjectConfig", "Erp.StructureUseColorFlag"); configService.RemoveData("ProjectConfig", "Trade.NeedSetMarginRatio"); } if (AppManager.Version.Major < 4) { configService.RemoveData("ProjectConfig", "Erp.SettlementReportCalcMode"); } configService.RemoveData("ProjectConfig", "Erp.ExternalAPIEnable"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ExternalAPIForCustomCalcEnable", "false", "bool", "是否启用外部API计算自定义交易"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ExternalAPIForCustomCalc", "", "string", "计算自定义交易的api地址,例:http://127.0.0.1/"); configService.AddDataIfNotExists("ProjectConfig", "Erp.ExternalAPIForCustomCalcTimeOut", "15", "int", "计算自定义交易超时时间(秒)"); } private static void UpgradeAppConfigV2(InnerAppConfigService configService) { var root = XElement.Parse(Properties.Resources.appconfig); var itemsAll = root.Elements().Where(a => new Version(a.Attribute("version").Value) >= AppManager.Version).SelectMany(n => n.Elements()); foreach (var item in itemsAll) { var name = item.Attribute("name")?.Value; if (string.IsNullOrWhiteSpace(name)) { continue; } var group = item.Attribute("group")?.Value.TrimToNull() ?? "ProjectConfig"; switch (item.Name.LocalName) { case "add": { var type = item.Attribute("type")?.Value ?? "string"; var remark = item.Attribute("remark")?.Value; var value = item.Value.TrimToNull() ?? item.Attribute("value")?.Value; configService.AddDataIfNotExists(pgroup: group, pname: name, pvalue: value, ptype: type, remark: remark); } break; case "remove": configService.RemoveData(group: group, name: name); break; case "update": configService.UpdateData(group: group, name: name, newRemark: item.Attribute("remark")?.Value); break; case "replace": { var type = item.Attribute("type")?.Value ?? "string"; var remark = item.Attribute("remark")?.Value; var data = configService.RemoveData(group: group, name: name); ; configService.AddDataIfNotExists(pgroup: group, pname: name, pvalue: data?.PValue, ptype: type, remark: remark); } break; } } } private static void UpgradeDictionaries() { try { using var adminDb = DbContextFactory.GetErpBaseContext(); var exists = adminDb.Dictionaries.Select(n => n.Name).ToArray() .Select(n => n.Trim()).ToHashSet(); // 记录本次新建的字典,确保初始项只写入一次,不覆盖后续人工维护结果。 var addedDictionaryNames = new HashSet(); var root = XElement.Parse(YLErp.Resources.Properties.Resources.db_dictionaries); var itemsAll = root.Elements(); foreach (var item in itemsAll) { var name = item.Attribute("name")?.Value; if (string.IsNullOrWhiteSpace(name)) { continue; } name = name.Trim(); if (exists.Contains(name)) { continue; } var catalog = item.Attribute("catalog")?.Value.TrimToEmpty(); adminDb.Dictionaries.Add(new BaseOUDAL.Dictionary { Name = name, Catalog = catalog }); addedDictionaryNames.Add(name); } adminDb.SaveChanges(); // 重点功能:解析 XML 中的初始项,仅为本次首次创建的字典生成 DictionaryItem。 foreach (var dictionaryElement in itemsAll.Where(item => item.Elements().Any() && addedDictionaryNames.Contains(item.Attribute("name")?.Value.TrimToEmpty()))) { var dictionaryName = dictionaryElement.Attribute("name")?.Value.TrimToNull(); var dictionary = adminDb.Dictionaries.FirstOrDefault(item => item.Name == dictionaryName); if (dictionary == null) { continue; } var existingItemNames = adminDb.DictionaryItems .Where(item => item.DictId == dictionary.Id) .Select(item => item.Name) .ToHashSet(); var nextDictionaryItemIndex = adminDb.DictionaryItems .Where(item => item.DictId == dictionary.Id) .Max(item => (int?)item.IndexNum) ?? -1; // XML 中的排列顺序写入 IndexNum,页面下拉按该顺序展示。 foreach (var itemElement in dictionaryElement.Elements()) { var itemName = itemElement.Attribute("name")?.Value.TrimToNull(); if (itemName == null || existingItemNames.Contains(itemName)) { continue; } adminDb.DictionaryItems.Add(new BaseOUDAL.DictionaryItem { DictId = dictionary.Id, Name = itemName, ShortName = itemElement.Attribute("short_name")?.Value.TrimToNull() ?? itemName, IndexNum = ++nextDictionaryItemIndex }); existingItemNames.Add(itemName); } } adminDb.SaveChanges(); var marginTemplateDictionary = adminDb.Dictionaries.FirstOrDefault(item => item.Name == YLErp.Modules.SwapModule.SwapMarginTemplateConfigService.DictionaryName); if (marginTemplateDictionary == null) { return; } var existingNames = adminDb.DictionaryItems .Where(item => item.DictId == marginTemplateDictionary.Id) .Select(item => item.Name) .ToHashSet(); var nextIndex = adminDb.DictionaryItems .Where(item => item.DictId == marginTemplateDictionary.Id) .Max(item => (int?)item.IndexNum) ?? -1; foreach (var templateName in YLErp.Modules.SwapModule.SwapMarginTemplateConfigService.InitialTemplateNames) { if (existingNames.Contains(templateName)) { continue; } adminDb.DictionaryItems.Add(new BaseOUDAL.DictionaryItem { DictId = marginTemplateDictionary.Id, Name = templateName, ShortName = templateName, IndexNum = ++nextIndex }); } adminDb.SaveChanges(); } catch (Exception ex) { LogFactory.GetLogger("升级字典项").Error(ex); } } } }